1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include <elf.h>
32 #include <link.h>
33 
34 #include "linker_soinfo.h"
35 
36 // The Elf* structures below are derived from the document
37 // Linux Extensions to gABI (https://github.com/hjl-tools/linux-abi/wiki).
38 // Essentially, these types would be defined in <elf.h>, but this is not
39 // the case at the moment.
40 
41 struct Elf32_Prop {
42   Elf32_Word pr_type;
43   Elf32_Word pr_datasz;
44   char pr_data[0];
45 };
46 
47 // On 32-bit machines this should be 4-byte aligned.
48 struct Elf32_NhdrGNUProperty {
49   Elf32_Nhdr nhdr;
50   char n_name[4];
51   char n_desc[0];
52 };
53 
54 struct Elf64_Prop {
55   Elf64_Word pr_type;
56   Elf64_Word pr_datasz;
57   char pr_data[0];
58 };
59 
60 // On 64-bit machines this should be 8-byte aligned.
61 struct Elf64_NhdrGNUProperty {
62   Elf64_Nhdr nhdr;
63   char n_name[4];
64   char n_desc[0];
65 };
66 
67 struct ElfProgramProperty {
68 #if defined(__aarch64__)
69   bool bti_compatible = false;
70 #endif
71 };
72 
73 // Representation of the .note.gnu.property section found in the segment
74 // with p_type = PT_GNU_PROPERTY.
75 class GnuPropertySection {
76  public:
GnuPropertySection()77   GnuPropertySection(){};
78   explicit GnuPropertySection(const soinfo* si);
79   GnuPropertySection(const ElfW(Phdr)* phdr, size_t phdr_count, const ElfW(Addr) load_bias,
80                      const char* name);
81 
82 #if defined(__aarch64__)
83   bool IsBTICompatible() const;
84 #endif
85 
86  private:
87   const ElfW(NhdrGNUProperty)* FindSegment(const ElfW(Phdr)* phdr, size_t phdr_count,
88                                            const ElfW(Addr) load_bias, const char* name) const;
89   bool SanityCheck(const ElfW(NhdrGNUProperty)* note_nhdr, const char* name) const;
90   bool Parse(const ElfW(NhdrGNUProperty)* note_nhdr, const char* name);
91 
92   ElfProgramProperty properties_ __unused;
93 };
94