150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray/*
250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray *
450cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * you may not use this file except in compliance with the License.
650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * You may obtain a copy of the License at
750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray *
850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray *
1050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * Unless required by applicable law or agreed to in writing, software
1150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
1250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * See the License for the specific language governing permissions and
1450cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray * limitations under the License.
1550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray */
1650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
1750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#ifndef ART_RUNTIME_ELF_UTILS_H_
1850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define ART_RUNTIME_ELF_UTILS_H_
1950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
208758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom#include <sys/cdefs.h>
218758c64a40e74ebb492a348556ec7b25a89c1491Brian Carlstrom
22e130ee6fe902315062ce17f8ce115b1dc506576dBrian Carlstrom// Explicitly include our own elf.h to avoid Linux and other dependencies.
23e130ee6fe902315062ce17f8ce115b1dc506576dBrian Carlstrom#include "./elf.h"
2450cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
2553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "base/logging.h"
2653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
27c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogersnamespace art {
28c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers
2950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray// Architecture dependent flags for the ELF header.
3050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EF_ARM_EABI_VER5 0x05000000
3150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EF_MIPS_ABI_O32 0x00001000
3250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EF_MIPS_ARCH_32R2 0x70000000
33c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe#define EF_MIPS_ARCH_32R6 0x90000000
3457b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe#define EF_MIPS_ARCH_64R6 0xa0000000
3550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
3650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EI_ABIVERSION 8
3750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EM_ARM 40
3850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EF_MIPS_NOREORDER 1
3950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EF_MIPS_PIC 2
4050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define EF_MIPS_CPIC 4
4150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define STV_DEFAULT 0
4250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
43b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith#define EM_AARCH64 183
44b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith
4550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_BIND_NOW 24
4650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_INIT_ARRAY 25
4750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_FINI_ARRAY 26
4850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_INIT_ARRAYSZ 27
4950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_FINI_ARRAYSZ 28
5050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_RUNPATH 29
5150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_FLAGS 30
5250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
5350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray/* MIPS dependent d_tag field for Elf32_Dyn.  */
5450cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime Linker Interface ID */
5550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
5650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_ICHECKSUM    0x70000003 /* Cksum of ext. str. and com. sizes */
5750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
5850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_FLAGS        0x70000005 /* Flags */
5950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */
6050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_CONFLICT     0x70000008 /* Adr of .conflict section */
6150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_LIBLIST      0x70000009 /* Address of .liblist section */
6250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local .GOT entries */
6350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_CONFLICTNO   0x7000000b /* Number of .conflict entries */
6450cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_LIBLISTNO    0x70000010 /* Number of .liblist entries */
6550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_SYMTABNO     0x70000011 /* Number of .dynsym entries */
6650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
6750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in .dynsym */
6850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
6950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#define DT_MIPS_RLD_MAP      0x70000016 /* Address of debug map pointer */
7050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
7153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light// Patching section type
7253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#define SHT_OAT_PATCH        SHT_LOUSER
7353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
74d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogersstatic inline void SetBindingAndType(Elf32_Sym* sym, unsigned char b, unsigned char t) {
7550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray  sym->st_info = (b << 4) + (t & 0x0f);
7650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray}
7750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray
78d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogersstatic inline bool IsDynamicSectionPointer(Elf32_Word d_tag, Elf32_Word e_machine) {
7953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  switch (d_tag) {
8053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // case 1: well known d_tag values that imply Elf32_Dyn.d_un contains an address in d_ptr
8153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_PLTGOT:
8253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_HASH:
8353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_STRTAB:
8453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_SYMTAB:
8553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RELA:
8653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_INIT:
8753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_FINI:
8853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_REL:
8953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_DEBUG:
9053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_JMPREL: {
9153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return true;
9253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
9353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // d_val or ignored values
9453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_NULL:
9553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_NEEDED:
9653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_PLTRELSZ:
9753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RELASZ:
9853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RELAENT:
9953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_STRSZ:
10053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_SYMENT:
10153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_SONAME:
10253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RPATH:
10353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_SYMBOLIC:
10453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RELSZ:
10553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RELENT:
10653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_PLTREL:
10753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_TEXTREL:
10853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_BIND_NOW:
10953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_INIT_ARRAYSZ:
11053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_FINI_ARRAYSZ:
11153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_RUNPATH:
11253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_FLAGS: {
11353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
11453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
11553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // boundary values that should not be used
11653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_ENCODING:
11753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_LOOS:
11853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_HIOS:
11953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_LOPROC:
12053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case DT_HIPROC: {
12153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(FATAL) << "Illegal d_tag value 0x" << std::hex << d_tag;
12253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
12353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
12453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    default: {
12553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      // case 2: "regular" DT_* ranges where even d_tag values imply an address in d_ptr
12653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if ((DT_ENCODING  < d_tag && d_tag < DT_LOOS)
12753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light          || (DT_LOOS   < d_tag && d_tag < DT_HIOS)
12853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light          || (DT_LOPROC < d_tag && d_tag < DT_HIPROC)) {
12953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        // Special case for MIPS which breaks the regular rules between DT_LOPROC and DT_HIPROC
13053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        if (e_machine == EM_MIPS) {
13153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light          switch (d_tag) {
13253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_RLD_VERSION:
13353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_TIME_STAMP:
13453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_ICHECKSUM:
13553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_IVERSION:
13653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_FLAGS:
13753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_LOCAL_GOTNO:
13853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_CONFLICTNO:
13953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_LIBLISTNO:
14053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_SYMTABNO:
14153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_UNREFEXTNO:
14253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_GOTSYM:
14353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_HIPAGENO: {
14453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              return false;
14553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            }
14653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_BASE_ADDRESS:
14753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_CONFLICT:
14853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_LIBLIST:
14953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            case DT_MIPS_RLD_MAP: {
15053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              return true;
15153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            }
15253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            default: {
15353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              LOG(FATAL) << "Unknown MIPS d_tag value 0x" << std::hex << d_tag;
15453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              return false;
15553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            }
15653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light          }
15753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        } else if ((d_tag % 2) == 0) {
15853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light          return true;
15953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        } else {
16053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light          return false;
16153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        }
16253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else {
16353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        LOG(FATAL) << "Unknown d_tag value 0x" << std::hex << d_tag;
16453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        return false;
16553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
16653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
16753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
16853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
16953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
170c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers}  // namespace art
171c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers
17250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#endif  // ART_RUNTIME_ELF_UTILS_H_
173