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