HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / file-elf.c
blobd91c8031991cc1a435ead76807bb265150b621bd
1 /* file-elf.c
2 * Routines for Executable and Linkable Format
3 * Based on: SYSTEM V APPLICATION BINARY INTERFACE Edition 4.1
4 * http://www.sco.com/developers/devspecs/
5 * http://www.sco.com/developers/gabi/latest/contents.html
6 * http://refspecs.linuxfoundation.org/
7 * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
8 * http://dwarfstd.org/doc/DWARF4.pdf
9 * http://www.sco.com/developers/devspecs/
11 * Copyright 2013, Michal Labedzki for Tieto Corporation
13 * $Id$
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "config.h"
36 #include <epan/packet.h>
37 #include <epan/prefs.h>
38 #include <epan/expert.h>
39 #include <epan/wmem/wmem.h>
41 #include "dwarf.h"
43 static int proto_elf = -1;
45 static int hf_elf_magic_bytes = -1;
46 static int hf_elf_file_class = -1;
47 static int hf_elf_data_encoding = -1;
48 static int hf_elf_file_version = -1;
49 static int hf_elf_os_abi = -1;
50 static int hf_elf_abi_version = -1;
51 static int hf_elf_file_padding = -1;
52 static int hf_elf_type = -1;
53 static int hf_elf_machine = -1;
54 static int hf_elf_version = -1;
55 static int hf_elf_entry = -1;
56 static int hf_elf_phoff = -1;
57 static int hf_elf_shoff = -1;
58 static int hf_elf64_entry = -1;
59 static int hf_elf64_phoff = -1;
60 static int hf_elf64_shoff = -1;
61 static int hf_elf_flags = -1;
62 static int hf_elf_ehsize = -1;
63 static int hf_elf_phentsize = -1;
64 static int hf_elf_phnum = -1;
65 static int hf_elf_shentsize = -1;
66 static int hf_elf_shnum = -1;
67 static int hf_elf_shstrndx = -1;
68 static int hf_elf_p_type = -1;
69 static int hf_elf_p_type_operating_system_specific = -1;
70 static int hf_elf_p_type_processor_specific = -1;
71 static int hf_elf_p_flags_execute = -1;
72 static int hf_elf_p_flags_write = -1;
73 static int hf_elf_p_flags_read = -1;
74 static int hf_elf_p_flags_reserved = -1;
75 static int hf_elf_p_flags_operating_system_specific = -1;
76 static int hf_elf_p_flags_processor_specific = -1;
77 static int hf_elf_p_offset = -1;
78 static int hf_elf64_p_offset = -1;
79 static int hf_elf_p_vaddr = -1;
80 static int hf_elf64_p_vaddr = -1;
81 static int hf_elf_p_paddr = -1;
82 static int hf_elf64_p_paddr = -1;
83 static int hf_elf_p_filesz = -1;
84 static int hf_elf64_p_filesz = -1;
85 static int hf_elf_p_memsz = -1;
86 static int hf_elf64_p_memsz = -1;
87 static int hf_elf_p_align = -1;
88 static int hf_elf64_p_align = -1;
90 static int hf_elf_sh_name = -1;
91 static int hf_elf_sh_type_user_specific = -1;
92 static int hf_elf_sh_type_operating_system_specific = -1;
93 static int hf_elf_sh_type_processor_specific = -1;
94 static int hf_elf_sh_type = -1;
96 static int hf_elf_sh_flags_processor_specific = -1;
97 static int hf_elf_sh_flags_operating_system_specific = -1;
98 static int hf_elf_sh_flags_reserved = -1;
99 static int hf_elf_sh_flags_tls = -1;
100 static int hf_elf_sh_flags_group = -1;
101 static int hf_elf_sh_flags_os_nonconforming = -1;
102 static int hf_elf_sh_flags_link_order = -1;
103 static int hf_elf_sh_flags_info_link = -1;
104 static int hf_elf_sh_flags_strings = -1;
105 static int hf_elf_sh_flags_merge = -1;
106 static int hf_elf_sh_flags_reserved_8 = -1;
107 static int hf_elf_sh_flags_exec_instr = -1;
108 static int hf_elf_sh_flags_alloc = -1;
109 static int hf_elf_sh_flags_write = -1;
110 static int hf_elf_sh_addr = -1;
111 static int hf_elf64_sh_addr = -1;
113 static int hf_elf_sh_offset = -1;
114 static int hf_elf64_sh_offset = -1;
115 static int hf_elf_sh_size = -1;
116 static int hf_elf64_sh_size = -1;
117 static int hf_elf_sh_link = -1;
118 static int hf_elf_sh_info = -1;
119 static int hf_elf_sh_addralign = -1;
120 static int hf_elf64_sh_addralign = -1;
121 static int hf_elf_sh_entsize = -1;
122 static int hf_elf64_sh_entsize = -1;
124 static int hf_elf_eh_frame_length = -1;
125 static int hf_elf_eh_frame_extended_length = -1;
126 static int hf_elf_eh_frame_cie_id = -1;
127 static int hf_elf_eh_frame_version = -1;
128 static int hf_elf_eh_frame_augmentation_string = -1;
129 static int hf_elf_eh_frame_code_alignment_factor = -1;
130 static int hf_elf_eh_frame_data_alignment_factor = -1;
131 static int hf_elf_eh_frame_return_address_register = -1;
132 static int hf_elf_eh_frame_augmentation_length = -1;
133 static int hf_elf_eh_frame_augmentation_data = -1;
134 static int hf_elf_eh_frame_initial_instructions = -1;
136 static int hf_elf_eh_frame_fde_length = -1;
137 static int hf_elf_eh_frame_fde_extended_length = -1;
138 static int hf_elf_eh_frame_fde_cie_pointer = -1;
139 static int hf_elf_eh_frame_fde_pc_begin = -1;
140 static int hf_elf_eh_frame_fde_pc_range = -1;
141 static int hf_elf_eh_frame_fde_augmentation_length = -1;
142 static int hf_elf_eh_frame_fde_augmentation_data = -1;
143 static int hf_elf_eh_frame_fde_call_frame_instructions = -1;
145 static int hf_elf_eh_frame_hdr_version = -1;
146 static int hf_elf_eh_frame_hdr_exception_frame_pointer_encoding = -1;
147 static int hf_elf_eh_frame_hdr_fde_count_encoding = -1;
148 static int hf_elf_eh_frame_hdr_binary_search_table_encoding = -1;
149 static int hf_elf_eh_frame_hdr_eh_frame_ptr = -1;
150 static int hf_elf_eh_frame_hdr_fde_count = -1;
151 static int hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location = -1;
152 static int hf_elf_eh_frame_hdr_binary_search_table_entry_address = -1;
154 static int hf_elf_symbol_table_name_index = -1;
155 static int hf_elf_symbol_table_value = -1;
156 static int hf_elf64_symbol_table_value = -1;
157 static int hf_elf_symbol_table_size = -1;
158 static int hf_elf64_symbol_table_size = -1;
159 static int hf_elf_symbol_table_info = -1;
160 static int hf_elf_symbol_table_info_bind = -1;
161 static int hf_elf_symbol_table_info_type = -1;
162 static int hf_elf_symbol_table_other = -1;
163 static int hf_elf_symbol_table_shndx = -1;
165 static int hf_elf_dynamic_tag = -1;
166 static int hf_elf_dynamic_value = -1;
167 static int hf_elf_dynamic_pointer = -1;
168 static int hf_elf_dynamic_ignored = -1;
169 static int hf_elf_dynamic_unspecified = -1;
170 static int hf_elf64_dynamic_tag = -1;
171 static int hf_elf64_dynamic_value = -1;
172 static int hf_elf64_dynamic_pointer = -1;
173 static int hf_elf64_dynamic_ignored = -1;
174 static int hf_elf64_dynamic_unspecified = -1;
176 static int hf_elf_string = -1;
178 static int hf_dwarf_omit = -1;
179 static int hf_dwarf_upper = -1;
180 static int hf_dwarf_format = -1;
182 static expert_field ei_invalid_segment_size = EI_INIT;
183 static expert_field ei_invalid_entry_size = EI_INIT;
185 static gint ett_elf = -1;
186 static gint ett_elf_header = -1;
187 static gint ett_elf_program_header = -1;
188 static gint ett_elf_section_header = -1;
189 static gint ett_elf_segment = -1;
190 static gint ett_elf_cie = -1;
191 static gint ett_elf_fde = -1;
192 static gint ett_elf_entry = -1;
193 static gint ett_elf_info = -1;
194 static gint ett_elf_black_holes = -1;
195 static gint ett_elf_overlapping = -1;
196 static gint ett_dwarf_encoding = -1;
197 static gint ett_binary_table = -1;
198 static gint ett_binary_table_entry = -1;
199 static gint ett_symbol_table_entry = -1;
200 static gint ett_symbol_table_info = -1;
202 #define REGISTER_32_SIZE 4
203 #define REGISTER_64_SIZE 8
205 static const value_string class_vals[] = {
206 { 0x00, "Invalid class" },
207 { 0x01, "32-bit object" },
208 { 0x02, "64-bit object" },
209 { 0, NULL }
212 static const value_string data_encoding_vals[] = {
213 { 0x00, "None" },
214 { 0x01, "Least Significant Bit" },
215 { 0x02, "Most Significant Bit " },
216 { 0, NULL }
219 static const value_string version_vals[] = {
220 { 0x00, "None" },
221 { 0x01, "Current" },
222 { 0, NULL }
225 static const value_string type_vals[] = {
226 { 0x0000, "No file type" },
227 { 0x0001, "Relocatable file" },
228 { 0x0002, "Executable file" },
229 { 0x0003, "Shared object file" },
230 { 0x0004, "Core file" },
231 { 0xFE00, "Operating system-specific Lo" }, /* From Draft */
232 { 0xFEFF, "Operating system-specific Hi" }, /* From Draft */
233 { 0xFF00, "Processor Specific Lo" },
234 { 0xFFFF, "Processor Specific Hi" },
235 { 0, NULL }
238 static const value_string machine_vals[] = {
239 { 0, "No machine" },
240 { 1, "AT&T WE 32100" },
241 { 2, "SPARC" },
242 { 3, "Intel 80386" },
243 { 4, "Motorola 68000" },
244 { 5, "Motorola 88000" },
245 { 7, "Intel 80860" },
246 /* From Draft */
247 { 8, "MIPS I Architecture" },
248 { 9, "IBM System/370 Processor" },
249 { 10, "MIPS RS3000 Little-endian" },
250 { 15, "Hewlett-Packard PA-RISC" },
251 { 17, "Fujitsu VPP500" },
252 { 18, "Enhanced instruction set SPARC" },
253 { 19, "Intel 80960" },
254 { 20, "PowerPC" },
255 { 21, "64-bit PowerPC" },
256 { 22, "IBM System/390 Processor" },
257 { 23, "IBM SPU/SPC" },
258 { 36, "NEC V800" },
259 { 37, "Fujitsu FR20" },
260 { 38, "TRW RH-32" },
261 { 39, "Motorola RCE" },
262 { 40, "ARM 32-bit architecture (AARCH32)" },
263 { 41, "Digital Alpha" },
264 { 42, "Hitachi SH" },
265 { 43, "SPARC Version 9" },
266 { 44, "Siemens TriCore embedded processor" },
267 { 45, "Argonaut RISC Core, Argonaut Technologies Inc." },
268 { 46, "Hitachi H8/300" },
269 { 47, "Hitachi H8/300H" },
270 { 48, "Hitachi H8S" },
271 { 49, "Hitachi H8/500" },
272 { 50, "Intel IA-64 processor architecture" },
273 { 51, "Stanford MIPS-X" },
274 { 52, "Motorola ColdFire" },
275 { 53, "Motorola M68HC12" },
276 { 54, "Fujitsu MMA Multimedia Accelerator" },
277 { 55, "Siemens PCP" },
278 { 56, "Sony nCPU embedded RISC processor" },
279 { 57, "Denso NDR1 microprocessor" },
280 { 58, "Motorola Star*Core processor" },
281 { 59, "Toyota ME16 processor" },
282 { 60, "STMicroelectronics ST100 processor" },
283 { 61, "Advanced Logic Corp. TinyJ embedded processor family" },
284 { 62, "AMD x86-64 architecture" },
285 { 63, "Sony DSP Processor" },
286 { 64, "Digital Equipment Corp. PDP-10" },
287 { 65, "Digital Equipment Corp. PDP-11" },
288 { 66, "Siemens FX66 microcontroller" },
289 { 67, "STMicroelectronics ST9+ 8/16 bit microcontroller" },
290 { 68, "STMicroelectronics ST7 8-bit microcontroller" },
291 { 69, "Motorola MC68HC16 Microcontroller" },
292 { 70, "Motorola MC68HC11 Microcontroller" },
293 { 71, "Motorola MC68HC08 Microcontroller" },
294 { 72, "Motorola MC68HC05 Microcontroller" },
295 { 73, "Silicon Graphics SVx" },
296 { 74, "STMicroelectronics ST19 8-bit microcontroller" },
297 { 75, "Digital VAX" },
298 { 76, "Axis Communications 32-bit embedded processor" },
299 { 77, "Infineon Technologies 32-bit embedded processor" },
300 { 78, "Element 14 64-bit DSP Processor" },
301 { 79, "LSI Logic 16-bit DSP Processor" },
302 { 80, "Donald Knuth's educational 64-bit processor" },
303 { 81, "Harvard University machine-independent object files" },
304 { 82, "SiTera Prism" },
305 { 83, "Atmel AVR 8-bit microcontroller" },
306 { 84, "Fujitsu FR30" },
307 { 85, "Mitsubishi D10V" },
308 { 86, "Mitsubishi D30V" },
309 { 87, "NEC v850" },
310 { 88, "Mitsubishi M32R" },
311 { 89, "Matsushita MN10300" },
312 { 90, "Matsushita MN10200" },
313 { 91, "picoJava" },
314 { 92, "OpenRISC 32-bit embedded processor" },
315 { 93, "ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)" },
316 { 94, "Tensilica Xtensa Architecture" },
317 { 95, "Alphamosaic VideoCore processor" },
318 { 96, "Thompson Multimedia General Purpose Processor" },
319 { 97, "National Semiconductor 32000 series" },
320 { 98, "Tenor Network TPC processor" },
321 { 99, "Trebia SNP 1000 processor" },
322 { 100, "STMicroelectronics (www.st.com) ST200 microcontroller" },
323 { 101, "Ubicom IP2xxx microcontroller family" },
324 { 102, "MAX Processor" },
325 { 103, "National Semiconductor CompactRISC microprocessor" },
326 { 104, "Fujitsu F2MC16" },
327 { 105, "Texas Instruments embedded microcontroller msp430" },
328 { 106, "Analog Devices Blackfin (DSP) processor" },
329 { 107, "S1C33 Family of Seiko Epson processors" },
330 { 108, "Sharp embedded microprocessor" },
331 { 109, "Arca RISC Microprocessor" },
332 { 110, "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University" },
333 { 111, "eXcess: 16/32/64-bit configurable embedded CPU" },
334 { 112, "Icera Semiconductor Inc. Deep Execution Processor" },
335 { 113, "Altera Nios II soft-core processor" },
336 { 114, "National Semiconductor CompactRISC CRX microprocessor" },
337 { 115, "Motorola XGATE embedded processor" },
338 { 116, "Infineon C16x/XC16x processor" },
339 { 117, "Renesas M16C series microprocessors" },
340 { 118, "Microchip Technology dsPIC30F Digital Signal Controller" },
341 { 119, "Freescale Communication Engine RISC core" },
342 { 120, "Renesas M32C series microprocessors" },
343 { 131, "Altium TSK3000 core" },
344 { 132, "Freescale RS08 embedded processor" },
345 { 133, "Analog Devices SHARC family of 32-bit DSP processors" },
346 { 134, "Cyan Technology eCOG2 microprocessor" },
347 { 135, "Sunplus S+core7 RISC processor" },
348 { 136, "New Japan Radio (NJR) 24-bit DSP Processor" },
349 { 137, "Broadcom VideoCore III processor" },
350 { 138, "RISC processor for Lattice FPGA architecture" },
351 { 139, "Seiko Epson C17 family" },
352 { 140, "The Texas Instruments TMS320C6000 DSP family" },
353 { 141, "The Texas Instruments TMS320C2000 DSP family" },
354 { 142, "The Texas Instruments TMS320C55x DSP family" },
355 { 160, "STMicroelectronics 64bit VLIW Data Signal Processor" },
356 { 161, "Cypress M8C microprocessor" },
357 { 162, "Renesas R32C series microprocessors" },
358 { 163, "NXP Semiconductors TriMedia architecture family" },
359 { 164, "QUALCOMM DSP6 Processor" },
360 { 165, "Intel 8051 and variants" },
361 { 166, "STMicroelectronics STxP7x family of configurable and extensible RISC processors" },
362 { 167, "Andes Technology compact code size embedded RISC processor family" },
363 { 168, "Cyan Technology eCOG1X family" },
364 { 168, "Cyan Technology eCOG1X family" },
365 { 169, "Dallas Semiconductor MAXQ30 Core Micro-controllers" },
366 { 170, "New Japan Radio (NJR) 16-bit DSP Processor" },
367 { 171, "M2000 Reconfigurable RISC Microprocessor" },
368 { 172, "Cray Inc. NV2 vector architecture" },
369 { 173, "Renesas RX family" },
370 { 174, "Imagination Technologies META processor architecture" },
371 { 175, "MCST Elbrus general purpose hardware architecture" },
372 { 176, "Cyan Technology eCOG16 family" },
373 { 177, "National Semiconductor CompactRISC CR16 16-bit microprocessor" },
374 { 178, "Freescale Extended Time Processing Unit" },
375 { 179, "Infineon Technologies SLE9X core" },
376 { 180, "Intel L10M" },
377 { 181, "Intel K10M" },
378 { 182, "Reserved for future Intel use" },
379 { 183, "ARM 64-bit architecture (AARCH64)" },
380 { 184, "Reserved for future ARM use" },
381 { 185, "Atmel Corporation 32-bit microprocessor family" },
382 { 186, "STMicroeletronics STM8 8-bit microcontroller" },
383 { 187, "Tilera TILE64 multicore architecture family" },
384 { 188, "Tilera TILEPro multicore architecture family" },
385 { 189, "Xilinx MicroBlaze 32-bit RISC soft processor core" },
386 { 190, "NVIDIA CUDA architecture" },
387 { 191, "Tilera TILE-Gx multicore architecture family" },
388 { 192, "CloudShield architecture family" },
389 { 193, "KIPO-KAIST Core-A 1st generation processor family" },
390 { 194, "KIPO-KAIST Core-A 2nd generation processor family" },
391 { 195, "Synopsys ARCompact V2" },
392 { 196, "Open8 8-bit RISC soft processor core" },
393 { 197, "Renesas RL78 family" },
394 { 198, "Broadcom VideoCore V processor" },
395 { 199, "Renesas 78KOR family" },
396 { 200, "Freescale 56800EX Digital Signal Controller (DSC)" },
397 { 201, "Beyond BA1 CPU architecture" },
398 { 202, "Beyond BA2 CPU architecture" },
399 { 203, "XMOS xCORE processor family" },
400 { 204, "Microchip 8-bit PIC(r) family" },
401 { 0, NULL }
404 /* From Draft */
405 static const value_string os_abi_vals[] = {
406 { 0x00, "No extensions or unspecified" },
407 { 0x01, "Hewlett-Packard HP-UX" },
408 { 0x02, "NetBSD" },
409 { 0x03, "GNU (historial alias: Linux)" },
410 { 0x06, "Sun Solaris" },
411 { 0x07, "AIX" },
412 { 0x08, "IRIX" },
413 { 0x09, "FreeBSD" },
414 { 0x0A, "Compaq TRU64 UNIX" },
415 { 0x0B, "Novell Modesto" },
416 { 0x0C, "Open BSD" },
417 { 0x0D, "Open VMS" },
418 { 0x0E, "Hewlett-Packard Non-Stop Kernel" },
419 { 0x0F, "Amiga Research OS" },
420 { 0x10, "The FenixOS highly scalable multi-core OS" },
421 { 0, NULL }
424 static const value_string p_type_vals[] = {
425 { 0, "PT_NULL" },
426 { 1, "PT_LOAD" },
427 { 2, "PT_DYNAMIC" },
428 { 3, "PT_INTERP" },
429 { 4, "PT_NOTE" },
430 { 5, "PT_SHLIB" },
431 { 6, "PT_PHDR" },
432 { 7, "PT_TLS" },
433 { 0, NULL }
436 static const value_string sh_type_vals[] = {
437 { 0, "SHT_NULL" },
438 { 1, "SHT_PROGBITS" },
439 { 2, "SHT_SYMTAB" },
440 { 3, "SHT_STRTAB" },
441 { 4, "SHT_RELA" },
442 { 5, "SHT_HASH" },
443 { 6, "SHT_DYNAMIC" },
444 { 7, "SHT_NOTE" },
445 { 8, "SHT_NOBITS" },
446 { 9, "SHT_REL" },
447 { 10, "SHT_SHLIB" },
448 { 11, "SHT_DYNSYM" },
449 { 14, "SHT_INIT_ARRAY" },
450 { 15, "SHT_FINI_ARRAY" },
451 { 16, "SHT_PREINIT_ARRAY" },
452 { 17, "SHT_GROUP" },
453 { 18, "SHT_SYMTAB_SHNDX" },
454 /* TODO: http://www.sco.com/developers/gabi/latest/ch4.sheader.html range_string? */
455 { 0, NULL }
458 static const value_string eh_dwarf_upper[] = {
459 { 0x0, "Normal Value" },
460 { 0x1, "Value is relative to the current program counter. (DW_EH_PE_pcrel)" },
461 { 0x2, "Value is relative to the beginning of the .text section. (DW_EH_PE_textrel)" },
462 { 0x3, "Value is relative to the beginning of the .got or .eh_frame_hdr section. (DW_EH_PE_datarel)" },
463 { 0x4, "Value is relative to the beginning of the function. (DW_EH_PE_funcrel)" },
464 { 0x5, "Value is aligned to an address unit sized boundary. (DW_EH_PE_aligned)" },
465 { 0, NULL }
468 static const value_string eh_dwarf_format[] = {
469 { 0x0, "The Value is a literal pointer whose size is determined by the architecture. (DW_EH_PE_absptr)" },
470 { 0x1, "Unsigned value is encoded using the Little Endian Base 128 (LEB128). (DW_EH_PE_uleb128)" },
471 { 0x2, "A 2 bytes unsigned value. (DW_EH_PE_udata2)" },
472 { 0x3, "A 4 bytes unsigned value. (DW_EH_PE_udata4)" },
473 { 0x4, "An 8 bytes unsigned value. (DW_EH_PE_udata8)" },
474 { 0x9, "Signed value is encoded using the Little Endian Base 128 (LEB128). (DW_EH_PE_sleb128)" },
475 { 0xA, "A 2 bytes signed value. (DW_EH_PE_sdata2)" },
476 { 0xB, "A 4 bytes signed value. (DW_EH_PE_sdata4)" },
477 { 0xC, "An 8 bytes signed value. (DW_EH_PE_sdata8)" },
478 { 0, NULL }
481 static const value_string symbol_table_other_vals[] = {
482 { 0, "Default" },
483 { 1, "Internal" },
484 { 2, "Hidden" },
485 { 3, "Protected" },
486 { 0, NULL }
490 static const value_string symbol_table_info_bind_vals[] = {
491 { 0, "Local" },
492 { 1, "Global" },
493 { 2, "Weak" },
494 { 10, "Operating System Specific" },
495 { 11, "Operating System Specific" },
496 { 12, "Operating System Specific" },
497 { 13, "Processor Specific" },
498 { 14, "Processor Specific" },
499 { 15, "Processor Specific" },
500 { 0, NULL }
503 static const value_string symbol_table_info_type_vals[] = {
504 { 0, "No Type" },
505 { 1, "Object" },
506 { 2, "Function" },
507 { 3, "Section" },
508 { 4, "File" },
509 { 5, "Common" },
510 { 6, "Thread-Local Storage" },
511 { 10, "Operating System Specific" },
512 { 11, "Operating System Specific" },
513 { 12, "Operating System Specific" },
514 { 13, "Processor Specific" },
515 { 14, "Processor Specific" },
516 { 15, "Processor Specific" },
517 { 0, NULL }
520 static const range_string symbol_table_shndx_rvals[] = {
521 { 0x0000, 0x0000, "Undefined" },
522 { 0x0001, 0xfeff, "Normal Section" },
523 { 0xff00, 0xff1f, "Processor Specific" },
524 { 0xff20, 0xff3f, "Operating System Specific" },
525 { 0xff40, 0xfff0, "Reserved" },
526 { 0xfff1, 0xfff1, "Absolute Value" },
527 { 0xfff2, 0xfff2, "Common" },
528 { 0xfff3, 0xfffe, "Reserved" },
529 { 0xffff, 0xffff, "Xindex" },
530 { 0, 0, NULL }
533 static const range_string dynamic_tag_rvals[] = {
534 { 0, 0, "NULL" },
535 { 1, 1, "Needed" },
536 { 2, 2, "Procedure Linkage Table Size" },
537 { 3, 3, "Procedure Linkage Table and/or the Global Offset Table Address" },
538 { 4, 4, "Hash" },
540 { 5, 5, "String Table Address" },
541 { 6, 6, "Symbol Table Address" },
542 { 7, 7, "Relocation Table Address" },
543 { 8, 8, "Relocation Table Size" },
544 { 9, 9, "Relocation Table Entry Size" },
545 { 10, 10, "String Table Size" },
546 { 11, 11, "Symbol Table Entry Size" },
547 { 12, 12, "Initialization Function Address" },
548 { 13, 13, "Termination Function Address" },
549 { 14, 14, "Shared Object Name Offset" },
550 { 15, 15, "Search Library Path (Rpath)" },
551 { 16, 16, "Symbolic" },
552 { 17, 17, "Relocation Table with Implicit Addends" },
553 { 18, 18, "Relocation Table with Implicit Addends Size" },
554 { 19, 19, "Relocation Table with Implicit Addends Entry Size" },
555 { 20, 20, "Procedure Linkage Table Relocation Entry Type" },
556 { 21, 21, "Debug" },
557 { 22, 22, "TEXT Relocation" },
558 { 23, 23, "Procedure Linkage Table Relocation Entries Address" },
559 { 24, 24, "Bind Now" },
560 { 25, 25, "Initialization Functions Array Address" },
561 { 26, 26, "Termination Functions Array Address" },
562 { 27, 27, "Initialization Functions Array Size" },
563 { 28, 28, "Termination Functions Array Size" },
564 { 29, 29, "Run Path" },
565 { 30, 30, "Flags" },
566 { 31, 31, "Preinitialization Functions Array Address" },
567 { 32, 32, "Preinitialization Functions Array Size" },
568 { 33, 33, "Encoding" },
570 { 0x6000000D, 0x6ffff000, "Operating System Specific" },
571 { 0x70000000, 0x7fffffff, "Processor Specific" },
572 { 0, 0, NULL }
576 typedef struct _segment_info_t {
577 guint64 offset;
578 guint64 size;
579 const guint8 *name;
580 } segment_info_t;
582 void proto_register_elf(void);
583 void proto_reg_handoff_elf(void);
586 /* Wireshark support "offset" as gint, but ELF needed guint64 size, so check if there is no overflow */
587 static gint
588 value_guard(guint64 value)
590 DISSECTOR_ASSERT_HINT(value <= G_MAXINT, "Too big file - not supported");
592 return (gint) value;
595 static guint8
596 dissect_dwarf_encoding(tvbuff_t *tvb, gint offset, proto_item *item)
598 guint8 value;
599 proto_tree *tree;
601 tree = proto_item_add_subtree(item, ett_dwarf_encoding);
603 value = tvb_get_guint8(tvb, offset);
605 if (value == 0xFF) {
606 proto_tree_add_item(tree, hf_dwarf_omit, tvb, offset, 1, ENC_NA);
607 } else {
608 proto_tree_add_item(tree, hf_dwarf_upper, tvb, offset, 1, ENC_NA);
609 proto_tree_add_item(tree, hf_dwarf_format, tvb, offset, 1, ENC_NA);
612 return value;
615 #define LENGTH_LEB128 -1
616 #define LENGTH_ULEB128 -2
618 static gint8
619 get_dwarf_extension_length(guint8 format, guint register_size)
621 switch (format & 0x0F) {
622 case 0x0:
623 return register_size;
624 case 0x1:
625 return LENGTH_ULEB128;
626 case 0x2:
627 return 2;
628 case 0x3:
629 return 4;
630 case 0x4:
631 return 8;
632 case 0x9:
633 return LENGTH_LEB128;
634 case 0xA:
635 return 2;
636 case 0xB:
637 return 4;
638 case 0xC:
639 return 8;
642 return 0;
645 static const guint8 *
646 get_section_name_offset(tvbuff_t *tvb, guint64 shoff, guint16 shnum, guint16 shentsize, guint16 shndx, guint64 shstrtab_offset, guint machine_encoding)
648 gint offset;
649 guint32 sh_name;
651 if (shndx > shnum)
652 return NULL;
654 offset = value_guard(shoff + shndx * shentsize);
655 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
656 return tvb_get_const_stringz(tvb, value_guard(shstrtab_offset + sh_name), NULL);
659 #define MAX_TAG_TO_TYPE 34
660 static gint
661 dissect_dynamic(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *entry_tree, proto_item *entry_item,
662 gint offset, gint register_size, guint machine_encoding)
664 enum enum_tag_type {
665 DYNAMIC_TYPE_VALUE,
666 DYNAMIC_TYPE_POINTER,
667 DYNAMIC_TYPE_IGNORED,
668 DYNAMIC_TYPE_UNSPECIFIED
671 guint64 tag;
672 static const enum enum_tag_type tag_to_type[MAX_TAG_TO_TYPE] = {
673 DYNAMIC_TYPE_IGNORED,
674 DYNAMIC_TYPE_VALUE,
675 DYNAMIC_TYPE_VALUE,
676 DYNAMIC_TYPE_POINTER,
677 DYNAMIC_TYPE_POINTER,
678 DYNAMIC_TYPE_POINTER,
679 DYNAMIC_TYPE_POINTER,
680 DYNAMIC_TYPE_POINTER,
681 DYNAMIC_TYPE_VALUE,
682 DYNAMIC_TYPE_VALUE,
683 DYNAMIC_TYPE_VALUE,
684 DYNAMIC_TYPE_VALUE,
685 DYNAMIC_TYPE_POINTER,
686 DYNAMIC_TYPE_POINTER,
687 DYNAMIC_TYPE_VALUE,
688 DYNAMIC_TYPE_VALUE,
689 DYNAMIC_TYPE_IGNORED,
690 DYNAMIC_TYPE_POINTER,
691 DYNAMIC_TYPE_VALUE,
692 DYNAMIC_TYPE_VALUE,
693 DYNAMIC_TYPE_VALUE,
694 DYNAMIC_TYPE_POINTER,
695 DYNAMIC_TYPE_IGNORED,
696 DYNAMIC_TYPE_POINTER,
697 DYNAMIC_TYPE_IGNORED,
698 DYNAMIC_TYPE_POINTER,
699 DYNAMIC_TYPE_POINTER,
700 DYNAMIC_TYPE_VALUE,
701 DYNAMIC_TYPE_VALUE,
702 DYNAMIC_TYPE_VALUE,
703 DYNAMIC_TYPE_VALUE,
704 DYNAMIC_TYPE_UNSPECIFIED,
705 DYNAMIC_TYPE_POINTER,
706 DYNAMIC_TYPE_VALUE
709 if (register_size == REGISTER_32_SIZE) {
710 proto_tree_add_item(entry_tree, hf_elf_dynamic_tag, tvb, offset, 4, machine_encoding);
711 tag = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
712 offset += 4;
714 if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_VALUE)
715 proto_tree_add_item(entry_tree, hf_elf_dynamic_value, tvb, offset, 4, machine_encoding);
716 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_POINTER)
717 proto_tree_add_item(entry_tree, hf_elf_dynamic_pointer, tvb, offset, 4, machine_encoding);
718 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_IGNORED)
719 proto_tree_add_item(entry_tree, hf_elf_dynamic_ignored, tvb, offset, 4, machine_encoding);
720 else
721 proto_tree_add_item(entry_tree, hf_elf_dynamic_unspecified, tvb, offset, 4, machine_encoding);
722 offset += 4;
723 } else {
724 proto_item *pitem;
726 pitem = proto_tree_add_item(entry_tree, hf_elf64_dynamic_tag, tvb, offset, 8, machine_encoding);
727 tag = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
728 proto_item_append_text(pitem, " (%s)", rval_to_str(value_guard(tag), dynamic_tag_rvals, "Unknown"));
729 offset += 8;
731 if (tag < sizeof(tag_to_type) && tag_to_type[tag] == DYNAMIC_TYPE_VALUE)
732 proto_tree_add_item(entry_tree, hf_elf64_dynamic_value, tvb, offset, 8, machine_encoding);
733 else if (tag < sizeof(tag_to_type) && tag_to_type[tag] == DYNAMIC_TYPE_POINTER)
734 proto_tree_add_item(entry_tree, hf_elf64_dynamic_pointer, tvb, offset, 8, machine_encoding);
735 else if (tag < sizeof(tag_to_type) && tag_to_type[tag] == DYNAMIC_TYPE_IGNORED)
736 proto_tree_add_item(entry_tree, hf_elf64_dynamic_ignored, tvb, offset, 8, machine_encoding);
737 else
738 proto_tree_add_item(entry_tree, hf_elf64_dynamic_unspecified, tvb, offset, 8, machine_encoding);
739 offset += 8;
742 proto_item_append_text(entry_item, ": %s", rval_to_str(value_guard(tag), dynamic_tag_rvals, "Unknown"));
744 return offset;
747 static gint
748 dissect_symbol_table(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *entry_tree, proto_item *entry_item,
749 gint offset, gint register_size, guint machine_encoding, guint64 strtab_offset,
750 guint64 shoff, guint16 shnum, guint16 shentsize, guint64 shstrtab_offset)
752 proto_item *pitem;
753 proto_item *info_item;
754 proto_tree *info_tree;
755 guint16 shndx;
756 guint32 name_index;
757 const guint8 *section_name;
758 const guint8 *name;
759 guint8 info_bind;
760 guint8 info_type;
762 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_name_index, tvb, offset, 4, machine_encoding);
763 if (strtab_offset) {
764 name_index = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
765 name = tvb_get_const_stringz(tvb, value_guard(strtab_offset + name_index), NULL);
766 if (name) {
767 proto_item_append_text(pitem, ": %s", name);
768 proto_item_append_text(entry_item, ": %s", name);
771 offset += 4;
773 if (register_size == REGISTER_32_SIZE) {
774 proto_tree_add_item(entry_tree, hf_elf_symbol_table_value, tvb, offset, 4, machine_encoding);
775 offset += 4;
777 proto_tree_add_item(entry_tree, hf_elf_symbol_table_size, tvb, offset, 4, machine_encoding);
778 offset += 4;
780 info_item = proto_tree_add_item(entry_tree, hf_elf_symbol_table_info, tvb, offset, 1, machine_encoding);
781 info_tree = proto_item_add_subtree(info_item, ett_symbol_table_info);
782 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_bind, tvb, offset, 1, machine_encoding);
783 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_type, tvb, offset, 1, machine_encoding);
784 info_bind = tvb_get_guint8(tvb, offset) >> 4;
785 info_type = tvb_get_guint8(tvb, offset) & 0x0F;
786 offset += 1;
788 proto_tree_add_item(entry_tree, hf_elf_symbol_table_other, tvb, offset, 1, machine_encoding);
789 offset += 1;
791 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_shndx, tvb, offset, 2, machine_encoding);
792 shndx = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
793 if (shndx <= shnum) {
794 section_name = get_section_name_offset(tvb, shoff, shnum, shentsize, shndx, shstrtab_offset, machine_encoding);
795 if (section_name && section_name[0] != '\0')
796 proto_item_append_text(pitem, " (%u: %s)", shndx, section_name);
797 } else {
798 proto_item_append_text(pitem, " (%u)", shndx);
800 offset += 2;
801 } else {
802 info_item = proto_tree_add_item(entry_tree, hf_elf_symbol_table_info, tvb, offset, 1, machine_encoding);
803 info_tree = proto_item_add_subtree(info_item, ett_symbol_table_info);
804 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_bind, tvb, offset, 1, machine_encoding);
805 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_type, tvb, offset, 1, machine_encoding);
806 info_bind = tvb_get_guint8(tvb, offset) >> 4;
807 info_type = tvb_get_guint8(tvb, offset) & 0x0F;
808 offset += 1;
810 proto_tree_add_item(entry_tree, hf_elf_symbol_table_other, tvb, offset, 1, machine_encoding);
811 offset += 1;
813 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_shndx, tvb, offset, 2, machine_encoding);
814 shndx = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
815 if (shndx <= shnum) {
816 section_name = get_section_name_offset(tvb, shoff, shnum, shentsize, shndx, shstrtab_offset, machine_encoding);
817 if (section_name && section_name[0] != '\0')
818 proto_item_append_text(pitem, " (%u: %s)", shndx, section_name);
819 } else {
820 proto_item_append_text(pitem, " (%u)", shndx);
822 offset += 2;
824 proto_tree_add_item(entry_tree, hf_elf64_symbol_table_value, tvb, offset, 8, machine_encoding);
825 offset += 8;
827 proto_tree_add_item(entry_tree, hf_elf64_symbol_table_size, tvb, offset, 8, machine_encoding);
828 offset += 8;
831 proto_item_append_text(info_item, " (Bind: %s, Type: %s)",
832 val_to_str_const(info_bind, symbol_table_info_bind_vals, "Unknown"),
833 val_to_str_const(info_type, symbol_table_info_type_vals, "Unknown"));
835 proto_item_append_text(entry_item, " (Bind: %s, Type: %s)",
836 val_to_str_const(info_bind, symbol_table_info_bind_vals, "Unknown"),
837 val_to_str_const(info_type, symbol_table_info_type_vals, "Unknown"));
839 return offset;
842 static gint
843 dissect_eh_frame_hdr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *segment_tree,
844 gint offset, gint segment_size _U_, gint register_size, guint machine_encoding)
846 proto_item *item;
847 proto_item *table_item;
848 proto_tree *table_tree;
849 guint8 format;
850 gint efp_length;
851 gint fde_count_length;
852 gint table_entry_length;
853 guint64 fde_count;
854 guint i_entry;
856 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_version, tvb, offset, 1, machine_encoding);
857 offset += 1;
859 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_exception_frame_pointer_encoding, tvb, offset, 1, machine_encoding);
860 format = dissect_dwarf_encoding(tvb, offset, item);
861 efp_length = get_dwarf_extension_length(format, register_size);
862 offset += 1;
864 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_fde_count_encoding, tvb, offset, 1, machine_encoding);
865 format = dissect_dwarf_encoding(tvb, offset, item);
866 fde_count_length = get_dwarf_extension_length(format, register_size);
867 offset += 1;
869 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_binary_search_table_encoding, tvb, offset, 1, machine_encoding);
870 format = dissect_dwarf_encoding(tvb, offset, item);
871 table_entry_length = get_dwarf_extension_length(format, register_size);
872 offset += 1;
874 if (efp_length == LENGTH_ULEB128) {
875 guint64 value;
877 efp_length = dissect_uleb128(tvb, offset, &value);
878 } else if (efp_length == LENGTH_LEB128) {
879 gint64 value;
881 efp_length = dissect_leb128(tvb, offset, &value);
884 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_eh_frame_ptr, tvb, offset, efp_length, machine_encoding);
885 offset += efp_length;
888 if (fde_count_length == LENGTH_ULEB128) {
889 fde_count_length = dissect_uleb128(tvb, offset, &fde_count);
890 } else if (fde_count_length == LENGTH_LEB128) {
891 gint64 value;
893 fde_count_length = dissect_leb128(tvb, offset, &value);
894 fde_count = (guint64) value;
895 } else {
896 if (fde_count_length == 0) fde_count_length = register_size;
898 switch(fde_count_length) {
899 case 2:
900 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
901 break;
902 case 4:
903 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
904 break;
905 case 8:
906 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
907 break;
908 case 0:
909 default:
910 fde_count = 0;
911 break;
915 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_fde_count, tvb, offset, fde_count_length, machine_encoding);
916 offset += fde_count_length;
918 if (table_entry_length == LENGTH_ULEB128) {
919 guint64 value;
921 table_entry_length = dissect_uleb128(tvb, offset, &value);
922 } else if (table_entry_length == LENGTH_LEB128) {
923 gint64 value;
925 table_entry_length = dissect_leb128(tvb, offset, &value);
928 i_entry = 0;
930 table_item = proto_tree_add_text(segment_tree, tvb, offset, value_guard(fde_count * table_entry_length * 2), "Binary Search Table");
931 table_tree = proto_item_add_subtree(table_item, ett_binary_table);
933 while (++i_entry <= fde_count) {
934 proto_item *entry_item;
935 proto_tree *entry_tree;
937 entry_item = proto_tree_add_text(table_tree, tvb, offset, table_entry_length * 2, "Binary Table Entry #%u", i_entry);
938 entry_tree = proto_item_add_subtree(entry_item, ett_binary_table_entry);
940 proto_tree_add_item(entry_tree, hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location, tvb, offset, table_entry_length, machine_encoding);
941 offset += table_entry_length;
943 proto_tree_add_item(entry_tree, hf_elf_eh_frame_hdr_binary_search_table_entry_address, tvb, offset, table_entry_length, machine_encoding);
944 offset += table_entry_length;
947 return offset;
951 static gint
952 dissect_eh_frame(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *segment_tree,
953 gint offset, gint segment_size _U_, gint register_size _U_, guint machine_encoding)
955 proto_tree *record_tree;
956 proto_item *record_item;
957 proto_tree *entry_tree;
958 proto_item *entry_item;
959 guint64 length;
960 guint64 length_remaining;
961 guint64 unsigned_value;
962 gint64 signed_value;
963 gint size;
964 gint augmentation_string_length;
965 const guint8 *augmentation_string;
966 gboolean is_extended_length = FALSE;
967 gint start_offset = offset;
968 gint entry_number;
970 length = (machine_encoding == ENC_BIG_ENDIAN) ?
971 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
972 if (length == 0xFFFFFFFF) {
973 is_extended_length = TRUE;
974 length = (machine_encoding == ENC_BIG_ENDIAN) ?
975 tvb_get_ntoh64(tvb, offset + 4) : tvb_get_letoh64(tvb, offset + 4);
978 length_remaining = length;
980 record_item = proto_tree_add_text(segment_tree, tvb, offset, value_guard(length + (is_extended_length ? 4 + 8 : 4)), "Common Information Entry");
981 record_tree = proto_item_add_subtree(record_item, ett_elf_cie);
983 proto_tree_add_item(record_tree, hf_elf_eh_frame_length, tvb, offset, 4, machine_encoding);
984 offset += 4;
986 if (is_extended_length) {
987 proto_tree_add_item(record_tree, hf_elf_eh_frame_extended_length, tvb, offset, 8, machine_encoding);
988 offset += 8;
991 proto_tree_add_item(record_tree, hf_elf_eh_frame_cie_id, tvb, offset, 4, machine_encoding);
992 length_remaining -= 4;
993 offset += 4;
995 proto_tree_add_item(record_tree, hf_elf_eh_frame_version, tvb, offset, 1, machine_encoding);
996 length_remaining -= 1;
997 offset += 1;
999 augmentation_string = tvb_get_const_stringz(tvb, offset, &augmentation_string_length);
1000 proto_tree_add_item(record_tree, hf_elf_eh_frame_augmentation_string, tvb, offset, augmentation_string_length, machine_encoding);
1001 length_remaining -= augmentation_string_length;
1002 offset += augmentation_string_length;
1004 size = dissect_uleb128(tvb, offset, &unsigned_value);
1005 proto_tree_add_uint64(record_tree, hf_elf_eh_frame_code_alignment_factor, tvb, offset, size, unsigned_value);
1006 length_remaining -= size;
1007 offset += size;
1009 size = dissect_leb128(tvb, offset, &signed_value);
1010 proto_tree_add_int64(record_tree, hf_elf_eh_frame_data_alignment_factor, tvb, offset, size, signed_value);
1011 length_remaining -= size;
1012 offset += size;
1014 /* according to DWARF v4 this is uLEB128 */
1015 size = dissect_uleb128(tvb, offset, &unsigned_value);
1016 proto_tree_add_uint64(record_tree, hf_elf_eh_frame_return_address_register, tvb, offset, size, unsigned_value);
1017 length_remaining -= size;
1018 offset += size;
1020 if (strchr(augmentation_string, 'z')) {
1021 size = dissect_uleb128(tvb, offset, &unsigned_value);
1022 proto_tree_add_uint64(record_tree, hf_elf_eh_frame_augmentation_length, tvb, offset, size, unsigned_value);
1023 length_remaining -= size;
1024 offset += size;
1026 proto_tree_add_item(record_tree, hf_elf_eh_frame_augmentation_data, tvb, offset, value_guard(unsigned_value), machine_encoding);
1027 length_remaining -= unsigned_value;
1028 offset += value_guard(unsigned_value);
1031 proto_tree_add_item(record_tree, hf_elf_eh_frame_initial_instructions, tvb, offset, value_guard(length_remaining), machine_encoding);
1032 offset += value_guard(length_remaining);
1034 record_item = proto_tree_add_text(segment_tree, tvb, offset, value_guard(segment_size - length - 4), "Frame Description Entries");
1035 record_tree = proto_item_add_subtree(record_item, ett_elf_fde);
1037 is_extended_length = FALSE;
1038 entry_number = 1;
1040 while (segment_size - (offset - start_offset)) {
1041 length = (machine_encoding == ENC_BIG_ENDIAN) ?
1042 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1043 if (length == 0xFFFFFFFF) {
1044 is_extended_length = TRUE;
1045 length = (machine_encoding == ENC_BIG_ENDIAN) ?
1046 tvb_get_ntoh64(tvb, offset + 4) : tvb_get_letoh64(tvb, offset + 4);
1049 entry_item = proto_tree_add_text(record_tree, tvb, offset, value_guard(length + (is_extended_length ? 4 + 8 : 4)), "Entry %i", entry_number);
1050 entry_tree = proto_item_add_subtree(entry_item, ett_elf_entry);
1052 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_length, tvb, offset, 4, machine_encoding);
1053 offset += 4;
1055 if (is_extended_length) {
1056 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_extended_length, tvb, offset, 8, machine_encoding);
1057 offset += 8;
1060 if (length == 0) break;
1062 length_remaining = length;
1064 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_cie_pointer, tvb, offset, 4, machine_encoding);
1065 length_remaining -= 4;
1066 offset += 4;
1068 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_pc_begin, tvb, offset, 4, machine_encoding);
1069 length_remaining -= 4;
1070 offset += 4;
1072 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_pc_range, tvb, offset, 4, machine_encoding);
1073 length_remaining -= 4;
1074 offset += 4;
1076 if (strchr(augmentation_string, 'z')) {
1077 size = dissect_uleb128(tvb, offset, &unsigned_value);
1078 proto_tree_add_uint64(entry_tree, hf_elf_eh_frame_fde_augmentation_length, tvb, offset, size, unsigned_value);
1079 length_remaining -= size;
1080 offset += size;
1082 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_augmentation_data, tvb, offset, value_guard(unsigned_value), machine_encoding);
1083 length_remaining -= unsigned_value;
1084 offset += value_guard(unsigned_value);
1087 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_call_frame_instructions, tvb, offset, value_guard(length_remaining), machine_encoding);
1088 offset += value_guard(length_remaining);
1090 entry_number += 1;
1093 return offset;
1096 static int
1097 dissect_elf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1099 static const guint8 magic[] = { 0x7F, 'E', 'L', 'F'};
1100 gint offset = 0;
1101 proto_tree *main_tree;
1102 proto_item *main_item;
1103 proto_tree *header_tree;
1104 proto_item *header_item;
1105 proto_item *program_header_item;
1106 proto_tree *program_header_tree;
1107 proto_item *section_header_item;
1108 proto_tree *section_header_tree;
1109 proto_item *ph_entry_item;
1110 proto_tree *ph_entry_tree;
1111 proto_item *sh_entry_item;
1112 proto_tree *sh_entry_tree;
1113 proto_item *segment_item;
1114 proto_tree *segment_tree;
1115 proto_item *generated_item;
1116 proto_tree *generated_tree;
1117 proto_item *overlapping_item;
1118 proto_tree *overlapping_tree;
1119 proto_item *blackhole_item;
1120 proto_tree *blackhole_tree;
1121 proto_item *entry_item;
1122 proto_tree *entry_tree;
1123 guint machine_encoding = ENC_NA;
1124 gint register_size = 4;
1125 guint16 phentsize;
1126 guint16 phnum;
1127 guint16 shentsize;
1128 guint16 shnum;
1129 guint64 phoff;
1130 guint64 shoff;
1131 guint16 i_16;
1132 guint32 p_type;
1133 guint32 sh_type;
1134 guint16 shstrndx;
1135 guint64 shstrtab_offset;
1136 guint32 sh_name;
1137 const guint8 *section_name;
1138 guint64 length;
1139 guint64 segment_offset;
1140 guint64 segment_size;
1141 guint64 file_size;
1142 guint64 p_offset;
1143 gint ehsize;
1144 guint area_counter = 0;
1145 segment_info_t *segment_info;
1146 guint i;
1147 guint i_next;
1148 gint next_offset;
1149 gint len;
1150 guint64 sh_entsize;
1151 guint64 strtab_offset = 0;
1152 guint64 dynstr_offset = 0;
1154 if (tvb_length(tvb) < 52)
1155 return 0;
1157 if (tvb_memeql(tvb, 0, magic, sizeof(magic)) != 0)
1158 return 0;
1160 main_item = proto_tree_add_item(tree, proto_elf, tvb, offset, -1, ENC_NA);
1161 main_tree = proto_item_add_subtree(main_item, ett_elf);
1163 header_item = proto_tree_add_text(main_tree, tvb, offset, 1, "Header");
1164 header_tree = proto_item_add_subtree(header_item, ett_elf_header);
1166 /* e_ident */
1167 proto_tree_add_item(header_tree, hf_elf_magic_bytes, tvb, offset, sizeof(magic), ENC_NA);
1168 offset += sizeof(magic);
1170 proto_tree_add_item(header_tree, hf_elf_file_class, tvb, offset, 1, ENC_NA);
1171 register_size *= tvb_get_guint8(tvb, offset);
1172 offset += 1;
1174 proto_tree_add_item(header_tree, hf_elf_data_encoding, tvb, offset, 1, ENC_NA);
1175 if (tvb_get_guint8(tvb, offset) == 1)
1176 machine_encoding = ENC_LITTLE_ENDIAN;
1177 else
1178 machine_encoding = ENC_BIG_ENDIAN;
1179 offset += 1;
1181 proto_tree_add_item(header_tree, hf_elf_file_version, tvb, offset, 1, ENC_NA);
1182 offset += 1;
1184 /* From Draft */
1185 proto_tree_add_item(header_tree, hf_elf_os_abi, tvb, offset, 1, ENC_NA);
1186 offset += 1;
1188 proto_tree_add_item(header_tree, hf_elf_abi_version, tvb, offset, 1, ENC_NA);
1189 offset += 1;
1191 proto_tree_add_item(header_tree, hf_elf_file_padding, tvb, offset, 7, ENC_NA);
1192 offset += 7;
1194 /* other */
1196 proto_tree_add_item(header_tree, hf_elf_type, tvb, offset, 2, machine_encoding);
1197 offset += 2;
1199 proto_tree_add_item(header_tree, hf_elf_machine, tvb, offset, 2, machine_encoding);
1200 offset += 2;
1202 proto_tree_add_item(header_tree, hf_elf_version, tvb, offset, 4, machine_encoding);
1203 offset += 4;
1205 proto_tree_add_item(header_tree,
1206 (register_size == REGISTER_32_SIZE) ? hf_elf_entry : hf_elf64_entry,
1207 tvb, offset, register_size, machine_encoding);
1208 offset += register_size;
1210 if (register_size == REGISTER_32_SIZE) {
1211 proto_tree_add_item(header_tree, hf_elf_phoff, tvb, offset,
1212 register_size, machine_encoding);
1213 phoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1214 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1215 } else {
1216 proto_tree_add_item(header_tree, hf_elf64_phoff, tvb, offset,
1217 register_size, machine_encoding);
1218 phoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1219 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1221 offset += register_size;
1224 if (register_size == REGISTER_32_SIZE) {
1225 proto_tree_add_item(header_tree, hf_elf_shoff, tvb, offset,
1226 register_size, machine_encoding);
1227 shoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1228 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1229 } else {
1230 proto_tree_add_item(header_tree, hf_elf64_shoff, tvb, offset,
1231 register_size, machine_encoding);
1232 shoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1233 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1235 offset += register_size;
1237 proto_tree_add_item(header_tree, hf_elf_flags, tvb, offset, 4, machine_encoding);
1238 offset += 4;
1240 proto_tree_add_item(header_tree, hf_elf_ehsize, tvb, offset, 2, machine_encoding);
1241 ehsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1242 proto_item_set_len(header_item, ehsize);
1243 offset += 2;
1245 proto_tree_add_item(header_tree, hf_elf_phentsize, tvb, offset, 2, machine_encoding);
1246 phentsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1247 offset += 2;
1249 proto_tree_add_item(header_tree, hf_elf_phnum, tvb, offset, 2, machine_encoding);
1250 phnum = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1251 offset += 2;
1253 proto_tree_add_item(header_tree, hf_elf_shentsize, tvb, offset, 2, machine_encoding);
1254 shentsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1255 offset += 2;
1257 proto_tree_add_item(header_tree, hf_elf_shnum, tvb, offset, 2, machine_encoding);
1258 shnum = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1259 offset += 2;
1261 proto_tree_add_item(header_tree, hf_elf_shstrndx, tvb, offset, 2, machine_encoding);
1262 shstrndx = (machine_encoding == ENC_BIG_ENDIAN) ?
1263 tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1264 /*offset += 2;*/
1266 program_header_item = proto_tree_add_text(main_tree, tvb, value_guard(phoff),
1267 phnum * phentsize, "Program Header Table [%d entries]", phnum);
1268 program_header_tree = proto_item_add_subtree(program_header_item, ett_elf_program_header);
1270 section_header_item = proto_tree_add_text(main_tree, tvb, value_guard(shoff),
1271 shnum * shentsize, "Section Header Table [%d entries]", shnum);
1272 section_header_tree = proto_item_add_subtree(section_header_item, ett_elf_section_header);
1274 file_size = ehsize + phnum * phentsize + shnum * shentsize;
1276 /* Collect infos for blackholes */
1277 segment_info = (segment_info_t *) wmem_alloc(wmem_packet_scope(), sizeof(segment_info_t) * (shnum + phnum + 3));
1279 segment_info[area_counter].offset = 0;
1280 segment_info[area_counter].size = ehsize;
1281 segment_info[area_counter].name = "Header";
1282 area_counter += 1;
1284 if (phoff) {
1285 segment_info[area_counter].offset = phoff;
1286 segment_info[area_counter].size = phnum * phentsize;
1287 segment_info[area_counter].name = "ProgramHeader";
1288 area_counter += 1;
1291 if (shoff) {
1292 segment_info[area_counter].offset = shoff;
1293 segment_info[area_counter].size = shnum * shentsize;
1294 segment_info[area_counter].name = "SectionHeader";
1295 area_counter += 1;
1298 offset = value_guard(phoff);
1300 i_16 = phnum;
1301 while (i_16-- > 0) {
1302 p_type = (machine_encoding == ENC_BIG_ENDIAN) ?
1303 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1304 if (p_type >= 0x60000000 && p_type <= 0x6FFFFFFF) {
1305 ph_entry_item = proto_tree_add_text(program_header_tree, tvb, offset,
1306 phentsize, "Entry #%d: Operating System Specific (0x%08x)", phnum - i_16 - 1, p_type);
1307 ph_entry_tree = proto_item_add_subtree(ph_entry_item, ett_elf_program_header);
1308 proto_tree_add_item(ph_entry_tree, hf_elf_p_type_operating_system_specific, tvb, offset, 4, machine_encoding);
1309 } else if (p_type >= 0x70000000 && p_type <= 0x7FFFFFFF) {
1310 ph_entry_item = proto_tree_add_text(program_header_tree, tvb, offset,
1311 phentsize, "Entry #%d: Processor Specific (0x%08x)", phnum - i_16 - 1, p_type);
1312 ph_entry_tree = proto_item_add_subtree(ph_entry_item, ett_elf_program_header);
1313 proto_tree_add_item(ph_entry_tree, hf_elf_p_type_processor_specific, tvb, offset, 4, machine_encoding);
1314 } else {
1315 ph_entry_item = proto_tree_add_text(program_header_tree, tvb, offset,
1316 phentsize, "Entry #%d: %s", phnum - i_16 - 1,
1317 val_to_str_const(p_type, p_type_vals, "Unknown"));
1318 ph_entry_tree = proto_item_add_subtree(ph_entry_item, ett_elf_program_header);
1319 proto_tree_add_item(ph_entry_tree, hf_elf_p_type, tvb, offset, 4, machine_encoding);
1321 offset += 4;
1323 if (register_size == REGISTER_64_SIZE) {
1324 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_processor_specific, tvb, offset, 4, machine_encoding);
1325 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1326 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_reserved, tvb, offset, 4, machine_encoding);
1327 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_read, tvb, offset, 4, machine_encoding);
1328 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_write, tvb, offset, 4, machine_encoding);
1329 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_execute, tvb, offset, 4, machine_encoding);
1330 offset += 4;
1333 proto_tree_add_item(ph_entry_tree,
1334 (register_size == REGISTER_32_SIZE) ? hf_elf_p_offset : hf_elf64_p_offset,
1335 tvb, offset, register_size, machine_encoding);
1336 if (register_size == REGISTER_32_SIZE) {
1337 p_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1338 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1339 } else {
1340 p_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1341 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1344 offset += register_size;
1346 proto_tree_add_item(ph_entry_tree,
1347 (register_size == REGISTER_32_SIZE) ? hf_elf_p_vaddr : hf_elf64_p_vaddr,
1348 tvb, offset, register_size, machine_encoding);
1349 offset += register_size;
1351 proto_tree_add_item(ph_entry_tree,
1352 (register_size == REGISTER_32_SIZE) ? hf_elf_p_paddr : hf_elf64_p_paddr,
1353 tvb, offset, register_size, machine_encoding);
1354 offset += register_size;
1356 proto_tree_add_item(ph_entry_tree,
1357 (register_size == REGISTER_32_SIZE) ? hf_elf_p_filesz : hf_elf64_p_filesz,
1358 tvb, offset, register_size, machine_encoding);
1359 if (register_size == REGISTER_32_SIZE) {
1360 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1361 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1362 } else {
1363 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1364 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1366 offset += register_size;
1368 proto_tree_add_item(ph_entry_tree,
1369 (register_size == REGISTER_32_SIZE) ? hf_elf_p_memsz : hf_elf64_p_memsz,
1370 tvb, offset, register_size, machine_encoding);
1371 offset += register_size;
1373 if (register_size == REGISTER_32_SIZE) {
1374 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_processor_specific, tvb, offset, 4, machine_encoding);
1375 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1376 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_reserved, tvb, offset, 4, machine_encoding);
1377 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_read, tvb, offset, 4, machine_encoding);
1378 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_write, tvb, offset, 4, machine_encoding);
1379 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_execute, tvb, offset, 4, machine_encoding);
1380 offset += 4;
1383 proto_tree_add_item(ph_entry_tree,
1384 (register_size == REGISTER_32_SIZE) ? hf_elf_p_align : hf_elf64_p_align,
1385 tvb, offset, register_size, machine_encoding);
1386 offset += register_size;
1388 if (segment_size) {
1389 gchar *name;
1391 name = wmem_strdup_printf(wmem_packet_scope(), "ProgramHeaderEntry #%u", phnum - i_16 - 1);
1393 proto_tree_add_text(ph_entry_tree, tvb, value_guard(p_offset), value_guard(segment_size), "Segment");
1395 file_size += segment_size;
1397 segment_info[area_counter].offset = p_offset;
1398 segment_info[area_counter].size = segment_size;
1399 segment_info[area_counter].name = name;
1401 area_counter += 1;
1405 /* Find and save some information for later */
1406 offset = value_guard(shoff);
1408 i_16 = shnum;
1409 while (i_16-- > 0) {
1410 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ?
1411 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1413 offset += 4;
1415 offset += 4;
1417 length = shoff + shstrndx * shentsize + 2 * 4 + 2 * register_size;
1418 if (register_size == REGISTER_32_SIZE) {
1419 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1420 tvb_get_ntohl(tvb, value_guard(length)) : tvb_get_letohl(tvb, value_guard(length));
1421 } else {
1422 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1423 tvb_get_ntoh64(tvb, value_guard(length)) : tvb_get_letoh64(tvb, value_guard(length));
1426 section_name = tvb_get_const_stringz(tvb, value_guard(shstrtab_offset + sh_name), NULL);
1428 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_BIG_ENDIAN) {
1429 offset += 4;
1432 offset += 4;
1434 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_LITTLE_ENDIAN) {
1435 offset += 4;
1438 offset += register_size;
1440 if (register_size == REGISTER_32_SIZE) {
1441 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1442 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1443 } else {
1444 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1445 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1448 if (g_strcmp0(section_name, ".strtab") == 0) {
1449 strtab_offset = segment_offset;
1450 } else if (g_strcmp0(section_name, ".dynstr") == 0) {
1451 dynstr_offset = segment_offset;
1453 offset += register_size;
1454 offset += register_size;
1455 offset += 4;
1456 offset += 4;
1457 offset += register_size;
1458 offset += register_size;
1461 /* Sections */
1462 offset = value_guard(shoff);
1464 i_16 = shnum;
1465 while (i_16-- > 0) {
1466 sh_entry_item = proto_tree_add_text(section_header_tree, tvb, offset,
1467 shentsize, "Entry #%d: ", shnum - i_16 - 1);
1468 sh_entry_tree = proto_item_add_subtree(sh_entry_item, ett_elf_section_header);
1470 proto_tree_add_item(sh_entry_tree, hf_elf_sh_name, tvb, offset, 4, machine_encoding);
1471 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ?
1472 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1473 offset += 4;
1475 sh_type = (machine_encoding == ENC_BIG_ENDIAN) ?
1476 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1477 if (sh_type >= 0x60000000 && sh_type <= 0x6FFFFFFF) {
1478 proto_item_append_text(sh_entry_item, "Operating System Specific (0x%08x)", sh_type);
1479 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_operating_system_specific, tvb, offset, 4, machine_encoding);
1480 } else if (sh_type >= 0x70000000 && sh_type <= 0x7FFFFFFF) {
1481 proto_item_append_text(sh_entry_item, "Processor Specific (0x%08x)", sh_type);
1482 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_processor_specific, tvb, offset, 4, machine_encoding);
1483 } else if (sh_type >= 0x80000000 && sh_type <= 0xFFFFFFFF) {
1484 proto_item_append_text(sh_entry_item, "User Specific (0x%08x)", sh_type);
1485 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_user_specific, tvb, offset, 4, machine_encoding);
1486 }else {
1487 proto_item_append_text(sh_entry_item, "%s", val_to_str_const(sh_type, sh_type_vals, "Unknown"));
1488 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type, tvb, offset, 4, machine_encoding);
1490 offset += 4;
1492 length = shoff + shstrndx * shentsize + 2 * 4 + 2 * register_size;
1493 if (register_size == REGISTER_32_SIZE) {
1494 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1495 tvb_get_ntohl(tvb, value_guard(length)) : tvb_get_letohl(tvb, value_guard(length));
1496 } else {
1497 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1498 tvb_get_ntoh64(tvb, value_guard(length)) : tvb_get_letoh64(tvb, value_guard(length));
1501 section_name = tvb_get_const_stringz(tvb, value_guard(shstrtab_offset + sh_name), NULL);
1502 if (section_name)
1503 proto_item_append_text(sh_entry_item, ": %s", section_name);
1505 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_BIG_ENDIAN) {
1506 offset += 4;
1509 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_processor_specific, tvb, offset, 4, machine_encoding);
1510 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1511 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_reserved, tvb, offset, 4, machine_encoding);
1512 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_tls, tvb, offset, 4, machine_encoding);
1513 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_group, tvb, offset, 4, machine_encoding);
1514 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_os_nonconforming, tvb, offset, 4, machine_encoding);
1515 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_link_order, tvb, offset, 4, machine_encoding);
1516 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_info_link, tvb, offset, 4, machine_encoding);
1517 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_strings, tvb, offset, 4, machine_encoding);
1518 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_merge, tvb, offset, 4, machine_encoding);
1519 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_reserved_8, tvb, offset, 4, machine_encoding);
1520 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_exec_instr, tvb, offset, 4, machine_encoding);
1521 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_alloc, tvb, offset, 4, machine_encoding);
1522 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_write, tvb, offset, 4, machine_encoding);
1523 offset += 4;
1525 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_LITTLE_ENDIAN) {
1526 offset += 4;
1529 proto_tree_add_item(sh_entry_tree,
1530 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_addr : hf_elf64_sh_addr,
1531 tvb, offset, register_size, machine_encoding);
1532 offset += register_size;
1534 proto_tree_add_item(sh_entry_tree,
1535 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_offset : hf_elf64_sh_offset,
1536 tvb, offset, register_size, machine_encoding);
1537 if (register_size == REGISTER_32_SIZE) {
1538 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1539 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1540 } else {
1541 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1542 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1544 offset += register_size;
1546 proto_tree_add_item(sh_entry_tree,
1547 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_size : hf_elf64_sh_size,
1548 tvb, offset, register_size, machine_encoding);
1549 if (register_size == REGISTER_32_SIZE) {
1550 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1551 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1552 } else {
1553 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1554 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1556 offset += register_size;
1558 proto_tree_add_item(sh_entry_tree, hf_elf_sh_link, tvb, offset, 4, machine_encoding);
1559 offset += 4;
1561 proto_tree_add_item(sh_entry_tree, hf_elf_sh_info, tvb, offset, 4, machine_encoding);
1562 offset += 4;
1564 proto_tree_add_item(sh_entry_tree,
1565 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_addralign : hf_elf64_sh_addralign,
1566 tvb, offset, register_size, machine_encoding);
1567 offset += register_size;
1569 proto_tree_add_item(sh_entry_tree,
1570 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_entsize : hf_elf64_sh_entsize,
1571 tvb, offset, register_size, machine_encoding);
1572 if (register_size == REGISTER_32_SIZE) {
1573 sh_entsize = (machine_encoding == ENC_BIG_ENDIAN) ?
1574 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1575 } else {
1576 sh_entsize = (machine_encoding == ENC_BIG_ENDIAN) ?
1577 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1579 offset += register_size;
1581 if (segment_size > 0 && sh_type != 8) {
1582 file_size += segment_size;
1584 segment_info[area_counter].offset = segment_offset;
1585 segment_info[area_counter].size = segment_size;
1586 segment_info[area_counter].name = section_name;
1587 area_counter += 1;
1589 segment_item = proto_tree_add_text(sh_entry_tree, tvb,
1590 value_guard(segment_offset), value_guard(segment_size), "Segment");
1591 segment_tree = proto_item_add_subtree(segment_item, ett_elf_segment);
1593 if (g_strcmp0(section_name, ".eh_frame") == 0) {
1594 next_offset = dissect_eh_frame(tvb, pinfo, segment_tree,
1595 value_guard(segment_offset), value_guard(segment_size), register_size,
1596 machine_encoding);
1597 if (next_offset != (gint) (segment_offset + segment_size))
1598 expert_add_info(pinfo, segment_item, &ei_invalid_segment_size);
1599 } else if (g_strcmp0(section_name, ".eh_frame_hdr") == 0) {
1600 next_offset = dissect_eh_frame_hdr(tvb, pinfo, segment_tree,
1601 value_guard(segment_offset), value_guard(segment_size), register_size,
1602 machine_encoding);
1603 if (next_offset != (gint) (segment_offset + segment_size))
1604 expert_add_info(pinfo, segment_item, &ei_invalid_segment_size);
1605 } else if (sh_type == 0x06) { /* SHT_DYNAMIC */
1606 if (sh_entsize > 0) {
1607 next_offset = value_guard(segment_offset);
1608 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1609 entry_item = proto_tree_add_text(segment_tree, tvb, next_offset,
1610 value_guard(sh_entsize), "Entry #%d", i);
1611 entry_tree = proto_item_add_subtree(entry_item, ett_symbol_table_entry);
1613 next_offset = dissect_dynamic(tvb, pinfo, entry_tree, entry_item,
1614 next_offset, register_size, machine_encoding);
1615 if (next_offset != (gint) (segment_offset + i * sh_entsize))
1616 expert_add_info(pinfo, segment_item, &ei_invalid_entry_size);
1619 } else if (sh_type == 0x02 || sh_type == 0x0b) { /* SHT_SYMTAB || SHT_DYNSYM */
1620 if (sh_entsize > 0) {
1621 next_offset = value_guard(segment_offset);
1622 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1623 entry_item = proto_tree_add_text(segment_tree, tvb, next_offset,
1624 value_guard(sh_entsize), "Entry #%d", i);
1625 entry_tree = proto_item_add_subtree(entry_item, ett_symbol_table_entry);
1627 next_offset = dissect_symbol_table(tvb, pinfo, entry_tree, entry_item,
1628 next_offset, register_size, machine_encoding, (sh_type == 0x02) ? strtab_offset : dynstr_offset,
1629 shoff, shnum, shentsize, shstrtab_offset);
1630 if (next_offset != (gint) (segment_offset + i * sh_entsize))
1631 expert_add_info(pinfo, segment_item, &ei_invalid_entry_size);
1634 } else if (sh_type == 0x03) { /* SHT_STRTAB */
1635 next_offset = value_guard(segment_offset);
1636 i = 1;
1637 while (next_offset < (gint) (segment_offset + segment_size)) {
1638 tvb_get_const_stringz(tvb, next_offset, &len);
1639 entry_item = proto_tree_add_item(segment_tree, hf_elf_string, tvb, next_offset, len, ENC_ASCII | ENC_NA);
1640 proto_item_append_text(entry_item, " (Number: %u, Index: %u, Length: %u)", (guint) i, (guint) (next_offset - segment_offset), len - 1);
1641 next_offset += len;
1642 i += 1;
1644 } else {
1645 if (sh_entsize > 0) {
1646 next_offset = value_guard(segment_offset);
1647 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1648 proto_tree_add_text(segment_tree, tvb, next_offset,
1649 value_guard(sh_entsize), "Entry #%d ", i);
1650 next_offset += value_guard(sh_entsize);
1657 /* Try to detect blackholes and overlapping segments */
1658 generated_item = proto_tree_add_text(main_tree, tvb, 0, 0, "Infos");
1659 PROTO_ITEM_SET_GENERATED(generated_item);
1660 generated_tree = proto_item_add_subtree(generated_item, ett_elf_info);
1662 blackhole_item = proto_tree_add_text(generated_tree, tvb, 0, 0, "Backholes");
1663 blackhole_tree = proto_item_add_subtree(blackhole_item, ett_elf_black_holes);
1665 overlapping_item = proto_tree_add_text(generated_tree, tvb, 0, 0, "Overlapping");
1666 overlapping_tree = proto_item_add_subtree(overlapping_item, ett_elf_overlapping);
1668 /* sorting... */
1669 for (i = 0; i < area_counter; i += 1) {
1670 segment_info_t tmp_segment;
1671 segment_info_t *min_offset_segment;
1673 min_offset_segment = &segment_info[i];
1675 for (i_next = i + 1; i_next < area_counter; i_next += 1) {
1676 if (min_offset_segment->offset <= segment_info[i_next].offset) continue;
1678 tmp_segment = *min_offset_segment;
1679 *min_offset_segment = segment_info[i_next];
1680 segment_info[i_next] = tmp_segment;
1684 for (i = 1; i < area_counter; i += 1) {
1685 if (segment_info[i - 1].offset + segment_info[i - 1].size < segment_info[i].offset) {
1686 /* blackhole */
1687 len = (guint) (segment_info[i].offset - segment_info[i - 1].offset - segment_info[i - 1].size);
1689 proto_tree_add_text(blackhole_tree, tvb, value_guard(segment_info[i].offset - len), len, "Blackhole between: %s and %s, size: %u",
1690 segment_info[i - 1].name, segment_info[i].name, len);
1691 } else if (segment_info[i - 1].offset + segment_info[i - 1].size > segment_info[i].offset) {
1692 /* overlapping */
1693 len = (guint) (segment_info[i - 1].offset + segment_info[i - 1].size - segment_info[i].offset);
1695 proto_tree_add_text(overlapping_tree, tvb, value_guard(segment_info[i - 1].offset + segment_info[i - 1].size - len), len, "Overlapping between: %s and %s, size: %u",
1696 segment_info[i - 1].name, segment_info[i].name, len);
1698 file_size -= len;
1702 if (segment_info[area_counter - 1].offset + segment_info[area_counter - 1].size < tvb_length(tvb)) {
1703 len = tvb_length(tvb) - (guint) (segment_info[area_counter - 1].offset - segment_info[area_counter - 1].size);
1705 proto_tree_add_text(blackhole_tree, tvb,
1706 value_guard(segment_info[area_counter - 1].offset +
1707 segment_info[area_counter - 1].size),
1708 len, "Blackhole between: %s and <EOF>, size: %u",
1709 segment_info[area_counter - 1].name, len);
1712 proto_tree_add_text(generated_tree, tvb, 0, 0, "File size: %i", tvb_length(tvb));
1713 proto_tree_add_text(generated_tree, tvb, 0, 0, "Header size + all segment size: %i", (int) file_size);
1714 proto_tree_add_text(generated_tree, tvb, 0, 0, "Total blackholes size: %i", tvb_length(tvb) - (int) file_size);
1716 col_clear(pinfo->cinfo, COL_INFO);
1717 col_add_str(pinfo->cinfo, COL_INFO, "(ELF)");
1719 /* We jumping around offsets, so treat as bytes as read */
1720 offset = tvb_length(tvb);
1722 return offset;
1725 static gboolean
1726 dissect_elf_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1728 return dissect_elf(tvb, pinfo, tree, NULL) > 0;
1731 void
1732 proto_register_elf(void)
1734 module_t *module;
1735 expert_module_t *expert_module;
1737 static hf_register_info hf[] = {
1738 /* Header */
1739 { &hf_elf_magic_bytes,
1740 { "Magic Bytes", "elf.magic_bytes",
1741 FT_BYTES, BASE_NONE, NULL, 0x00,
1742 NULL, HFILL }
1744 { &hf_elf_file_class,
1745 { "File Class", "elf.file_class",
1746 FT_UINT8, BASE_HEX, VALS(class_vals), 0x00,
1747 NULL, HFILL }
1749 { &hf_elf_data_encoding,
1750 { "Data Encoding", "elf.data_encoding",
1751 FT_UINT8, BASE_HEX, VALS(data_encoding_vals), 0x00,
1752 NULL, HFILL }
1754 { &hf_elf_file_version,
1755 { "File Version", "elf.file_version",
1756 FT_UINT8, BASE_HEX, VALS(version_vals), 0x00,
1757 NULL, HFILL }
1759 { &hf_elf_os_abi,
1760 { "OS ABI", "elf.os_abi",
1761 FT_UINT8, BASE_HEX, VALS(os_abi_vals), 0x00,
1762 NULL, HFILL }
1764 { &hf_elf_abi_version,
1765 { "ABI Version", "elf.abi_version",
1766 FT_UINT8, BASE_HEX_DEC, NULL, 0x00,
1767 NULL, HFILL }
1769 { &hf_elf_file_padding,
1770 { "File Padding", "elf.file_padding",
1771 FT_BYTES, BASE_NONE, NULL, 0x00,
1772 NULL, HFILL }
1774 { &hf_elf_type,
1775 { "Type", "elf.type",
1776 FT_UINT16, BASE_HEX, VALS(type_vals), 0x00,
1777 NULL, HFILL }
1779 { &hf_elf_machine,
1780 { "Machine", "elf.machine",
1781 FT_UINT16, BASE_HEX, VALS(machine_vals), 0x00,
1782 NULL, HFILL }
1784 { &hf_elf_version,
1785 { "Version", "elf.version",
1786 FT_UINT32, BASE_HEX, VALS(version_vals), 0x00,
1787 NULL, HFILL }
1789 { &hf_elf_entry,
1790 { "Entry", "elf.entry",
1791 FT_UINT32, BASE_HEX, NULL, 0x00,
1792 "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 }
1794 { &hf_elf64_entry,
1795 { "Entry", "elf.entry",
1796 FT_UINT64, BASE_HEX, NULL, 0x00,
1797 "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 }
1799 { &hf_elf_phoff,
1800 { "Program Header Table File Offset", "elf.phoff",
1801 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1802 "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 }
1804 { &hf_elf64_phoff,
1805 { "Program Header Table File Offset", "elf.phoff",
1806 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1807 "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 }
1809 { &hf_elf_shoff,
1810 { "Section Header Table File Offset", "elf.shoff",
1811 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1812 "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 }
1814 { &hf_elf64_shoff,
1815 { "Section Header Table File Offset", "elf.shoff",
1816 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1817 "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 }
1819 { &hf_elf_flags, /* TODO: dissect flags */
1820 { "Flags", "elf.flags",
1821 FT_UINT32, BASE_HEX, NULL, 0x00,
1822 "This member holds processor-specific flags associated with the file. Flag names take the form EF_machine_flag.", HFILL }
1824 { &hf_elf_ehsize,
1825 { "ELF Header Size", "elf.ehsize",
1826 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1827 "This member holds the ELF header's size in bytes.", HFILL }
1829 { &hf_elf_phentsize,
1830 { "Entry Size in Program Header Table", "elf.phentsize",
1831 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1832 "This member holds the size in bytes of one entry in the file's program header table; all entries are the same size.", HFILL }
1834 { &hf_elf_phnum,
1835 { "Number of Entries in the Program Header Table", "elf.phnum",
1836 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1837 "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 }
1839 { &hf_elf_shentsize,
1840 { "Entry Size in Section Header Table", "elf.shentsize",
1841 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1842 "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 }
1844 { &hf_elf_shnum,
1845 { "Number of Entries in the Section Header Table", "elf.shnum",
1846 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1847 "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 }
1849 { &hf_elf_shstrndx,
1850 { "Section Header Table String Index", "elf.shstrndx",
1851 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1852 "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 }
1854 /* Program Header */
1855 { &hf_elf_p_type,
1856 { "Element Type", "elf.p_type",
1857 FT_UINT32, BASE_HEX_DEC, VALS(p_type_vals), 0x00,
1858 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1860 { &hf_elf_p_type_operating_system_specific,
1861 { "Element Type: Operating System Specific", "elf.p_type",
1862 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1863 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1865 { &hf_elf_p_type_processor_specific,
1866 { "Element Type: Processor Specific", "elf.p_type",
1867 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1868 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1870 { &hf_elf_p_offset,
1871 { "File Offset", "elf.p_offset",
1872 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1873 "This member gives the offset from the beginning of the file at which the first byte of the segment resides.", HFILL }
1875 { &hf_elf64_p_offset,
1876 { "File Offset", "elf.p_offset",
1877 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1878 "This member gives the offset from the beginning of the file at which the first byte of the segment resides.", HFILL }
1880 { &hf_elf_p_vaddr,
1881 { "Virtual Address", "elf.p_vaddr",
1882 FT_UINT32, BASE_HEX, NULL, 0x00,
1883 "This member gives the virtual address at which the first byte of the segment resides in memory.", HFILL }
1885 { &hf_elf64_p_vaddr,
1886 { "Virtual Address", "elf.p_vaddr",
1887 FT_UINT64, BASE_HEX, NULL, 0x00,
1888 "This member gives the virtual address at which the first byte of the segment resides in memory.", HFILL }
1890 { &hf_elf_p_paddr,
1891 { "Physical Address", "elf.p_paddr",
1892 FT_UINT32, BASE_HEX, NULL, 0x00,
1893 "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 }
1895 { &hf_elf64_p_paddr,
1896 { "Physical Address", "elf.p_paddr",
1897 FT_UINT64, BASE_HEX, NULL, 0x00,
1898 "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 }
1900 { &hf_elf_p_filesz,
1901 { "File Image Size", "elf.p_filesz",
1902 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1903 "This member gives the number of bytes in the file image of the segment; it may be zero.", HFILL }
1905 { &hf_elf64_p_filesz,
1906 { "File Image Size", "elf.p_filesz",
1907 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1908 "This member gives the number of bytes in the file image of the segment; it may be zero.", HFILL }
1910 { &hf_elf_p_memsz,
1911 { "Memory Image Size", "elf.p_memsz",
1912 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1913 "This member gives the number of bytes in the memory image of the segment; it may be zero.", HFILL }
1915 { &hf_elf64_p_memsz,
1916 { "Memory Image Size", "elf.p_memsz",
1917 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1918 "This member gives the number of bytes in the memory image of the segment; it may be zero.", HFILL }
1920 { &hf_elf_p_flags_processor_specific,
1921 { "Processor Specific Flags", "elf.p_flags.maskproc",
1922 FT_BOOLEAN, 32, NULL, 0xF0000000,
1923 NULL, HFILL }
1925 { &hf_elf_p_flags_operating_system_specific,
1926 { "Operating System Specific Flags", "elf.p_flags.maskos",
1927 FT_BOOLEAN, 32, NULL, 0x0FF00000,
1928 NULL, HFILL }
1930 { &hf_elf_p_flags_reserved,
1931 { "Reserrved Flags", "elf.p_flags.reserved",
1932 FT_BOOLEAN, 32, NULL, 0x000FFFF8,
1933 NULL, HFILL }
1935 { &hf_elf_p_flags_read,
1936 { "Read Flag", "elf.p_flags.read",
1937 FT_BOOLEAN, 32, NULL, 0x00000004,
1938 NULL, HFILL }
1940 { &hf_elf_p_flags_write,
1941 { "Write Flag", "elf.p_flags.write",
1942 FT_BOOLEAN, 32, NULL, 0x00000002,
1943 NULL, HFILL }
1945 { &hf_elf_p_flags_execute,
1946 { "Execute Flag", "elf.p_flags.execute",
1947 FT_BOOLEAN, 32, NULL, 0x00000001,
1948 NULL, HFILL }
1950 { &hf_elf_p_align,
1951 { "Align", "elf.p_align",
1952 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1953 "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 }
1955 { &hf_elf64_p_align,
1956 { "Align", "elf.p_align",
1957 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1958 "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 }
1960 /* Section Header */
1961 { &hf_elf_sh_name,
1962 { "Name Index", "elf.sh_name",
1963 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1964 "Section Name. Its value is an index into the section header string table section, giving the location of a null-terminated string.", HFILL }
1966 { &hf_elf_sh_type,
1967 { "Type", "elf.sh_type",
1968 FT_UINT32, BASE_HEX_DEC, VALS(sh_type_vals), 0x00,
1969 "This member categorizes the section's contents and semantics.", HFILL }
1971 { &hf_elf_sh_type_operating_system_specific,
1972 { "Type: Operating System Specific", "elf.sh_type",
1973 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1974 "This member categorizes the section's contents and semantics.", HFILL }
1976 { &hf_elf_sh_type_processor_specific,
1977 { "Type: Procesor Specific", "elf.sh_type",
1978 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1979 "This member categorizes the section's contents and semantics.", HFILL }
1981 { &hf_elf_sh_type_user_specific,
1982 { "Type: User Specific", "elf.sh_type",
1983 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1984 "This member categorizes the section's contents and semantics.", HFILL }
1986 { &hf_elf_sh_flags_processor_specific,
1987 { "Processor Specific Flags", "elf.sh_flags.maskproc",
1988 FT_BOOLEAN, 32, NULL, 0xF0000000,
1989 NULL, HFILL }
1991 { &hf_elf_sh_flags_operating_system_specific,
1992 { "Operating System Specific Flags", "elf.sh_flags.maskos",
1993 FT_BOOLEAN, 32, NULL, 0x0FF00000,
1994 NULL, HFILL }
1996 { &hf_elf_sh_flags_reserved,
1997 { "Reserved", "elf.sh_flags.reserved",
1998 FT_BOOLEAN, 32, NULL, 0x000FF800,
1999 NULL, HFILL }
2001 { &hf_elf_sh_flags_tls,
2002 { "TLS Flag", "elf.sh_flags.tls",
2003 FT_BOOLEAN, 32, NULL, 0x00000400,
2004 "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 }
2006 { &hf_elf_sh_flags_group,
2007 { "Group Flag", "elf.sh_flags.group",
2008 FT_BOOLEAN, 32, NULL, 0x00000200,
2009 "This section is a member (perhaps the only one) of a section group.", HFILL }
2011 { &hf_elf_sh_flags_os_nonconforming,
2012 { "OS NonConforming Flag", "elf.sh_flags.os_nonconforming",
2013 FT_BOOLEAN, 32, NULL, 0x00000100,
2014 "This section requires special OS-specific processing to avoid incorrect behavior.", HFILL }
2016 { &hf_elf_sh_flags_link_order,
2017 { "Link Order Flag", "elf.sh_flags.link_order",
2018 FT_BOOLEAN, 32, NULL, 0x00000080,
2019 "This flag adds special ordering requirements for link editors.", HFILL }
2021 { &hf_elf_sh_flags_info_link,
2022 { "Info Link Flag", "elf.sh_flags.info_link",
2023 FT_BOOLEAN, 32, NULL, 0x00000040,
2024 "The sh_info field of this section header holds a section header table index.", HFILL }
2026 { &hf_elf_sh_flags_strings,
2027 { "Strings Flag", "elf.sh_flags.strings",
2028 FT_BOOLEAN, 32, NULL, 0x00000020,
2029 "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 }
2031 { &hf_elf_sh_flags_merge,
2032 { "Merge Flag", "elf.sh_flags.merge",
2033 FT_BOOLEAN, 32, NULL, 0x00000010,
2034 "The data in the section may be merged to eliminate duplication.", HFILL }
2036 { &hf_elf_sh_flags_reserved_8,
2037 { "Reserved", "elf.sh_flags.reserved.8",
2038 FT_BOOLEAN, 32, NULL, 0x00000008,
2039 NULL, HFILL }
2041 { &hf_elf_sh_flags_exec_instr,
2042 { "Exec Instr Flag", "elf.sh_flags.exec_instr",
2043 FT_BOOLEAN, 32, NULL, 0x00000004,
2044 "The section contains executable machine instructions.", HFILL }
2046 { &hf_elf_sh_flags_alloc,
2047 { "Alloc Flag", "elf.sh_flags.alloc",
2048 FT_BOOLEAN, 32, NULL, 0x00000002,
2049 "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 }
2051 { &hf_elf_sh_flags_write,
2052 { "Write Flag", "elf.sh_flags.write",
2053 FT_BOOLEAN, 32, NULL, 0x00000001,
2054 "The section contains data that should be writable during process execution.", HFILL }
2056 { &hf_elf_sh_addr,
2057 { "Address", "elf.sh_addr",
2058 FT_UINT32, BASE_HEX, NULL, 0x00,
2059 "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 }
2061 { &hf_elf64_sh_addr,
2062 { "Address", "elf.sh_addr",
2063 FT_UINT64, BASE_HEX, NULL, 0x00,
2064 "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 }
2066 { &hf_elf_sh_offset,
2067 { "File Offset", "elf.sh_offset",
2068 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2069 "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 }
2071 { &hf_elf64_sh_offset,
2072 { "File Offset", "elf.sh_offset",
2073 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2074 "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 }
2076 { &hf_elf_sh_size,
2077 { "Size", "elf.sh_size",
2078 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2079 "This member gives the section's size in bytes.", HFILL }
2081 { &hf_elf64_sh_size,
2082 { "Size", "elf.sh_size",
2083 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2084 "This member gives the section's size in bytes.", HFILL }
2087 { &hf_elf_sh_link,
2088 { "Link Index", "elf.sh_link",
2089 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2090 "This member holds a section header table index link, whose interpretation depends on the section type.", HFILL }
2092 { &hf_elf_sh_info,
2093 { "Info", "elf.sh_info",
2094 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2095 "This member holds extra information, whose interpretation depends on the section type.", HFILL }
2097 { &hf_elf_sh_addralign,
2098 { "Address Alignment", "elf.sh_addralign",
2099 FT_UINT32, BASE_HEX, NULL, 0x00,
2100 "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 }
2102 { &hf_elf64_sh_addralign,
2103 { "Address Alignment", "elf.sh_addralign",
2104 FT_UINT64, BASE_HEX, NULL, 0x00,
2105 "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 }
2107 { &hf_elf_sh_entsize,
2108 { "Entry Size", "elf.sh_entsize",
2109 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2110 "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 }
2112 { &hf_elf64_sh_entsize,
2113 { "Entry Size", "elf.sh_entsize",
2114 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2115 "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 }
2117 /* .eh_frame */
2118 { &hf_elf_eh_frame_length,
2119 { "Length", "elf.eh_frame.length",
2120 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2121 "A 4 byte unsigned value indicating the length in bytes of the CIE structure, not including the Length field itself. If Length contains the value 0xffffffff, then the length is contained in the Extended Length field. If Length contains the value 0, then this CIE shall be considered a terminator and processing shall end.", HFILL }
2123 { &hf_elf_eh_frame_extended_length,
2124 { "Length", "elf.eh_frame.length",
2125 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2126 "A 4 byte unsigned value indicating the length in bytes of the CIE structure, not including the Length field itself. If Length contains the value 0xffffffff, then the length is contained in the Extended Length field. If Length contains the value 0, then this CIE shall be considered a terminator and processing shall end.", HFILL }
2128 { &hf_elf_eh_frame_cie_id,
2129 { "CIE ID", "elf.eh_frame.cie_id",
2130 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2131 "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 }
2133 { &hf_elf_eh_frame_version,
2134 { "Version", "elf.eh_frame.version",
2135 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2136 "A 1 byte value that identifies the version number of the frame information structure. This value shall be 1.", HFILL }
2138 { &hf_elf_eh_frame_augmentation_string,
2139 { "Augmentation String", "elf.eh_frame.version",
2140 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2141 "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 }
2143 { &hf_elf_eh_frame_code_alignment_factor,
2144 { "Code Alignment Factor", "elf.eh_frame.code_alignment_factor",
2145 FT_UINT64, BASE_DEC, NULL, 0x00,
2146 "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 adavance location instruction to obtain the new location value.", HFILL }
2148 { &hf_elf_eh_frame_data_alignment_factor,
2149 { "Data Alignment Factor", "elf.eh_frame.data_alignment_factor",
2150 FT_INT64, BASE_DEC, NULL, 0x00,
2151 "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 }
2153 { &hf_elf_eh_frame_return_address_register,
2154 { "Return Address Register", "elf.eh_frame.return_address_register",
2155 FT_UINT64, BASE_DEC, NULL, 0x00,
2156 "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 }
2158 { &hf_elf_eh_frame_augmentation_length,
2159 { "Augmentation Length", "elf.eh_frame.augmentation_length",
2160 FT_UINT64, BASE_DEC, NULL, 0x00,
2161 "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 }
2163 { &hf_elf_eh_frame_augmentation_data,
2164 { "Augmentation Data", "elf.eh_frame.augmentation_data",
2165 FT_BYTES, BASE_NONE, NULL, 0x00,
2166 "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 }
2168 { &hf_elf_eh_frame_initial_instructions,
2169 { "Initial Instructions", "elf.eh_frame.initial_instructions",
2170 FT_BYTES, BASE_NONE, NULL, 0x00,
2171 "Initial set of Call Frame Instructions.", HFILL }
2173 /* .eh_frame fde */
2174 { &hf_elf_eh_frame_fde_length,
2175 { "Length", "elf.eh_frame.fde.length",
2176 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2177 "A 4 byte unsigned value indicating the length in bytes of the CIE structure, not including the Length field itself. If Length contains the value 0xffffffff, then the length is contained in the Extended Length field. If Length contains the value 0, then this CIE shall be considered a terminator and processing shall end.", HFILL }
2179 { &hf_elf_eh_frame_fde_extended_length,
2180 { "Length", "elf.eh_frame.fde.length",
2181 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2182 "A 4 byte unsigned value indicating the length in bytes of the CIE structure, not including the Length field itself. If Length contains the value 0xffffffff, then the length is contained in the Extended Length field. If Length contains the value 0, then this CIE shall be considered a terminator and processing shall end.", HFILL }
2184 { &hf_elf_eh_frame_fde_cie_pointer,
2185 { "CIE Pointer", "elf.eh_frame.fde.cie_pointer",
2186 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2187 "A 4 byte unsigned value that when subtracted from the offset of the the CIE Pointer in the current FDE yields the offset of the start of the associated CIE. This value shall never be 0.", HFILL }
2189 { &hf_elf_eh_frame_fde_pc_begin,
2190 { "PC Begin", "elf.eh_frame.fde.pc_begin",
2191 FT_UINT32, BASE_HEX, NULL, 0x00,
2192 "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 }
2194 { &hf_elf_eh_frame_fde_pc_range,
2195 { "PC Range", "elf.eh_frame.fde.pc_range",
2196 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2197 "An absolute value that indicates the number of bytes of instructions associated with this FDE.", HFILL }
2199 { &hf_elf_eh_frame_fde_augmentation_length,
2200 { "Augmentation Length", "elf.eh_frame.fde.augmentation_length",
2201 FT_UINT64, BASE_DEC, NULL, 0x00,
2202 "An unsigned LEB128 encoded value indicating the length in bytes of the Augmentation Data. This field is only present if the Augmentation String in the associated CIE contains the character 'z'.", HFILL }
2204 { &hf_elf_eh_frame_fde_augmentation_data,
2205 { "Augmentation Data", "elf.eh_frame.fde.augmentation_data",
2206 FT_BYTES, BASE_NONE, NULL, 0x00,
2207 "A block of data whose contents are defined by the contents of the Augmentation String in the associated CIE as described above. This field is only present if the Augmentation String in the associated CIE contains the character 'z'. The size of this data is given by the Augentation Length.", HFILL }
2209 { &hf_elf_eh_frame_fde_call_frame_instructions,
2210 { "Call Frame Instructions", "elf.eh_frame.fde.call_frame_instructions",
2211 FT_BYTES, BASE_NONE, NULL, 0x00,
2212 "A set of Call Frame Instructions.", HFILL }
2214 /* .eh_frame_hdr */
2215 { &hf_elf_eh_frame_hdr_version,
2216 { "Version", "elf.eh_frame_hdr.version",
2217 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2218 "Version of the .eh_frame_hdr format. This value shall be 1.", HFILL }
2220 { &hf_elf_eh_frame_hdr_exception_frame_pointer_encoding,
2221 { "Exeption Frame Pointer Encoding", "elf.eh_frame_hdr.eh_frame_ptr_enc",
2222 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2223 "The encoding format of the eh_frame_ptr field.", HFILL }
2225 { &hf_elf_eh_frame_hdr_fde_count_encoding,
2226 { "FDE Count Encoding", "elf.eh_frame_hdr.fde_count_enc",
2227 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2228 "The encoding format of the fde_count field. A value of DW_EH_PE_omit indicates the binary search table is not present.", HFILL }
2230 { &hf_elf_eh_frame_hdr_binary_search_table_encoding,
2231 { "Binary Search Table Encoding", "elf.eh_frame_hdr.binary_search_table_encoding",
2232 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2233 "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 }
2237 { &hf_elf_eh_frame_hdr_eh_frame_ptr,
2238 { "Exeption Frame Pointer", "elf.eh_frame_hdr.eh_frame_ptr",
2239 FT_BYTES, BASE_NONE, NULL, 0x00,
2240 NULL, HFILL }
2242 { &hf_elf_eh_frame_hdr_fde_count,
2243 { "FDE Count", "elf.eh_frame_hdr.fde_count",
2244 FT_BYTES, BASE_NONE, NULL, 0x00,
2245 NULL, HFILL }
2247 { &hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location,
2248 { "Initial location", "elf.eh_frame_hdr.binary_search_table_entry.initial_location",
2249 FT_BYTES, BASE_NONE, NULL, 0x00,
2250 NULL, HFILL }
2252 { &hf_elf_eh_frame_hdr_binary_search_table_entry_address,
2253 { "Address", "elf.eh_frame_hdr.binary_search_table_entry.address",
2254 FT_BYTES, BASE_NONE, NULL, 0x00,
2255 NULL, HFILL }
2258 /* symbol_table */
2259 { &hf_elf_symbol_table_name_index,
2260 { "Name Index", "elf.symbol_table.name_index",
2261 FT_UINT32, BASE_DEC, NULL, 0x00,
2262 NULL, HFILL }
2264 { &hf_elf_symbol_table_info,
2265 { "Info", "elf.symbol_table.info",
2266 FT_UINT8, BASE_HEX, NULL, 0x00,
2267 NULL, HFILL }
2269 { &hf_elf_symbol_table_info_bind,
2270 { "Bind", "elf.symbol_table.info.bind",
2271 FT_UINT8, BASE_HEX, VALS(symbol_table_info_bind_vals), 0xF0,
2272 NULL, HFILL }
2274 { &hf_elf_symbol_table_info_type,
2275 { "Type", "elf.symbol_table.info.type",
2276 FT_UINT8, BASE_HEX, VALS(symbol_table_info_type_vals), 0x0F,
2277 NULL, HFILL }
2279 { &hf_elf_symbol_table_other,
2280 { "Other", "elf.symbol_table.other",
2281 FT_UINT8, BASE_HEX, VALS(symbol_table_other_vals), 0x00,
2282 NULL, HFILL }
2284 { &hf_elf_symbol_table_shndx,
2285 { "Releated Section Header Index", "elf.symbol_table.shndx",
2286 FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(symbol_table_shndx_rvals), 0x00,
2287 NULL, HFILL }
2289 { &hf_elf_symbol_table_value,
2290 { "Value", "elf.symbol_table.value",
2291 FT_UINT32, BASE_HEX, NULL, 0x00,
2292 NULL, HFILL }
2294 { &hf_elf64_symbol_table_value,
2295 { "Value", "elf.symbol_table.value",
2296 FT_UINT64, BASE_HEX, NULL, 0x00,
2297 NULL, HFILL }
2299 { &hf_elf_symbol_table_size,
2300 { "Size", "elf.symbol_table.size",
2301 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2302 NULL, HFILL }
2304 { &hf_elf64_symbol_table_size,
2305 { "Size", "elf.symbol_table.size",
2306 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2307 NULL, HFILL }
2310 /* dynamic */
2311 { &hf_elf_dynamic_tag,
2312 { "Tag", "elf.dynamic.tag",
2313 FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(dynamic_tag_rvals), 0x00,
2314 NULL, HFILL }
2316 { &hf_elf_dynamic_value,
2317 { "Value", "elf.dynamic.value",
2318 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2319 NULL, HFILL }
2321 { &hf_elf_dynamic_pointer,
2322 { "Pointer", "elf.dynamic.pointer",
2323 FT_UINT32, BASE_HEX, NULL, 0x00,
2324 NULL, HFILL }
2326 { &hf_elf_dynamic_ignored,
2327 { "Ignored", "elf.dynamic.ignored",
2328 FT_UINT32, BASE_HEX, NULL, 0x00,
2329 NULL, HFILL }
2331 { &hf_elf_dynamic_unspecified,
2332 { "Unspecified", "elf.dynamic.unspecified",
2333 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2334 NULL, HFILL }
2336 { &hf_elf64_dynamic_tag,
2337 { "Tag", "elf.dynamic.tag",
2338 FT_UINT64, BASE_HEX /*| BASE_RANGE_STRING*/, NULL /*RVALS(dynamic_tag_rvals)*/, 0x00,
2339 NULL, HFILL }
2341 { &hf_elf64_dynamic_value,
2342 { "Value", "elf.dynamic.value",
2343 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2344 NULL, HFILL }
2346 { &hf_elf64_dynamic_pointer,
2347 { "Pointer", "elf.dynamic.pointer",
2348 FT_UINT64, BASE_HEX, NULL, 0x00,
2349 NULL, HFILL }
2351 { &hf_elf64_dynamic_ignored,
2352 { "Ignored", "elf.dynamic.ignored",
2353 FT_UINT64, BASE_HEX, NULL, 0x00,
2354 NULL, HFILL }
2356 { &hf_elf64_dynamic_unspecified,
2357 { "Unspecified", "elf.dynamic.unspecified",
2358 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2359 NULL, HFILL }
2362 /* dwarf */
2363 { &hf_dwarf_omit,
2364 { "DW_EH_PE_omit", "elf.dwarf.omit",
2365 FT_UINT8, BASE_HEX, NULL, 0x00,
2366 "Used to indicate that no value is present.", HFILL }
2368 { &hf_dwarf_upper,
2369 { "DWARF Exception Header application", "elf.dwarf.upper",
2370 FT_UINT8, BASE_HEX, VALS(eh_dwarf_upper), 0xF0,
2371 "The upper 4 bits indicate how the value is to be applied.", HFILL }
2373 { &hf_dwarf_format,
2374 { "DWARF Exception Header value format", "elf.dwarf.format",
2375 FT_UINT8, BASE_HEX, VALS(eh_dwarf_format), 0x0F,
2376 "The lower 4 bits indicate the format of the data.", HFILL }
2378 { &hf_elf_string,
2379 { "String", "elf.string",
2380 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2381 NULL, HFILL }
2385 static ei_register_info ei[] = {
2386 { &ei_invalid_segment_size, { "elf.invalid_segment_size", PI_PROTOCOL, PI_WARN, "Segment size is different then currently parsed bytes", EXPFILL }},
2387 { &ei_invalid_entry_size, { "elf.invalid_entry_size", PI_PROTOCOL, PI_WARN, "Entry size is different then currently parsed bytes", EXPFILL }},
2390 static gint *ett[] = {
2391 &ett_elf,
2392 &ett_elf_header,
2393 &ett_elf_program_header,
2394 &ett_elf_section_header,
2395 &ett_elf_segment,
2396 &ett_elf_cie,
2397 &ett_elf_fde,
2398 &ett_elf_entry,
2399 &ett_elf_info,
2400 &ett_elf_black_holes,
2401 &ett_elf_overlapping,
2402 &ett_dwarf_encoding,
2403 &ett_binary_table,
2404 &ett_binary_table_entry,
2405 &ett_symbol_table_entry,
2406 &ett_symbol_table_info
2409 proto_elf = proto_register_protocol("Executable and Linkable Format", "ELF", "elf");
2410 proto_register_field_array(proto_elf, hf, array_length(hf));
2411 proto_register_subtree_array(ett, array_length(ett));
2412 new_register_dissector("elf", dissect_elf, proto_elf);
2414 module = prefs_register_protocol(proto_elf, NULL);
2415 prefs_register_static_text_preference(module, "version",
2416 "ELF version: 4.1 DRAFT",
2417 "Version of file-format supported by this dissector.");
2419 expert_module = expert_register_protocol(proto_elf);
2420 expert_register_field_array(expert_module, ei, array_length(ei));
2423 void
2424 proto_reg_handoff_elf(void)
2426 dissector_handle_t elf_handle;
2428 elf_handle = find_dissector("elf");
2430 dissector_add_string("media_type", "application/x-executable", elf_handle);
2431 dissector_add_string("media_type", "application/x-coredump", elf_handle);
2432 dissector_add_string("media_type", "application/x-object", elf_handle);
2433 dissector_add_string("media_type", "application/x-sharedlib", elf_handle);
2435 heur_dissector_add("wtap_file", dissect_elf_heur, proto_elf);
2439 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2441 * Local variables:
2442 * c-basic-offset: 4
2443 * tab-width: 8
2444 * indent-tabs-mode: nil
2445 * End:
2447 * vi: set shiftwidth=4 tabstop=8 expandtab:
2448 * :indentSize=4:tabSize=8:noTabs=true: