1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_LIBELFFILE_ELF_ELF_UTILS_H_ 18 #define ART_LIBELFFILE_ELF_ELF_UTILS_H_ 19 20 #include <elf.h> 21 22 #include <sys/cdefs.h> 23 24 #include <android-base/logging.h> 25 26 namespace art { 27 28 struct ElfTypes32 { 29 typedef Elf32_Addr Addr; 30 typedef Elf32_Off Off; 31 typedef Elf32_Half Half; 32 typedef Elf32_Word Word; 33 typedef Elf32_Sword Sword; 34 typedef Elf32_Ehdr Ehdr; 35 typedef Elf32_Shdr Shdr; 36 typedef Elf32_Sym Sym; 37 typedef Elf32_Rel Rel; 38 typedef Elf32_Rela Rela; 39 typedef Elf32_Phdr Phdr; 40 typedef Elf32_Dyn Dyn; 41 }; 42 43 struct ElfTypes64 { 44 typedef Elf64_Addr Addr; 45 typedef Elf64_Off Off; 46 typedef Elf64_Half Half; 47 typedef Elf64_Word Word; 48 typedef Elf64_Sword Sword; 49 typedef Elf64_Xword Xword; 50 typedef Elf64_Sxword Sxword; 51 typedef Elf64_Ehdr Ehdr; 52 typedef Elf64_Shdr Shdr; 53 typedef Elf64_Sym Sym; 54 typedef Elf64_Rel Rel; 55 typedef Elf64_Rela Rela; 56 typedef Elf64_Phdr Phdr; 57 typedef Elf64_Dyn Dyn; 58 }; 59 60 #define ELF_ST_BIND(x) ((x) >> 4) 61 #define ELF_ST_TYPE(x) ((x) & 0xf) 62 63 // Architecture dependent flags for the ELF header. 64 #define EF_ARM_EABI_VER5 0x05000000 65 #define EF_MIPS_ABI_O32 0x00001000 66 #define EF_MIPS_ARCH_32R2 0x70000000 67 #define EF_MIPS_ARCH_32R6 0x90000000 68 #define EF_MIPS_ARCH_64R6 0xa0000000 69 70 #define EI_ABIVERSION 8 71 #define EM_ARM 40 72 #define EF_MIPS_NOREORDER 1 73 #define STV_DEFAULT 0 74 75 #define EM_AARCH64 183 76 77 #define DT_BIND_NOW 24 78 #define DT_INIT_ARRAY 25 79 #define DT_FINI_ARRAY 26 80 #define DT_INIT_ARRAYSZ 27 81 #define DT_FINI_ARRAYSZ 28 82 #define DT_RUNPATH 29 83 #define DT_FLAGS 30 84 85 /* MIPS dependent d_tag field for Elf32_Dyn. */ 86 #define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime Linker Interface ID */ 87 #define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ 88 #define DT_MIPS_ICHECKSUM 0x70000003 /* Cksum of ext. str. and com. sizes */ 89 #define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ 90 #define DT_MIPS_FLAGS 0x70000005 /* Flags */ 91 #define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */ 92 #define DT_MIPS_CONFLICT 0x70000008 /* Adr of .conflict section */ 93 #define DT_MIPS_LIBLIST 0x70000009 /* Address of .liblist section */ 94 #define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local .GOT entries */ 95 #define DT_MIPS_CONFLICTNO 0x7000000b /* Number of .conflict entries */ 96 #define DT_MIPS_LIBLISTNO 0x70000010 /* Number of .liblist entries */ 97 #define DT_MIPS_SYMTABNO 0x70000011 /* Number of .dynsym entries */ 98 #define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ 99 #define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in .dynsym */ 100 #define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ 101 #define DT_MIPS_RLD_MAP 0x70000016 /* Address of debug map pointer */ 102 103 // Patching section type 104 #define SHT_OAT_PATCH SHT_LOUSER 105 106 static inline void SetBindingAndType(Elf32_Sym* sym, unsigned char b, unsigned char t) { 107 sym->st_info = (b << 4) + (t & 0x0f); 108 } 109 110 static inline bool IsDynamicSectionPointer(Elf32_Word d_tag, Elf32_Word e_machine) { 111 switch (d_tag) { 112 // case 1: well known d_tag values that imply Elf32_Dyn.d_un contains an address in d_ptr 113 case DT_PLTGOT: 114 case DT_HASH: 115 case DT_STRTAB: 116 case DT_SYMTAB: 117 case DT_RELA: 118 case DT_INIT: 119 case DT_FINI: 120 case DT_REL: 121 case DT_DEBUG: 122 case DT_JMPREL: { 123 return true; 124 } 125 // d_val or ignored values 126 case DT_NULL: 127 case DT_NEEDED: 128 case DT_PLTRELSZ: 129 case DT_RELASZ: 130 case DT_RELAENT: 131 case DT_STRSZ: 132 case DT_SYMENT: 133 case DT_SONAME: 134 case DT_RPATH: 135 case DT_SYMBOLIC: 136 case DT_RELSZ: 137 case DT_RELENT: 138 case DT_PLTREL: 139 case DT_TEXTREL: 140 case DT_BIND_NOW: 141 case DT_INIT_ARRAYSZ: 142 case DT_FINI_ARRAYSZ: 143 case DT_RUNPATH: 144 case DT_FLAGS: { 145 return false; 146 } 147 // boundary values that should not be used 148 case DT_ENCODING: 149 case DT_LOOS: 150 case DT_HIOS: 151 case DT_LOPROC: 152 case DT_HIPROC: { 153 LOG(FATAL) << "Illegal d_tag value 0x" << std::hex << d_tag; 154 return false; 155 } 156 default: { 157 // case 2: "regular" DT_* ranges where even d_tag values imply an address in d_ptr 158 if ((DT_ENCODING < d_tag && d_tag < DT_LOOS) 159 || (DT_LOOS < d_tag && d_tag < DT_HIOS) 160 || (DT_LOPROC < d_tag && d_tag < DT_HIPROC)) { 161 // Special case for MIPS which breaks the regular rules between DT_LOPROC and DT_HIPROC 162 if (e_machine == EM_MIPS) { 163 switch (d_tag) { 164 case DT_MIPS_RLD_VERSION: 165 case DT_MIPS_TIME_STAMP: 166 case DT_MIPS_ICHECKSUM: 167 case DT_MIPS_IVERSION: 168 case DT_MIPS_FLAGS: 169 case DT_MIPS_LOCAL_GOTNO: 170 case DT_MIPS_CONFLICTNO: 171 case DT_MIPS_LIBLISTNO: 172 case DT_MIPS_SYMTABNO: 173 case DT_MIPS_UNREFEXTNO: 174 case DT_MIPS_GOTSYM: 175 case DT_MIPS_HIPAGENO: { 176 return false; 177 } 178 case DT_MIPS_BASE_ADDRESS: 179 case DT_MIPS_CONFLICT: 180 case DT_MIPS_LIBLIST: 181 case DT_MIPS_RLD_MAP: { 182 return true; 183 } 184 default: { 185 LOG(FATAL) << "Unknown MIPS d_tag value 0x" << std::hex << d_tag; 186 return false; 187 } 188 } 189 } else if ((d_tag % 2) == 0) { 190 return true; 191 } else { 192 return false; 193 } 194 } else { 195 LOG(FATAL) << "Unknown d_tag value 0x" << std::hex << d_tag; 196 return false; 197 } 198 } 199 } 200 } 201 202 } // namespace art 203 204 #endif // ART_LIBELFFILE_ELF_ELF_UTILS_H_ 205