LCOV - code coverage report
Current view: top level - vppinfra - elf.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 44 51 86.3 %
Date: 2023-07-05 22:20:52 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Cisco and/or its affiliates.
       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             : /*
      16             :   Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
      17             : 
      18             :   Permission is hereby granted, free of charge, to any person obtaining
      19             :   a copy of this software and associated documentation files (the
      20             :   "Software"), to deal in the Software without restriction, including
      21             :   without limitation the rights to use, copy, modify, merge, publish,
      22             :   distribute, sublicense, and/or sell copies of the Software, and to
      23             :   permit persons to whom the Software is furnished to do so, subject to
      24             :   the following conditions:
      25             : 
      26             :   The above copyright notice and this permission notice shall be
      27             :   included in all copies or substantial portions of the Software.
      28             : 
      29             :   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      30             :   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      31             :   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      32             :   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      33             :   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      34             :   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      35             :   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      36             : */
      37             : 
      38             : #ifndef included_clib_elf_h
      39             : #define included_clib_elf_h
      40             : 
      41             : #include <vppinfra/format.h>
      42             : #include <vppinfra/hash.h>
      43             : #include <vppinfra/vec.h>
      44             : #include <vppinfra/byte_order.h>
      45             : 
      46             : #define foreach_elf_file_class \
      47             :   _ (CLASS_NONE) _ (32BIT) _ (64BIT)
      48             : 
      49             : #define foreach_elf_data_encoding               \
      50             :   _ (ENCODING_NONE)                             \
      51             :   _ (TWOS_COMPLEMENT_LITTLE_ENDIAN)             \
      52             :   _ (TWOS_COMPLEMENT_BIG_ENDIAN)
      53             : 
      54             : #define ELF_VERSION_NONE (0)
      55             : #define ELF_VERSION_CURRENT (1)
      56             : 
      57             : #define foreach_elf_abi                         \
      58             :   _ (SYSV, 0)                                   \
      59             :   _ (HPUX, 1)                                   \
      60             :   _ (NETBSD, 2)                                 \
      61             :   _ (LINUX, 3)                                  \
      62             :   _ (SOLARIS, 6)                                \
      63             :   _ (AIX, 7)                                    \
      64             :   _ (IRIX, 8)                                   \
      65             :   _ (FREEBSD, 9)                                \
      66             :   _ (COMPAQ_TRU64, 10)                          \
      67             :   _ (MODESTO, 11)                               \
      68             :   _ (OPENBSD, 12)                               \
      69             :   _ (ARM, 97)                                   \
      70             :   _ (STANDALONE, 255)
      71             : 
      72             : /* Legal values for type (object file type).  */
      73             : #define foreach_elf_file_type                   \
      74             :   _ (NONE, 0)                                   \
      75             :   _ (RELOC, 1)                                  \
      76             :   _ (EXEC, 2)                                   \
      77             :   _ (SHARED, 3)                                 \
      78             :   _ (CORE, 4)                                   \
      79             :   _ (OS_SPECIFIC_LO, 0xfe00)                    \
      80             :   _ (OS_SPECIFIC_HI, 0xfeff)                    \
      81             :   _ (ARCH_SPECIFIC_LO, 0xff00)                  \
      82             :   _ (ARCH_SPECIFIC_HI, 0xffff)
      83             : 
      84             : /* Legal values for architecture.  */
      85             : #define foreach_elf_architecture                                        \
      86             :   _ (NONE, 0)                   /* No machine */                        \
      87             :   _ (M32, 1)                    /* AT&T WE 32100 */                 \
      88             :   _ (SPARC, 2)                  /* SUN SPARC */                         \
      89             :   _ (386, 3)                    /* Intel 80386 */                       \
      90             :   _ (68K, 4)                    /* Motorola m68k family */              \
      91             :   _ (88K, 5)                    /* Motorola m88k family */              \
      92             :   _ (860, 7)                    /* Intel 80860 */                       \
      93             :   _ (MIPS, 8)                   /* MIPS R3000 big-endian */             \
      94             :   _ (S370, 9)                   /* IBM System/370 */                    \
      95             :   _ (MIPS_RS3_LE, 10)           /* MIPS R3000 little-endian */          \
      96             :   _ (PARISC, 15)                /* HPPA */                              \
      97             :   _ (VPP500, 17)                /* Fujitsu VPP500 */                    \
      98             :   _ (SPARC32PLUS, 18)           /* Sun's "v8plus" */                  \
      99             :   _ (960, 19)                   /* Intel 80960 */                       \
     100             :   _ (PPC, 20)                   /* PowerPC */                           \
     101             :   _ (PPC64, 21)                 /* PowerPC 64-bit */                    \
     102             :   _ (S390, 22)                  /* IBM S390 */                          \
     103             :   _ (V800, 36)                  /* NEC V800 series */                   \
     104             :   _ (FR20, 37)                  /* Fujitsu FR20 */                      \
     105             :   _ (RH32, 38)                  /* TRW RH-32 */                         \
     106             :   _ (RCE, 39)                   /* Motorola RCE */                      \
     107             :   _ (ARM, 40)                   /* ARM */                               \
     108             :   _ (FAKE_ALPHA, 41)            /* Digital Alpha */                     \
     109             :   _ (SH, 42)                    /* Hitachi SH */                        \
     110             :   _ (SPARCV9, 43)               /* SPARC v9 64-bit */                   \
     111             :   _ (TRICORE, 44)               /* Siemens Tricore */                   \
     112             :   _ (ARC, 45)                   /* Argonaut RISC Core */                \
     113             :   _ (H8_300, 46)                /* Hitachi H8/300 */                    \
     114             :   _ (H8_300H, 47)               /* Hitachi H8/300H */                   \
     115             :   _ (H8S, 48)                   /* Hitachi H8S */                       \
     116             :   _ (H8_500, 49)                /* Hitachi H8/500 */                    \
     117             :   _ (IA_64, 50)                 /* Intel Merced */                      \
     118             :   _ (MIPS_X, 51)                /* Stanford MIPS-X */                   \
     119             :   _ (COLDFIRE, 52)              /* Motorola Coldfire */                 \
     120             :   _ (68HC12, 53)                /* Motorola M68HC12 */                  \
     121             :   _ (MMA, 54)                   /* Fujitsu MMA Multimedia Accel. */     \
     122             :   _ (PCP, 55)                   /* Siemens PCP */                       \
     123             :   _ (NCPU, 56)                  /* Sony nCPU embedded RISC */           \
     124             :   _ (NDR1, 57)                  /* Denso NDR1 microprocessor */         \
     125             :   _ (STARCORE, 58)              /* Motorola Start*Core processor */     \
     126             :   _ (ME16, 59)                  /* Toyota ME16 processor */             \
     127             :   _ (ST100, 60)                 /* STMicroelectronic ST100  */          \
     128             :   _ (TINYJ, 61)                 /* Advanced Logic Corp. Tinyj */        \
     129             :   _ (X86_64, 62)                /* AMD x86-64 architecture */           \
     130             :   _ (PDSP, 63)                  /* Sony DSP Processor */                \
     131             :   _ (FX66, 66)                  /* Siemens FX66 microcontroller */      \
     132             :   _ (ST9PLUS, 67)               /* STMicroelectronics ST9+ 8/16 mc */   \
     133             :   _ (ST7, 68)                   /* STmicroelectronics ST7 8 bit mc */   \
     134             :   _ (68HC16, 69)                /* Motorola MC68HC16 */                 \
     135             :   _ (68HC11, 70)                /* Motorola MC68HC11 */                 \
     136             :   _ (68HC08, 71)                /* Motorola MC68HC08 */                 \
     137             :   _ (68HC05, 72)                /* Motorola MC68HC05 */                 \
     138             :   _ (SVX, 73)                   /* Silicon Graphics SVx */              \
     139             :   _ (ST19, 74)                  /* STMicroelectronics ST19 8 bit mc */  \
     140             :   _ (VAX, 75)                   /* Digital VAX */                       \
     141             :   _ (CRIS, 76)                  /* Axis 32-bit embedded proc. */        \
     142             :   _ (JAVELIN, 77)               /* Infineon 32-bit embedded proc. */    \
     143             :   _ (FIREPATH, 78)              /* Element 14 64-bit DSP Processor */   \
     144             :   _ (ZSP, 79)                   /* LSI Logic 16-bit DSP Processor */    \
     145             :   _ (MMIX, 80)                  /* Knuth's 64-bit processor */          \
     146             :   _ (HUANY, 81)                 /* Harvard machine-independent */       \
     147             :   _ (PRISM, 82)                 /* SiTera Prism */                      \
     148             :   _ (AVR, 83)                   /* Atmel AVR 8-bit microcontroller */   \
     149             :   _ (FR30, 84)                  /* Fujitsu FR30 */                      \
     150             :   _ (D10V, 85)                  /* Mitsubishi D10V */                   \
     151             :   _ (D30V, 86)                  /* Mitsubishi D30V */                   \
     152             :   _ (V850, 87)                  /* NEC v850 */                          \
     153             :   _ (M32R, 88)                  /* Mitsubishi M32R */                   \
     154             :   _ (MN10300, 89)               /* Matsushita MN10300 */                \
     155             :   _ (MN10200, 90)               /* Matsushita MN10200 */                \
     156             :   _ (PJ, 91)                    /* picoJava */                          \
     157             :   _ (OPENRISC, 92)              /* OpenRISC 32-bit processor */         \
     158             :   _ (ARC_A5, 93)                /* ARC Cores Tangent-A5 */              \
     159             :   _ (XTENSA, 94)                /* Tensilica Xtensa Architecture */     \
     160             :   _ (ALPHA, 0x9026)
     161             : 
     162             : #define _(f) ELF_##f,
     163             : 
     164             : typedef enum
     165             : {
     166             :   foreach_elf_file_class ELF_N_FILE_CLASS,
     167             : } elf_file_class_t;
     168             : 
     169             : typedef enum
     170             : {
     171             :   foreach_elf_data_encoding ELF_N_DATA_ENCODING,
     172             : } elf_data_encoding_t;
     173             : 
     174             : #undef _
     175             : 
     176             : #define _(f,i) ELF_##f = i,
     177             : 
     178             : typedef enum
     179             : {
     180             :   foreach_elf_abi
     181             : } elf_abi_t;
     182             : 
     183             : typedef enum
     184             : {
     185             :   foreach_elf_file_type
     186             : } elf_file_type_t;
     187             : 
     188             : #undef _
     189             : 
     190             : typedef enum
     191             : {
     192             : #define _(f,i) ELF_ARCH_##f = i,
     193             :   foreach_elf_architecture
     194             : #undef _
     195             : } elf_architecture_t;
     196             : 
     197             : typedef struct
     198             : {
     199             :   /* 0x7f ELF */
     200             :   u8 magic[4];
     201             : 
     202             :   elf_file_class_t file_class:8;
     203             :   elf_data_encoding_t data_encoding:8;
     204             :   u8 file_version_ident;
     205             :   elf_abi_t abi:8;
     206             :   u8 abi_version;
     207             : 
     208             :   u8 pad[7];
     209             : 
     210             :   elf_file_type_t file_type:16;
     211             :   elf_architecture_t architecture:16;
     212             : 
     213             :   u32 file_version;
     214             : } elf_first_header_t;
     215             : 
     216             : /* 32/64 bit file header following basic file header. */
     217             : #define foreach_elf32_file_header               \
     218             :   _ (u32, entry_point)                          \
     219             :   _ (u32, segment_header_file_offset)           \
     220             :   _ (u32, section_header_file_offset)           \
     221             :   _ (u32, flags)                                \
     222             :   _ (u16, n_bytes_this_header)                  \
     223             :   _ (u16, segment_header_size)                  \
     224             :   _ (u16, segment_header_count)                 \
     225             :   _ (u16, section_header_size)                  \
     226             :   _ (u16, section_header_count)                 \
     227             :   _ (u16, section_header_string_table_index)
     228             : 
     229             : #define foreach_elf64_file_header               \
     230             :   _ (u64, entry_point)                          \
     231             :   _ (u64, segment_header_file_offset)           \
     232             :   _ (u64, section_header_file_offset)           \
     233             :   _ (u32, flags)                                \
     234             :   _ (u16, n_bytes_this_header)                  \
     235             :   _ (u16, segment_header_size)                  \
     236             :   _ (u16, segment_header_count)                 \
     237             :   _ (u16, section_header_size)                  \
     238             :   _ (u16, section_header_count)                 \
     239             :   _ (u16, section_header_string_table_index)
     240             : 
     241             : /* Section header.  */
     242             : #define foreach_elf32_section_header            \
     243             :   _ (u32, name)                                 \
     244             :   _ (u32, type)                                 \
     245             :   _ (u32, flags)                                \
     246             :   _ (u32, exec_address)                         \
     247             :   _ (u32, file_offset)                          \
     248             :   _ (u32, file_size)                            \
     249             :   _ (u32, link)                                 \
     250             :   _ (u32, additional_info)                      \
     251             :   _ (u32, align)                                \
     252             :   _ (u32, entry_size)
     253             : 
     254             : #define foreach_elf64_section_header            \
     255             :   _ (u32, name)                                 \
     256             :   _ (u32, type)                                 \
     257             :   _ (u64, flags)                                \
     258             :   _ (u64, exec_address)                         \
     259             :   _ (u64, file_offset)                          \
     260             :   _ (u64, file_size)                            \
     261             :   _ (u32, link)                                 \
     262             :   _ (u32, additional_info)                      \
     263             :   _ (u64, align)                                \
     264             :   _ (u64, entry_size)
     265             : 
     266             : /* Program segment header.  */
     267             : #define foreach_elf32_segment_header            \
     268             :   _ (u32, type)                                 \
     269             :   _ (u32, file_offset)                          \
     270             :   _ (u32, virtual_address)                      \
     271             :   _ (u32, physical_address)                     \
     272             :   _ (u32, file_size)                            \
     273             :   _ (u32, memory_size)                          \
     274             :   _ (u32, flags)                                \
     275             :   _ (u32, align)
     276             : 
     277             : #define foreach_elf64_segment_header            \
     278             :   _ (u32, type)                                 \
     279             :   _ (u32, flags)                                \
     280             :   _ (u64, file_offset)                          \
     281             :   _ (u64, virtual_address)                      \
     282             :   _ (u64, physical_address)                     \
     283             :   _ (u64, file_size)                            \
     284             :   _ (u64, memory_size)                          \
     285             :   _ (u64, align)
     286             : 
     287             : /* Symbol table.  */
     288             : #define foreach_elf32_symbol_header             \
     289             :   _ (u32, name)                                 \
     290             :   _ (u32, value)                                \
     291             :   _ (u32, size)                                 \
     292             :   /* binding upper 4 bits; type lower 4 bits */ \
     293             :   _ (u8, binding_and_type)                      \
     294             :   _ (u8, visibility)                            \
     295             :   _ (u16, section_index)
     296             : 
     297             : #define foreach_elf64_symbol_header             \
     298             :   _ (u32, name)                                 \
     299             :   _ (u8, binding_and_type)                      \
     300             :   _ (u8, visibility)                            \
     301             :   _ (u16, section_index)                        \
     302             :   _ (u64, value)                                \
     303             :   _ (u64, size)
     304             : 
     305             : #define _(t,f) t f;
     306             : 
     307             : typedef struct
     308             : {
     309             : foreach_elf32_file_header} elf32_file_header_t;
     310             : 
     311             : typedef struct
     312             : {
     313             : foreach_elf64_file_header} elf64_file_header_t;
     314             : 
     315             : typedef struct
     316             : {
     317             : foreach_elf32_section_header} elf32_section_header_t;
     318             : 
     319             : typedef struct
     320             : {
     321             : foreach_elf64_section_header} elf64_section_header_t;
     322             : 
     323             : typedef struct
     324             : {
     325             : foreach_elf32_segment_header} elf32_segment_header_t;
     326             : 
     327             : typedef struct
     328             : {
     329             : foreach_elf64_segment_header} elf64_segment_header_t;
     330             : 
     331             : typedef struct
     332             : {
     333             : foreach_elf32_symbol_header} elf32_symbol_t;
     334             : 
     335             : typedef struct
     336             : {
     337             : foreach_elf64_symbol_header} elf64_symbol_t;
     338             : #undef _
     339             : 
     340             : /* Special section names.  */
     341             : #define foreach_elf_symbol_reserved_section_index                       \
     342             :   _ (ABSOLUTE, 0xfff1)          /* Associated symbol is absolute */     \
     343             :   _ (COMMON, 0xfff2)            /* Associated symbol is common */       \
     344             :   _ (XINDEX, 0xffff)            /* Index is in extra table.  */
     345             : 
     346             : #define ELF_SYMBOL_SECTION_RESERVED_LO 0xff00
     347             : #define ELF_SYMBOL_SECTION_RESERVED_HI 0xffff
     348             : #define ELF_SYMBOL_SECTION_ARCH_SPECIFIC_LO 0xff00
     349             : #define ELF_SYMBOL_SECTION_ARCH_SPECIFIC_HI 0xff1f
     350             : #define ELF_SYMBOL_SECTION_OS_SPECIFIC_LO 0xff20
     351             : #define ELF_SYMBOL_SECTION_OS_SPECIFIC_HI 0xff3f
     352             : 
     353             : /* Section types. */
     354             : #define foreach_elf_section_type                                        \
     355             :   _ (UNUSED, 0)                                                         \
     356             :   _ (PROGRAM_DATA, 1)                                                   \
     357             :   _ (SYMBOL_TABLE, 2)                                                   \
     358             :   _ (STRING_TABLE, 3)                                                   \
     359             :   _ (RELOCATION_ADD, 4)                                                 \
     360             :   _ (SYMBOL_TABLE_HASH, 5)                                              \
     361             :   _ (DYNAMIC, 6)                /* Dynamic linking information */       \
     362             :   _ (NOTE, 7)                   /* Notes */                             \
     363             :   _ (NO_BITS, 8)                /* Program space with no data (bss) */  \
     364             :   _ (RELOCATION, 9)             /* Relocation entries, no addends */    \
     365             :   _ (DYNAMIC_SYMBOL_TABLE, 11)  /* Dynamic linker symbol table */       \
     366             :   _ (INIT_ARRAY, 14)            /* Array of constructors */             \
     367             :   _ (FINI_ARRAY, 15)            /* Array of destructors */              \
     368             :   _ (PREINIT_ARRAY, 16)         /* Array of pre-constructors */         \
     369             :   _ (GROUP, 17)                 /* Section group */                     \
     370             :   _ (SYMTAB_SHNDX, 18)          /* Extended section indices */          \
     371             :   _ (OS_SPECIFIC_LO, 0x60000000) /* Start OS-specific */                \
     372             :   _ (GNU_LIBLIST, 0x6ffffff7)   /* Prelink library list */              \
     373             :   _ (CHECKSUM, 0x6ffffff8)      /* Checksum for DSO content.  */        \
     374             :   _ (SUNW_MOVE, 0x6ffffffa)                                             \
     375             :   _ (SUNW_COMDAT, 0x6ffffffb)                                           \
     376             :   _ (SUNW_SYMINFO, 0x6ffffffc)                                          \
     377             :   _ (GNU_VERDEF, 0x6ffffffd)    /* Version definition section.  */      \
     378             :   _ (GNU_VERNEED, 0x6ffffffe) /* Version needs section.  */             \
     379             :   _ (GNU_VERSYM, 0x6fffffff)    /* Version symbol table.  */            \
     380             :   _ (ARCH_SPECIFIC_LO, 0x70000000) /* Start of processor-specific */    \
     381             :   _ (ARCH_SPECIFIC_HI, 0x7fffffff) /* End of processor-specific */      \
     382             :   _ (APP_SPECIFIC_LO, 0x80000000) /* Start of application-specific */   \
     383             :   _ (APP_SPECIFIC_HI, 0x8fffffff)       /* End of application-specific */
     384             : 
     385             : /* Section flags. */
     386             : #define foreach_elf_section_flag                \
     387             :   _ (WRITE, 0)                                  \
     388             :   _ (ALLOC, 1)                                  \
     389             :   _ (EXEC, 2)                                   \
     390             :   _ (MERGE, 3)                                  \
     391             :   _ (STRING_TABLE, 5)                           \
     392             :   _ (INFO_LINK, 6)                              \
     393             :   _ (PRESERVE_LINK_ORDER, 7)                    \
     394             :   _ (OS_NON_CONFORMING, 8)                      \
     395             :   _ (GROUP, 9)                                  \
     396             :   _ (TLS, 10)                                   \
     397             :   _ (OS_SPECIFIC_LO, 20)                        \
     398             :   _ (OS_SPECIFIC_HI, 27)                        \
     399             :   _ (ARCH_SPECIFIC_LO, 28)                      \
     400             :   _ (ARCH_SPECIFIC_HI, 31)
     401             : 
     402             : typedef enum
     403             : {
     404             : #define _(f,i) ELF_SECTION_##f = i,
     405             :   foreach_elf_section_type
     406             : #undef _
     407             :     ELF_SECTION_OS_SPECIFIC_HI = 0x6fffffff,
     408             : } elf_section_type_t;
     409             : 
     410             : typedef enum
     411             : {
     412             : #define _(f,i) ELF_SECTION_FLAG_BIT_##f = i,
     413             :   foreach_elf_section_flag
     414             : #undef _
     415             : } elf_section_flag_bit_t;
     416             : 
     417             : typedef enum
     418             : {
     419             : #define _(f,i) ELF_SECTION_FLAG_##f = 1 << ELF_SECTION_FLAG_BIT_##f,
     420             :   foreach_elf_section_flag
     421             : #undef _
     422             : } elf_section_flag_t;
     423             : 
     424             : /* Symbol bindings (upper 4 bits of binding_and_type). */
     425             : #define foreach_elf_symbol_binding                                      \
     426             :   _ (LOCAL, 0)                  /* Local symbol */                      \
     427             :   _ (GLOBAL, 1)                 /* Global symbol */                     \
     428             :   _ (WEAK, 2)                   /* Weak symbol */                       \
     429             :   _ (OS_SPECIFIC_LO, 10)        /* Start of OS-specific */              \
     430             :   _ (OS_SPECIFIC_HI, 12)        /* End of OS-specific */                \
     431             :   _ (ARCH_SPECIFIC_LO, 13)      /* Start of processor-specific */       \
     432             :   _ (ARCH_SPECIFIC_HI, 15)      /* End of processor-specific */
     433             : 
     434             : /* Symbol types (lower 4 bits of binding_and_type). */
     435             : #define foreach_elf_symbol_type                                         \
     436             :   _ (NONE, 0)                                                           \
     437             :   _ (DATA, 1)                   /* Symbol is a data object */           \
     438             :   _ (CODE, 2)                   /* Symbol is a code object */           \
     439             :   _ (SECTION, 3)                /* Symbol associated with a section */  \
     440             :   _ (FILE, 4)                   /* Symbol's name is file name */        \
     441             :   _ (COMMON, 5)                 /* Symbol is a common data object */    \
     442             :   _ (TLS, 6)                    /* Symbol is thread-local data */       \
     443             :   _ (OS_SPECIFIC_LO, 10)        /* Start of OS-specific */              \
     444             :   _ (OS_SPECIFIC_HI, 12)        /* End of OS-specific */                \
     445             :   _ (ARCH_SPECIFIC_LO, 13)      /* Start of processor-specific */       \
     446             :   _ (ARCH_SPECIFIC_HI, 15)      /* End of processor-specific */
     447             : 
     448             : /* Symbol visibility. */
     449             : #define foreach_elf_symbol_visibility                                   \
     450             :   _ (DEFAULT, 0)                /* Default symbol visibility rules */   \
     451             :   _ (INTERNAL, 1)               /* Processor specific hidden class */   \
     452             :   _ (HIDDEN, 2)                 /* Unavailable in other modules */      \
     453             :   _ (PROTECTED, 3)              /* Not preemptible, not exported */
     454             : 
     455             : /* The syminfo section if available contains additional
     456             :    information about every dynamic symbol.  */
     457             : typedef struct
     458             : {
     459             :   u16 bound_to;
     460             :   u16 flags;
     461             : } elf_symbol_info_t;
     462             : 
     463             : /* Possible values for bound_to.  */
     464             : #define foreach_elf_symbol_info_bound_to                        \
     465             :   _ (SELF, 0xffff)              /* Symbol bound to self */      \
     466             :   _ (PARENT, 0xfffe)            /* Symbol bound to parent */    \
     467             :   _ (RESERVED_LO, 0xff00)                                       \
     468             :   _ (RESERVED_HI, 0xffff)
     469             : 
     470             : /* Symbol info flags. */
     471             : #define foreach_elf_symbol_info_flags                                   \
     472             :   _ (DIRECT)                    /* Direct bound symbol */               \
     473             :   _ (PASS_THRU)                 /* Pass-thru symbol for translator */   \
     474             :   _ (COPY)                      /* Symbol is a copy-reloc */            \
     475             :   _ (LAZY_LOAD)                 /* Symbol bound to object to be lazy loaded */
     476             : 
     477             : /* Relocation table entry with/without addend. */
     478             : typedef struct
     479             : {
     480             :   u32 address;
     481             :   u32 symbol_and_type;          /* high 24 symbol, low 8 type. */
     482             :   i32 addend[0];
     483             : } elf32_relocation_t;
     484             : 
     485             : typedef struct
     486             : {
     487             :   u64 address;
     488             :   u64 symbol_and_type;          /* high 32 symbol, low 32 type. */
     489             :   i64 addend[0];
     490             : } elf64_relocation_t;
     491             : 
     492             : typedef struct
     493             : {
     494             :   u64 address;
     495             :   u64 symbol_and_type;
     496             :   u64 addend;
     497             : } elf_relocation_with_addend_t;
     498             : 
     499             : #define elf_relocation_next(r,type)                                     \
     500             :   ((void *) ((r) + 1)                                                   \
     501             :    + ((type) == ELF_SECTION_RELOCATION_ADD ? sizeof ((r)->addend[0]) : 0))
     502             : 
     503             : /* Segment type. */
     504             : #define foreach_elf_segment_type                                        \
     505             :   _ (UNUSED, 0)                                                         \
     506             :   _ (LOAD, 1)                   /* Loadable program segment */          \
     507             :   _ (DYNAMIC, 2)                /* Dynamic linking information */       \
     508             :   _ (INTERP, 3)                 /* Program interpreter */               \
     509             :   _ (NOTE, 4)                   /* Auxiliary information */             \
     510             :   _ (SEGMENT_TABLE, 6)          /* Entry for header table itself */     \
     511             :   _ (TLS, 7)                    /* Thread-local storage segment */      \
     512             :   _ (OS_SPECIFIC_LO, 0x60000000) /* Start of OS-specific */             \
     513             :   _ (GNU_EH_FRAME, 0x6474e550)  /* GCC .eh_frame_hdr segment */         \
     514             :   _ (GNU_STACK, 0x6474e551)     /* Indicates stack executability */     \
     515             :   _ (GNU_RELRO, 0x6474e552)     /* Read-only after relocation */        \
     516             :   _ (SUNW_BSS, 0x6ffffffa)      /* Sun specific BSS */                  \
     517             :   _ (SUNW_STACK, 0x6ffffffb)    /* Sun specific stack */                \
     518             :   _ (OS_SPECIFIC_HI, 0x6fffffff) /* End of OS-specific */               \
     519             :   _ (ARCH_SPECIFIC_LO, 0x70000000) /* Start of processor-specific */    \
     520             :   _ (ARCH_SPECIFIC_HI, 0x7fffffff)      /* End of processor-specific */
     521             : 
     522             : /* Segment flags. */
     523             : #define foreach_elf_segment_flag                \
     524             :   _ (EXEC, 0)                                   \
     525             :   _ (WRITE, 1)                                  \
     526             :   _ (READ, 2)                                   \
     527             :   _ (OS_SPECIFIC_LO, 20)                        \
     528             :   _ (OS_SPECIFIC_HI, 27)                        \
     529             :   _ (ARCH_SPECIFIC_LO, 28)                      \
     530             :   _ (ARCH_SPECIFIC_HI, 31)
     531             : 
     532             : typedef enum
     533             : {
     534             : #define _(f,i) ELF_SEGMENT_##f = i,
     535             :   foreach_elf_segment_type
     536             : #undef _
     537             : } elf_segment_type_t;
     538             : 
     539             : typedef enum
     540             : {
     541             : #define _(f,i) ELF_SEGMENT_FLAG_BIT_##f = i,
     542             :   foreach_elf_segment_flag
     543             : #undef _
     544             : } elf_segment_flag_bit_t;
     545             : 
     546             : typedef enum
     547             : {
     548             : #define _(f,i) ELF_SEGMENT_FLAG_##f = 1 << ELF_SEGMENT_FLAG_BIT_##f,
     549             :   foreach_elf_segment_flag
     550             : #undef _
     551             : } elf_segment_flag_t;
     552             : 
     553             : #define foreach_elf32_dynamic_entry_header      \
     554             :   _ (u32, type)                                 \
     555             :   _ (u32, data)
     556             : 
     557             : #define foreach_elf64_dynamic_entry_header      \
     558             :   _ (u64, type)                                 \
     559             :   _ (u64, data)
     560             : 
     561             : #define _(t,f) t f;
     562             : 
     563             : typedef struct
     564             : {
     565             : foreach_elf32_dynamic_entry_header} elf32_dynamic_entry_t;
     566             : 
     567             : typedef struct
     568             : {
     569             : foreach_elf64_dynamic_entry_header} elf64_dynamic_entry_t;
     570             : 
     571             : #undef _
     572             : 
     573             : #define foreach_elf_dynamic_entry_type                                  \
     574             :   _ (END, 0)                    /* Marks end of dynamic section */      \
     575             :   _ (NEEDED_LIBRARY, 1)         /* Name of needed library */            \
     576             :   _ (PLT_RELOCATION_SIZE, 2)    /* Size in bytes of PLT relocs */       \
     577             :   _ (PLT_GOT, 3)                /* Processor defined value */           \
     578             :   _ (SYMBOL_HASH, 4)            /* Address of symbol hash table */      \
     579             :   _ (STRING_TABLE, 5)           /* Address of string table */           \
     580             :   _ (SYMBOL_TABLE, 6)           /* Address of symbol table */           \
     581             :   _ (RELA_ADDRESS, 7)           /* Address of Rela relocs */            \
     582             :   _ (RELA_SIZE, 8)              /* Total size of Rela relocs */         \
     583             :   _ (RELA_ENTRY_SIZE, 9)        /* Size of one Rela reloc */            \
     584             :   _ (STRING_TABLE_SIZE, 10)     /* Size of string table */              \
     585             :   _ (SYMBOL_TABLE_ENTRY_SIZE, 11) /* Size of one symbol table entry */  \
     586             :   _ (INIT_FUNCTION, 12)         /* Address of init function */          \
     587             :   _ (FINI_FUNCTION, 13)         /* Address of termination function */   \
     588             :   _ (SONAME, 14)                /* Name of shared object */             \
     589             :   _ (RPATH, 15)                 /* Library search path (deprecated) */  \
     590             :   _ (SYMBOLIC, 16)              /* Start symbol search here */          \
     591             :   _ (REL, 17)                   /* Address of Rel relocs */             \
     592             :   _ (RELSZ, 18)                 /* Total size of Rel relocs */          \
     593             :   _ (RELENT, 19)                /* Size of one Rel reloc */             \
     594             :   _ (PLT_RELOCATION_TYPE, 20)   /* Type of reloc in PLT */              \
     595             :   _ (DEBUG, 21)                 /* For debugging; unspecified */        \
     596             :   _ (TEXTREL, 22)               /* Reloc might modify .text */          \
     597             :   _ (PLT_RELOCATION_ADDRESS, 23) /* Address of PLT relocs */            \
     598             :   _ (BIND_NOW, 24)              /* Process relocations of object */     \
     599             :   _ (INIT_ARRAY, 25)            /* Array with addresses of init fct */  \
     600             :   _ (FINI_ARRAY, 26)            /* Array with addresses of fini fct */  \
     601             :   _ (INIT_ARRAYSZ, 27)          /* Size in bytes of DT_INIT_ARRAY */    \
     602             :   _ (FINI_ARRAYSZ, 28)          /* Size in bytes of DT_FINI_ARRAY */    \
     603             :   _ (RUN_PATH, 29)              /* Library search path */               \
     604             :   _ (FLAGS, 30)                 /* Flags for object being loaded */     \
     605             :   _ (ENCODING, 31)              /* Start of encoded range */            \
     606             :   _ (PREINIT_ARRAY, 32)         /* Array with addresses of fns */       \
     607             :   _ (PREINIT_ARRAY_SIZE, 33)    /* Size of PREINIT_ARRAY in bytes. */   \
     608             :   _ (GNU_PRELINKED, 0x6ffffdf5) /* Prelinking timestamp */              \
     609             :   _ (GNU_CONFLICTSZ, 0x6ffffdf6)        /* Size of conflict section */  \
     610             :   _ (GNU_LIBLISTSZ, 0x6ffffdf7) /* Size of library list */              \
     611             :   _ (CHECKSUM, 0x6ffffdf8)                                              \
     612             :   _ (PLTPADSZ, 0x6ffffdf9)                                              \
     613             :   _ (MOVEENT, 0x6ffffdfa)                                               \
     614             :   _ (MOVESZ, 0x6ffffdfb)                                                \
     615             :   _ (FEATURE_1, 0x6ffffdfc)     /* Feature selection (DTF_*).  */       \
     616             :   _ (POSFLAG_1, 0x6ffffdfd)     /* Flags for following entries.  */     \
     617             :   _ (SYMINSZ, 0x6ffffdfe)       /* Size of syminfo table (in bytes) */  \
     618             :   _ (SYMINENT, 0x6ffffdff)      /* Entry size of syminfo */             \
     619             :   _ (GNU_HASH, 0x6ffffef5)                                              \
     620             :   _ (GNU_CONFLICT, 0x6ffffef8)  /* Start of conflict section */         \
     621             :   _ (GNU_LIBLIST, 0x6ffffef9)   /* Library list */                      \
     622             :   _ (CONFIG, 0x6ffffefa)        /* Configuration information.  */       \
     623             :   _ (DEPAUDIT, 0x6ffffefb)      /* Dependency auditing.  */             \
     624             :   _ (AUDIT, 0x6ffffefc) /* Object auditing.  */                         \
     625             :   _ (PLTPAD, 0x6ffffefd)        /* PLT padding.  */                     \
     626             :   _ (MOVETAB, 0x6ffffefe)       /* Move table.  */                      \
     627             :   _ (SYMINFO, 0x6ffffeff)       /* Syminfo table.  */                   \
     628             :   _ (VERSYM, 0x6ffffff0)                                                \
     629             :   _ (RELACOUNT, 0x6ffffff9)                                             \
     630             :   _ (RELCOUNT, 0x6ffffffa)                                              \
     631             :   _ (FLAGS_1, 0x6ffffffb)       /* State flags, see DF_1_* below.  */   \
     632             :   _ (VERSION_DEF, 0x6ffffffc)   /* Address of version definition table */ \
     633             :   _ (VERSION_DEF_COUNT, 0x6ffffffd)     /* Number of version definitions */ \
     634             :   _ (VERSION_NEED, 0x6ffffffe)  /* Address of table with needed versions */ \
     635             :   _ (VERSION_NEED_COUNT, 0x6fffffff)    /* Number of needed versions */ \
     636             :   _ (AUXILIARY, 0x7ffffffd)      /* Shared object to load before self */ \
     637             :   _ (FILTER, 0x7fffffff)        /* Shared object to get values from */
     638             : 
     639             : typedef enum
     640             : {
     641             : #define _(f,n) ELF_DYNAMIC_ENTRY_##f = (n),
     642             :   foreach_elf_dynamic_entry_type
     643             : #undef _
     644             : } elf_dynamic_entry_type_t;
     645             : 
     646             : /* Values of `d_un.d_val' in the DT_FLAGS entry.  */
     647             : #define ELF_DYNAMIC_FLAGS_ORIGIN        (1 << 0)  /* Object may use DF_ORIGIN */
     648             : #define ELF_DYNAMIC_FLAGS_SYMBOLIC      (1 << 1)  /* Symbol resolutions starts here */
     649             : #define ELF_DYNAMIC_FLAGS_TEXT_RELOCATIONS (1 << 2)       /* Object contains text relocations */
     650             : #define ELF_DYNAMIC_FLAGS_BIND_NOW      (1 << 3)  /* No lazy binding for this object */
     651             : #define ELF_DYNAMIC_FLAGS_STATIC_TLS    (1 << 4)  /* Module uses the static TLS model */
     652             : 
     653             : /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
     654             :    entry in the dynamic section.  */
     655             : #define DF_1_NOW        0x00000001      /* Set RTLD_NOW for this object.  */
     656             : #define DF_1_GLOBAL     0x00000002      /* Set RTLD_GLOBAL for this object.  */
     657             : #define DF_1_GROUP      0x00000004      /* Set RTLD_GROUP for this object.  */
     658             : #define DF_1_NODELETE   0x00000008      /* Set RTLD_NODELETE for this object. */
     659             : #define DF_1_LOADFLTR   0x00000010      /* Trigger filtee loading at runtime. */
     660             : #define DF_1_INITFIRST  0x00000020      /* Set RTLD_INITFIRST for this object */
     661             : #define DF_1_NOOPEN     0x00000040      /* Set RTLD_NOOPEN for this object.  */
     662             : #define DF_1_ORIGIN     0x00000080      /* $ORIGIN must be handled.  */
     663             : #define DF_1_DIRECT     0x00000100      /* Direct binding enabled.  */
     664             : #define DF_1_TRANS      0x00000200
     665             : #define DF_1_INTERPOSE  0x00000400      /* Object is used to interpose.  */
     666             : #define DF_1_NODEFLIB   0x00000800      /* Ignore default lib search path.  */
     667             : #define DF_1_NODUMP     0x00001000      /* Object can't be dldump'ed.  */
     668             : #define DF_1_CONFALT    0x00002000      /* Configuration alternative created. */
     669             : #define DF_1_ENDFILTEE  0x00004000      /* Filtee terminates filters search. */
     670             : #define DF_1_DISPRELDNE 0x00008000      /* Disp reloc applied at build time. */
     671             : #define DF_1_DISPRELPND 0x00010000      /* Disp reloc applied at run-time.  */
     672             : 
     673             : /* Flags for the feature selection in DT_FEATURE_1.  */
     674             : #define DTF_1_PARINIT   0x00000001
     675             : #define DTF_1_CONFEXP   0x00000002
     676             : 
     677             : /* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
     678             : #define DF_P1_LAZYLOAD  0x00000001      /* Lazyload following object.  */
     679             : #define DF_P1_GROUPPERM 0x00000002      /* Symbols from next object are not
     680             :                                            generally available.  */
     681             : 
     682             : /* Version definition sections.  */
     683             : typedef struct
     684             : {
     685             :   u16 version;
     686             :   u16 flags;
     687             :   u16 index;
     688             :   u16 aux_count;
     689             :   u32 name_hash;
     690             :   u32 aux_byte_offset;
     691             :   u32 byte_offset_next_version_definition;
     692             : } elf_dynamic_version_definition_t;
     693             : 
     694             : typedef struct
     695             : {
     696             :   u32 name;
     697             :   u32 next_offset;              /* byte offset of ver def aux next entry */
     698             : } elf_dynamic_version_definition_aux_t;
     699             : 
     700             : /* Version definition flags. */
     701             : #define ELF_DYNAMIC_VERSION_FILE (1 << 0) /* Version definition of file itself */
     702             : #define ELF_DYNAMIC_VERSION_WEAK (1 << 1) /* Weak version identifier */
     703             : 
     704             : /* Version symbol index. */
     705             : #define ELF_DYNAMIC_VERSYM_LOCAL 0      /* Symbol is local.  */
     706             : #define ELF_DYNAMIC_VERSYM_GLOBAL 1     /* Symbol is global.  */
     707             : #define ELF_DYNAMIC_VERSYM_RESERVED_LO  0xff00  /* Beginning of reserved entries.  */
     708             : #define ELF_DYNAMIC_VERSYM_ELIMINATE    0xff01  /* Symbol is to be eliminated.  */
     709             : 
     710             : /* Version dependency section.  */
     711             : #define foreach_elf_dynamic_version_need_field  \
     712             :   _ (u16, version)                              \
     713             :   _ (u16, aux_count)                            \
     714             :   _ (u32, file_name_offset)                     \
     715             :   _ (u32, first_aux_offset)                     \
     716             :   _ (u32, next_offset)
     717             : 
     718             : #define foreach_elf_dynamic_version_need_aux_field      \
     719             :   _ (u32, hash)                                         \
     720             :   _ (u16, flags)                                        \
     721             :   _ (u16, versym_index)                                 \
     722             :   _ (u32, name)                                         \
     723             :   _ (u32, next_offset)
     724             : 
     725             : typedef struct
     726             : {
     727             : #define _(t,f) t f;
     728             :   foreach_elf_dynamic_version_need_field
     729             : #undef _
     730             : } elf_dynamic_version_need_t;
     731             : 
     732             : typedef struct
     733             : {
     734             : #define _(t,f) t f;
     735             :   foreach_elf_dynamic_version_need_aux_field
     736             : #undef _
     737             : } elf_dynamic_version_need_aux_t;
     738             : 
     739             : typedef union
     740             : {
     741             :   elf_dynamic_version_need_t need;
     742             :   elf_dynamic_version_need_aux_t aux;
     743             : } elf_dynamic_version_need_union_t;
     744             : 
     745             : /* Note section contents.  Each entry in the note section begins with
     746             :    a header of a fixed form.  */
     747             : 
     748             : typedef struct
     749             : {
     750             :   u32 name_size;
     751             :   u32 descriptor_size;
     752             :   u32 type;
     753             : } elf_note_t;
     754             : 
     755             : /* Known names of notes.  */
     756             : 
     757             : /* Solaris entries in the note section have this name.  */
     758             : #define ELF_NOTE_SOLARIS        "SUNW Solaris"
     759             : 
     760             : /* Note entries for GNU systems have this name.  */
     761             : #define ELF_NOTE_GNU            "GNU"
     762             : 
     763             : 
     764             : /* Defined types of notes for Solaris.  */
     765             : 
     766             : /* Value of descriptor (one word) is desired pagesize for the binary.  */
     767             : #define ELF_NOTE_PAGESIZE_HINT  1
     768             : 
     769             : 
     770             : /* Defined note types for GNU systems.  */
     771             : 
     772             : /* ABI information.  The descriptor consists of words:
     773             :    word 0: OS descriptor
     774             :    word 1: major version of the ABI
     775             :    word 2: minor version of the ABI
     776             :    word 3: subminor version of the ABI
     777             : */
     778             : #ifndef ELF_NOTE_ABI
     779             : #define ELF_NOTE_ABI            1
     780             : #endif
     781             : 
     782             : /* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
     783             :    note section entry.  */
     784             : #define ELF_NOTE_OS_LINUX       0
     785             : #define ELF_NOTE_OS_GNU         1
     786             : #define ELF_NOTE_OS_SOLARIS2    2
     787             : #define ELF_NOTE_OS_FREEBSD     3
     788             : 
     789             : /* AMD x86-64 relocations.  */
     790             : #define foreach_elf_x86_64_relocation_type                              \
     791             :   _ (NONE, 0)                   /* No reloc */                          \
     792             :   _ (DIRECT_64, 1)              /* Direct 64 bit  */                    \
     793             :   _ (PC_REL_I32, 2)             /* PC relative 32 bit signed */         \
     794             :   _ (GOT_REL_32, 3)             /* 32 bit GOT entry */                  \
     795             :   _ (PLT_REL_32, 4)             /* 32 bit PLT address */                \
     796             :   _ (COPY, 5)                   /* Copy symbol at runtime */            \
     797             :   _ (CREATE_GOT, 6)             /* Create GOT entry */                  \
     798             :   _ (CREATE_PLT, 7)             /* Create PLT entry */                  \
     799             :   _ (RELATIVE, 8)               /* Adjust by program base */            \
     800             :   _ (PC_REL_I32_GOT, 9) /* 32 bit PC relative offset to GOT */          \
     801             :   _ (DIRECT_U32, 10)            /* Direct 32 bit zero extended */       \
     802             :   _ (DIRECT_I32, 11)            /* Direct 32 bit sign extended */       \
     803             :   _ (DIRECT_U16, 12)            /* Direct 16 bit zero extended */       \
     804             :   _ (PC_REL_I16, 13)    /* 16 bit sign extended pc relative */          \
     805             :   _ (DIRECT_I8, 14)             /* Direct 8 bit sign extended  */       \
     806             :   _ (PC_REL_I8, 15)     /* 8 bit sign extended pc relative */           \
     807             :   _ (DTPMOD64, 16)              /* ID of module containing symbol */    \
     808             :   _ (DTPOFF64, 17)              /* Offset in module's TLS block */      \
     809             :   _ (TPOFF64, 18)               /* Offset in initial TLS block */       \
     810             :   _ (TLSGD, 19) /* 32 bit signed PC relative offset to two GOT entries for GD symbol */ \
     811             :   _ (TLSLD, 20) /* 32 bit signed PC relative offset to two GOT entries for LD symbol */ \
     812             :   _ (DTPOFF32, 21)              /* Offset in TLS block */               \
     813             :   _ (GOTTPOFF, 22) /* 32 bit signed PC relative offset to GOT entry for IE symbol */ \
     814             :   _ (TPOFF32, 23)               /* Offset in initial TLS, block) */
     815             : 
     816             : typedef struct
     817             : {
     818             :   elf64_symbol_t *symbols;
     819             : 
     820             :   u32 section_index;
     821             : 
     822             :   u8 *string_table;
     823             : 
     824             :   uword *symbol_by_name;
     825             : } elf_symbol_table_t;
     826             : 
     827             : always_inline void
     828       93912 : elf_symbol_table_free (elf_symbol_table_t * s)
     829             : {
     830       93912 :   vec_free (s->symbols);
     831       93912 :   hash_free (s->symbol_by_name);
     832       93912 : }
     833             : 
     834             : always_inline u8 *
     835           0 : elf_symbol_name (elf_symbol_table_t * t, elf64_symbol_t * sym)
     836             : {
     837           0 :   return vec_elt_at_index (t->string_table, sym->name);
     838             : }
     839             : 
     840             : typedef struct
     841             : {
     842             :   elf_relocation_with_addend_t *relocations;
     843             : 
     844             :   u32 section_index;
     845             : } elf_relocation_table_t;
     846             : 
     847             : always_inline void
     848       93912 : elf_relocation_table_free (elf_relocation_table_t * r)
     849             : {
     850       93912 :   vec_free (r->relocations);
     851       93912 : }
     852             : 
     853             : typedef struct
     854             : {
     855             :   elf64_section_header_t header;
     856             : 
     857             :   u32 index;
     858             : 
     859             :   /* Index of segments containing this section. */
     860             :   uword *segment_index_bitmap;
     861             : 
     862             :   /* Aligned size (included padding not included in
     863             :      header.file_size). */
     864             :   u64 align_size;
     865             : 
     866             :   i64 exec_address_change;
     867             : 
     868             :   u8 *contents;
     869             : } elf_section_t;
     870             : 
     871             : typedef struct
     872             : {
     873             :   elf64_segment_header_t header;
     874             : 
     875             :   /* Sections contained in this segment. */
     876             :   uword *section_index_bitmap;
     877             : 
     878             :   u32 index;
     879             : 
     880             :   u8 *contents;
     881             : } elf_segment_t;
     882             : 
     883             : typedef struct
     884             : {
     885             :   u8 need_byte_swap;
     886             : 
     887             :   u8 parsed_symbols;
     888             : 
     889             :   char *file_name;
     890             : 
     891             :   elf_first_header_t first_header;
     892             : 
     893             :   elf64_file_header_t file_header;
     894             : 
     895             :   elf_segment_t *segments;
     896             : 
     897             :   elf_section_t *sections;
     898             : 
     899             :   uword *section_by_name;
     900             :   uword *section_by_start_address;
     901             : 
     902             :   elf_symbol_table_t *symbol_tables;
     903             :   elf_relocation_table_t *relocation_tables;
     904             : 
     905             :   char *interpreter;
     906             : 
     907             :   elf64_dynamic_entry_t *dynamic_entries;
     908             :   u8 *dynamic_string_table;
     909             :   u32 dynamic_string_table_section_index;
     910             :   u32 dynamic_symbol_table_section_index;
     911             :   u32 dynamic_symbol_table_index;
     912             :   u32 dynamic_section_index;
     913             :   u16 *versym;
     914             :   u32 versym_section_index;
     915             :   elf_dynamic_version_need_union_t *verneed;
     916             :   u32 verneed_section_index;
     917             : } elf_main_t;
     918             : 
     919             : always_inline void
     920       46956 : elf_main_init (elf_main_t * em)
     921             : {
     922       46956 :   clib_memset (em, 0, sizeof (em[0]));
     923       46956 : }
     924             : 
     925             : always_inline void
     926       47515 : elf_main_free (elf_main_t * em)
     927             : {
     928             :   uword i;
     929             : 
     930      564031 :   for (i = 0; i < vec_len (em->segments); i++)
     931      516516 :     vec_free (em->segments[i].contents);
     932       47515 :   vec_free (em->segments);
     933             : 
     934     1803889 :   for (i = 0; i < vec_len (em->sections); i++)
     935     1756380 :     vec_free (em->sections[i].contents);
     936       47515 :   vec_free (em->sections);
     937             : 
     938       47515 :   hash_free (em->section_by_name);
     939      141427 :   for (i = 0; i < vec_len (em->symbol_tables); i++)
     940       93912 :     elf_symbol_table_free (em->symbol_tables + i);
     941      141427 :   for (i = 0; i < vec_len (em->relocation_tables); i++)
     942       93912 :     elf_relocation_table_free (em->relocation_tables + i);
     943             : 
     944       47515 :   vec_free (em->dynamic_entries);
     945       47515 :   vec_free (em->interpreter);
     946       47515 : }
     947             : 
     948             : always_inline void
     949             : elf_get_segment_contents (elf_main_t * em, void *data, uword segment_index)
     950             : {
     951             :   elf_segment_t *g = vec_elt_at_index (em->segments, segment_index);
     952             :   if (!g->contents)
     953             :     vec_add (g->contents, data + g->header.file_offset,
     954             :              g->header.memory_size);
     955             : }
     956             : 
     957             : always_inline void *
     958      836466 : elf_get_section_contents (elf_main_t * em,
     959             :                           uword section_index, uword elt_size)
     960             : {
     961             :   elf_section_t *s;
     962             :   void *result;
     963             : 
     964      836466 :   s = vec_elt_at_index (em->sections, section_index);
     965             : 
     966      836466 :   result = 0;
     967      836466 :   if (vec_len (s->contents) > 0)
     968             :     {
     969      836466 :       vec_attr_t va = { .elt_sz = elt_size };
     970             :       /* Make vector copy of contents with given element size. */
     971             :       result =
     972      836466 :         _vec_realloc_internal (result, vec_len (s->contents) / elt_size, &va);
     973      836466 :       clib_memcpy (result, s->contents, vec_len (s->contents));
     974             :     }
     975             : 
     976      836466 :   return result;
     977             : }
     978             : 
     979             : always_inline void
     980           0 : elf_set_section_contents (elf_main_t * em,
     981             :                           uword section_index,
     982             :                           void *new_contents, uword n_content_bytes)
     983             : {
     984             :   elf_section_t *s;
     985             : 
     986           0 :   s = vec_elt_at_index (em->sections, section_index);
     987           0 :   vec_free (s->contents);
     988           0 :   vec_add (s->contents, new_contents, n_content_bytes);
     989           0 : }
     990             : 
     991             : always_inline u8 *
     992     5841940 : elf_section_name (elf_main_t * em, elf_section_t * s)
     993             : {
     994     5841940 :   elf_section_t *es = vec_elt_at_index (em->sections,
     995             :                                         em->
     996             :                                         file_header.section_header_string_table_index);
     997     5841940 :   return vec_elt_at_index (es->contents, s->header.name);
     998             : }
     999             : 
    1000             : always_inline u8
    1001   929065000 : elf_swap_u8 (elf_main_t * em, u8 x)
    1002             : {
    1003   929065000 :   return x;
    1004             : }
    1005             : 
    1006             : always_inline u16
    1007   465351000 : elf_swap_u16 (elf_main_t * em, u16 x)
    1008             : {
    1009   465351000 :   return em->need_byte_swap ? clib_byte_swap_u16 (x) : x;
    1010             : }
    1011             : 
    1012             : always_inline u32
    1013   482193000 : elf_swap_u32 (elf_main_t * em, u32 x)
    1014             : {
    1015   482193000 :   return em->need_byte_swap ? clib_byte_swap_u32 (x) : x;
    1016             : }
    1017             : 
    1018             : always_inline u64
    1019   958945000 : elf_swap_u64 (elf_main_t * em, u64 x)
    1020             : {
    1021   958945000 :   return em->need_byte_swap ? clib_byte_swap_u64 (x) : x;
    1022             : }
    1023             : 
    1024             : #define FORMAT_ELF_MAIN_SYMBOLS (1 << 0)
    1025             : #define FORMAT_ELF_MAIN_RELOCATIONS (1 << 1)
    1026             : #define FORMAT_ELF_MAIN_DYNAMIC (1 << 2)
    1027             : 
    1028             : format_function_t format_elf_main;
    1029             : format_function_t format_elf_symbol;
    1030             : 
    1031             : clib_error_t *elf_read_file (elf_main_t * em, char *file_name);
    1032             : clib_error_t *elf_write_file (elf_main_t * em, char *file_name);
    1033             : clib_error_t *elf_delete_named_section (elf_main_t * em, char *section_name);
    1034             : clib_error_t *elf_parse (elf_main_t * em, void *data, uword data_bytes);
    1035             : void elf_parse_symbols (elf_main_t * em);
    1036             : 
    1037             : clib_error_t *elf_get_section_by_name (elf_main_t * em, char *section_name,
    1038             :                                        elf_section_t ** result);
    1039             : clib_error_t *elf_get_section_by_start_address (elf_main_t * em,
    1040             :                                                 uword start_address,
    1041             :                                                 elf_section_t ** result);
    1042             : 
    1043             : void
    1044             : elf_create_section_with_contents (elf_main_t * em,
    1045             :                                   char *section_name,
    1046             :                                   elf64_section_header_t * header,
    1047             :                                   void *contents, uword n_content_bytes);
    1048             : uword elf_delete_segment_with_type (elf_main_t * em,
    1049             :                                     elf_segment_type_t segment_type);
    1050             : void elf_set_dynamic_entries (elf_main_t * em);
    1051             : 
    1052             : #endif /* included_clib_elf_h */
    1053             : 
    1054             : /*
    1055             :  * fd.io coding-style-patch-verification: ON
    1056             :  *
    1057             :  * Local Variables:
    1058             :  * eval: (c-set-style "gnu")
    1059             :  * End:
    1060             :  */

Generated by: LCOV version 1.14