Home | History | Annotate | Download | only in elf
      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