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  }