From b05efa39b47995db08c5537e4504271c8727702a Mon Sep 17 00:00:00 2001 From: Vsevolod Alekseyev Date: Fri, 10 Nov 2023 15:26:48 +0000 Subject: [PATCH] readelf..debug-dump=loc displays bogus base addresses PR 30880 * dwarf.c (read_and_display_attr_value): Fix loclist handling. (display_loclists_list): Likewise. --- binutils/ChangeLog | 6 + binutils/dwarf.c | 465 ++++++++++++++++----------------------------- 2 files changed, 166 insertions(+), 305 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 5833ec048e9..b64591e02c6 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2023-11-10 Vsevolod Alekseyev + + PR 30880 + * dwarf.c (read_and_display_attr_value): Fix loclist handling. + (display_loclists_list): Likewise. + 2023-10-24 Tom de Vries * dwarf.c (display_gdb_index): Handle unknown name of main. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 544ba6dff50..024b322b542 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -54,6 +54,7 @@ static const char *regname (unsigned int regno, int row); static const char *regname_internal_by_table_only (unsigned int regno); static int have_frame_base; +static int frame_base_level = -1; /* To support nested DW_TAG_subprogram's. */ static int need_base_address; static unsigned int num_debug_info_entries = 0; @@ -2770,9 +2771,7 @@ read_and_display_attr_value (unsigned long attribute, if (form == DW_FORM_loclistx) { - if (debug_info_p == NULL ) - idx = (uint64_t) -1; - else if (dwo) + if (dwo) { idx = fetch_indexed_offset (uvalue, loclists_dwo, debug_info_p->loclists_base, @@ -2780,7 +2779,7 @@ read_and_display_attr_value (unsigned long attribute, if (idx != (uint64_t) -1) idx += (offset_size == 8) ? 20 : 12; } - else if (dwarf_version > 4) + else if (debug_info_p == NULL || dwarf_version > 4) { idx = fetch_indexed_offset (uvalue, loclists, debug_info_p->loclists_base, @@ -2805,12 +2804,21 @@ read_and_display_attr_value (unsigned long attribute, } else if (form == DW_FORM_rnglistx) { - if (debug_info_p == NULL) - idx = (uint64_t) -1; + if (dwo) + { + idx = fetch_indexed_offset (uvalue, rnglists, + debug_info_p->rnglists_base, + debug_info_p->offset_size); + } else - idx = fetch_indexed_offset (uvalue, rnglists, - debug_info_p->rnglists_base, - debug_info_p->offset_size); + { + if (debug_info_p == NULL) + base = 0; + else + base = debug_info_p->rnglists_base; + idx = fetch_indexed_offset (uvalue, rnglists, base, + debug_info_p->offset_size); + } } else { @@ -2889,7 +2897,10 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_frame_base: + /* This is crude; the have_frame_base is reset on the next + subprogram, not at the end of the current topmost one. */ have_frame_base = 1; + frame_base_level = level; /* Fall through. */ case DW_AT_location: case DW_AT_GNU_locviews: @@ -2941,8 +2952,6 @@ read_and_display_attr_value (unsigned long attribute, debug_info_p->have_frame_base [num] = have_frame_base; if (attribute != DW_AT_GNU_locviews) { - uvalue += debug_info_p->loclists_base; - /* Corrupt DWARF info can produce more offsets than views. See PR 23062 for an example. */ if (debug_info_p->num_loc_offsets @@ -3698,7 +3707,7 @@ read_bases (abbrev_entry * entry, else warn (_("Unexpected form of DW_AT_rnglists_base in the top DIE\n")); } - else if(attr->attribute == DW_AT_addr_base || attr->attribute == DW_AT_GNU_addr_base) + else if (attr->attribute == DW_AT_addr_base || attr->attribute == DW_AT_GNU_addr_base) { if (attr->form == DW_FORM_sec_offset) { @@ -3709,7 +3718,8 @@ read_bases (abbrev_entry * entry, warn (_("Unexpected form of DW_AT_addr_base in the top DIE\n")); } else - data = skip_attribute(attr->form, data, end, pointer_size, offset_size, dwarf_version); + data = skip_attribute (attr->form, data, end, pointer_size, + offset_size, dwarf_version); } } @@ -4206,11 +4216,16 @@ process_debug_info (struct dwarf_section * section, need_dwo_info = do_loc; break; case DW_TAG_entry_point: - case DW_TAG_subprogram: need_base_address = 0; /* Assuming that there is no DW_AT_frame_base. */ have_frame_base = 0; break; + case DW_TAG_subprogram: + need_base_address = 0; + if (level <= frame_base_level) + /* Don't reset that for nested subprogram. */ + have_frame_base = 0; + break; } debug_info *debug_info_p = @@ -4221,11 +4236,12 @@ process_debug_info (struct dwarf_section * section, || (debug_info_p->num_loc_offsets == debug_info_p->num_loc_views)); - /* Look ahead so that the values of DW_AT_rnglists_base, DW_AT_[GNU_]addr_base - are available before attributes that reference them are parsed in the same DIE. + /* Look ahead so that the values of DW_AT_rnglists_base, + DW_AT_[GNU_]addr_base are available before attributes that + reference them are parsed in the same DIE. Only needed for the top DIE on DWARFv5+. - No simiar treatment for loclists_base because there should be no loclist - attributes in top DIE. */ + No simiar treatment for loclists_base because there should + be no loclist attributes in top DIE. */ if (compunit.cu_version >= 5 && level == 0) { int64_t stemp; @@ -4290,7 +4306,7 @@ process_debug_info (struct dwarf_section * section, break; case -1: - warn(_("DIE has locviews without loclist\n")); + warn (_("DIE has locviews without loclist\n")); debug_info_p->num_loc_views--; break; @@ -6804,7 +6820,7 @@ display_loc_list (struct dwarf_section *section, static void display_loclists_list (struct dwarf_section * section, unsigned char ** start_ptr, - unsigned int debug_info_entry, + debug_info * debug_info_p, uint64_t offset, uint64_t base_address, unsigned char ** vstart_ptr, @@ -6817,6 +6833,7 @@ display_loclists_list (struct dwarf_section * section, unsigned int pointer_size; unsigned int offset_size; unsigned int dwarf_version; + uint64_t index; /* Initialize it due to a false compiler warning. */ uint64_t begin = -1, vbegin = -1; @@ -6824,23 +6841,15 @@ display_loclists_list (struct dwarf_section * section, uint64_t length; int need_frame_base; - if (debug_info_entry >= num_debug_info_entries) - { - warn (_("No debug information available for " - "loclists lists of entry: %u\n"), - debug_info_entry); - return; - } - - cu_offset = debug_information [debug_info_entry].cu_offset; - pointer_size = debug_information [debug_info_entry].pointer_size; - offset_size = debug_information [debug_info_entry].offset_size; - dwarf_version = debug_information [debug_info_entry].dwarf_version; + cu_offset = debug_info_p->cu_offset; + pointer_size = debug_info_p->pointer_size; + offset_size = debug_info_p->offset_size; + dwarf_version = debug_info_p->dwarf_version; if (pointer_size < 2 || pointer_size > 8) { warn (_("Invalid pointer size (%d) in debug info for entry %d\n"), - pointer_size, debug_info_entry); + pointer_size, (int)(debug_info_p - debug_information)); return; } @@ -6883,24 +6892,28 @@ display_loclists_list (struct dwarf_section * section, break; case DW_LLE_base_addressx: - READ_ULEB (base_address, start, section_end); - print_hex (base_address, pointer_size); + READ_ULEB (index, start, section_end); + print_hex (index, pointer_size); printf (_("(index into .debug_addr) ")); - base_address = fetch_indexed_addr (base_address, pointer_size); + base_address = fetch_indexed_addr + (debug_info_p->addr_base + index * pointer_size, pointer_size); print_hex (base_address, pointer_size); printf (_("(base address)\n")); break; case DW_LLE_startx_endx: - READ_ULEB (begin, start, section_end); - begin = fetch_indexed_addr (begin, pointer_size); - READ_ULEB (end, start, section_end); - end = fetch_indexed_addr (end, pointer_size); + READ_ULEB (index, start, section_end); + begin = fetch_indexed_addr + (debug_info_p->addr_base + index * pointer_size, pointer_size); + READ_ULEB (index, start, section_end); + end = fetch_indexed_addr + (debug_info_p->addr_base + index * pointer_size, pointer_size); break; case DW_LLE_startx_length: - READ_ULEB (begin, start, section_end); - begin = fetch_indexed_addr (begin, pointer_size); + READ_ULEB (index, start, section_end); + begin = fetch_indexed_addr + (debug_info_p->addr_base + index * pointer_size, pointer_size); READ_ULEB (end, start, section_end); end += begin; break; @@ -7197,202 +7210,74 @@ loc_offsets_compar (const void *ap, const void *bp) return ret; } -static int -display_offset_entry_loclists (struct dwarf_section *section) +/* Reads and dumps the DWARFv5 loclists compiler unit header, + including the offset table. + Returns the offset of the next compile unit header. */ + +static uint64_t +display_loclists_unit_header (struct dwarf_section * section, + uint64_t header_offset, + uint32_t * offset_count, + unsigned char ** loclists_start) { - unsigned char * start = section->start; - unsigned char * const end = start + section->size; + uint64_t length; + unsigned char *start = section->start + header_offset; + unsigned char *end = section->start + section->size; + unsigned short version; + unsigned char address_size; + unsigned char segment_selector_size; + bool is_64bit; + uint32_t i; - introduce (section, false); + printf (_("Table at Offset %#" PRIx64 "\n"), header_offset); - do + SAFE_BYTE_GET_AND_INC (length, start, 4, end); + if (length == 0xffffffff) { - uint64_t length; - unsigned short version; - unsigned char address_size; - unsigned char segment_selector_size; - uint32_t offset_entry_count; - uint32_t i; - bool is_64bit; - - printf (_("Table at Offset %#tx\n"), start - section->start); - - SAFE_BYTE_GET_AND_INC (length, start, 4, end); - if (length == 0xffffffff) - { - is_64bit = true; - SAFE_BYTE_GET_AND_INC (length, start, 8, end); - } - else - is_64bit = false; - - SAFE_BYTE_GET_AND_INC (version, start, 2, end); - SAFE_BYTE_GET_AND_INC (address_size, start, 1, end); - SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, end); - SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, end); - - printf (_(" Length: %#" PRIx64 "\n"), length); - printf (_(" DWARF version: %u\n"), version); - printf (_(" Address size: %u\n"), address_size); - printf (_(" Segment size: %u\n"), segment_selector_size); - printf (_(" Offset entries: %u\n"), offset_entry_count); + is_64bit = true; + SAFE_BYTE_GET_AND_INC (length, start, 8, end); + } + else + is_64bit = false; - if (version < 5) - { - warn (_("The %s section contains a corrupt or " - "unsupported version number: %d.\n"), - section->name, version); - return 0; - } + SAFE_BYTE_GET_AND_INC (version, start, 2, end); + SAFE_BYTE_GET_AND_INC (address_size, start, 1, end); + SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, end); + SAFE_BYTE_GET_AND_INC (*offset_count, start, 4, end); - if (segment_selector_size != 0) - { - warn (_("The %s section contains an " - "unsupported segment selector size: %d.\n"), - section->name, segment_selector_size); - return 0; - } + printf (_(" Length: %#" PRIx64 "\n"), length); + printf (_(" DWARF version: %u\n"), version); + printf (_(" Address size: %u\n"), address_size); + printf (_(" Segment size: %u\n"), segment_selector_size); + printf (_(" Offset entries: %u\n"), *offset_count); - if (offset_entry_count == 0) - { - warn (_("The %s section contains a table without offset\n"), - section->name); - return 0; - } + if (segment_selector_size != 0) + { + warn (_("The %s section contains an " + "unsupported segment selector size: %d.\n"), + section->name, segment_selector_size); + return (uint64_t)-1; + } + if ( *offset_count) + { printf (_("\n Offset Entries starting at %#tx:\n"), start - section->start); - for (i = 0; i < offset_entry_count; i++) + for (i = 0; i < *offset_count; i++) { uint64_t entry; SAFE_BYTE_GET_AND_INC (entry, start, is_64bit ? 8 : 4, end); printf (_(" [%6u] %#" PRIx64 "\n"), i, entry); } - - putchar ('\n'); - - uint32_t j; - - for (j = 1, i = 0; i < offset_entry_count;) - { - unsigned char lle; - uint64_t base_address = 0; - uint64_t begin; - uint64_t finish; - uint64_t off = start - section->start; - - if (j != i) - { - printf (_(" Offset Entry %u\n"), i); - j = i; - } - - printf (" "); - print_hex (off, 4); - - SAFE_BYTE_GET_AND_INC (lle, start, 1, end); - - switch (lle) - { - case DW_LLE_end_of_list: - printf (_("\n\n")); - i ++; - continue; - - case DW_LLE_base_addressx: - READ_ULEB (base_address, start, end); - print_hex (base_address, address_size); - printf (_("(index into .debug_addr) ")); - base_address = fetch_indexed_addr (base_address, address_size); - print_hex (base_address, address_size); - printf (_("(base address)\n")); - continue; - - case DW_LLE_startx_endx: - READ_ULEB (begin, start, end); - begin = fetch_indexed_addr (begin, address_size); - READ_ULEB (finish, start, end); - finish = fetch_indexed_addr (finish, address_size); - break; - - case DW_LLE_startx_length: - READ_ULEB (begin, start, end); - begin = fetch_indexed_addr (begin, address_size); - READ_ULEB (finish, start, end); - finish += begin; - break; - - case DW_LLE_offset_pair: - READ_ULEB (begin, start, end); - begin += base_address; - READ_ULEB (finish, start, end); - finish += base_address; - break; - - case DW_LLE_default_location: - begin = finish = 0; - break; - - case DW_LLE_base_address: - SAFE_BYTE_GET_AND_INC (base_address, start, address_size, end); - print_hex (base_address, address_size); - printf (_("(base address)\n")); - continue; - - case DW_LLE_start_end: - SAFE_BYTE_GET_AND_INC (begin, start, address_size, end); - SAFE_BYTE_GET_AND_INC (finish, start, address_size, end); - break; - - case DW_LLE_start_length: - SAFE_BYTE_GET_AND_INC (begin, start, address_size, end); - READ_ULEB (finish, start, end); - finish += begin; - break; - - default: - error (_("Invalid location list entry type %d\n"), lle); - return 0; - } - - if (start == end) - { - warn (_("Location list starting at offset %#" PRIx64 - " is not terminated.\n"), off); - break; - } - - print_hex (begin, address_size); - print_hex (finish, address_size); - - if (begin == finish) - fputs (_("(start == end)"), stdout); - else if (begin > finish) - fputs (_("(start > end)"), stdout); - - /* Read the counted location descriptions. */ - READ_ULEB (length, start, end); - - if (length > (size_t) (end - start)) - { - warn (_("Location list starting at offset %#" PRIx64 - " is not terminated.\n"), off); - break; - } - - (void) decode_location_expression (start, address_size, address_size, - version, length, 0, section); - start += length; - putchar ('\n'); - } - - putchar ('\n'); } - while (start < end); - return 1; + putchar ('\n'); + *loclists_start = start; + + /* The length field doesn't include the length field itself. */ + return header_offset + length + (is_64bit ? 12 : 4); } static int @@ -7414,7 +7299,7 @@ display_debug_loc (struct dwarf_section *section, void *file) const char *suffix = strrchr (section->name, '.'); bool is_dwo = false; int is_loclists = strstr (section->name, "debug_loclists") != NULL; - uint64_t header_size = 0; + uint64_t next_header_offset = 0; if (suffix && strcmp (suffix, ".dwo") == 0) is_dwo = true; @@ -7462,10 +7347,10 @@ display_debug_loc (struct dwarf_section *section, void *file) SAFE_BYTE_GET_AND_INC (offset_entry_count, hdrptr, 4, end); - if (offset_entry_count != 0) - return display_offset_entry_loclists (section); + /*if (offset_entry_count != 0) + return display_offset_entry_loclists (section);*/ - header_size = hdrptr - section_begin; + //header_size = hdrptr - section_begin; } if (load_debug_info (file) == 0) @@ -7520,14 +7405,6 @@ display_debug_loc (struct dwarf_section *section, void *file) if (!seen_first_offset) error (_("No location lists in .debug_info section!\n")); - if (debug_information [first].num_loc_offsets > 0 - && debug_information [first].loc_offsets [0] != header_size - && debug_information [first].loc_views [0] != header_size) - warn (_("Location lists in %s section start at %#" PRIx64 - " rather than %#" PRIx64 "\n"), - section->name, debug_information [first].loc_offsets [0], - header_size); - if (!locs_sorted) array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int)); @@ -7536,7 +7413,8 @@ display_debug_loc (struct dwarf_section *section, void *file) if (reloc_at (section, 0)) printf (_(" Warning: This section has relocations - addresses seen here may not be accurate.\n\n")); - printf (_(" Offset Begin End Expression\n")); + if (!is_loclists) + printf (_(" Offset Begin End Expression\n")); for (i = first; i < num_debug_info_entries; i++) { @@ -7544,56 +7422,74 @@ display_debug_loc (struct dwarf_section *section, void *file) uint64_t base_address; unsigned int k; int has_frame_base; + debug_info *debug_info_p = debug_information + i; + uint32_t offset_count; + if (!locs_sorted) { - for (k = 0; k < debug_information [i].num_loc_offsets; k++) + for (k = 0; k < debug_info_p->num_loc_offsets; k++) array[k] = k; - loc_offsets = debug_information [i].loc_offsets; - loc_views = debug_information [i].loc_views; - qsort (array, debug_information [i].num_loc_offsets, + loc_offsets = debug_info_p->loc_offsets; + loc_views = debug_info_p->loc_views; + qsort (array, debug_info_p->num_loc_offsets, sizeof (*array), loc_offsets_compar); } /* .debug_loclists has a per-unit header. Update start if we are detecting it. */ - if (debug_information [i].dwarf_version == 5) + if (debug_info_p->dwarf_version == 5) { j = locs_sorted ? 0 : array [0]; - if (debug_information [i].num_loc_offsets) - offset = debug_information [i].loc_offsets [j]; + if (debug_info_p->num_loc_offsets) + offset = debug_info_p->loc_offsets [j]; - if (debug_information [i].num_loc_views) - voffset = debug_information [i].loc_views [j]; + if (debug_info_p->num_loc_views) + voffset = debug_info_p->loc_views [j]; - /* Assume that the size of the header is constant across CUs. */ - if (((start - section_begin) + header_size == offset) - || ((start -section_begin) + header_size == voffset)) - start += header_size; + /* Parse and dump unit headers in loclists. + This will misbehave if the order of CUs in debug_info + doesn't match the one in loclists. */ + if (next_header_offset < offset) + { + while (next_header_offset < offset) + { + next_header_offset = display_loclists_unit_header + (section, next_header_offset, &offset_count, &start); + + if (next_header_offset == (uint64_t)-1) + /* Header parsing error. */ + return 0; + } + + printf (_("\ + Offset Begin End Expression\n")); + } } int adjacent_view_loclists = 1; - for (k = 0; k < debug_information [i].num_loc_offsets; k++) + + for (k = 0; k < debug_info_p->num_loc_offsets; k++) { j = locs_sorted ? k : array[k]; if (k - && (debug_information [i].loc_offsets [locs_sorted + && (debug_info_p->loc_offsets [locs_sorted ? k - 1 : array [k - 1]] - == debug_information [i].loc_offsets [j]) - && (debug_information [i].loc_views [locs_sorted + == debug_info_p->loc_offsets [j]) + && (debug_info_p->loc_views [locs_sorted ? k - 1 : array [k - 1]] - == debug_information [i].loc_views [j])) + == debug_info_p->loc_views [j])) continue; - has_frame_base = debug_information [i].have_frame_base [j]; - offset = debug_information [i].loc_offsets [j]; + has_frame_base = debug_info_p->have_frame_base [j]; + offset = debug_info_p->loc_offsets [j]; next = section_begin + offset; - voffset = debug_information [i].loc_views [j]; + voffset = debug_info_p->loc_views [j]; if (voffset != (uint64_t) -1) vnext = section_begin + voffset; else vnext = NULL; - base_address = debug_information [i].base_address; + base_address = debug_info_p->base_address; if (vnext && vnext < next) { @@ -7649,8 +7545,8 @@ display_debug_loc (struct dwarf_section *section, void *file) if (is_dwo) warn (_("DWO is not yet supported.\n")); else - display_loclists_list (section, &start, i, offset, base_address, - &vstart, has_frame_base); + display_loclists_list (section, &start, debug_info_p, offset, + base_address, &vstart, has_frame_base); } /* FIXME: this arrangement is quite simplistic. Nothing @@ -10745,31 +10641,29 @@ display_gdb_index (struct dwarf_section *section, unsigned char *start = section->start; uint32_t version; uint32_t cu_list_offset, tu_list_offset; - uint32_t address_table_offset, symbol_table_offset, constant_pool_offset, - shortcut_table_offset; + uint32_t address_table_offset, symbol_table_offset, constant_pool_offset; unsigned int cu_list_elements, tu_list_elements; unsigned int address_table_elements, symbol_table_slots; unsigned char *cu_list, *tu_list; - unsigned char *address_table, *symbol_table, *shortcut_table, *constant_pool; + unsigned char *address_table, *symbol_table, *constant_pool; unsigned int i; /* The documentation for the format of this file is in gdb/dwarf2read.c. */ introduce (section, false); - version = section->size < 4 ? 0 : byte_get_little_endian (start, 4); - size_t header_size = (version < 9 ? 6 : 7) * sizeof (uint32_t); - if (section->size < header_size) + if (section->size < 6 * sizeof (uint32_t)) { warn (_("Truncated header in the %s section.\n"), section->name); return 0; } + version = byte_get_little_endian (start, 4); printf (_("Version %lu\n"), (unsigned long) version); /* Prior versions are obsolete, and future versions may not be backwards compatible. */ - if (version < 3 || version > 9) + if (version < 3 || version > 8) { warn (_("Unsupported version %lu.\n"), (unsigned long) version); return 0; @@ -10791,23 +10685,17 @@ display_gdb_index (struct dwarf_section *section, tu_list_offset = byte_get_little_endian (start + 8, 4); address_table_offset = byte_get_little_endian (start + 12, 4); symbol_table_offset = byte_get_little_endian (start + 16, 4); - shortcut_table_offset = byte_get_little_endian (start + 20, 4); - if (version < 9) - constant_pool_offset = shortcut_table_offset; - else - constant_pool_offset = byte_get_little_endian (start + 24, 4); + constant_pool_offset = byte_get_little_endian (start + 20, 4); if (cu_list_offset > section->size || tu_list_offset > section->size || address_table_offset > section->size || symbol_table_offset > section->size - || shortcut_table_offset > section->size || constant_pool_offset > section->size || tu_list_offset < cu_list_offset || address_table_offset < tu_list_offset || symbol_table_offset < address_table_offset - || shortcut_table_offset < symbol_table_offset - || constant_pool_offset < shortcut_table_offset) + || constant_pool_offset < symbol_table_offset) { warn (_("Corrupt header in the %s section.\n"), section->name); return 0; @@ -10816,13 +10704,12 @@ display_gdb_index (struct dwarf_section *section, cu_list_elements = (tu_list_offset - cu_list_offset) / 16; tu_list_elements = (address_table_offset - tu_list_offset) / 24; address_table_elements = (symbol_table_offset - address_table_offset) / 20; - symbol_table_slots = (shortcut_table_offset - symbol_table_offset) / 8; + symbol_table_slots = (constant_pool_offset - symbol_table_offset) / 8; cu_list = start + cu_list_offset; tu_list = start + tu_list_offset; address_table = start + address_table_offset; symbol_table = start + symbol_table_offset; - shortcut_table = start + shortcut_table_offset; constant_pool = start + constant_pool_offset; printf (_("\nCU table:\n")); @@ -10934,38 +10821,6 @@ display_gdb_index (struct dwarf_section *section, } } - if (version >= 9) - { - printf (_("\nShortcut table:\n")); - - if (shortcut_table_offset + 8 > constant_pool_offset) - { - warn (_("Corrupt shortcut table in the %s section.\n"), section->name); - return 0; - } - - uint32_t lang = byte_get_little_endian (shortcut_table, 4); - printf (_("Language of main: ")); - display_lang (lang); - printf ("\n"); - - printf (_("Name of main: ")); - if (lang == 0) - printf (_("\n")); - else - { - uint32_t name_offset = byte_get_little_endian (shortcut_table + 4, 4); - if (name_offset >= section->size - constant_pool_offset) - { - printf (_("\n"), name_offset); - warn (_("Corrupt name offset of 0x%x found for name of main\n"), - name_offset); - } - else - printf ("%s\n", constant_pool + name_offset); - } - } - return 1; } -- 2.30.2