From 2e0c2015a558ad03179676b153e7527c30439337 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Aug 25 2020 15:57:53 +0000 Subject: Import fixes from GNU binutils mainline for handling DWARF-5 debug information. --- diff --git a/binutils-dwarf-5-fixes.patch b/binutils-dwarf-5-fixes.patch new file mode 100644 index 0000000..1187973 --- /dev/null +++ b/binutils-dwarf-5-fixes.patch @@ -0,0 +1,426 @@ +diff -rup binutils.orig/bfd/dwarf2.c binutils-2.35/bfd/dwarf2.c +--- binutils.orig/bfd/dwarf2.c 2020-08-25 15:40:47.642219922 +0100 ++++ binutils-2.35/bfd/dwarf2.c 2020-08-25 15:41:16.271039143 +0100 +@@ -130,6 +130,12 @@ struct dwarf2_debug_file + /* Length of the loaded .debug_ranges section. */ + bfd_size_type dwarf_ranges_size; + ++ /* Pointer to the .debug_rnglists section loaded into memory. */ ++ bfd_byte *dwarf_rnglists_buffer; ++ ++ /* Length of the loaded .debug_rnglists section. */ ++ bfd_size_type dwarf_rnglists_size; ++ + /* A list of all previously read comp_units. */ + struct comp_unit *all_comp_units; + +@@ -327,6 +333,7 @@ const struct dwarf_debug_section dwarf_d + { ".debug_pubnames", ".zdebug_pubnames" }, + { ".debug_pubtypes", ".zdebug_pubtypes" }, + { ".debug_ranges", ".zdebug_ranges" }, ++ { ".debug_rnglists", ".zdebug_rnglist" }, + { ".debug_static_func", ".zdebug_static_func" }, + { ".debug_static_vars", ".zdebug_static_vars" }, + { ".debug_str", ".zdebug_str", }, +@@ -360,6 +367,7 @@ enum dwarf_debug_section_enum + debug_pubnames, + debug_pubtypes, + debug_ranges, ++ debug_rnglists, + debug_static_func, + debug_static_vars, + debug_str, +@@ -1329,6 +1337,17 @@ read_attribute_value (struct attribute * + attr->form = DW_FORM_sdata; + attr->u.sval = implicit_const; + break; ++ case DW_FORM_data16: ++ /* This is really a "constant", but there is no way to store that ++ so pretend it is a 16 byte block instead. */ ++ amt = sizeof (struct dwarf_block); ++ blk = (struct dwarf_block *) bfd_alloc (abfd, amt); ++ if (blk == NULL) ++ return NULL; ++ blk->size = 16; ++ info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk); ++ attr->u.blk = blk; ++ break; + default: + _bfd_error_handler (_("DWARF error: invalid or unhandled FORM value: %#x"), + form); +@@ -2069,11 +2088,17 @@ read_formatted_entries (struct comp_unit + case DW_FORM_udata: + *uintp = attr.u.val; + break; ++ ++ case DW_FORM_data16: ++ /* MD5 data is in the attr.blk, but we are ignoring those. */ ++ break; + } + } + +- if (!callback (table, fe.name, fe.dir, fe.time, fe.size)) +- return FALSE; ++ /* Skip the first "zero entry", which is the compilation dir/file. */ ++ if (datai != 0) ++ if (!callback (table, fe.name, fe.dir, fe.time, fe.size)) ++ return FALSE; + } + + *bufp = buf; +@@ -2617,6 +2642,19 @@ read_debug_ranges (struct comp_unit * un + &file->dwarf_ranges_buffer, &file->dwarf_ranges_size); + } + ++/* Read in the .debug_rnglists section for future reference. */ ++ ++static bfd_boolean ++read_debug_rnglists (struct comp_unit * unit) ++{ ++ struct dwarf2_debug *stash = unit->stash; ++ struct dwarf2_debug_file *file = unit->file; ++ ++ return read_section (unit->abfd, &stash->debug_sections[debug_rnglists], ++ file->syms, 0, ++ &file->dwarf_rnglists_buffer, &file->dwarf_rnglists_size); ++} ++ + /* Function table functions. */ + + static int +@@ -3107,8 +3145,8 @@ find_abstract_instance (struct comp_unit + } + + static bfd_boolean +-read_rangelist (struct comp_unit *unit, struct arange *arange, +- bfd_uint64_t offset) ++read_ranges (struct comp_unit *unit, struct arange *arange, ++ bfd_uint64_t offset) + { + bfd_byte *ranges_ptr; + bfd_byte *ranges_end; +@@ -3153,6 +3191,107 @@ read_rangelist (struct comp_unit *unit, + return TRUE; + } + ++static bfd_boolean ++read_rnglists (struct comp_unit *unit, struct arange *arange, ++ bfd_uint64_t offset) ++{ ++ bfd_byte *rngs_ptr; ++ bfd_byte *rngs_end; ++ bfd_vma base_address = unit->base_address; ++ bfd_vma low_pc; ++ bfd_vma high_pc; ++ bfd *abfd = unit->abfd; ++ ++ if (! unit->file->dwarf_rnglists_buffer) ++ { ++ if (! read_debug_rnglists (unit)) ++ return FALSE; ++ } ++ ++ rngs_ptr = unit->file->dwarf_rnglists_buffer + offset; ++ if (rngs_ptr < unit->file->dwarf_rnglists_buffer) ++ return FALSE; ++ rngs_end = unit->file->dwarf_rnglists_buffer; ++ rngs_end += unit->file->dwarf_rnglists_size; ++ ++ for (;;) ++ { ++ enum dwarf_range_list_entry rlet; ++ unsigned int bytes_read; ++ ++ if (rngs_ptr + 1 > rngs_end) ++ return FALSE; ++ ++ rlet = read_1_byte (abfd, rngs_ptr, rngs_end); ++ rngs_ptr++; ++ ++ switch (rlet) ++ { ++ case DW_RLE_end_of_list: ++ return TRUE; ++ ++ case DW_RLE_base_address: ++ if (rngs_ptr + unit->addr_size > rngs_end) ++ return FALSE; ++ base_address = read_address (unit, rngs_ptr, rngs_end); ++ rngs_ptr += unit->addr_size; ++ continue; ++ ++ case DW_RLE_start_length: ++ if (rngs_ptr + unit->addr_size > rngs_end) ++ return FALSE; ++ low_pc = read_address (unit, rngs_ptr, rngs_end); ++ rngs_ptr += unit->addr_size; ++ high_pc = low_pc; ++ high_pc += _bfd_safe_read_leb128 (abfd, rngs_ptr, &bytes_read, ++ FALSE, rngs_end); ++ rngs_ptr += bytes_read; ++ break; ++ ++ case DW_RLE_offset_pair: ++ low_pc = base_address; ++ low_pc += _bfd_safe_read_leb128 (abfd, rngs_ptr, &bytes_read, ++ FALSE, rngs_end); ++ high_pc = base_address; ++ high_pc += _bfd_safe_read_leb128 (abfd, rngs_ptr, &bytes_read, ++ FALSE, rngs_end); ++ break; ++ ++ case DW_RLE_start_end: ++ if (rngs_ptr + 2 * unit->addr_size > rngs_end) ++ return FALSE; ++ low_pc = read_address (unit, rngs_ptr, rngs_end); ++ rngs_ptr += unit->addr_size; ++ high_pc = read_address (unit, rngs_ptr, rngs_end); ++ rngs_ptr += unit->addr_size; ++ break; ++ ++ /* TODO x-variants need .debug_addr support used for split-dwarf. */ ++ case DW_RLE_base_addressx: ++ case DW_RLE_startx_endx: ++ case DW_RLE_startx_length: ++ default: ++ return FALSE; ++ } ++ ++ if ((low_pc == 0 && high_pc == 0) || low_pc == high_pc) ++ return FALSE; ++ ++ if (!arange_add (unit, arange, low_pc, high_pc)) ++ return FALSE; ++ } ++} ++ ++static bfd_boolean ++read_rangelist (struct comp_unit *unit, struct arange *arange, ++ bfd_uint64_t offset) ++{ ++ if (unit->version <= 4) ++ return read_ranges (unit, arange, offset); ++ else ++ return read_rnglists (unit, arange, offset); ++} ++ + static struct varinfo * + lookup_var_by_offset (bfd_uint64_t offset, struct varinfo * table) + { +diff -rup binutils.orig/binutils/testsuite/binutils-all/readelf.exp binutils-2.35/binutils/testsuite/binutils-all/readelf.exp +--- binutils.orig/binutils/testsuite/binutils-all/readelf.exp 2020-08-25 15:40:46.998223989 +0100 ++++ binutils-2.35/binutils/testsuite/binutils-all/readelf.exp 2020-08-25 15:41:08.408088795 +0100 +@@ -188,7 +188,7 @@ proc readelf_wi_test {} { + ".*DW_TAG_subprogram.*" + ".*DW_TAG_base_type.*" + ".*DW_AT_producer.*(GNU C|indirect string).*" +- ".*DW_AT_language.*ANSI C.*" ++ ".*DW_AT_language.*(ANSI C|C11).*" + ".*DW_AT_name.*(testprog.c|indirect string).*" + ".*DW_AT_name.*fn.*" + ".*DW_AT_name.*(main|indirect string).*" +diff -rup binutils.orig/gas/dwarf2dbg.c binutils-2.35/gas/dwarf2dbg.c +--- binutils.orig/gas/dwarf2dbg.c 2020-08-25 15:40:47.251222391 +0100 ++++ binutils-2.35/gas/dwarf2dbg.c 2020-08-25 15:41:44.775859148 +0100 +@@ -1992,18 +1992,29 @@ out_dir_and_file_list (void) + the .debug_line_str section and reference them here. */ + out_uleb128 (DW_FORM_string); + +- /* Now state how many rows there are in the table. */ +- out_uleb128 (dirs_in_use); ++ /* Now state how many rows there are in the table. We need at ++ least 1 if there is one or more file names to store the ++ "working directory". */ ++ if (dirs_in_use == 0 && files_in_use > 0) ++ out_uleb128 (1); ++ else ++ out_uleb128 (dirs_in_use); + } + + /* Emit directory list. */ +- if (DWARF2_LINE_VERSION >= 5 && dirs_in_use > 0) ++ if (DWARF2_LINE_VERSION >= 5 && (dirs_in_use > 0 || files_in_use > 0)) + { +- if (dirs == NULL || dirs[0] == NULL) +- dir = remap_debug_filename ("."); +- else ++ /* DWARF5 uses slot zero, but that is only set explicitly ++ using a .file 0 directive. If that isn't used, but dir ++ one is used, then use that as main file directory. ++ Otherwise use pwd as main file directory. */ ++ if (dirs_in_use > 0 && dirs != NULL && dirs[0] != NULL) + dir = remap_debug_filename (dirs[0]); +- ++ else if (dirs_in_use > 1 && dirs != NULL && dirs[1] != NULL) ++ dir = remap_debug_filename (dirs[1]); ++ else ++ dir = remap_debug_filename (getpwd ()); ++ + size = strlen (dir) + 1; + cp = frag_more (size); + memcpy (cp, dir, size); +@@ -2089,8 +2100,14 @@ out_dir_and_file_list (void) + + if (files[i].filename == NULL) + { +- /* Prevent a crash later, particularly for file 1. */ +- files[i].filename = ""; ++ /* Prevent a crash later, particularly for file 1. DWARF5 ++ uses slot zero, but that is only set explicitly using a ++ .file 0 directive. If that isn't used, but file 1 is, ++ then use that as main file name. */ ++ if (DWARF2_LINE_VERSION >= 5 && i == 0 && files_in_use >= 1) ++ files[0].filename = files[1].filename; ++ else ++ files[i].filename = ""; + if (DWARF2_LINE_VERSION < 5 || i != 0) + { + as_bad (_("unassigned file number %ld"), (long) i); +@@ -2427,8 +2444,7 @@ out_debug_abbrev (segT abbrev_seg, + if (DWARF2_VERSION < 4) + out_abbrev (DW_AT_high_pc, DW_FORM_addr); + else +- out_abbrev (DW_AT_high_pc, (sizeof_address == 4 +- ? DW_FORM_data4 : DW_FORM_data8)); ++ out_abbrev (DW_AT_high_pc, DW_FORM_udata); + } + else + { +@@ -2464,12 +2480,26 @@ out_debug_info (segT info_seg, segT abbr + /* DWARF version. */ + out_two (DWARF2_VERSION); + +- /* .debug_abbrev offset */ +- TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); ++ if (DWARF2_VERSION < 5) ++ { ++ /* .debug_abbrev offset */ ++ TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); ++ } ++ else ++ { ++ /* unit (header) type */ ++ out_byte (DW_UT_compile); ++ } + + /* Target address size. */ + out_byte (sizeof_address); + ++ if (DWARF2_VERSION >= 5) ++ { ++ /* .debug_abbrev offset */ ++ TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); ++ } ++ + /* DW_TAG_compile_unit DIE abbrev */ + out_uleb128 (1); + +@@ -2497,7 +2527,10 @@ out_debug_info (segT info_seg, segT abbr + } + exp.X_add_symbol = all_segs->text_end; + exp.X_add_number = 0; +- emit_expr (&exp, sizeof_address); ++ if (DWARF2_VERSION < 4) ++ emit_expr (&exp, sizeof_address); ++ else ++ emit_leb128_expr (&exp, 0); + } + else + { +diff -rup binutils.orig/gas/read.c binutils-2.35/gas/read.c +--- binutils.orig/gas/read.c 2020-08-25 15:40:47.251222391 +0100 ++++ binutils-2.35/gas/read.c 2020-08-25 15:41:44.776859141 +0100 +@@ -5138,7 +5138,7 @@ output_big_leb128 (char *p, LITTLENUM_TY + /* Generate the appropriate fragments for a given expression to emit a + leb128 value. SIGN is 1 for sleb, 0 for uleb. */ + +-static void ++void + emit_leb128_expr (expressionS *exp, int sign) + { + operatorT op = exp->X_op; +diff -rup binutils.orig/gas/read.h binutils-2.35/gas/read.h +--- binutils.orig/gas/read.h 2020-08-25 15:40:47.618220074 +0100 ++++ binutils-2.35/gas/read.h 2020-08-25 15:41:44.776859141 +0100 +@@ -132,6 +132,7 @@ extern void emit_expr_with_reloc (expres + TC_PARSE_CONS_RETURN_TYPE); + extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *, + TC_PARSE_CONS_RETURN_TYPE); ++extern void emit_leb128_expr (expressionS *, int); + extern void equals (char *, int); + extern void float_cons (int); + extern void ignore_rest_of_line (void); +diff -rup binutils.orig/gas/testsuite/gas/elf/elf.exp binutils-2.35/gas/testsuite/gas/elf/elf.exp +--- binutils.orig/gas/testsuite/gas/elf/elf.exp 2020-08-25 15:40:47.343221810 +0100 ++++ binutils-2.35/gas/testsuite/gas/elf/elf.exp 2020-08-25 15:41:25.841978707 +0100 +@@ -274,6 +274,8 @@ if { [is_elf_format] } then { + run_dump_test "dwarf2-18" $dump_opts + run_dump_test "dwarf2-19" $dump_opts + run_dump_test "dwarf-5-file0" $dump_opts ++ run_dump_test "dwarf-4-cu" $dump_opts ++ run_dump_test "dwarf-5-cu" $dump_opts + run_dump_test "pr25917" + run_dump_test "bss" + run_dump_test "bad-bss" +--- /dev/null 2020-08-25 08:24:40.895324651 +0100 ++++ binutils-2.35/gas/testsuite/gas/elf/dwarf-4-cu.s 2020-08-25 15:41:25.841978707 +0100 +@@ -0,0 +1,14 @@ ++ .text ++ .file 1 "foo/bar.s" ++ .loc_mark_labels 1 ++ .globl foobar ++ .type foobar, %function ++foobar: ++ .quad 0x1 ++ .size foobar, .-foobar ++ ++ .globl baz ++ .type baz, %function ++baz: ++ .quad 0x1 ++ .size baz, .-baz +--- /dev/null 2020-08-25 08:24:40.895324651 +0100 ++++ binutils-2.35/gas/testsuite/gas/elf/dwarf-4-cu.d 2020-08-25 15:41:25.841978707 +0100 +@@ -0,0 +1,11 @@ ++#as: --gdwarf-4 ++#name: DWARF4 CU ++#readelf: -wi ++ ++#... ++ Compilation Unit @ offset 0x0: ++ Length: 0x.* ++ Version: 4 ++ Abbrev Offset: 0x0 ++ Pointer Size: . ++#pass +--- /dev/null 2020-08-25 08:24:40.895324651 +0100 ++++ binutils-2.35/gas/testsuite/gas/elf/dwarf-5-cu.d 2020-08-25 15:41:25.841978707 +0100 +@@ -0,0 +1,11 @@ ++#as: --gdwarf-5 ++#name: DWARF5 CU ++#readelf: -wi ++ ++#... ++ Compilation Unit @ offset 0x0: ++ Length: 0x.* ++ Version: 5 ++ Abbrev Offset: 0x0 ++ Pointer Size: . ++#pass +--- /dev/null 2020-08-25 08:24:40.895324651 +0100 ++++ binutils-2.35/gas/testsuite/gas/elf/dwarf-5-cu.s 2020-08-25 15:41:25.841978707 +0100 +@@ -0,0 +1,14 @@ ++ .text ++ .file 1 "foo/bar.s" ++ .loc_mark_labels 1 ++ .globl foobar ++ .type foobar, %function ++foobar: ++ .quad 0x1 ++ .size foobar, .-foobar ++ ++ .globl baz ++ .type baz, %function ++baz: ++ .quad 0x1 ++ .size baz, .-baz diff --git a/binutils.spec b/binutils.spec index 4c20fcf..81e8389 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.35 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ URL: https://sourceware.org/binutils @@ -241,6 +241,10 @@ Patch26: binutils-elf-add-objects.patch # Lifetime: Fixed in 2.36 Patch27: binutils-ppc-rename-xvcvbf16sp-to-xvcvbf16spn.patch +# Purpose: Fixes for handling DWARF-5 debug information. +# Lifetime: Fixed in 2.36 +Patch28: binutils-dwarf-5-fixes.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -814,6 +818,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Tue Aug 25 2020 Nick Clifton - 2.35-12 +- Import fixes from GNU binutils mainline for handling DWARF-5 debug information. + * Mon Aug 24 2020 Nick Clifton - 2.35-11 - Rename the PPC xvcvbf16sp instruction to xvcvbf16spn.