Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 */ \ |
Paul Vinciguerra | ec11b13 | 2018-09-24 05:25:00 -0700 | [diff] [blame] | 123 | _ (NCPU, 56) /* Sony nCPU embedded RISC */ \ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 164 | typedef enum |
| 165 | { |
| 166 | foreach_elf_file_class ELF_N_FILE_CLASS, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 167 | } elf_file_class_t; |
| 168 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 169 | typedef enum |
| 170 | { |
| 171 | foreach_elf_data_encoding ELF_N_DATA_ENCODING, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 172 | } elf_data_encoding_t; |
| 173 | |
| 174 | #undef _ |
| 175 | |
| 176 | #define _(f,i) ELF_##f = i, |
| 177 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 178 | typedef enum |
| 179 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 180 | foreach_elf_abi |
| 181 | } elf_abi_t; |
| 182 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 183 | typedef enum |
| 184 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 185 | foreach_elf_file_type |
| 186 | } elf_file_type_t; |
| 187 | |
| 188 | #undef _ |
| 189 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 190 | typedef enum |
| 191 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 192 | #define _(f,i) ELF_ARCH_##f = i, |
| 193 | foreach_elf_architecture |
| 194 | #undef _ |
| 195 | } elf_architecture_t; |
| 196 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 197 | typedef struct |
| 198 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 199 | /* 0x7f ELF */ |
| 200 | u8 magic[4]; |
| 201 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 202 | elf_file_class_t file_class:8; |
| 203 | elf_data_encoding_t data_encoding:8; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 204 | u8 file_version_ident; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 205 | elf_abi_t abi:8; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 206 | u8 abi_version; |
| 207 | |
| 208 | u8 pad[7]; |
| 209 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 210 | elf_file_type_t file_type:16; |
| 211 | elf_architecture_t architecture:16; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 307 | typedef struct |
| 308 | { |
| 309 | foreach_elf32_file_header} elf32_file_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 310 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 311 | typedef struct |
| 312 | { |
| 313 | foreach_elf64_file_header} elf64_file_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 314 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 315 | typedef struct |
| 316 | { |
| 317 | foreach_elf32_section_header} elf32_section_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 318 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 319 | typedef struct |
| 320 | { |
| 321 | foreach_elf64_section_header} elf64_section_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 322 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 323 | typedef struct |
| 324 | { |
| 325 | foreach_elf32_segment_header} elf32_segment_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 326 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 327 | typedef struct |
| 328 | { |
| 329 | foreach_elf64_segment_header} elf64_segment_header_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 330 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 331 | typedef struct |
| 332 | { |
| 333 | foreach_elf32_symbol_header} elf32_symbol_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 334 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 335 | typedef struct |
| 336 | { |
| 337 | foreach_elf64_symbol_header} elf64_symbol_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 */ \ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 383 | _ (APP_SPECIFIC_HI, 0x8fffffff) /* End of application-specific */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 402 | typedef enum |
| 403 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 404 | #define _(f,i) ELF_SECTION_##f = i, |
| 405 | foreach_elf_section_type |
| 406 | #undef _ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 407 | ELF_SECTION_OS_SPECIFIC_HI = 0x6fffffff, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 408 | } elf_section_type_t; |
| 409 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 410 | typedef enum |
| 411 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 412 | #define _(f,i) ELF_SECTION_FLAG_BIT_##f = i, |
| 413 | foreach_elf_section_flag |
| 414 | #undef _ |
| 415 | } elf_section_flag_bit_t; |
| 416 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 417 | typedef enum |
| 418 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 457 | typedef struct |
| 458 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 478 | typedef struct |
| 479 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 480 | u32 address; |
| 481 | u32 symbol_and_type; /* high 24 symbol, low 8 type. */ |
| 482 | i32 addend[0]; |
| 483 | } elf32_relocation_t; |
| 484 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 485 | typedef struct |
| 486 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 487 | u64 address; |
| 488 | u64 symbol_and_type; /* high 32 symbol, low 32 type. */ |
| 489 | i64 addend[0]; |
| 490 | } elf64_relocation_t; |
| 491 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 492 | typedef struct |
| 493 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 */ \ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 520 | _ (ARCH_SPECIFIC_HI, 0x7fffffff) /* End of processor-specific */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 532 | typedef enum |
| 533 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 534 | #define _(f,i) ELF_SEGMENT_##f = i, |
| 535 | foreach_elf_segment_type |
| 536 | #undef _ |
| 537 | } elf_segment_type_t; |
| 538 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 539 | typedef enum |
| 540 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 541 | #define _(f,i) ELF_SEGMENT_FLAG_BIT_##f = i, |
| 542 | foreach_elf_segment_flag |
| 543 | #undef _ |
| 544 | } elf_segment_flag_bit_t; |
| 545 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 546 | typedef enum |
| 547 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 560 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 561 | #define _(t,f) t f; |
| 562 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 563 | typedef struct |
| 564 | { |
| 565 | foreach_elf32_dynamic_entry_header} elf32_dynamic_entry_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 566 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 567 | typedef struct |
| 568 | { |
| 569 | foreach_elf64_dynamic_entry_header} elf64_dynamic_entry_t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 */ \ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 637 | _ (FILTER, 0x7fffffff) /* Shared object to get values from */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 638 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 639 | typedef enum |
| 640 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 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 */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 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 */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 668 | #define DF_1_CONFALT 0x00002000 /* Configuration alternative created. */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 694 | typedef struct |
| 695 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 696 | u32 name; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 697 | u32 next_offset; /* byte offset of ver def aux next entry */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 698 | } elf_dynamic_version_definition_aux_t; |
| 699 | |
| 700 | /* Version definition flags. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 701 | #define ELF_DYNAMIC_VERSION_FILE (1 << 0) /* Version definition of file itself */ |
| 702 | #define ELF_DYNAMIC_VERSION_WEAK (1 << 1) /* Weak version identifier */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 707 | #define ELF_DYNAMIC_VERSYM_RESERVED_LO 0xff00 /* Beginning of reserved entries. */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 816 | typedef struct |
| 817 | { |
| 818 | elf64_symbol_t *symbols; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 819 | |
| 820 | u32 section_index; |
| 821 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 822 | u8 *string_table; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 823 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 824 | uword *symbol_by_name; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 825 | } elf_symbol_table_t; |
| 826 | |
| 827 | always_inline void |
| 828 | elf_symbol_table_free (elf_symbol_table_t * s) |
| 829 | { |
| 830 | vec_free (s->symbols); |
| 831 | hash_free (s->symbol_by_name); |
| 832 | } |
| 833 | |
| 834 | always_inline u8 * |
| 835 | elf_symbol_name (elf_symbol_table_t * t, elf64_symbol_t * sym) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 836 | { |
| 837 | return vec_elt_at_index (t->string_table, sym->name); |
| 838 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 839 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 840 | typedef struct |
| 841 | { |
| 842 | elf_relocation_with_addend_t *relocations; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 843 | |
| 844 | u32 section_index; |
| 845 | } elf_relocation_table_t; |
| 846 | |
| 847 | always_inline void |
| 848 | elf_relocation_table_free (elf_relocation_table_t * r) |
| 849 | { |
| 850 | vec_free (r->relocations); |
| 851 | } |
| 852 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 853 | typedef struct |
| 854 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 855 | elf64_section_header_t header; |
| 856 | |
| 857 | u32 index; |
| 858 | |
| 859 | /* Index of segments containing this section. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 860 | uword *segment_index_bitmap; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 861 | |
| 862 | /* Aligned size (included padding not included in |
| 863 | header.file_size). */ |
| 864 | u64 align_size; |
| 865 | |
| 866 | i64 exec_address_change; |
| 867 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 868 | u8 *contents; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 869 | } elf_section_t; |
| 870 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 871 | typedef struct |
| 872 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 873 | elf64_segment_header_t header; |
| 874 | |
| 875 | /* Sections contained in this segment. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 876 | uword *section_index_bitmap; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 877 | |
| 878 | u32 index; |
| 879 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 880 | u8 *contents; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 881 | } elf_segment_t; |
| 882 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 883 | typedef struct |
| 884 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 885 | u8 need_byte_swap; |
| 886 | |
| 887 | u8 parsed_symbols; |
| 888 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 889 | char *file_name; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 890 | |
| 891 | elf_first_header_t first_header; |
| 892 | |
| 893 | elf64_file_header_t file_header; |
| 894 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 895 | elf_segment_t *segments; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 896 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 897 | elf_section_t *sections; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 898 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 899 | uword *section_by_name; |
| 900 | uword *section_by_start_address; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 901 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 902 | elf_symbol_table_t *symbol_tables; |
| 903 | elf_relocation_table_t *relocation_tables; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 904 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 905 | char *interpreter; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 906 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 907 | elf64_dynamic_entry_t *dynamic_entries; |
| 908 | u8 *dynamic_string_table; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 913 | u16 *versym; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 914 | u32 versym_section_index; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 915 | elf_dynamic_version_need_union_t *verneed; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 916 | u32 verneed_section_index; |
| 917 | } elf_main_t; |
| 918 | |
| 919 | always_inline void |
| 920 | elf_main_init (elf_main_t * em) |
| 921 | { |
| 922 | memset (em, 0, sizeof (em[0])); |
| 923 | } |
| 924 | |
| 925 | always_inline void |
| 926 | elf_main_free (elf_main_t * em) |
| 927 | { |
| 928 | uword i; |
| 929 | |
| 930 | for (i = 0; i < vec_len (em->segments); i++) |
| 931 | vec_free (em->segments[i].contents); |
| 932 | vec_free (em->segments); |
| 933 | |
| 934 | for (i = 0; i < vec_len (em->sections); i++) |
| 935 | vec_free (em->sections[i].contents); |
| 936 | vec_free (em->sections); |
| 937 | |
| 938 | hash_free (em->section_by_name); |
| 939 | for (i = 0; i < vec_len (em->symbol_tables); i++) |
| 940 | elf_symbol_table_free (em->symbol_tables + i); |
| 941 | for (i = 0; i < vec_len (em->relocation_tables); i++) |
| 942 | elf_relocation_table_free (em->relocation_tables + i); |
| 943 | |
| 944 | vec_free (em->dynamic_entries); |
| 945 | vec_free (em->interpreter); |
| 946 | } |
| 947 | |
| 948 | always_inline void |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 949 | elf_get_segment_contents (elf_main_t * em, void *data, uword segment_index) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 950 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 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); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 955 | } |
| 956 | |
| 957 | always_inline void * |
| 958 | elf_get_section_contents (elf_main_t * em, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 959 | uword section_index, uword elt_size) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 960 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 961 | elf_section_t *s; |
| 962 | void *result; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 963 | |
| 964 | s = vec_elt_at_index (em->sections, section_index); |
| 965 | |
| 966 | result = 0; |
| 967 | if (vec_len (s->contents) > 0) |
| 968 | { |
| 969 | /* Make vector copy of contents with given element size. */ |
| 970 | result = _vec_resize (result, |
| 971 | vec_len (s->contents) / elt_size, |
| 972 | vec_len (s->contents), |
| 973 | /* header_bytes */ 0, |
| 974 | /* align */ 0); |
Damjan Marion | f1213b8 | 2016-03-13 02:22:06 +0100 | [diff] [blame] | 975 | clib_memcpy (result, s->contents, vec_len (s->contents)); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 976 | } |
| 977 | |
| 978 | return result; |
| 979 | } |
| 980 | |
| 981 | always_inline void |
| 982 | elf_set_section_contents (elf_main_t * em, |
| 983 | uword section_index, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 984 | void *new_contents, uword n_content_bytes) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 985 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 986 | elf_section_t *s; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 987 | |
| 988 | s = vec_elt_at_index (em->sections, section_index); |
| 989 | vec_free (s->contents); |
| 990 | vec_add (s->contents, new_contents, n_content_bytes); |
| 991 | } |
| 992 | |
| 993 | always_inline u8 * |
| 994 | elf_section_name (elf_main_t * em, elf_section_t * s) |
| 995 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 996 | elf_section_t *es = vec_elt_at_index (em->sections, |
| 997 | em-> |
| 998 | file_header.section_header_string_table_index); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 999 | return vec_elt_at_index (es->contents, s->header.name); |
| 1000 | } |
| 1001 | |
| 1002 | always_inline u8 |
| 1003 | elf_swap_u8 (elf_main_t * em, u8 x) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1004 | { |
| 1005 | return x; |
| 1006 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1007 | |
| 1008 | always_inline u16 |
| 1009 | elf_swap_u16 (elf_main_t * em, u16 x) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1010 | { |
| 1011 | return em->need_byte_swap ? clib_byte_swap_u16 (x) : x; |
| 1012 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1013 | |
| 1014 | always_inline u32 |
| 1015 | elf_swap_u32 (elf_main_t * em, u32 x) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1016 | { |
| 1017 | return em->need_byte_swap ? clib_byte_swap_u32 (x) : x; |
| 1018 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1019 | |
| 1020 | always_inline u64 |
| 1021 | elf_swap_u64 (elf_main_t * em, u64 x) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1022 | { |
| 1023 | return em->need_byte_swap ? clib_byte_swap_u64 (x) : x; |
| 1024 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1025 | |
| 1026 | #define FORMAT_ELF_MAIN_SYMBOLS (1 << 0) |
| 1027 | #define FORMAT_ELF_MAIN_RELOCATIONS (1 << 1) |
| 1028 | #define FORMAT_ELF_MAIN_DYNAMIC (1 << 2) |
| 1029 | |
| 1030 | format_function_t format_elf_main; |
| 1031 | format_function_t format_elf_symbol; |
| 1032 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1033 | clib_error_t *elf_read_file (elf_main_t * em, char *file_name); |
| 1034 | clib_error_t *elf_write_file (elf_main_t * em, char *file_name); |
| 1035 | clib_error_t *elf_delete_named_section (elf_main_t * em, char *section_name); |
| 1036 | clib_error_t *elf_parse (elf_main_t * em, void *data, uword data_bytes); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1037 | void elf_parse_symbols (elf_main_t * em); |
| 1038 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1039 | clib_error_t *elf_get_section_by_name (elf_main_t * em, char *section_name, |
| 1040 | elf_section_t ** result); |
| 1041 | clib_error_t *elf_get_section_by_start_address (elf_main_t * em, |
| 1042 | uword start_address, |
| 1043 | elf_section_t ** result); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1044 | |
| 1045 | void |
| 1046 | elf_create_section_with_contents (elf_main_t * em, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1047 | char *section_name, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1048 | elf64_section_header_t * header, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1049 | void *contents, uword n_content_bytes); |
| 1050 | uword elf_delete_segment_with_type (elf_main_t * em, |
| 1051 | elf_segment_type_t segment_type); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1052 | void elf_set_dynamic_entries (elf_main_t * em); |
| 1053 | |
| 1054 | #endif /* included_clib_elf_h */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 1055 | |
| 1056 | /* |
| 1057 | * fd.io coding-style-patch-verification: ON |
| 1058 | * |
| 1059 | * Local Variables: |
| 1060 | * eval: (c-set-style "gnu") |
| 1061 | * End: |
| 1062 | */ |