github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/stage1/diagnostic/elf.h (about) 1 // Copyright 2014 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 /* just enough ELF support for finding the interpreter in the program header 16 * table, this should theoretically work as-is on both big-endian and 17 * little-endian 18 */ 19 20 /* values of interest */ 21 #define ELF_BITS_32 0x1 22 #define ELF_BITS_64 0x2 23 #define ELF_ENDIAN_LITL 0x1 24 #define ELF_ENDIAN_BIG 0x2 25 #define ELF_PT_INTERP 0x3 26 27 /* offsets of interest */ 28 #define ELF_BITS 0x4 29 #define ELF_ENDIAN 0x5 30 #define ELF_VERSION 0x6 31 #define ELF32_PHT_OFF 0x1c 32 #define ELF32_PHTE_SIZE 0x2a 33 #define ELF32_PHTE_CNT 0x2c 34 #define ELF32_PHE_OFF 0x4 35 #define ELF32_PHE_SIZE 0x10 36 #define ELF64_PHT_OFF 0x20 37 #define ELF64_PHTE_SIZE 0x36 38 #define ELF64_PHTE_CNT 0x38 39 #define ELF64_PHE_OFF 0x8 40 #define ELF64_PHE_SIZE 0x20 41 42 /* multibyte value accessors, choose which based on ELF_BITS and ELF_ENDIAN */ 43 44 #define SHIFT(_val, _bytes) ((unsigned long long)(_val) << ((_bytes) * 8)) 45 static uint64_t le32_lget(const uint8_t *addr) 46 { 47 uint64_t val = 0; 48 val += SHIFT(addr[3], 3); 49 val += SHIFT(addr[2], 2); 50 val += SHIFT(addr[1], 1); 51 val += SHIFT(addr[0], 0); 52 return val; 53 } 54 static uint64_t be32_lget(const uint8_t *addr) 55 { 56 uint64_t val = 0; 57 val += SHIFT(addr[0], 3); 58 val += SHIFT(addr[1], 2); 59 val += SHIFT(addr[2], 1); 60 val += SHIFT(addr[3], 0); 61 return val; 62 } 63 64 static uint64_t le64_lget(const uint8_t *addr) 65 { 66 uint64_t val = 0; 67 val += SHIFT(addr[7], 7); 68 val += SHIFT(addr[6], 6); 69 val += SHIFT(addr[5], 5); 70 val += SHIFT(addr[4], 4); 71 val += SHIFT(addr[3], 3); 72 val += SHIFT(addr[2], 2); 73 val += SHIFT(addr[1], 1); 74 val += SHIFT(addr[0], 0); 75 return val; 76 } 77 static uint64_t be64_lget(const uint8_t *addr) 78 { 79 uint64_t val = 0; 80 val += SHIFT(addr[0], 7); 81 val += SHIFT(addr[1], 6); 82 val += SHIFT(addr[2], 5); 83 val += SHIFT(addr[3], 4); 84 val += SHIFT(addr[4], 3); 85 val += SHIFT(addr[5], 2); 86 val += SHIFT(addr[6], 1); 87 val += SHIFT(addr[7], 0); 88 return val; 89 } 90 static uint32_t le_iget(const uint8_t *addr) 91 { 92 return (uint32_t)le32_lget(addr); 93 } 94 static uint32_t be_iget(const uint8_t *addr) 95 { 96 return (uint32_t)be32_lget(addr); 97 } 98 static uint16_t le_sget(const uint8_t *addr) 99 { 100 uint16_t val = 0; 101 val += SHIFT(addr[1], 1); 102 val += SHIFT(addr[0], 0); 103 return val; 104 } 105 static uint16_t be_sget(const uint8_t *addr) 106 { 107 uint16_t val = 0; 108 val += SHIFT(addr[0], 0); 109 val += SHIFT(addr[1], 1); 110 return val; 111 }