Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / file-elf.c
blob9ed52c265e3548095ec1de0d0c5f6916ec24a0cb
1 /* file-elf.c
2 * Routines for Executable and Linkable Format
3 * Based on: SYSTEM V APPLICATION BINARY INTERFACE Edition 4.1
4 * https://www.sco.com/developers/devspecs/
5 * https://www.sco.com/developers/gabi/latest/contents.html
6 * https://refspecs.linuxfoundation.org/
7 * https://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
8 * http://dwarfstd.org/doc/DWARF4.pdf
10 * Copyright 2013, Michal Labedzki for Tieto Corporation
11 * Copyright (C) 2019 Peter Wu <peter@lekensteyn.nl>
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include "config.h"
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/expert.h>
25 #include <wsutil/array.h>
27 static dissector_handle_t elf_handle;
29 static int proto_elf;
31 static int hf_elf_magic_bytes;
32 static int hf_elf_file_size;
33 static int hf_elf_header_segment_size;
34 static int hf_elf_blackholes_size;
35 static int hf_elf_blackhole_size;
36 static int hf_elf_overlapping_size;
37 static int hf_elf_segment;
38 static int hf_elf_entry_bytes;
39 static int hf_elf_file_class;
40 static int hf_elf_data_encoding;
41 static int hf_elf_file_version;
42 static int hf_elf_os_abi;
43 static int hf_elf_abi_version;
44 static int hf_elf_file_padding;
45 static int hf_elf_type;
46 static int hf_elf_machine;
47 static int hf_elf_version;
48 static int hf_elf_entry;
49 static int hf_elf_phoff;
50 static int hf_elf_shoff;
51 static int hf_elf64_entry;
52 static int hf_elf64_phoff;
53 static int hf_elf64_shoff;
54 static int hf_elf_flags;
55 static int hf_elf_ehsize;
56 static int hf_elf_phentsize;
57 static int hf_elf_phnum;
58 static int hf_elf_shentsize;
59 static int hf_elf_shnum;
60 static int hf_elf_shstrndx;
61 static int hf_elf_p_type;
62 static int hf_elf_p_type_operating_system_specific;
63 static int hf_elf_p_type_processor_specific;
64 static int hf_elf_p_flags_execute;
65 static int hf_elf_p_flags_write;
66 static int hf_elf_p_flags_read;
67 static int hf_elf_p_flags_reserved;
68 static int hf_elf_p_flags_operating_system_specific;
69 static int hf_elf_p_flags_processor_specific;
70 static int hf_elf_p_offset;
71 static int hf_elf64_p_offset;
72 static int hf_elf_p_vaddr;
73 static int hf_elf64_p_vaddr;
74 static int hf_elf_p_paddr;
75 static int hf_elf64_p_paddr;
76 static int hf_elf_p_filesz;
77 static int hf_elf64_p_filesz;
78 static int hf_elf_p_memsz;
79 static int hf_elf64_p_memsz;
80 static int hf_elf_p_align;
81 static int hf_elf64_p_align;
83 static int hf_elf_sh_name;
84 static int hf_elf_sh_type_user_specific;
85 static int hf_elf_sh_type_operating_system_specific;
86 static int hf_elf_sh_type_processor_specific;
87 static int hf_elf_sh_type;
89 static int hf_elf_sh_flags_processor_specific;
90 static int hf_elf_sh_flags_operating_system_specific;
91 static int hf_elf_sh_flags_reserved;
92 static int hf_elf_sh_flags_tls;
93 static int hf_elf_sh_flags_group;
94 static int hf_elf_sh_flags_os_nonconforming;
95 static int hf_elf_sh_flags_link_order;
96 static int hf_elf_sh_flags_info_link;
97 static int hf_elf_sh_flags_strings;
98 static int hf_elf_sh_flags_merge;
99 static int hf_elf_sh_flags_reserved_8;
100 static int hf_elf_sh_flags_exec_instr;
101 static int hf_elf_sh_flags_alloc;
102 static int hf_elf_sh_flags_write;
103 static int hf_elf_sh_addr;
104 static int hf_elf64_sh_addr;
106 static int hf_elf_sh_offset;
107 static int hf_elf64_sh_offset;
108 static int hf_elf_sh_size;
109 static int hf_elf64_sh_size;
110 static int hf_elf_sh_link;
111 static int hf_elf_sh_info;
112 static int hf_elf_sh_addralign;
113 static int hf_elf64_sh_addralign;
114 static int hf_elf_sh_entsize;
115 static int hf_elf64_sh_entsize;
117 static int hf_elf_eh_frame_length;
118 static int hf_elf_eh_frame_extended_length;
119 static int hf_elf_eh_frame_cie_id;
120 static int hf_elf_eh_frame_version;
121 static int hf_elf_eh_frame_augmentation_string;
122 static int hf_elf_eh_frame_code_alignment_factor;
123 static int hf_elf_eh_frame_data_alignment_factor;
124 static int hf_elf_eh_frame_return_address_register;
125 static int hf_elf_eh_frame_augmentation_length;
126 static int hf_elf_eh_frame_augmentation_data;
127 static int hf_elf_eh_frame_initial_instructions;
129 static int hf_elf_eh_frame_fde_length;
130 static int hf_elf_eh_frame_fde_extended_length;
131 static int hf_elf_eh_frame_fde_cie_pointer;
132 static int hf_elf_eh_frame_fde_pc_begin;
133 static int hf_elf_eh_frame_fde_pc_range;
134 static int hf_elf_eh_frame_fde_augmentation_length;
135 static int hf_elf_eh_frame_fde_augmentation_data;
136 static int hf_elf_eh_frame_fde_call_frame_instructions;
138 static int hf_elf_eh_frame_hdr_version;
139 static int hf_elf_eh_frame_hdr_exception_frame_pointer_encoding;
140 static int hf_elf_eh_frame_hdr_fde_count_encoding;
141 static int hf_elf_eh_frame_hdr_binary_search_table_encoding;
142 static int hf_elf_eh_frame_hdr_eh_frame_ptr;
143 static int hf_elf_eh_frame_hdr_fde_count;
144 static int hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location;
145 static int hf_elf_eh_frame_hdr_binary_search_table_entry_address;
147 static int hf_elf_symbol_table_name_index;
148 static int hf_elf_symbol_table_value;
149 static int hf_elf64_symbol_table_value;
150 static int hf_elf_symbol_table_size;
151 static int hf_elf64_symbol_table_size;
152 static int hf_elf_symbol_table_info;
153 static int hf_elf_symbol_table_info_bind;
154 static int hf_elf_symbol_table_info_type;
155 static int hf_elf_symbol_table_other;
156 static int hf_elf_symbol_table_shndx;
158 static int hf_elf_dynamic_tag;
159 static int hf_elf_dynamic_value;
160 static int hf_elf_dynamic_pointer;
161 static int hf_elf_dynamic_ignored;
162 static int hf_elf_dynamic_unspecified;
163 static int hf_elf64_dynamic_tag;
164 static int hf_elf64_dynamic_value;
165 static int hf_elf64_dynamic_pointer;
166 static int hf_elf64_dynamic_ignored;
167 static int hf_elf64_dynamic_unspecified;
169 static int hf_elf_string;
171 static int hf_dwarf_omit;
172 static int hf_dwarf_upper;
173 static int hf_dwarf_format;
175 static expert_field ei_invalid_segment_size;
176 static expert_field ei_invalid_entry_size;
177 static expert_field ei_cfi_extraneous_data;
178 static expert_field ei_invalid_cie_length;
180 static int ett_elf;
181 static int ett_elf_header;
182 static int ett_elf_program_header;
183 static int ett_elf_program_header_entry;
184 static int ett_elf_section_header;
185 static int ett_elf_section_header_entry;
186 static int ett_elf_segment;
187 static int ett_elf_cfi_record;
188 static int ett_elf_cie_entry;
189 static int ett_elf_fde_entry;
190 static int ett_elf_cie_terminator;
191 static int ett_elf_info;
192 static int ett_elf_black_holes;
193 static int ett_elf_overlapping;
194 static int ett_dwarf_encoding;
195 static int ett_binary_table;
196 static int ett_binary_table_entry;
197 static int ett_symbol_table_entry;
198 static int ett_symbol_table_info;
200 #define REGISTER_32_SIZE 4
201 #define REGISTER_64_SIZE 8
203 static const value_string class_vals[] = {
204 { 0x00, "Invalid class" },
205 { 0x01, "32-bit object" },
206 { 0x02, "64-bit object" },
207 { 0, NULL }
210 static const value_string data_encoding_vals[] = {
211 { 0x00, "None" },
212 { 0x01, "Least Significant Bit" },
213 { 0x02, "Most Significant Bit " },
214 { 0, NULL }
217 static const value_string version_vals[] = {
218 { 0x00, "None" },
219 { 0x01, "Current" },
220 { 0, NULL }
223 static const value_string type_vals[] = {
224 { 0x0000, "No file type" },
225 { 0x0001, "Relocatable file" },
226 { 0x0002, "Executable file" },
227 { 0x0003, "Shared object file" },
228 { 0x0004, "Core file" },
229 { 0xFE00, "Operating system-specific Lo" }, /* From Draft */
230 { 0xFEFF, "Operating system-specific Hi" }, /* From Draft */
231 { 0xFF00, "Processor Specific Lo" },
232 { 0xFFFF, "Processor Specific Hi" },
233 { 0, NULL }
236 /* From https://www.sco.com/developers/gabi/latest/ch4.eheader.html */
237 static const value_string machine_vals[] = {
238 { 0, "No machine" },
239 { 1, "AT&T WE 32100" },
240 { 2, "SPARC" },
241 { 3, "Intel 80386" },
242 { 4, "Motorola 68000" },
243 { 5, "Motorola 88000" },
244 { 6, "Intel MCU" },
245 { 7, "Intel 80860" },
246 { 8, "MIPS I Architecture" },
247 { 9, "IBM System/370 Processor" },
248 { 10, "MIPS RS3000 Little-endian" },
249 { 15, "Hewlett-Packard PA-RISC" },
250 { 17, "Fujitsu VPP500" },
251 { 18, "Enhanced instruction set SPARC" },
252 { 19, "Intel 80960" },
253 { 20, "PowerPC" },
254 { 21, "64-bit PowerPC" },
255 { 22, "IBM System/390 Processor" },
256 { 23, "IBM SPU/SPC" },
257 { 36, "NEC V800" },
258 { 37, "Fujitsu FR20" },
259 { 38, "TRW RH-32" },
260 { 39, "Motorola RCE" },
261 { 40, "ARM 32-bit architecture (AARCH32)" },
262 { 41, "Digital Alpha" },
263 { 42, "Hitachi SH" },
264 { 43, "SPARC Version 9" },
265 { 44, "Siemens TriCore embedded processor" },
266 { 45, "Argonaut RISC Core, Argonaut Technologies Inc." },
267 { 46, "Hitachi H8/300" },
268 { 47, "Hitachi H8/300H" },
269 { 48, "Hitachi H8S" },
270 { 49, "Hitachi H8/500" },
271 { 50, "Intel IA-64 processor architecture" },
272 { 51, "Stanford MIPS-X" },
273 { 52, "Motorola ColdFire" },
274 { 53, "Motorola M68HC12" },
275 { 54, "Fujitsu MMA Multimedia Accelerator" },
276 { 55, "Siemens PCP" },
277 { 56, "Sony nCPU embedded RISC processor" },
278 { 57, "Denso NDR1 microprocessor" },
279 { 58, "Motorola Star*Core processor" },
280 { 59, "Toyota ME16 processor" },
281 { 60, "STMicroelectronics ST100 processor" },
282 { 61, "Advanced Logic Corp. TinyJ embedded processor family" },
283 { 62, "AMD x86-64 architecture" },
284 { 63, "Sony DSP Processor" },
285 { 64, "Digital Equipment Corp. PDP-10" },
286 { 65, "Digital Equipment Corp. PDP-11" },
287 { 66, "Siemens FX66 microcontroller" },
288 { 67, "STMicroelectronics ST9+ 8/16 bit microcontroller" },
289 { 68, "STMicroelectronics ST7 8-bit microcontroller" },
290 { 69, "Motorola MC68HC16 Microcontroller" },
291 { 70, "Motorola MC68HC11 Microcontroller" },
292 { 71, "Motorola MC68HC08 Microcontroller" },
293 { 72, "Motorola MC68HC05 Microcontroller" },
294 { 73, "Silicon Graphics SVx" },
295 { 74, "STMicroelectronics ST19 8-bit microcontroller" },
296 { 75, "Digital VAX" },
297 { 76, "Axis Communications 32-bit embedded processor" },
298 { 77, "Infineon Technologies 32-bit embedded processor" },
299 { 78, "Element 14 64-bit DSP Processor" },
300 { 79, "LSI Logic 16-bit DSP Processor" },
301 { 80, "Donald Knuth's educational 64-bit processor" },
302 { 81, "Harvard University machine-independent object files" },
303 { 82, "SiTera Prism" },
304 { 83, "Atmel AVR 8-bit microcontroller" },
305 { 84, "Fujitsu FR30" },
306 { 85, "Mitsubishi D10V" },
307 { 86, "Mitsubishi D30V" },
308 { 87, "NEC v850" },
309 { 88, "Mitsubishi M32R" },
310 { 89, "Matsushita MN10300" },
311 { 90, "Matsushita MN10200" },
312 { 91, "picoJava" },
313 { 92, "OpenRISC 32-bit embedded processor" },
314 { 93, "ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)" },
315 { 94, "Tensilica Xtensa Architecture" },
316 { 95, "Alphamosaic VideoCore processor" },
317 { 96, "Thompson Multimedia General Purpose Processor" },
318 { 97, "National Semiconductor 32000 series" },
319 { 98, "Tenor Network TPC processor" },
320 { 99, "Trebia SNP 1000 processor" },
321 { 100, "STMicroelectronics (www.st.com) ST200 microcontroller" },
322 { 101, "Ubicom IP2xxx microcontroller family" },
323 { 102, "MAX Processor" },
324 { 103, "National Semiconductor CompactRISC microprocessor" },
325 { 104, "Fujitsu F2MC16" },
326 { 105, "Texas Instruments embedded microcontroller msp430" },
327 { 106, "Analog Devices Blackfin (DSP) processor" },
328 { 107, "S1C33 Family of Seiko Epson processors" },
329 { 108, "Sharp embedded microprocessor" },
330 { 109, "Arca RISC Microprocessor" },
331 { 110, "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University" },
332 { 111, "eXcess: 16/32/64-bit configurable embedded CPU" },
333 { 112, "Icera Semiconductor Inc. Deep Execution Processor" },
334 { 113, "Altera Nios II soft-core processor" },
335 { 114, "National Semiconductor CompactRISC CRX microprocessor" },
336 { 115, "Motorola XGATE embedded processor" },
337 { 116, "Infineon C16x/XC16x processor" },
338 { 117, "Renesas M16C series microprocessors" },
339 { 118, "Microchip Technology dsPIC30F Digital Signal Controller" },
340 { 119, "Freescale Communication Engine RISC core" },
341 { 120, "Renesas M32C series microprocessors" },
342 { 131, "Altium TSK3000 core" },
343 { 132, "Freescale RS08 embedded processor" },
344 { 133, "Analog Devices SHARC family of 32-bit DSP processors" },
345 { 134, "Cyan Technology eCOG2 microprocessor" },
346 { 135, "Sunplus S+core7 RISC processor" },
347 { 136, "New Japan Radio (NJR) 24-bit DSP Processor" },
348 { 137, "Broadcom VideoCore III processor" },
349 { 138, "RISC processor for Lattice FPGA architecture" },
350 { 139, "Seiko Epson C17 family" },
351 { 140, "The Texas Instruments TMS320C6000 DSP family" },
352 { 141, "The Texas Instruments TMS320C2000 DSP family" },
353 { 142, "The Texas Instruments TMS320C55x DSP family" },
354 { 143, "Texas Instruments Application Specific RISC Processor, 32bit fetch" },
355 { 144, "Texas Instruments Programmable Realtime Unit" },
356 { 160, "STMicroelectronics 64bit VLIW Data Signal Processor" },
357 { 161, "Cypress M8C microprocessor" },
358 { 162, "Renesas R32C series microprocessors" },
359 { 163, "NXP Semiconductors TriMedia architecture family" },
360 { 164, "QUALCOMM DSP6 Processor" },
361 { 165, "Intel 8051 and variants" },
362 { 166, "STMicroelectronics STxP7x family of configurable and extensible RISC processors" },
363 { 167, "Andes Technology compact code size embedded RISC processor family" },
364 { 168, "Cyan Technology eCOG1X family" },
365 { 168, "Cyan Technology eCOG1X family" },
366 { 169, "Dallas Semiconductor MAXQ30 Core Micro-controllers" },
367 { 170, "New Japan Radio (NJR) 16-bit DSP Processor" },
368 { 171, "M2000 Reconfigurable RISC Microprocessor" },
369 { 172, "Cray Inc. NV2 vector architecture" },
370 { 173, "Renesas RX family" },
371 { 174, "Imagination Technologies META processor architecture" },
372 { 175, "MCST Elbrus general purpose hardware architecture" },
373 { 176, "Cyan Technology eCOG16 family" },
374 { 177, "National Semiconductor CompactRISC CR16 16-bit microprocessor" },
375 { 178, "Freescale Extended Time Processing Unit" },
376 { 179, "Infineon Technologies SLE9X core" },
377 { 180, "Intel L10M" },
378 { 181, "Intel K10M" },
379 { 182, "Reserved for future Intel use" },
380 { 183, "ARM 64-bit architecture (AARCH64)" },
381 { 184, "Reserved for future ARM use" },
382 { 185, "Atmel Corporation 32-bit microprocessor family" },
383 { 186, "STMicroeletronics STM8 8-bit microcontroller" },
384 { 187, "Tilera TILE64 multicore architecture family" },
385 { 188, "Tilera TILEPro multicore architecture family" },
386 { 189, "Xilinx MicroBlaze 32-bit RISC soft processor core" },
387 { 190, "NVIDIA CUDA architecture" },
388 { 191, "Tilera TILE-Gx multicore architecture family" },
389 { 192, "CloudShield architecture family" },
390 { 193, "KIPO-KAIST Core-A 1st generation processor family" },
391 { 194, "KIPO-KAIST Core-A 2nd generation processor family" },
392 { 195, "Synopsys ARCompact V2" },
393 { 196, "Open8 8-bit RISC soft processor core" },
394 { 197, "Renesas RL78 family" },
395 { 198, "Broadcom VideoCore V processor" },
396 { 199, "Renesas 78KOR family" },
397 { 200, "Freescale 56800EX Digital Signal Controller (DSC)" },
398 { 201, "Beyond BA1 CPU architecture" },
399 { 202, "Beyond BA2 CPU architecture" },
400 { 203, "XMOS xCORE processor family" },
401 { 204, "Microchip 8-bit PIC(r) family" },
402 { 205, "Reserved by Intel" },
403 { 206, "Reserved by Intel" },
404 { 207, "Reserved by Intel" },
405 { 208, "Reserved by Intel" },
406 { 209, "Reserved by Intel" },
407 { 210, "KM211 KM32 32-bit processor" },
408 { 211, "KM211 KMX32 32-bit processor" },
409 { 212, "KM211 KMX16 16-bit processor" },
410 { 213, "KM211 KMX8 8-bit processor" },
411 { 214, "KM211 KVARC processor" },
412 { 215, "Paneve CDP architecture family" },
413 { 216, "Cognitive Smart Memory Processor" },
414 { 217, "Bluechip Systems CoolEngine" },
415 { 218, "Nanoradio Optimized RISC" },
416 { 219, "CSR Kalimba architecture family" },
417 { 220, "Zilog Z80" },
418 { 221, "Controls and Data Services VISIUMcore processor" },
419 { 222, "FTDI Chip FT32 high performance 32-bit RISC architecture" },
420 { 223, "Moxie processor family" },
421 { 224, "AMD GPU architecture" },
422 { 243, "RISC-V" },
423 { 247, "Linux kernel bpf virtual machine" }, /* From LLVM / glibc 2.24 */
424 { 252, "C-SKY" }, /* from glibc 2.30 elf/elf.h commit 5fbcd76351ee */
425 { 0, NULL }
427 static value_string_ext machine_vals_ext = VALUE_STRING_EXT_INIT(machine_vals);
429 /* From Draft */
430 static const value_string os_abi_vals[] = {
431 { 0x00, "No extensions or unspecified" },
432 { 0x01, "Hewlett-Packard HP-UX" },
433 { 0x02, "NetBSD" },
434 { 0x03, "GNU (historical alias: Linux)" },
435 { 0x06, "Sun Solaris" },
436 { 0x07, "AIX" },
437 { 0x08, "IRIX" },
438 { 0x09, "FreeBSD" },
439 { 0x0A, "Compaq TRU64 UNIX" },
440 { 0x0B, "Novell Modesto" },
441 { 0x0C, "Open BSD" },
442 { 0x0D, "Open VMS" },
443 { 0x0E, "Hewlett-Packard Non-Stop Kernel" },
444 { 0x0F, "Amiga Research OS" },
445 { 0x10, "The FenixOS highly scalable multi-core OS" },
446 { 0x11, "Nuxi CloudABI" },
447 { 0x12, "Stratus Technologies OpenVOS" },
448 { 0, NULL }
450 static value_string_ext os_abi_vals_ext = VALUE_STRING_EXT_INIT(os_abi_vals);
452 /* https://www.sco.com/developers/gabi/latest/ch5.pheader.html */
453 static const range_string p_type_rvals[] = {
454 { 0, 0, "PT_NULL" },
455 { 1, 1, "PT_LOAD" },
456 { 2, 2, "PT_DYNAMIC" },
457 { 3, 3, "PT_INTERP" },
458 { 4, 4, "PT_NOTE" },
459 { 5, 5, "PT_SHLIB" },
460 { 6, 6, "PT_PHDR" },
461 { 7, 7, "PT_TLS" },
462 { 0x60000000, 0x6fffffff, "PT_OS" },
463 { 0x70000000, 0x7fffffff, "PT_PROC" },
464 { 0, 0, NULL }
467 /* https://www.sco.com/developers/gabi/latest/ch4.sheader.html */
468 static const range_string sh_type_rvals[] = {
469 { 0, 0, "SHT_NULL" },
470 { 1, 1, "SHT_PROGBITS" },
471 { 2, 2, "SHT_SYMTAB" },
472 { 3, 3, "SHT_STRTAB" },
473 { 4, 4, "SHT_RELA" },
474 { 5, 5, "SHT_HASH" },
475 { 6, 6, "SHT_DYNAMIC" },
476 { 7, 7, "SHT_NOTE" },
477 { 8, 8, "SHT_NOBITS" },
478 { 9, 9, "SHT_REL" },
479 { 10, 10, "SHT_SHLIB" },
480 { 11, 11, "SHT_DYNSYM" },
481 { 14, 14, "SHT_INIT_ARRAY" },
482 { 15, 15, "SHT_FINI_ARRAY" },
483 { 16, 16, "SHT_PREINIT_ARRAY" },
484 { 17, 17, "SHT_GROUP" },
485 { 18, 18, "SHT_SYMTAB_SHNDX" },
486 { 0x60000000, 0x6fffffff, "SHT_OS" },
487 { 0x70000000, 0x7fffffff, "SHT_PROC" },
488 { 0x80000000, 0xffffffff, "SHT_USER" },
489 { 0, 0, NULL }
492 static const value_string eh_dwarf_upper[] = {
493 { 0x0, "Normal Value" },
494 { 0x1, "Value is relative to the current program counter. (DW_EH_PE_pcrel)" },
495 { 0x2, "Value is relative to the beginning of the .text section. (DW_EH_PE_textrel)" },
496 { 0x3, "Value is relative to the beginning of the .got or .eh_frame_hdr section. (DW_EH_PE_datarel)" },
497 { 0x4, "Value is relative to the beginning of the function. (DW_EH_PE_funcrel)" },
498 { 0x5, "Value is aligned to an address unit sized boundary. (DW_EH_PE_aligned)" },
499 { 0, NULL }
502 static const value_string eh_dwarf_format[] = {
503 { 0x0, "The Value is a literal pointer whose size is determined by the architecture. (DW_EH_PE_absptr)" },
504 { 0x1, "Unsigned value is encoded using the Little Endian Base 128 (LEB128). (DW_EH_PE_uleb128)" },
505 { 0x2, "A 2 bytes unsigned value. (DW_EH_PE_udata2)" },
506 { 0x3, "A 4 bytes unsigned value. (DW_EH_PE_udata4)" },
507 { 0x4, "An 8 bytes unsigned value. (DW_EH_PE_udata8)" },
508 { 0x9, "Signed value is encoded using the Little Endian Base 128 (LEB128). (DW_EH_PE_sleb128)" },
509 { 0xA, "A 2 bytes signed value. (DW_EH_PE_sdata2)" },
510 { 0xB, "A 4 bytes signed value. (DW_EH_PE_sdata4)" },
511 { 0xC, "An 8 bytes signed value. (DW_EH_PE_sdata8)" },
512 { 0, NULL }
515 static const value_string symbol_table_other_vals[] = {
516 { 0, "Default" },
517 { 1, "Internal" },
518 { 2, "Hidden" },
519 { 3, "Protected" },
520 { 0, NULL }
524 static const value_string symbol_table_info_bind_vals[] = {
525 { 0, "Local" },
526 { 1, "Global" },
527 { 2, "Weak" },
528 { 10, "Operating System Specific" },
529 { 11, "Operating System Specific" },
530 { 12, "Operating System Specific" },
531 { 13, "Processor Specific" },
532 { 14, "Processor Specific" },
533 { 15, "Processor Specific" },
534 { 0, NULL }
537 static const value_string symbol_table_info_type_vals[] = {
538 { 0, "No Type" },
539 { 1, "Object" },
540 { 2, "Function" },
541 { 3, "Section" },
542 { 4, "File" },
543 { 5, "Common" },
544 { 6, "Thread-Local Storage" },
545 { 10, "Operating System Specific" },
546 { 11, "Operating System Specific" },
547 { 12, "Operating System Specific" },
548 { 13, "Processor Specific" },
549 { 14, "Processor Specific" },
550 { 15, "Processor Specific" },
551 { 0, NULL }
553 static value_string_ext symbol_table_info_type_vals_ext = VALUE_STRING_EXT_INIT(symbol_table_info_type_vals);
555 static const range_string symbol_table_shndx_rvals[] = {
556 { 0x0000, 0x0000, "Undefined" },
557 { 0x0001, 0xfeff, "Normal Section" },
558 { 0xff00, 0xff1f, "Processor Specific" },
559 { 0xff20, 0xff3f, "Operating System Specific" },
560 { 0xff40, 0xfff0, "Reserved" },
561 { 0xfff1, 0xfff1, "Absolute Value" },
562 { 0xfff2, 0xfff2, "Common" },
563 { 0xfff3, 0xfffe, "Reserved" },
564 { 0xffff, 0xffff, "Xindex" },
565 { 0, 0, NULL }
568 static const range_string dynamic_tag_rvals[] = {
569 { 0, 0, "NULL" },
570 { 1, 1, "Needed" },
571 { 2, 2, "Procedure Linkage Table Size" },
572 { 3, 3, "Procedure Linkage Table and/or the Global Offset Table Address" },
573 { 4, 4, "Hash" },
575 { 5, 5, "String Table Address" },
576 { 6, 6, "Symbol Table Address" },
577 { 7, 7, "Relocation Table Address" },
578 { 8, 8, "Relocation Table Size" },
579 { 9, 9, "Relocation Table Entry Size" },
580 { 10, 10, "String Table Size" },
581 { 11, 11, "Symbol Table Entry Size" },
582 { 12, 12, "Initialization Function Address" },
583 { 13, 13, "Termination Function Address" },
584 { 14, 14, "Shared Object Name Offset" },
585 { 15, 15, "Search Library Path (Rpath)" },
586 { 16, 16, "Symbolic" },
587 { 17, 17, "Relocation Table with Implicit Addends" },
588 { 18, 18, "Relocation Table with Implicit Addends Size" },
589 { 19, 19, "Relocation Table with Implicit Addends Entry Size" },
590 { 20, 20, "Procedure Linkage Table Relocation Entry Type" },
591 { 21, 21, "Debug" },
592 { 22, 22, "TEXT Relocation" },
593 { 23, 23, "Procedure Linkage Table Relocation Entries Address" },
594 { 24, 24, "Bind Now" },
595 { 25, 25, "Initialization Functions Array Address" },
596 { 26, 26, "Termination Functions Array Address" },
597 { 27, 27, "Initialization Functions Array Size" },
598 { 28, 28, "Termination Functions Array Size" },
599 { 29, 29, "Run Path" },
600 { 30, 30, "Flags" },
601 { 31, 31, "Preinitialization Functions Array Address" },
602 { 32, 32, "Preinitialization Functions Array Size" },
603 { 33, 33, "Encoding" },
605 { 0x6000000D, 0x6ffff000, "Operating System Specific" },
606 { 0x70000000, 0x7fffffff, "Processor Specific" },
607 { 0, 0, NULL }
611 typedef struct _segment_info_t {
612 uint64_t offset;
613 uint64_t size;
614 const char *name;
615 } segment_info_t;
617 void proto_register_elf(void);
618 void proto_reg_handoff_elf(void);
620 static int
621 dissect_leb128(tvbuff_t *tvb, int offset, int64_t *value)
623 unsigned start_offset = offset;
624 unsigned shift = 0;
625 uint8_t byte;
627 *value = 0;
629 do {
630 byte = tvb_get_uint8(tvb, offset);
631 offset += 1;
633 *value |= ((uint64_t)(byte & 0x7F) << shift);
634 shift += 7;
635 } while ((byte & 0x80) && (shift < 64));
637 if (shift < 64 && byte & 0x40)
638 *value |= - ((int64_t)1 << shift);
640 return offset - start_offset;
643 /* Wireshark support "offset" as int, but ELF needed uint64_t size, so check if there is no overflow */
644 static int
645 value_guard(uint64_t value)
647 DISSECTOR_ASSERT_HINT(value <= INT_MAX, "Too big file - not supported");
649 return (int) value;
652 static uint8_t
653 dissect_dwarf_encoding(tvbuff_t *tvb, int offset, proto_item *item)
655 uint8_t value;
656 proto_tree *tree;
658 tree = proto_item_add_subtree(item, ett_dwarf_encoding);
660 value = tvb_get_uint8(tvb, offset);
662 if (value == 0xFF) {
663 proto_tree_add_item(tree, hf_dwarf_omit, tvb, offset, 1, ENC_NA);
664 } else {
665 proto_tree_add_item(tree, hf_dwarf_upper, tvb, offset, 1, ENC_NA);
666 proto_tree_add_item(tree, hf_dwarf_format, tvb, offset, 1, ENC_NA);
669 return value;
672 #define LENGTH_LEB128 -1
673 #define LENGTH_ULEB128 -2
675 static int8_t
676 get_dwarf_extension_length(uint8_t format, unsigned register_size)
678 switch (format & 0x0F) {
679 case 0x0:
680 return register_size;
681 case 0x1:
682 return LENGTH_ULEB128;
683 case 0x2:
684 return 2;
685 case 0x3:
686 return 4;
687 case 0x4:
688 return 8;
689 case 0x9:
690 return LENGTH_LEB128;
691 case 0xA:
692 return 2;
693 case 0xB:
694 return 4;
695 case 0xC:
696 return 8;
699 return 0;
702 static const char *
703 get_section_name_offset(wmem_allocator_t *scope, tvbuff_t *tvb, uint64_t shoff, uint16_t shnum, uint16_t shentsize, uint16_t shndx, uint64_t shstrtab_offset, unsigned machine_encoding)
705 int offset;
706 uint32_t sh_name;
708 if (shndx > shnum)
709 return NULL;
711 offset = value_guard(shoff + (uint32_t)shndx * (uint32_t)shentsize);
712 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
713 return tvb_get_stringz_enc(scope, tvb, value_guard(shstrtab_offset + sh_name), NULL, ENC_ASCII);
716 #define MAX_TAG_TO_TYPE 34
717 static int
718 dissect_dynamic(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *entry_tree, proto_item *entry_item,
719 int offset, int register_size, unsigned machine_encoding)
721 enum enum_tag_type {
722 DYNAMIC_TYPE_VALUE,
723 DYNAMIC_TYPE_POINTER,
724 DYNAMIC_TYPE_IGNORED,
725 DYNAMIC_TYPE_UNSPECIFIED
728 uint64_t tag;
729 static const enum enum_tag_type tag_to_type[MAX_TAG_TO_TYPE] = {
730 DYNAMIC_TYPE_IGNORED,
731 DYNAMIC_TYPE_VALUE,
732 DYNAMIC_TYPE_VALUE,
733 DYNAMIC_TYPE_POINTER,
734 DYNAMIC_TYPE_POINTER,
735 DYNAMIC_TYPE_POINTER,
736 DYNAMIC_TYPE_POINTER,
737 DYNAMIC_TYPE_POINTER,
738 DYNAMIC_TYPE_VALUE,
739 DYNAMIC_TYPE_VALUE,
740 DYNAMIC_TYPE_VALUE,
741 DYNAMIC_TYPE_VALUE,
742 DYNAMIC_TYPE_POINTER,
743 DYNAMIC_TYPE_POINTER,
744 DYNAMIC_TYPE_VALUE,
745 DYNAMIC_TYPE_VALUE,
746 DYNAMIC_TYPE_IGNORED,
747 DYNAMIC_TYPE_POINTER,
748 DYNAMIC_TYPE_VALUE,
749 DYNAMIC_TYPE_VALUE,
750 DYNAMIC_TYPE_VALUE,
751 DYNAMIC_TYPE_POINTER,
752 DYNAMIC_TYPE_IGNORED,
753 DYNAMIC_TYPE_POINTER,
754 DYNAMIC_TYPE_IGNORED,
755 DYNAMIC_TYPE_POINTER,
756 DYNAMIC_TYPE_POINTER,
757 DYNAMIC_TYPE_VALUE,
758 DYNAMIC_TYPE_VALUE,
759 DYNAMIC_TYPE_VALUE,
760 DYNAMIC_TYPE_VALUE,
761 DYNAMIC_TYPE_UNSPECIFIED,
762 DYNAMIC_TYPE_POINTER,
763 DYNAMIC_TYPE_VALUE
766 if (register_size == REGISTER_32_SIZE) {
767 proto_tree_add_item(entry_tree, hf_elf_dynamic_tag, tvb, offset, 4, machine_encoding);
768 tag = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
769 offset += 4;
771 if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_VALUE)
772 proto_tree_add_item(entry_tree, hf_elf_dynamic_value, tvb, offset, 4, machine_encoding);
773 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_POINTER)
774 proto_tree_add_item(entry_tree, hf_elf_dynamic_pointer, tvb, offset, 4, machine_encoding);
775 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_IGNORED)
776 proto_tree_add_item(entry_tree, hf_elf_dynamic_ignored, tvb, offset, 4, machine_encoding);
777 else
778 proto_tree_add_item(entry_tree, hf_elf_dynamic_unspecified, tvb, offset, 4, machine_encoding);
779 offset += 4;
780 } else {
781 proto_item *pitem;
783 pitem = proto_tree_add_item(entry_tree, hf_elf64_dynamic_tag, tvb, offset, 8, machine_encoding);
784 tag = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
785 proto_item_append_text(pitem, " (%s)", rval_to_str_const(value_guard(tag), dynamic_tag_rvals, "Unknown"));
786 offset += 8;
788 if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_VALUE)
789 proto_tree_add_item(entry_tree, hf_elf64_dynamic_value, tvb, offset, 8, machine_encoding);
790 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_POINTER)
791 proto_tree_add_item(entry_tree, hf_elf64_dynamic_pointer, tvb, offset, 8, machine_encoding);
792 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_IGNORED)
793 proto_tree_add_item(entry_tree, hf_elf64_dynamic_ignored, tvb, offset, 8, machine_encoding);
794 else
795 proto_tree_add_item(entry_tree, hf_elf64_dynamic_unspecified, tvb, offset, 8, machine_encoding);
796 offset += 8;
799 proto_item_append_text(entry_item, ": %s", rval_to_str_const(value_guard(tag), dynamic_tag_rvals, "Unknown"));
801 return offset;
804 static int
805 dissect_symbol_table(tvbuff_t *tvb, packet_info *pinfo, proto_tree *entry_tree, proto_item *entry_item,
806 int offset, int register_size, unsigned machine_encoding, uint64_t strtab_offset,
807 uint64_t shoff, uint16_t shnum, uint16_t shentsize, uint64_t shstrtab_offset)
809 proto_item *pitem;
810 proto_item *info_item;
811 proto_tree *info_tree;
812 uint16_t shndx;
813 uint32_t name_index;
814 const char *section_name;
815 const char *name;
816 uint8_t info_bind;
817 uint8_t info_type;
819 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_name_index, tvb, offset, 4, machine_encoding);
820 if (strtab_offset) {
821 name_index = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
822 name = tvb_get_stringz_enc(pinfo->pool, tvb, value_guard(strtab_offset + name_index), NULL, ENC_ASCII);
823 if (name) {
824 proto_item_append_text(pitem, ": %s", name);
825 proto_item_append_text(entry_item, ": %s", name);
828 offset += 4;
830 if (register_size == REGISTER_32_SIZE) {
831 proto_tree_add_item(entry_tree, hf_elf_symbol_table_value, tvb, offset, 4, machine_encoding);
832 offset += 4;
834 proto_tree_add_item(entry_tree, hf_elf_symbol_table_size, tvb, offset, 4, machine_encoding);
835 offset += 4;
837 info_item = proto_tree_add_item(entry_tree, hf_elf_symbol_table_info, tvb, offset, 1, machine_encoding);
838 info_tree = proto_item_add_subtree(info_item, ett_symbol_table_info);
839 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_bind, tvb, offset, 1, machine_encoding);
840 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_type, tvb, offset, 1, machine_encoding);
841 info_bind = tvb_get_uint8(tvb, offset) >> 4;
842 info_type = tvb_get_uint8(tvb, offset) & 0x0F;
843 offset += 1;
845 proto_tree_add_item(entry_tree, hf_elf_symbol_table_other, tvb, offset, 1, machine_encoding);
846 offset += 1;
848 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_shndx, tvb, offset, 2, machine_encoding);
849 shndx = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
850 if (shndx <= shnum) {
851 section_name = get_section_name_offset(pinfo->pool, tvb, shoff, shnum, shentsize, shndx, shstrtab_offset, machine_encoding);
852 if (section_name && section_name[0] != '\0')
853 proto_item_append_text(pitem, " (%u: %s)", shndx, section_name);
854 } else {
855 proto_item_append_text(pitem, " (%u)", shndx);
857 offset += 2;
858 } else {
859 info_item = proto_tree_add_item(entry_tree, hf_elf_symbol_table_info, tvb, offset, 1, machine_encoding);
860 info_tree = proto_item_add_subtree(info_item, ett_symbol_table_info);
861 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_bind, tvb, offset, 1, machine_encoding);
862 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_type, tvb, offset, 1, machine_encoding);
863 info_bind = tvb_get_uint8(tvb, offset) >> 4;
864 info_type = tvb_get_uint8(tvb, offset) & 0x0F;
865 offset += 1;
867 proto_tree_add_item(entry_tree, hf_elf_symbol_table_other, tvb, offset, 1, machine_encoding);
868 offset += 1;
870 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_shndx, tvb, offset, 2, machine_encoding);
871 shndx = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
872 if (shndx <= shnum) {
873 section_name = get_section_name_offset(pinfo->pool, tvb, shoff, shnum, shentsize, shndx, shstrtab_offset, machine_encoding);
874 if (section_name && section_name[0] != '\0')
875 proto_item_append_text(pitem, " (%u: %s)", shndx, section_name);
876 } else {
877 proto_item_append_text(pitem, " (%u)", shndx);
879 offset += 2;
881 proto_tree_add_item(entry_tree, hf_elf64_symbol_table_value, tvb, offset, 8, machine_encoding);
882 offset += 8;
884 proto_tree_add_item(entry_tree, hf_elf64_symbol_table_size, tvb, offset, 8, machine_encoding);
885 offset += 8;
888 proto_item_append_text(info_item, " (Bind: %s, Type: %s)",
889 val_to_str_const(info_bind, symbol_table_info_bind_vals, "Unknown"),
890 val_to_str_ext_const(info_type, &symbol_table_info_type_vals_ext, "Unknown"));
892 proto_item_append_text(entry_item, " (Bind: %s, Type: %s)",
893 val_to_str_const(info_bind, symbol_table_info_bind_vals, "Unknown"),
894 val_to_str_ext_const(info_type, &symbol_table_info_type_vals_ext, "Unknown"));
896 return offset;
899 static int
900 dissect_eh_frame_hdr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *segment_tree,
901 int offset, int segment_size _U_, int register_size, unsigned machine_encoding)
903 proto_item *item;
904 proto_tree *table_tree;
905 uint8_t format;
906 int efp_length;
907 int fde_count_length;
908 int table_entry_length;
909 uint64_t fde_count;
910 unsigned i_entry;
912 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_version, tvb, offset, 1, machine_encoding);
913 offset += 1;
915 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_exception_frame_pointer_encoding, tvb, offset, 1, machine_encoding);
916 format = dissect_dwarf_encoding(tvb, offset, item);
917 efp_length = get_dwarf_extension_length(format, register_size);
918 offset += 1;
920 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_fde_count_encoding, tvb, offset, 1, machine_encoding);
921 format = dissect_dwarf_encoding(tvb, offset, item);
922 fde_count_length = get_dwarf_extension_length(format, register_size);
923 offset += 1;
925 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_binary_search_table_encoding, tvb, offset, 1, machine_encoding);
926 format = dissect_dwarf_encoding(tvb, offset, item);
927 table_entry_length = get_dwarf_extension_length(format, register_size);
928 offset += 1;
930 if (efp_length == LENGTH_ULEB128) {
931 uint64_t value;
933 efp_length = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_PROTOBUF);
934 } else if (efp_length == LENGTH_LEB128) {
935 int64_t value;
937 efp_length = dissect_leb128(tvb, offset, &value);
940 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_eh_frame_ptr, tvb, offset, efp_length, machine_encoding);
941 offset += efp_length;
944 if (fde_count_length == LENGTH_ULEB128) {
945 fde_count_length = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &fde_count, ENC_VARINT_PROTOBUF);
946 } else if (fde_count_length == LENGTH_LEB128) {
947 int64_t value;
949 fde_count_length = dissect_leb128(tvb, offset, &value);
950 fde_count = (uint64_t) value;
951 } else {
952 if (fde_count_length == 0) fde_count_length = register_size;
954 switch(fde_count_length) {
955 case 2:
956 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
957 break;
958 case 4:
959 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
960 break;
961 case 8:
962 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
963 break;
964 case 0:
965 default:
966 fde_count = 0;
967 break;
971 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_fde_count, tvb, offset,
972 fde_count_length, machine_encoding);
973 offset += fde_count_length;
975 if (table_entry_length == LENGTH_ULEB128) {
976 uint64_t value;
978 table_entry_length = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_PROTOBUF);
979 } else if (table_entry_length == LENGTH_LEB128) {
980 int64_t value;
982 table_entry_length = dissect_leb128(tvb, offset, &value);
985 i_entry = 0;
987 table_tree = proto_tree_add_subtree(segment_tree, tvb, offset, value_guard(fde_count * table_entry_length * 2),
988 ett_binary_table, NULL, "Binary Search Table");
990 while (++i_entry <= fde_count) {
991 proto_tree *entry_tree;
993 entry_tree = proto_tree_add_subtree_format(table_tree, tvb, offset, table_entry_length * 2, ett_binary_table_entry,
994 NULL, "Binary Table Entry #%u", i_entry);
996 proto_tree_add_item(entry_tree, hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location, tvb, offset, table_entry_length, machine_encoding);
997 offset += table_entry_length;
999 proto_tree_add_item(entry_tree, hf_elf_eh_frame_hdr_binary_search_table_entry_address, tvb, offset, table_entry_length, machine_encoding);
1000 offset += table_entry_length;
1003 return offset;
1007 static int
1008 dissect_eh_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *segment_tree,
1009 int offset, int segment_size, int register_size _U_, unsigned machine_encoding)
1011 proto_tree *cfi_tree = NULL;
1012 proto_item *cfi_tree_item = NULL;
1013 proto_tree *entry_tree;
1014 proto_item *pi = NULL;
1015 uint64_t length;
1016 unsigned lengths_size;
1017 bool is_cie;
1018 unsigned entry_size, entry_end = 0;
1019 unsigned cfi_size = 0;
1020 uint64_t unsigned_value;
1021 int64_t signed_value;
1022 int size;
1023 const char *augmentation_string = "";
1024 bool is_extended_length;
1025 int start_offset = offset;
1026 unsigned cfi_number = 0;
1027 int entry_number = 0;
1029 while (offset - start_offset < segment_size) {
1030 length = (machine_encoding == ENC_BIG_ENDIAN) ?
1031 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1032 is_extended_length = length == 0xFFFFFFFF;
1033 if (is_extended_length) {
1034 length = (machine_encoding == ENC_BIG_ENDIAN) ?
1035 tvb_get_ntoh64(tvb, offset + 4) :
1036 tvb_get_letoh64(tvb, offset + 4);
1038 /* CIE ID/pointer is located after Length (4 bytes), or Length (4 bytes)
1039 * + Extended Length (8 bytes). Entry is CIE when field is 0. */
1040 lengths_size = is_extended_length ? 12 : 4;
1041 is_cie = length == 0 || tvb_get_ntohl(tvb, offset + lengths_size) == 0;
1042 entry_size = value_guard(length + lengths_size);
1043 entry_end = offset + entry_size;
1045 if (length == 0) {
1046 /* CIE Terminator, add it directly under the Segment tree as we stop
1047 * processing after this item. */
1048 entry_tree = proto_tree_add_subtree(segment_tree,
1049 tvb, offset, entry_size,
1050 ett_elf_cie_terminator, NULL, "CIE Terminator");
1051 } else if (cfi_number == 0 || is_cie) {
1052 /* New CIE, so create a new CFI subtree and reset FDE Entry. */
1053 ++cfi_number;
1054 cfi_tree = proto_tree_add_subtree_format(segment_tree,
1055 tvb, offset, entry_size, ett_elf_cfi_record, &cfi_tree_item,
1056 "Call Frame Information Entry %i", cfi_number);
1057 entry_tree = proto_tree_add_subtree(cfi_tree, tvb, offset,
1058 entry_size, ett_elf_cie_entry, NULL, "Common Information Entry");
1059 cfi_size = entry_size;
1060 entry_number = 0;
1061 } else {
1062 /* FDE, add it in the CFI subtree. */
1063 ++entry_number;
1064 cfi_size += entry_size;
1065 proto_item_set_len(cfi_tree_item, cfi_size);
1066 entry_tree = proto_tree_add_subtree_format(cfi_tree,
1067 tvb, offset, entry_size, ett_elf_fde_entry, NULL,
1068 "Frame Description Entry %i", entry_number);
1071 pi = proto_tree_add_item(entry_tree, is_cie ?
1072 hf_elf_eh_frame_length :
1073 hf_elf_eh_frame_fde_length,
1074 tvb, offset, 4, machine_encoding);
1075 offset += 4;
1077 if (is_extended_length) {
1078 pi = proto_tree_add_item(entry_tree, is_cie ?
1079 hf_elf_eh_frame_extended_length :
1080 hf_elf_eh_frame_fde_extended_length,
1081 tvb, offset, 8, machine_encoding);
1082 offset += 8;
1085 /* CIE terminator */
1086 if (length == 0)
1087 break;
1089 /* CIE ID (8) + Augment. Str (1) + CAF+DAF+Aug.Len (3) = 12 (min. length) */
1090 if (length < 12 || entry_end - start_offset > (uint64_t)segment_size) {
1091 expert_add_info(pinfo, pi, &ei_invalid_cie_length);
1092 return offset;
1095 proto_tree_add_item(entry_tree, is_cie ?
1096 hf_elf_eh_frame_cie_id :
1097 hf_elf_eh_frame_fde_cie_pointer,
1098 tvb, offset, 4, machine_encoding);
1099 offset += 4;
1100 if (is_cie) {
1101 proto_tree_add_item(entry_tree, hf_elf_eh_frame_version,
1102 tvb, offset, 1, machine_encoding);
1103 offset += 1;
1105 augmentation_string = tvb_get_stringz_enc(pinfo->pool, tvb, offset, &size, ENC_ASCII);
1106 proto_tree_add_item(entry_tree, hf_elf_eh_frame_augmentation_string,
1107 tvb, offset, size, machine_encoding);
1108 offset += size;
1110 proto_tree_add_item_ret_length(entry_tree, hf_elf_eh_frame_code_alignment_factor, tvb, offset, -1, ENC_LITTLE_ENDIAN|ENC_VARINT_PROTOBUF, &size);
1111 offset += size;
1113 size = dissect_leb128(tvb, offset, &signed_value);
1114 proto_tree_add_int64(entry_tree, hf_elf_eh_frame_data_alignment_factor,
1115 tvb, offset, size, signed_value);
1116 offset += size;
1118 /* according to DWARF v4 this is uLEB128 */
1119 proto_tree_add_item_ret_length(entry_tree, hf_elf_eh_frame_return_address_register, tvb, offset, -1, ENC_LITTLE_ENDIAN|ENC_VARINT_PROTOBUF, &size);
1120 offset += size;
1121 } else {
1122 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_pc_begin, tvb,
1123 offset, 4, machine_encoding);
1124 offset += 4;
1126 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_pc_range, tvb,
1127 offset, 4, machine_encoding);
1128 offset += 4;
1131 /* "A 'z' may be present as the first character of the string. If
1132 * present, the Augmentation Data field shall be present." (LSB 4.1) */
1133 if (augmentation_string[0] == 'z') {
1134 proto_tree_add_item_ret_varint(entry_tree, is_cie ? hf_elf_eh_frame_augmentation_length : hf_elf_eh_frame_fde_augmentation_length,
1135 tvb, offset, -1, ENC_LITTLE_ENDIAN|ENC_VARINT_PROTOBUF, &unsigned_value, &size);
1136 offset += size;
1138 proto_tree_add_item(entry_tree, is_cie ?
1139 hf_elf_eh_frame_augmentation_data :
1140 hf_elf_eh_frame_fde_augmentation_data,
1141 tvb, offset, value_guard(unsigned_value),
1142 machine_encoding);
1143 offset += value_guard(unsigned_value);
1146 proto_tree_add_item(entry_tree, is_cie ?
1147 hf_elf_eh_frame_initial_instructions :
1148 hf_elf_eh_frame_fde_call_frame_instructions,
1149 tvb, offset, value_guard(entry_end - offset),
1150 machine_encoding);
1151 offset = value_guard(entry_end);
1154 if (entry_end - start_offset != (uint64_t)segment_size)
1155 expert_add_info(pinfo, pi, &ei_cfi_extraneous_data);
1157 return offset;
1160 static int
1161 dissect_elf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1163 static const uint8_t magic[] = { 0x7F, 'E', 'L', 'F'};
1164 int offset = 0;
1165 proto_tree *main_tree;
1166 proto_item *main_item, *ti;
1167 proto_tree *header_tree;
1168 proto_item *header_item;
1169 proto_tree *program_header_tree;
1170 proto_tree *section_header_tree;
1171 proto_tree *ph_entry_tree;
1172 proto_item *sh_entry_item;
1173 proto_tree *sh_entry_tree;
1174 proto_item *segment_item;
1175 proto_tree *segment_tree;
1176 proto_item *generated_item;
1177 proto_tree *generated_tree;
1178 proto_tree *overlapping_tree;
1179 proto_tree *blackhole_tree;
1180 proto_item *entry_item;
1181 proto_tree *entry_tree;
1182 unsigned machine_encoding = ENC_NA;
1183 int register_size = 4;
1184 uint16_t phentsize;
1185 uint16_t phnum;
1186 uint16_t shentsize;
1187 uint16_t shnum;
1188 uint64_t phoff;
1189 uint64_t shoff;
1190 uint16_t i_16;
1191 uint32_t p_type;
1192 uint32_t sh_type;
1193 uint16_t shstrndx;
1194 uint64_t shstrtab_offset;
1195 uint32_t sh_name;
1196 const char *section_name;
1197 uint64_t length;
1198 uint64_t segment_offset;
1199 uint64_t segment_size;
1200 uint64_t file_size;
1201 uint64_t p_offset;
1202 int ehsize;
1203 unsigned area_counter = 0;
1204 segment_info_t *segment_info;
1205 unsigned i;
1206 unsigned i_next;
1207 int next_offset;
1208 int len;
1209 uint64_t sh_entsize;
1210 uint64_t strtab_offset = 0;
1211 uint64_t dynstr_offset = 0;
1213 if (tvb_captured_length(tvb) < 52)
1214 return 0;
1216 if (tvb_memeql(tvb, 0, magic, sizeof(magic)) != 0)
1217 return 0;
1219 main_item = proto_tree_add_item(tree, proto_elf, tvb, offset, -1, ENC_NA);
1220 main_tree = proto_item_add_subtree(main_item, ett_elf);
1222 header_tree = proto_tree_add_subtree(main_tree, tvb, offset, 1, ett_elf_header, &header_item, "Header");
1224 /* e_ident */
1225 proto_tree_add_item(header_tree, hf_elf_magic_bytes, tvb, offset, sizeof(magic), ENC_NA);
1226 offset += (int)sizeof(magic);
1228 proto_tree_add_item(header_tree, hf_elf_file_class, tvb, offset, 1, ENC_NA);
1229 register_size *= tvb_get_uint8(tvb, offset);
1230 offset += 1;
1232 proto_tree_add_item(header_tree, hf_elf_data_encoding, tvb, offset, 1, ENC_NA);
1233 if (tvb_get_uint8(tvb, offset) == 1)
1234 machine_encoding = ENC_LITTLE_ENDIAN;
1235 else
1236 machine_encoding = ENC_BIG_ENDIAN;
1237 offset += 1;
1239 proto_tree_add_item(header_tree, hf_elf_file_version, tvb, offset, 1, ENC_NA);
1240 offset += 1;
1242 /* From Draft */
1243 proto_tree_add_item(header_tree, hf_elf_os_abi, tvb, offset, 1, ENC_NA);
1244 offset += 1;
1246 proto_tree_add_item(header_tree, hf_elf_abi_version, tvb, offset, 1, ENC_NA);
1247 offset += 1;
1249 proto_tree_add_item(header_tree, hf_elf_file_padding, tvb, offset, 7, ENC_NA);
1250 offset += 7;
1252 /* other */
1254 proto_tree_add_item(header_tree, hf_elf_type, tvb, offset, 2, machine_encoding);
1255 offset += 2;
1257 proto_tree_add_item(header_tree, hf_elf_machine, tvb, offset, 2, machine_encoding);
1258 offset += 2;
1260 proto_tree_add_item(header_tree, hf_elf_version, tvb, offset, 4, machine_encoding);
1261 offset += 4;
1263 proto_tree_add_item(header_tree,
1264 (register_size == REGISTER_32_SIZE) ? hf_elf_entry : hf_elf64_entry,
1265 tvb, offset, register_size, machine_encoding);
1266 offset += register_size;
1268 if (register_size == REGISTER_32_SIZE) {
1269 proto_tree_add_item(header_tree, hf_elf_phoff, tvb, offset,
1270 register_size, machine_encoding);
1271 phoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1272 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1273 } else {
1274 proto_tree_add_item(header_tree, hf_elf64_phoff, tvb, offset,
1275 register_size, machine_encoding);
1276 phoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1277 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1279 offset += register_size;
1282 if (register_size == REGISTER_32_SIZE) {
1283 proto_tree_add_item(header_tree, hf_elf_shoff, tvb, offset,
1284 register_size, machine_encoding);
1285 shoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1286 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1287 } else {
1288 proto_tree_add_item(header_tree, hf_elf64_shoff, tvb, offset,
1289 register_size, machine_encoding);
1290 shoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1291 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1293 offset += register_size;
1295 proto_tree_add_item(header_tree, hf_elf_flags, tvb, offset, 4, machine_encoding);
1296 offset += 4;
1298 proto_tree_add_item(header_tree, hf_elf_ehsize, tvb, offset, 2, machine_encoding);
1299 ehsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1300 proto_item_set_len(header_item, ehsize);
1301 offset += 2;
1303 proto_tree_add_item(header_tree, hf_elf_phentsize, tvb, offset, 2, machine_encoding);
1304 phentsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1305 offset += 2;
1307 proto_tree_add_item(header_tree, hf_elf_phnum, tvb, offset, 2, machine_encoding);
1308 phnum = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1309 offset += 2;
1311 proto_tree_add_item(header_tree, hf_elf_shentsize, tvb, offset, 2, machine_encoding);
1312 shentsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1313 offset += 2;
1315 proto_tree_add_item(header_tree, hf_elf_shnum, tvb, offset, 2, machine_encoding);
1316 shnum = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1317 offset += 2;
1319 proto_tree_add_item(header_tree, hf_elf_shstrndx, tvb, offset, 2, machine_encoding);
1320 shstrndx = (machine_encoding == ENC_BIG_ENDIAN) ?
1321 tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1322 /*offset += 2;*/
1324 program_header_tree = proto_tree_add_subtree_format(main_tree, tvb, value_guard(phoff),
1325 phnum * phentsize, ett_elf_program_header, NULL, "Program Header Table [%d entries]", phnum);
1327 section_header_tree = proto_tree_add_subtree_format(main_tree, tvb, value_guard(shoff),
1328 shnum * shentsize, ett_elf_section_header, NULL, "Section Header Table [%d entries]", shnum);
1330 file_size = ehsize + (uint32_t)phnum * (uint32_t)phentsize + (uint32_t)shnum * (uint32_t)shentsize;
1332 /* Collect infos for blackholes */
1333 segment_info = (segment_info_t *) wmem_alloc(pinfo->pool, sizeof(segment_info_t) * (shnum + phnum + 3));
1335 segment_info[area_counter].offset = 0;
1336 segment_info[area_counter].size = ehsize;
1337 segment_info[area_counter].name = "Header";
1338 area_counter += 1;
1340 if (phoff) {
1341 segment_info[area_counter].offset = phoff;
1342 segment_info[area_counter].size = (uint32_t)phnum * (uint32_t)phentsize;
1343 segment_info[area_counter].name = "ProgramHeader";
1344 area_counter += 1;
1347 if (shoff) {
1348 segment_info[area_counter].offset = shoff;
1349 segment_info[area_counter].size = (uint32_t)shnum * (uint32_t)shentsize;
1350 segment_info[area_counter].name = "SectionHeader";
1351 area_counter += 1;
1354 offset = value_guard(phoff);
1356 i_16 = phnum;
1357 while (i_16-- > 0) {
1358 p_type = (machine_encoding == ENC_BIG_ENDIAN) ?
1359 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1360 if (p_type >= 0x60000000 && p_type <= 0x6FFFFFFF) {
1361 ph_entry_tree = proto_tree_add_subtree_format(program_header_tree,
1362 tvb, offset, phentsize, ett_elf_program_header_entry, NULL,
1363 "Entry #%d: Operating System Specific (0x%08x)", phnum - i_16 - 1, p_type);
1364 proto_tree_add_item(ph_entry_tree, hf_elf_p_type_operating_system_specific, tvb, offset, 4, machine_encoding);
1365 } else if (p_type >= 0x70000000 && p_type <= 0x7FFFFFFF) {
1366 ph_entry_tree = proto_tree_add_subtree_format(program_header_tree,
1367 tvb, offset, phentsize, ett_elf_program_header_entry, NULL,
1368 "Entry #%d: Processor Specific (0x%08x)", phnum - i_16 - 1, p_type);
1369 proto_tree_add_item(ph_entry_tree, hf_elf_p_type_processor_specific, tvb, offset, 4, machine_encoding);
1370 } else {
1371 ph_entry_tree = proto_tree_add_subtree_format(program_header_tree,
1372 tvb, offset, phentsize, ett_elf_program_header_entry, NULL,
1373 "Entry #%d: %s", phnum - i_16 - 1,
1374 rval_to_str_const(p_type, p_type_rvals, "Unknown"));
1375 proto_tree_add_item(ph_entry_tree, hf_elf_p_type, tvb, offset, 4, machine_encoding);
1377 offset += 4;
1379 if (register_size == REGISTER_64_SIZE) {
1380 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_processor_specific, tvb, offset, 4, machine_encoding);
1381 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1382 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_reserved, tvb, offset, 4, machine_encoding);
1383 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_read, tvb, offset, 4, machine_encoding);
1384 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_write, tvb, offset, 4, machine_encoding);
1385 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_execute, tvb, offset, 4, machine_encoding);
1386 offset += 4;
1389 proto_tree_add_item(ph_entry_tree,
1390 (register_size == REGISTER_32_SIZE) ? hf_elf_p_offset : hf_elf64_p_offset,
1391 tvb, offset, register_size, machine_encoding);
1392 if (register_size == REGISTER_32_SIZE) {
1393 p_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1394 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1395 } else {
1396 p_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1397 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1400 offset += register_size;
1402 proto_tree_add_item(ph_entry_tree,
1403 (register_size == REGISTER_32_SIZE) ? hf_elf_p_vaddr : hf_elf64_p_vaddr,
1404 tvb, offset, register_size, machine_encoding);
1405 offset += register_size;
1407 proto_tree_add_item(ph_entry_tree,
1408 (register_size == REGISTER_32_SIZE) ? hf_elf_p_paddr : hf_elf64_p_paddr,
1409 tvb, offset, register_size, machine_encoding);
1410 offset += register_size;
1412 proto_tree_add_item(ph_entry_tree,
1413 (register_size == REGISTER_32_SIZE) ? hf_elf_p_filesz : hf_elf64_p_filesz,
1414 tvb, offset, register_size, machine_encoding);
1415 if (register_size == REGISTER_32_SIZE) {
1416 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1417 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1418 } else {
1419 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1420 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1422 offset += register_size;
1424 proto_tree_add_item(ph_entry_tree,
1425 (register_size == REGISTER_32_SIZE) ? hf_elf_p_memsz : hf_elf64_p_memsz,
1426 tvb, offset, register_size, machine_encoding);
1427 offset += register_size;
1429 if (register_size == REGISTER_32_SIZE) {
1430 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_processor_specific, tvb, offset, 4, machine_encoding);
1431 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1432 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_reserved, tvb, offset, 4, machine_encoding);
1433 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_read, tvb, offset, 4, machine_encoding);
1434 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_write, tvb, offset, 4, machine_encoding);
1435 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_execute, tvb, offset, 4, machine_encoding);
1436 offset += 4;
1439 proto_tree_add_item(ph_entry_tree,
1440 (register_size == REGISTER_32_SIZE) ? hf_elf_p_align : hf_elf64_p_align,
1441 tvb, offset, register_size, machine_encoding);
1442 offset += register_size;
1444 if (segment_size) {
1445 char *name;
1447 name = wmem_strdup_printf(pinfo->pool, "ProgramHeaderEntry #%u", phnum - i_16 - 1);
1449 proto_tree_add_bytes_format(ph_entry_tree, hf_elf_segment, tvb, value_guard(p_offset), value_guard(segment_size), NULL, "Segment");
1451 file_size += segment_size;
1453 segment_info[area_counter].offset = p_offset;
1454 segment_info[area_counter].size = segment_size;
1455 segment_info[area_counter].name = name;
1457 area_counter += 1;
1461 /* Find and save some information for later */
1462 offset = value_guard(shoff);
1464 i_16 = shnum;
1465 while (i_16-- > 0) {
1466 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ?
1467 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1469 offset += 4;
1471 offset += 4;
1473 length = shoff + (uint32_t)shstrndx * (uint32_t)shentsize + 2 * 4 + 2 * register_size;
1474 if (register_size == REGISTER_32_SIZE) {
1475 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1476 tvb_get_ntohl(tvb, value_guard(length)) : tvb_get_letohl(tvb, value_guard(length));
1477 } else {
1478 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1479 tvb_get_ntoh64(tvb, value_guard(length)) : tvb_get_letoh64(tvb, value_guard(length));
1482 section_name = tvb_get_stringz_enc(pinfo->pool, tvb, value_guard(shstrtab_offset + sh_name), NULL, ENC_ASCII);
1484 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_BIG_ENDIAN) {
1485 offset += 4;
1488 offset += 4;
1490 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_LITTLE_ENDIAN) {
1491 offset += 4;
1494 offset += register_size;
1496 if (register_size == REGISTER_32_SIZE) {
1497 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1498 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1499 } else {
1500 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1501 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1504 if (g_strcmp0(section_name, ".strtab") == 0) {
1505 strtab_offset = segment_offset;
1506 } else if (g_strcmp0(section_name, ".dynstr") == 0) {
1507 dynstr_offset = segment_offset;
1509 offset += register_size;
1510 offset += register_size;
1511 offset += 4;
1512 offset += 4;
1513 offset += register_size;
1514 offset += register_size;
1517 /* Sections */
1518 offset = value_guard(shoff);
1520 i_16 = shnum;
1521 while (i_16-- > 0) {
1522 sh_entry_tree = proto_tree_add_subtree_format(section_header_tree, tvb, offset, shentsize,
1523 ett_elf_section_header_entry, &sh_entry_item,
1524 "Entry #%d: ", shnum - i_16 - 1);
1526 proto_tree_add_item(sh_entry_tree, hf_elf_sh_name, tvb, offset, 4, machine_encoding);
1527 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ?
1528 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1529 offset += 4;
1531 sh_type = (machine_encoding == ENC_BIG_ENDIAN) ?
1532 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1533 if (sh_type >= 0x60000000 && sh_type <= 0x6FFFFFFF) {
1534 proto_item_append_text(sh_entry_item, "Operating System Specific (0x%08x)", sh_type);
1535 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_operating_system_specific, tvb, offset, 4, machine_encoding);
1536 } else if (sh_type >= 0x70000000 && sh_type <= 0x7FFFFFFF) {
1537 proto_item_append_text(sh_entry_item, "Processor Specific (0x%08x)", sh_type);
1538 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_processor_specific, tvb, offset, 4, machine_encoding);
1539 } else if (sh_type >= 0x80000000) {
1540 proto_item_append_text(sh_entry_item, "User Specific (0x%08x)", sh_type);
1541 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_user_specific, tvb, offset, 4, machine_encoding);
1542 }else {
1543 proto_item_append_text(sh_entry_item, "%s", rval_to_str_const(sh_type, sh_type_rvals, "Unknown"));
1544 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type, tvb, offset, 4, machine_encoding);
1546 offset += 4;
1548 length = shoff + (uint32_t)shstrndx * (uint32_t)shentsize + 2 * 4 + 2 * register_size;
1549 if (register_size == REGISTER_32_SIZE) {
1550 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1551 tvb_get_ntohl(tvb, value_guard(length)) : tvb_get_letohl(tvb, value_guard(length));
1552 } else {
1553 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1554 tvb_get_ntoh64(tvb, value_guard(length)) : tvb_get_letoh64(tvb, value_guard(length));
1557 section_name = tvb_get_stringz_enc(pinfo->pool, tvb, value_guard(shstrtab_offset + sh_name), NULL, ENC_ASCII);
1558 if (section_name)
1559 proto_item_append_text(sh_entry_item, ": %s", section_name);
1561 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_BIG_ENDIAN) {
1562 offset += 4;
1565 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_processor_specific, tvb, offset, 4, machine_encoding);
1566 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1567 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_reserved, tvb, offset, 4, machine_encoding);
1568 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_tls, tvb, offset, 4, machine_encoding);
1569 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_group, tvb, offset, 4, machine_encoding);
1570 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_os_nonconforming, tvb, offset, 4, machine_encoding);
1571 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_link_order, tvb, offset, 4, machine_encoding);
1572 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_info_link, tvb, offset, 4, machine_encoding);
1573 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_strings, tvb, offset, 4, machine_encoding);
1574 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_merge, tvb, offset, 4, machine_encoding);
1575 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_reserved_8, tvb, offset, 4, machine_encoding);
1576 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_exec_instr, tvb, offset, 4, machine_encoding);
1577 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_alloc, tvb, offset, 4, machine_encoding);
1578 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_write, tvb, offset, 4, machine_encoding);
1579 offset += 4;
1581 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_LITTLE_ENDIAN) {
1582 offset += 4;
1585 proto_tree_add_item(sh_entry_tree,
1586 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_addr : hf_elf64_sh_addr,
1587 tvb, offset, register_size, machine_encoding);
1588 offset += register_size;
1590 proto_tree_add_item(sh_entry_tree,
1591 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_offset : hf_elf64_sh_offset,
1592 tvb, offset, register_size, machine_encoding);
1593 if (register_size == REGISTER_32_SIZE) {
1594 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1595 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1596 } else {
1597 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1598 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1600 offset += register_size;
1602 proto_tree_add_item(sh_entry_tree,
1603 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_size : hf_elf64_sh_size,
1604 tvb, offset, register_size, machine_encoding);
1605 if (register_size == REGISTER_32_SIZE) {
1606 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1607 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1608 } else {
1609 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1610 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1612 offset += register_size;
1614 proto_tree_add_item(sh_entry_tree, hf_elf_sh_link, tvb, offset, 4, machine_encoding);
1615 offset += 4;
1617 proto_tree_add_item(sh_entry_tree, hf_elf_sh_info, tvb, offset, 4, machine_encoding);
1618 offset += 4;
1620 proto_tree_add_item(sh_entry_tree,
1621 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_addralign : hf_elf64_sh_addralign,
1622 tvb, offset, register_size, machine_encoding);
1623 offset += register_size;
1625 proto_tree_add_item(sh_entry_tree,
1626 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_entsize : hf_elf64_sh_entsize,
1627 tvb, offset, register_size, machine_encoding);
1628 if (register_size == REGISTER_32_SIZE) {
1629 sh_entsize = (machine_encoding == ENC_BIG_ENDIAN) ?
1630 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1631 } else {
1632 sh_entsize = (machine_encoding == ENC_BIG_ENDIAN) ?
1633 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1635 offset += register_size;
1637 if (segment_size > 0 && sh_type != 8) { /* ! SHT_NOBITS */
1638 file_size += segment_size;
1640 segment_info[area_counter].offset = segment_offset;
1641 segment_info[area_counter].size = segment_size;
1642 segment_info[area_counter].name = section_name;
1643 area_counter += 1;
1645 segment_tree = proto_tree_add_subtree(sh_entry_tree, tvb, value_guard(segment_offset),
1646 value_guard(segment_size), ett_elf_segment, &segment_item, "Segment");
1648 if (g_strcmp0(section_name, ".eh_frame") == 0) {
1649 next_offset = dissect_eh_frame(tvb, pinfo, segment_tree,
1650 value_guard(segment_offset), value_guard(segment_size), register_size,
1651 machine_encoding);
1652 if (next_offset != (int) (segment_offset + segment_size))
1653 expert_add_info(pinfo, segment_item, &ei_invalid_segment_size);
1654 } else if (g_strcmp0(section_name, ".eh_frame_hdr") == 0) {
1655 next_offset = dissect_eh_frame_hdr(tvb, pinfo, segment_tree,
1656 value_guard(segment_offset), value_guard(segment_size), register_size,
1657 machine_encoding);
1658 if (next_offset != (int) (segment_offset + segment_size))
1659 expert_add_info(pinfo, segment_item, &ei_invalid_segment_size);
1660 } else if (sh_type == 0x06) { /* SHT_DYNAMIC */
1661 if (sh_entsize > 0) {
1662 next_offset = value_guard(segment_offset);
1663 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1664 entry_tree = proto_tree_add_subtree_format(segment_tree, tvb, next_offset,
1665 value_guard(sh_entsize), ett_symbol_table_entry, &entry_item, "Entry #%d", i);
1667 next_offset = dissect_dynamic(tvb, pinfo, entry_tree, entry_item,
1668 next_offset, register_size, machine_encoding);
1669 if (next_offset != (int) (segment_offset + i * sh_entsize))
1670 expert_add_info(pinfo, segment_item, &ei_invalid_entry_size);
1673 } else if (sh_type == 0x02 || sh_type == 0x0b) { /* SHT_SYMTAB || SHT_DYNSYM */
1674 if (sh_entsize > 0) {
1675 next_offset = value_guard(segment_offset);
1676 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1677 entry_tree = proto_tree_add_subtree_format(segment_tree, tvb, next_offset,
1678 value_guard(sh_entsize), ett_symbol_table_entry, &entry_item, "Entry #%d", i);
1680 next_offset = dissect_symbol_table(tvb, pinfo, entry_tree, entry_item,
1681 next_offset, register_size, machine_encoding, (sh_type == 0x02) ? strtab_offset : dynstr_offset,
1682 shoff, shnum, shentsize, shstrtab_offset);
1683 if (next_offset != (int) (segment_offset + i * sh_entsize))
1684 expert_add_info(pinfo, segment_item, &ei_invalid_entry_size);
1687 } else if (sh_type == 0x03) { /* SHT_STRTAB */
1688 next_offset = value_guard(segment_offset);
1689 i = 1;
1690 while (next_offset < (int) (segment_offset + segment_size)) {
1691 len = tvb_strsize(tvb, next_offset);
1692 entry_item = proto_tree_add_item(segment_tree, hf_elf_string, tvb, next_offset, len, ENC_ASCII | ENC_NA);
1693 proto_item_append_text(entry_item, " (Number: %u, Index: %u, Length: %u)", (unsigned) i, (unsigned) (next_offset - segment_offset), len - 1);
1694 next_offset += len;
1695 i += 1;
1697 } else {
1698 /* .debug_str sections have sh_entsize 1, displaying every byte
1699 * individually can explode the tree size, so require > 1. */
1700 if (sh_entsize > 1) {
1701 next_offset = value_guard(segment_offset);
1702 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1703 proto_tree_add_bytes_format(segment_tree, hf_elf_entry_bytes, tvb, next_offset,
1704 value_guard(sh_entsize), NULL, "Entry #%d ", i);
1705 next_offset += value_guard(sh_entsize);
1712 /* Try to detect blackholes and overlapping segments */
1713 generated_tree = proto_tree_add_subtree(main_tree, tvb, 0, 0, ett_elf_info, &generated_item, "Infos");
1714 proto_item_set_generated(generated_item);
1716 blackhole_tree = proto_tree_add_subtree(generated_tree, tvb, 0, 0, ett_elf_black_holes, NULL, "Backholes");
1717 overlapping_tree = proto_tree_add_subtree(generated_tree, tvb, 0, 0, ett_elf_overlapping, NULL, "Overlapping");
1719 /* sorting... */
1720 for (i = 0; i < area_counter; i += 1) {
1721 segment_info_t tmp_segment;
1722 segment_info_t *min_offset_segment;
1724 min_offset_segment = &segment_info[i];
1726 for (i_next = i + 1; i_next < area_counter; i_next += 1) {
1727 if (min_offset_segment->offset <= segment_info[i_next].offset) continue;
1729 tmp_segment = *min_offset_segment;
1730 *min_offset_segment = segment_info[i_next];
1731 segment_info[i_next] = tmp_segment;
1735 for (i = 1; i < area_counter; i += 1) {
1736 if (segment_info[i - 1].offset + segment_info[i - 1].size < segment_info[i].offset) {
1737 /* blackhole */
1738 len = (unsigned) (segment_info[i].offset - segment_info[i - 1].offset - segment_info[i - 1].size);
1740 ti = proto_tree_add_uint_format(blackhole_tree, hf_elf_blackhole_size, tvb, value_guard(segment_info[i].offset - len), 1, len,
1741 "Blackhole between: %s and %s, size: %u", segment_info[i - 1].name, segment_info[i].name, len);
1742 proto_item_set_len(ti, len);
1744 } else if (segment_info[i - 1].offset + segment_info[i - 1].size > segment_info[i].offset) {
1745 /* overlapping */
1746 len = (unsigned) (segment_info[i - 1].offset + segment_info[i - 1].size - segment_info[i].offset);
1748 ti = proto_tree_add_uint_format(overlapping_tree, hf_elf_overlapping_size, tvb, value_guard(segment_info[i - 1].offset + segment_info[i - 1].size - len), 1, len,
1749 "Overlapping between: %s and %s, size: %u", segment_info[i - 1].name, segment_info[i].name, len);
1750 proto_item_set_len(ti, len);
1752 file_size -= len;
1756 if (segment_info[area_counter - 1].offset + segment_info[area_counter - 1].size < tvb_captured_length(tvb)) {
1757 len = tvb_captured_length(tvb) - (unsigned) (segment_info[area_counter - 1].offset - segment_info[area_counter - 1].size);
1759 ti = proto_tree_add_uint_format(blackhole_tree, hf_elf_blackhole_size, tvb,
1760 value_guard(segment_info[area_counter - 1].offset +
1761 segment_info[area_counter - 1].size), 1,
1762 len, "Blackhole between: %s and <EOF>, size: %u",
1763 segment_info[area_counter - 1].name, len);
1764 proto_item_set_len(ti, len);
1767 proto_tree_add_uint(generated_tree, hf_elf_file_size, tvb, 0, 0, tvb_captured_length(tvb));
1768 proto_tree_add_uint(generated_tree, hf_elf_header_segment_size, tvb, 0, 0, (unsigned)file_size);
1769 proto_tree_add_uint(generated_tree, hf_elf_blackholes_size, tvb, 0, 0, tvb_captured_length(tvb) - (unsigned)file_size);
1771 col_clear(pinfo->cinfo, COL_INFO);
1772 col_set_str(pinfo->cinfo, COL_INFO, "(ELF)");
1774 /* We jumping around offsets, so treat as bytes as read */
1775 return tvb_captured_length(tvb);
1778 static bool
1779 dissect_elf_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1781 return dissect_elf(tvb, pinfo, tree, data) > 0;
1784 void
1785 proto_register_elf(void)
1787 module_t *module;
1788 expert_module_t *expert_module;
1790 static hf_register_info hf[] = {
1791 /* Header */
1792 { &hf_elf_magic_bytes,
1793 { "Magic Bytes", "elf.magic_bytes",
1794 FT_BYTES, BASE_NONE, NULL, 0x00,
1795 NULL, HFILL }
1797 { &hf_elf_file_size,
1798 { "File size", "elf.file_size",
1799 FT_UINT32, BASE_DEC, NULL, 0x00,
1800 NULL, HFILL }
1802 { &hf_elf_header_segment_size,
1803 { "Header size + all segment size", "elf.header_segment_size",
1804 FT_UINT32, BASE_DEC, NULL, 0x00,
1805 NULL, HFILL }
1807 { &hf_elf_blackholes_size,
1808 { "Total blackholes size", "elf.blackholes_size",
1809 FT_UINT32, BASE_DEC, NULL, 0x00,
1810 NULL, HFILL }
1812 { &hf_elf_blackhole_size,
1813 { "Blackhole size", "elf.blackhole_size",
1814 FT_UINT32, BASE_DEC, NULL, 0x00,
1815 "Blackhole size between sections or program headers", HFILL }
1817 { &hf_elf_overlapping_size,
1818 { "Overlapping size", "elf.overlapping_size",
1819 FT_UINT32, BASE_DEC, NULL, 0x00,
1820 "Overlapping size between sections or program headers", HFILL }
1822 { &hf_elf_segment,
1823 { "Segment", "elf.segment",
1824 FT_BYTES, BASE_NONE, NULL, 0x00,
1825 NULL, HFILL }
1827 { &hf_elf_entry_bytes,
1828 { "Entry", "elf.entry_bytes",
1829 FT_BYTES, BASE_NONE, NULL, 0x00,
1830 NULL, HFILL }
1832 { &hf_elf_file_class,
1833 { "File Class", "elf.file_class",
1834 FT_UINT8, BASE_HEX, VALS(class_vals), 0x00,
1835 NULL, HFILL }
1837 { &hf_elf_data_encoding,
1838 { "Data Encoding", "elf.data_encoding",
1839 FT_UINT8, BASE_HEX, VALS(data_encoding_vals), 0x00,
1840 NULL, HFILL }
1842 { &hf_elf_file_version,
1843 { "File Version", "elf.file_version",
1844 FT_UINT8, BASE_HEX, VALS(version_vals), 0x00,
1845 NULL, HFILL }
1847 { &hf_elf_os_abi,
1848 { "OS ABI", "elf.os_abi",
1849 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &os_abi_vals_ext, 0x00,
1850 NULL, HFILL }
1852 { &hf_elf_abi_version,
1853 { "ABI Version", "elf.abi_version",
1854 FT_UINT8, BASE_HEX_DEC, NULL, 0x00,
1855 NULL, HFILL }
1857 { &hf_elf_file_padding,
1858 { "File Padding", "elf.file_padding",
1859 FT_BYTES, BASE_NONE, NULL, 0x00,
1860 NULL, HFILL }
1862 { &hf_elf_type,
1863 { "Type", "elf.type",
1864 FT_UINT16, BASE_HEX, VALS(type_vals), 0x00,
1865 NULL, HFILL }
1867 { &hf_elf_machine,
1868 { "Machine", "elf.machine",
1869 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &machine_vals_ext, 0x00,
1870 NULL, HFILL }
1872 { &hf_elf_version,
1873 { "Version", "elf.version",
1874 FT_UINT32, BASE_HEX, VALS(version_vals), 0x00,
1875 NULL, HFILL }
1877 { &hf_elf_entry,
1878 { "Entry", "elf.entry",
1879 FT_UINT32, BASE_HEX, NULL, 0x00,
1880 "This member gives the virtual address to which the system first transfers control, thus starting the process. If the file has no associated entry point, this member holds zero.", HFILL }
1882 { &hf_elf64_entry,
1883 { "Entry", "elf.entry64",
1884 FT_UINT64, BASE_HEX, NULL, 0x00,
1885 "This member gives the virtual address to which the system first transfers control, thus starting the process. If the file has no associated entry point, this member holds zero.", HFILL }
1887 { &hf_elf_phoff,
1888 { "Program Header Table File Offset", "elf.phoff",
1889 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1890 "This member holds the program header table's file offset in bytes. If the file has no program header table, this member holds zero.", HFILL }
1892 { &hf_elf64_phoff,
1893 { "Program Header Table File Offset", "elf.phoff64",
1894 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1895 "This member holds the program header table's file offset in bytes. If the file has no program header table, this member holds zero.", HFILL }
1897 { &hf_elf_shoff,
1898 { "Section Header Table File Offset", "elf.shoff",
1899 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1900 "This member holds the section header table's file offset in bytes. If the file has no section header table, this member holds zero.", HFILL }
1902 { &hf_elf64_shoff,
1903 { "Section Header Table File Offset", "elf.shoff64",
1904 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1905 "This member holds the section header table's file offset in bytes. If the file has no section header table, this member holds zero.", HFILL }
1907 { &hf_elf_flags, /* TODO: dissect flags */
1908 { "Flags", "elf.flags",
1909 FT_UINT32, BASE_HEX, NULL, 0x00,
1910 "This member holds processor-specific flags associated with the file. Flag names take the form EF_machine_flag.", HFILL }
1912 { &hf_elf_ehsize,
1913 { "ELF Header Size", "elf.ehsize",
1914 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1915 "This member holds the ELF header's size in bytes.", HFILL }
1917 { &hf_elf_phentsize,
1918 { "Entry Size in Program Header Table", "elf.phentsize",
1919 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1920 "This member holds the size in bytes of one entry in the file's program header table; all entries are the same size.", HFILL }
1922 { &hf_elf_phnum,
1923 { "Number of Entries in the Program Header Table", "elf.phnum",
1924 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1925 "This member holds the number of entries in the program header table. Thus the product of e_phentsize and e_phnum gives the table's size in bytes. If a file has no program header table, e_phnum holds the value zero.", HFILL }
1927 { &hf_elf_shentsize,
1928 { "Entry Size in Section Header Table", "elf.shentsize",
1929 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1930 "This member holds a section header's size in bytes. A section header is one entry in the section header table; all entries are the same size.", HFILL }
1932 { &hf_elf_shnum,
1933 { "Number of Entries in the Section Header Table", "elf.shnum",
1934 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1935 "This member holds the number of entries in the section header table. Thus the product of e_shentsize and e_shnum gives the section header table's size in bytes. If a file has no section header table, e_shnum holds the value zero.", HFILL }
1937 { &hf_elf_shstrndx,
1938 { "Section Header Table String Index", "elf.shstrndx",
1939 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1940 "This member holds the section header table index of the entry associated with the section name string table. If the file has no section name string table, this member holds the value SHN_UNDEF.", HFILL }
1942 /* Program Header */
1943 { &hf_elf_p_type,
1944 { "Element Type", "elf.p_type",
1945 FT_UINT32, BASE_HEX_DEC | BASE_RANGE_STRING, RVALS(p_type_rvals), 0x00,
1946 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1948 { &hf_elf_p_type_operating_system_specific,
1949 { "Element Type: Operating System Specific", "elf.p_type",
1950 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1951 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1953 { &hf_elf_p_type_processor_specific,
1954 { "Element Type: Processor Specific", "elf.p_type",
1955 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1956 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1958 { &hf_elf_p_offset,
1959 { "File Offset", "elf.p_offset",
1960 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1961 "This member gives the offset from the beginning of the file at which the first byte of the segment resides.", HFILL }
1963 { &hf_elf64_p_offset,
1964 { "File Offset", "elf.p_offset64",
1965 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1966 "This member gives the offset from the beginning of the file at which the first byte of the segment resides.", HFILL }
1968 { &hf_elf_p_vaddr,
1969 { "Virtual Address", "elf.p_vaddr",
1970 FT_UINT32, BASE_HEX, NULL, 0x00,
1971 "This member gives the virtual address at which the first byte of the segment resides in memory.", HFILL }
1973 { &hf_elf64_p_vaddr,
1974 { "Virtual Address", "elf.p_vaddr64",
1975 FT_UINT64, BASE_HEX, NULL, 0x00,
1976 "This member gives the virtual address at which the first byte of the segment resides in memory.", HFILL }
1978 { &hf_elf_p_paddr,
1979 { "Physical Address", "elf.p_paddr",
1980 FT_UINT32, BASE_HEX, NULL, 0x00,
1981 "On systems for which physical addressing is relevant, this member is reserved for the segment's physical address. Because System V ignores physical addressing for application programs, this member has unspecified contents for executable files and shared objects.", HFILL }
1983 { &hf_elf64_p_paddr,
1984 { "Physical Address", "elf.p_paddr64",
1985 FT_UINT64, BASE_HEX, NULL, 0x00,
1986 "On systems for which physical addressing is relevant, this member is reserved for the segment's physical address. Because System V ignores physical addressing for application programs, this member has unspecified contents for executable files and shared objects.", HFILL }
1988 { &hf_elf_p_filesz,
1989 { "File Image Size", "elf.p_filesz",
1990 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1991 "This member gives the number of bytes in the file image of the segment; it may be zero.", HFILL }
1993 { &hf_elf64_p_filesz,
1994 { "File Image Size", "elf.p_filesz64",
1995 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1996 "This member gives the number of bytes in the file image of the segment; it may be zero.", HFILL }
1998 { &hf_elf_p_memsz,
1999 { "Memory Image Size", "elf.p_memsz",
2000 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2001 "This member gives the number of bytes in the memory image of the segment; it may be zero.", HFILL }
2003 { &hf_elf64_p_memsz,
2004 { "Memory Image Size", "elf.p_memsz64",
2005 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2006 "This member gives the number of bytes in the memory image of the segment; it may be zero.", HFILL }
2008 { &hf_elf_p_flags_processor_specific,
2009 { "Processor Specific Flags", "elf.p_flags.maskproc",
2010 FT_BOOLEAN, 32, NULL, 0xF0000000,
2011 NULL, HFILL }
2013 { &hf_elf_p_flags_operating_system_specific,
2014 { "Operating System Specific Flags", "elf.p_flags.maskos",
2015 FT_BOOLEAN, 32, NULL, 0x0FF00000,
2016 NULL, HFILL }
2018 { &hf_elf_p_flags_reserved,
2019 { "Reserved Flags", "elf.p_flags.reserved",
2020 FT_BOOLEAN, 32, NULL, 0x000FFFF8,
2021 NULL, HFILL }
2023 { &hf_elf_p_flags_read,
2024 { "Read Flag", "elf.p_flags.read",
2025 FT_BOOLEAN, 32, NULL, 0x00000004,
2026 NULL, HFILL }
2028 { &hf_elf_p_flags_write,
2029 { "Write Flag", "elf.p_flags.write",
2030 FT_BOOLEAN, 32, NULL, 0x00000002,
2031 NULL, HFILL }
2033 { &hf_elf_p_flags_execute,
2034 { "Execute Flag", "elf.p_flags.execute",
2035 FT_BOOLEAN, 32, NULL, 0x00000001,
2036 NULL, HFILL }
2038 { &hf_elf_p_align,
2039 { "Align", "elf.p_align",
2040 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2041 "This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise, p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align.", HFILL }
2043 { &hf_elf64_p_align,
2044 { "Align", "elf.p_align64",
2045 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2046 "This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise, p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align.", HFILL }
2048 /* Section Header */
2049 { &hf_elf_sh_name,
2050 { "Name Index", "elf.sh_name",
2051 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2052 "Section Name. Its value is an index into the section header string table section, giving the location of a null-terminated string.", HFILL }
2054 { &hf_elf_sh_type,
2055 { "Type", "elf.sh_type",
2056 FT_UINT32, BASE_HEX_DEC | BASE_RANGE_STRING, RVALS(sh_type_rvals), 0x00,
2057 "This member categorizes the section's contents and semantics.", HFILL }
2059 { &hf_elf_sh_type_operating_system_specific,
2060 { "Type: Operating System Specific", "elf.sh_type",
2061 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
2062 "This member categorizes the section's contents and semantics.", HFILL }
2064 { &hf_elf_sh_type_processor_specific,
2065 { "Type: Processor Specific", "elf.sh_type",
2066 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
2067 "This member categorizes the section's contents and semantics.", HFILL }
2069 { &hf_elf_sh_type_user_specific,
2070 { "Type: User Specific", "elf.sh_type",
2071 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
2072 "This member categorizes the section's contents and semantics.", HFILL }
2074 { &hf_elf_sh_flags_processor_specific,
2075 { "Processor Specific Flags", "elf.sh_flags.maskproc",
2076 FT_BOOLEAN, 32, NULL, 0xF0000000,
2077 NULL, HFILL }
2079 { &hf_elf_sh_flags_operating_system_specific,
2080 { "Operating System Specific Flags", "elf.sh_flags.maskos",
2081 FT_BOOLEAN, 32, NULL, 0x0FF00000,
2082 NULL, HFILL }
2084 { &hf_elf_sh_flags_reserved,
2085 { "Reserved", "elf.sh_flags.reserved",
2086 FT_BOOLEAN, 32, NULL, 0x000FF800,
2087 NULL, HFILL }
2089 { &hf_elf_sh_flags_tls,
2090 { "TLS Flag", "elf.sh_flags.tls",
2091 FT_BOOLEAN, 32, NULL, 0x00000400,
2092 "This section holds Thread-Local Storage, meaning that each separate execution flow has its own distinct instance of this data. Implementations need not support this flag.", HFILL }
2094 { &hf_elf_sh_flags_group,
2095 { "Group Flag", "elf.sh_flags.group",
2096 FT_BOOLEAN, 32, NULL, 0x00000200,
2097 "This section is a member (perhaps the only one) of a section group.", HFILL }
2099 { &hf_elf_sh_flags_os_nonconforming,
2100 { "OS NonConforming Flag", "elf.sh_flags.os_nonconforming",
2101 FT_BOOLEAN, 32, NULL, 0x00000100,
2102 "This section requires special OS-specific processing to avoid incorrect behavior.", HFILL }
2104 { &hf_elf_sh_flags_link_order,
2105 { "Link Order Flag", "elf.sh_flags.link_order",
2106 FT_BOOLEAN, 32, NULL, 0x00000080,
2107 "This flag adds special ordering requirements for link editors.", HFILL }
2109 { &hf_elf_sh_flags_info_link,
2110 { "Info Link Flag", "elf.sh_flags.info_link",
2111 FT_BOOLEAN, 32, NULL, 0x00000040,
2112 "The sh_info field of this section header holds a section header table index.", HFILL }
2114 { &hf_elf_sh_flags_strings,
2115 { "Strings Flag", "elf.sh_flags.strings",
2116 FT_BOOLEAN, 32, NULL, 0x00000020,
2117 "The data elements in the section consist of null-terminated character strings. The size of each character is specified in the section header's sh_entsize field.", HFILL }
2119 { &hf_elf_sh_flags_merge,
2120 { "Merge Flag", "elf.sh_flags.merge",
2121 FT_BOOLEAN, 32, NULL, 0x00000010,
2122 "The data in the section may be merged to eliminate duplication.", HFILL }
2124 { &hf_elf_sh_flags_reserved_8,
2125 { "Reserved", "elf.sh_flags.reserved.8",
2126 FT_BOOLEAN, 32, NULL, 0x00000008,
2127 NULL, HFILL }
2129 { &hf_elf_sh_flags_exec_instr,
2130 { "Exec Instr Flag", "elf.sh_flags.exec_instr",
2131 FT_BOOLEAN, 32, NULL, 0x00000004,
2132 "The section contains executable machine instructions.", HFILL }
2134 { &hf_elf_sh_flags_alloc,
2135 { "Alloc Flag", "elf.sh_flags.alloc",
2136 FT_BOOLEAN, 32, NULL, 0x00000002,
2137 "The section occupies memory during process execution. Some control sections do not reside in the memory image of an object file; this attribute is off for those sections.", HFILL }
2139 { &hf_elf_sh_flags_write,
2140 { "Write Flag", "elf.sh_flags.write",
2141 FT_BOOLEAN, 32, NULL, 0x00000001,
2142 "The section contains data that should be writable during process execution.", HFILL }
2144 { &hf_elf_sh_addr,
2145 { "Address", "elf.sh_addr",
2146 FT_UINT32, BASE_HEX, NULL, 0x00,
2147 "If the section will appear in the memory image of a process, this member gives the address at which the section's first byte should reside. Otherwise, the member contains 0.", HFILL }
2149 { &hf_elf64_sh_addr,
2150 { "Address", "elf.sh_addr64",
2151 FT_UINT64, BASE_HEX, NULL, 0x00,
2152 "If the section will appear in the memory image of a process, this member gives the address at which the section's first byte should reside. Otherwise, the member contains 0.", HFILL }
2154 { &hf_elf_sh_offset,
2155 { "File Offset", "elf.sh_offset",
2156 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2157 "This member's value gives the byte offset from the beginning of the file to the first byte in the section. One section type, SHT_NOBITS, occupies no space in the file, and its sh_offset member locates the conceptual placement in the file.", HFILL }
2159 { &hf_elf64_sh_offset,
2160 { "File Offset", "elf.sh_offset64",
2161 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2162 "This member's value gives the byte offset from the beginning of the file to the first byte in the section. One section type, SHT_NOBITS, occupies no space in the file, and its sh_offset member locates the conceptual placement in the file.", HFILL }
2164 { &hf_elf_sh_size,
2165 { "Size", "elf.sh_size",
2166 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2167 "This member gives the section's size in bytes.", HFILL }
2169 { &hf_elf64_sh_size,
2170 { "Size", "elf.sh_size64",
2171 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2172 "This member gives the section's size in bytes.", HFILL }
2175 { &hf_elf_sh_link,
2176 { "Link Index", "elf.sh_link",
2177 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2178 "This member holds a section header table index link, whose interpretation depends on the section type.", HFILL }
2180 { &hf_elf_sh_info,
2181 { "Info", "elf.sh_info",
2182 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2183 "This member holds extra information, whose interpretation depends on the section type.", HFILL }
2185 { &hf_elf_sh_addralign,
2186 { "Address Alignment", "elf.sh_addralign",
2187 FT_UINT32, BASE_HEX, NULL, 0x00,
2188 "Some sections have address alignment constraints. Currently, only 0 and positive integral powers of two are allowed. Values 0 and 1 mean the section has no alignment constraints.", HFILL }
2190 { &hf_elf64_sh_addralign,
2191 { "Address Alignment", "elf.sh_addralign64",
2192 FT_UINT64, BASE_HEX, NULL, 0x00,
2193 "Some sections have address alignment constraints. Currently, only 0 and positive integral powers of two are allowed. Values 0 and 1 mean the section has no alignment constraints.", HFILL }
2195 { &hf_elf_sh_entsize,
2196 { "Entry Size", "elf.sh_entsize",
2197 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2198 "Some sections hold a table of fixed-size entries, such as a symbol table. For such a section, this member gives the size in bytes of each entry. The member contains 0 if the section does not hold a table of fixed-size entries.", HFILL }
2200 { &hf_elf64_sh_entsize,
2201 { "Entry Size", "elf.sh_entsize64",
2202 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2203 "Some sections hold a table of fixed-size entries, such as a symbol table. For such a section, this member gives the size in bytes of each entry. The member contains 0 if the section does not hold a table of fixed-size entries.", HFILL }
2205 /* .eh_frame */
2206 { &hf_elf_eh_frame_length,
2207 { "Length", "elf.eh_frame.length",
2208 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2209 "Length of CIE. Zero indicates a terminator, 0xffffffff means that "
2210 "the Extended Length field contains the actual length.", HFILL }
2212 { &hf_elf_eh_frame_extended_length,
2213 { "Extended Length", "elf.eh_frame.extended_length",
2214 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2215 "Extended Length of CIE.", HFILL }
2217 { &hf_elf_eh_frame_cie_id,
2218 { "CIE ID", "elf.eh_frame.cie_id",
2219 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2220 "A 4 byte unsigned value that is used to distinguish CIE records from FDE records. This value shall always be 0, which indicates this record is a CIE.", HFILL }
2222 { &hf_elf_eh_frame_version,
2223 { "Version", "elf.eh_frame.version",
2224 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2225 "A 1 byte value that identifies the version number of the frame information structure. This value shall be 1.", HFILL }
2227 { &hf_elf_eh_frame_augmentation_string,
2228 { "Augmentation String", "elf.eh_frame.augmentation_string",
2229 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2230 "This value is a NUL terminated string that identifies the augmentation to the CIE or to the FDEs associated with this CIE. A zero length string indicates that no augmentation data is present. The augmentation string is case sensitive.", HFILL }
2232 { &hf_elf_eh_frame_code_alignment_factor,
2233 { "Code Alignment Factor", "elf.eh_frame.code_alignment_factor",
2234 FT_UINT64, BASE_DEC, NULL, 0x00,
2235 "An unsigned LEB128 encoded value that is factored out of all advance location instructions that are associated with this CIE or its FDEs. This value shall be multiplied by the delta argument of an advance location instruction to obtain the new location value.", HFILL }
2237 { &hf_elf_eh_frame_data_alignment_factor,
2238 { "Data Alignment Factor", "elf.eh_frame.data_alignment_factor",
2239 FT_INT64, BASE_DEC, NULL, 0x00,
2240 "A signed LEB128 encoded value that is factored out of all offset instructions that are associated with this CIE or its FDEs. This value shall be multiplied by the register offset argument of an offset instruction to obtain the new offset value.", HFILL }
2242 { &hf_elf_eh_frame_return_address_register,
2243 { "Return Address Register", "elf.eh_frame.return_address_register",
2244 FT_UINT64, BASE_DEC, NULL, 0x00,
2245 "An unsigned LEB128 constant that indicates which column in the rule table represents the return address of the function. Note that this column might not correspond to an actual machine register.", HFILL }
2247 { &hf_elf_eh_frame_augmentation_length,
2248 { "Augmentation Length", "elf.eh_frame.augmentation_length",
2249 FT_UINT64, BASE_DEC, NULL, 0x00,
2250 "An unsigned LEB128 encoded value indicating the length in bytes of the Augmentation Data. This field is only present if the Augmentation String contains the character 'z'.", HFILL }
2252 { &hf_elf_eh_frame_augmentation_data,
2253 { "Augmentation Data", "elf.eh_frame.augmentation_data",
2254 FT_BYTES, BASE_NONE, NULL, 0x00,
2255 "A block of data whose contents are defined by the contents of the Augmentation String as described below. This field is only present if the Augmentation String contains the character 'z'.", HFILL }
2257 { &hf_elf_eh_frame_initial_instructions,
2258 { "Initial Instructions", "elf.eh_frame.initial_instructions",
2259 FT_BYTES, BASE_NONE, NULL, 0x00,
2260 "Initial set of Call Frame Instructions.", HFILL }
2262 /* .eh_frame fde */
2263 { &hf_elf_eh_frame_fde_length,
2264 { "Length", "elf.eh_frame.fde.length",
2265 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2266 "Length of FDE. Zero indicates a terminator, 0xffffffff means that "
2267 "the Extended Length field contains the actual length.", HFILL }
2269 { &hf_elf_eh_frame_fde_extended_length,
2270 { "Extended Length", "elf.eh_frame.fde.extended_length",
2271 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2272 "Extended Length of FDE.", HFILL }
2274 { &hf_elf_eh_frame_fde_cie_pointer,
2275 { "CIE Pointer", "elf.eh_frame.fde.cie_pointer",
2276 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2277 "A 4 byte unsigned value that when subtracted from the offset of the CIE Pointer in the current FDE yields the offset of the start of the associated CIE. This value shall never be 0.", HFILL }
2279 { &hf_elf_eh_frame_fde_pc_begin,
2280 { "PC Begin", "elf.eh_frame.fde.pc_begin",
2281 FT_UINT32, BASE_HEX, NULL, 0x00,
2282 "An encoded value that indicates the address of the initial location associated with this FDE. The encoding format is specified in the Augmentation Data.", HFILL }
2284 { &hf_elf_eh_frame_fde_pc_range,
2285 { "PC Range", "elf.eh_frame.fde.pc_range",
2286 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2287 "An absolute value that indicates the number of bytes of instructions associated with this FDE.", HFILL }
2289 { &hf_elf_eh_frame_fde_augmentation_length,
2290 { "Augmentation Length", "elf.eh_frame.fde.augmentation_length",
2291 FT_UINT64, BASE_DEC, NULL, 0x00,
2292 "An unsigned LEB128 encoded value indicating the length in bytes of the Augmentation Data.", HFILL }
2294 { &hf_elf_eh_frame_fde_augmentation_data,
2295 { "Augmentation Data", "elf.eh_frame.fde.augmentation_data",
2296 FT_BYTES, BASE_NONE, NULL, 0x00,
2297 "Data as described by the Augmentation String in the CIE.", HFILL }
2299 { &hf_elf_eh_frame_fde_call_frame_instructions,
2300 { "Call Frame Instructions", "elf.eh_frame.fde.call_frame_instructions",
2301 FT_BYTES, BASE_NONE, NULL, 0x00,
2302 "A set of Call Frame Instructions.", HFILL }
2304 /* .eh_frame_hdr */
2305 { &hf_elf_eh_frame_hdr_version,
2306 { "Version", "elf.eh_frame_hdr.version",
2307 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2308 "Version of the .eh_frame_hdr format. This value shall be 1.", HFILL }
2310 { &hf_elf_eh_frame_hdr_exception_frame_pointer_encoding,
2311 { "Exception Frame Pointer Encoding", "elf.eh_frame_hdr.eh_frame_ptr_enc",
2312 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2313 "The encoding format of the eh_frame_ptr field.", HFILL }
2315 { &hf_elf_eh_frame_hdr_fde_count_encoding,
2316 { "FDE Count Encoding", "elf.eh_frame_hdr.fde_count_enc",
2317 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2318 "The encoding format of the fde_count field. A value of DW_EH_PE_omit indicates the binary search table is not present.", HFILL }
2320 { &hf_elf_eh_frame_hdr_binary_search_table_encoding,
2321 { "Binary Search Table Encoding", "elf.eh_frame_hdr.binary_search_table_encoding",
2322 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2323 "The encoding format of the entries in the binary search table. A value of DW_EH_PE_omit indicates the binary search table is not present.", HFILL }
2327 { &hf_elf_eh_frame_hdr_eh_frame_ptr,
2328 { "Exception Frame Pointer", "elf.eh_frame_hdr.eh_frame_ptr",
2329 FT_BYTES, BASE_NONE, NULL, 0x00,
2330 "Start of .eh_frame pointer", HFILL }
2332 { &hf_elf_eh_frame_hdr_fde_count,
2333 { "Number of FDE entries", "elf.eh_frame_hdr.fde_count",
2334 FT_UINT64, BASE_DEC, NULL, 0x00,
2335 NULL, HFILL }
2337 { &hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location,
2338 { "Initial location", "elf.eh_frame_hdr.binary_search_table_entry.initial_location",
2339 FT_BYTES, BASE_NONE, NULL, 0x00,
2340 NULL, HFILL }
2342 { &hf_elf_eh_frame_hdr_binary_search_table_entry_address,
2343 { "Address", "elf.eh_frame_hdr.binary_search_table_entry.address",
2344 FT_BYTES, BASE_NONE, NULL, 0x00,
2345 NULL, HFILL }
2348 /* symbol_table */
2349 { &hf_elf_symbol_table_name_index,
2350 { "Name Index", "elf.symbol_table.name_index",
2351 FT_UINT32, BASE_DEC, NULL, 0x00,
2352 NULL, HFILL }
2354 { &hf_elf_symbol_table_info,
2355 { "Info", "elf.symbol_table.info",
2356 FT_UINT8, BASE_HEX, NULL, 0x00,
2357 NULL, HFILL }
2359 { &hf_elf_symbol_table_info_bind,
2360 { "Bind", "elf.symbol_table.info.bind",
2361 FT_UINT8, BASE_HEX, VALS(symbol_table_info_bind_vals), 0xF0,
2362 NULL, HFILL }
2364 { &hf_elf_symbol_table_info_type,
2365 { "Type", "elf.symbol_table.info.type",
2366 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &symbol_table_info_type_vals_ext, 0x0F,
2367 NULL, HFILL }
2369 { &hf_elf_symbol_table_other,
2370 { "Other", "elf.symbol_table.other",
2371 FT_UINT8, BASE_HEX, VALS(symbol_table_other_vals), 0x00,
2372 NULL, HFILL }
2374 { &hf_elf_symbol_table_shndx,
2375 { "Related Section Header Index", "elf.symbol_table.shndx",
2376 FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(symbol_table_shndx_rvals), 0x00,
2377 NULL, HFILL }
2379 { &hf_elf_symbol_table_value,
2380 { "Value", "elf.symbol_table.value",
2381 FT_UINT32, BASE_HEX, NULL, 0x00,
2382 NULL, HFILL }
2384 { &hf_elf64_symbol_table_value,
2385 { "Value", "elf.symbol_table.value64",
2386 FT_UINT64, BASE_HEX, NULL, 0x00,
2387 NULL, HFILL }
2389 { &hf_elf_symbol_table_size,
2390 { "Size", "elf.symbol_table.size",
2391 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2392 NULL, HFILL }
2394 { &hf_elf64_symbol_table_size,
2395 { "Size", "elf.symbol_table.size64",
2396 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2397 NULL, HFILL }
2400 /* dynamic */
2401 { &hf_elf_dynamic_tag,
2402 { "Tag", "elf.dynamic.tag",
2403 FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(dynamic_tag_rvals), 0x00,
2404 NULL, HFILL }
2406 { &hf_elf_dynamic_value,
2407 { "Value", "elf.dynamic.value",
2408 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2409 NULL, HFILL }
2411 { &hf_elf_dynamic_pointer,
2412 { "Pointer", "elf.dynamic.pointer",
2413 FT_UINT32, BASE_HEX, NULL, 0x00,
2414 NULL, HFILL }
2416 { &hf_elf_dynamic_ignored,
2417 { "Ignored", "elf.dynamic.ignored",
2418 FT_UINT32, BASE_HEX, NULL, 0x00,
2419 NULL, HFILL }
2421 { &hf_elf_dynamic_unspecified,
2422 { "Unspecified", "elf.dynamic.unspecified",
2423 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2424 NULL, HFILL }
2426 { &hf_elf64_dynamic_tag,
2427 { "Tag", "elf.dynamic.tag64",
2428 FT_UINT64, BASE_HEX /*| BASE_RANGE_STRING*/, NULL /*RVALS(dynamic_tag_rvals)*/, 0x00,
2429 NULL, HFILL }
2431 { &hf_elf64_dynamic_value,
2432 { "Value", "elf.dynamic.value64",
2433 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2434 NULL, HFILL }
2436 { &hf_elf64_dynamic_pointer,
2437 { "Pointer", "elf.dynamic.pointer64",
2438 FT_UINT64, BASE_HEX, NULL, 0x00,
2439 NULL, HFILL }
2441 { &hf_elf64_dynamic_ignored,
2442 { "Ignored", "elf.dynamic.ignored64",
2443 FT_UINT64, BASE_HEX, NULL, 0x00,
2444 NULL, HFILL }
2446 { &hf_elf64_dynamic_unspecified,
2447 { "Unspecified", "elf.dynamic.unspecified64",
2448 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2449 NULL, HFILL }
2452 /* dwarf */
2453 { &hf_dwarf_omit,
2454 { "DW_EH_PE_omit", "elf.dwarf.omit",
2455 FT_UINT8, BASE_HEX, NULL, 0x00,
2456 "Used to indicate that no value is present.", HFILL }
2458 { &hf_dwarf_upper,
2459 { "DWARF Exception Header application", "elf.dwarf.upper",
2460 FT_UINT8, BASE_HEX, VALS(eh_dwarf_upper), 0xF0,
2461 "The upper 4 bits indicate how the value is to be applied.", HFILL }
2463 { &hf_dwarf_format,
2464 { "DWARF Exception Header value format", "elf.dwarf.format",
2465 FT_UINT8, BASE_HEX, VALS(eh_dwarf_format), 0x0F,
2466 "The lower 4 bits indicate the format of the data.", HFILL }
2468 { &hf_elf_string,
2469 { "String", "elf.string",
2470 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2471 NULL, HFILL }
2475 static ei_register_info ei[] = {
2476 { &ei_invalid_segment_size, { "elf.invalid_segment_size", PI_PROTOCOL, PI_WARN, "Segment size is different then currently parsed bytes", EXPFILL }},
2477 { &ei_invalid_entry_size, { "elf.invalid_entry_size", PI_PROTOCOL, PI_WARN, "Entry size is different then currently parsed bytes", EXPFILL }},
2478 { &ei_cfi_extraneous_data, { "elf.cfi_extraneous_data", PI_PROTOCOL, PI_WARN, "Segment size is larger than CFI records combined", EXPFILL }},
2479 { &ei_invalid_cie_length, { "elf.invalid_cie_length", PI_PROTOCOL, PI_ERROR, "CIE length is too small or larger than segment size", EXPFILL }},
2482 static int *ett[] = {
2483 &ett_elf,
2484 &ett_elf_header,
2485 &ett_elf_program_header,
2486 &ett_elf_program_header_entry,
2487 &ett_elf_section_header,
2488 &ett_elf_section_header_entry,
2489 &ett_elf_segment,
2490 &ett_elf_cfi_record,
2491 &ett_elf_cie_entry,
2492 &ett_elf_fde_entry,
2493 &ett_elf_cie_terminator,
2494 &ett_elf_info,
2495 &ett_elf_black_holes,
2496 &ett_elf_overlapping,
2497 &ett_dwarf_encoding,
2498 &ett_binary_table,
2499 &ett_binary_table_entry,
2500 &ett_symbol_table_entry,
2501 &ett_symbol_table_info
2504 proto_elf = proto_register_protocol("Executable and Linkable Format", "ELF", "elf");
2505 proto_register_field_array(proto_elf, hf, array_length(hf));
2506 proto_register_subtree_array(ett, array_length(ett));
2508 elf_handle = register_dissector("elf", dissect_elf, proto_elf);
2510 module = prefs_register_protocol(proto_elf, NULL);
2511 prefs_register_static_text_preference(module, "version",
2512 "ELF version: 4.1 DRAFT",
2513 "Version of file-format supported by this dissector.");
2515 expert_module = expert_register_protocol(proto_elf);
2516 expert_register_field_array(expert_module, ei, array_length(ei));
2519 void
2520 proto_reg_handoff_elf(void)
2522 dissector_add_string("media_type", "application/x-executable", elf_handle);
2523 dissector_add_string("media_type", "application/x-coredump", elf_handle);
2524 dissector_add_string("media_type", "application/x-object", elf_handle);
2525 dissector_add_string("media_type", "application/x-sharedlib", elf_handle);
2527 /* XXX - TEMPORARY HACK */
2528 dissector_add_uint("ftap_encap", 1234, elf_handle);
2530 heur_dissector_add("wtap_file", dissect_elf_heur, "ELF file", "elf_wtap", proto_elf, HEURISTIC_ENABLE);
2534 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2536 * Local variables:
2537 * c-basic-offset: 4
2538 * tab-width: 8
2539 * indent-tabs-mode: nil
2540 * End:
2542 * vi: set shiftwidth=4 tabstop=8 expandtab:
2543 * :indentSize=4:tabSize=8:noTabs=true: