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_RUNTIME_ELF_UTILS_H_ 18 #define ART_RUNTIME_ELF_UTILS_H_ 19 20 #include <sys/cdefs.h> 21 22 // Explicitly include our own elf.h to avoid Linux and other dependencies. 23 #include "./elf.h" 24 25 #include "base/logging.h" 26 27 namespace art { 28 29 // Architecture dependent flags for the ELF header. 30 #define EF_ARM_EABI_VER5 0x05000000 31 #define EF_MIPS_ABI_O32 0x00001000 32 #define EF_MIPS_ARCH_32R2 0x70000000 33 #define EF_MIPS_ARCH_32R6 0x90000000 34 #define EF_MIPS_ARCH_64R6 0xa0000000 35 36 #define EI_ABIVERSION 8 37 #define EM_ARM 40 38 #define EF_MIPS_NOREORDER 1 39 #define EF_MIPS_PIC 2 40 #define EF_MIPS_CPIC 4 41 #define STV_DEFAULT 0 42 43 #define EM_AARCH64 183 44 45 #define DT_BIND_NOW 24 46 #define DT_INIT_ARRAY 25 47 #define DT_FINI_ARRAY 26 48 #define DT_INIT_ARRAYSZ 27 49 #define DT_FINI_ARRAYSZ 28 50 #define DT_RUNPATH 29 51 #define DT_FLAGS 30 52 53 /* MIPS dependent d_tag field for Elf32_Dyn. */ 54 #define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime Linker Interface ID */ 55 #define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ 56 #define DT_MIPS_ICHECKSUM 0x70000003 /* Cksum of ext. str. and com. sizes */ 57 #define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ 58 #define DT_MIPS_FLAGS 0x70000005 /* Flags */ 59 #define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */ 60 #define DT_MIPS_CONFLICT 0x70000008 /* Adr of .conflict section */ 61 #define DT_MIPS_LIBLIST 0x70000009 /* Address of .liblist section */ 62 #define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local .GOT entries */ 63 #define DT_MIPS_CONFLICTNO 0x7000000b /* Number of .conflict entries */ 64 #define DT_MIPS_LIBLISTNO 0x70000010 /* Number of .liblist entries */ 65 #define DT_MIPS_SYMTABNO 0x70000011 /* Number of .dynsym entries */ 66 #define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ 67 #define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in .dynsym */ 68 #define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ 69 #define DT_MIPS_RLD_MAP 0x70000016 /* Address of debug map pointer */ 70 71 // Patching section type 72 #define SHT_OAT_PATCH SHT_LOUSER 73 74 static inline void SetBindingAndType(Elf32_Sym* sym, unsigned char b, unsigned char t) { 75 sym->st_info = (b << 4) + (t & 0x0f); 76 } 77 78 static inline bool IsDynamicSectionPointer(Elf32_Word d_tag, Elf32_Word e_machine) { 79 switch (d_tag) { 80 // case 1: well known d_tag values that imply Elf32_Dyn.d_un contains an address in d_ptr 81 case DT_PLTGOT: 82 case DT_HASH: 83 case DT_STRTAB: 84 case DT_SYMTAB: 85 case DT_RELA: 86 case DT_INIT: 87 case DT_FINI: 88 case DT_REL: 89 case DT_DEBUG: 90 case DT_JMPREL: { 91 return true; 92 } 93 // d_val or ignored values 94 case DT_NULL: 95 case DT_NEEDED: 96 case DT_PLTRELSZ: 97 case DT_RELASZ: 98 case DT_RELAENT: 99 case DT_STRSZ: 100 case DT_SYMENT: 101 case DT_SONAME: 102 case DT_RPATH: 103 case DT_SYMBOLIC: 104 case DT_RELSZ: 105 case DT_RELENT: 106 case DT_PLTREL: 107 case DT_TEXTREL: 108 case DT_BIND_NOW: 109 case DT_INIT_ARRAYSZ: 110 case DT_FINI_ARRAYSZ: 111 case DT_RUNPATH: 112 case DT_FLAGS: { 113 return false; 114 } 115 // boundary values that should not be used 116 case DT_ENCODING: 117 case DT_LOOS: 118 case DT_HIOS: 119 case DT_LOPROC: 120 case DT_HIPROC: { 121 LOG(FATAL) << "Illegal d_tag value 0x" << std::hex << d_tag; 122 return false; 123 } 124 default: { 125 // case 2: "regular" DT_* ranges where even d_tag values imply an address in d_ptr 126 if ((DT_ENCODING < d_tag && d_tag < DT_LOOS) 127 || (DT_LOOS < d_tag && d_tag < DT_HIOS) 128 || (DT_LOPROC < d_tag && d_tag < DT_HIPROC)) { 129 // Special case for MIPS which breaks the regular rules between DT_LOPROC and DT_HIPROC 130 if (e_machine == EM_MIPS) { 131 switch (d_tag) { 132 case DT_MIPS_RLD_VERSION: 133 case DT_MIPS_TIME_STAMP: 134 case DT_MIPS_ICHECKSUM: 135 case DT_MIPS_IVERSION: 136 case DT_MIPS_FLAGS: 137 case DT_MIPS_LOCAL_GOTNO: 138 case DT_MIPS_CONFLICTNO: 139 case DT_MIPS_LIBLISTNO: 140 case DT_MIPS_SYMTABNO: 141 case DT_MIPS_UNREFEXTNO: 142 case DT_MIPS_GOTSYM: 143 case DT_MIPS_HIPAGENO: { 144 return false; 145 } 146 case DT_MIPS_BASE_ADDRESS: 147 case DT_MIPS_CONFLICT: 148 case DT_MIPS_LIBLIST: 149 case DT_MIPS_RLD_MAP: { 150 return true; 151 } 152 default: { 153 LOG(FATAL) << "Unknown MIPS d_tag value 0x" << std::hex << d_tag; 154 return false; 155 } 156 } 157 } else if ((d_tag % 2) == 0) { 158 return true; 159 } else { 160 return false; 161 } 162 } else { 163 LOG(FATAL) << "Unknown d_tag value 0x" << std::hex << d_tag; 164 return false; 165 } 166 } 167 } 168 } 169 170 } // namespace art 171 172 #endif // ART_RUNTIME_ELF_UTILS_H_ 173