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