|
|
0b07f1 |
commit 49fced1206db40c71208c201165d65f92c69cebe
|
|
|
0b07f1 |
Author: Mark Wielaard <mark@klomp.org>
|
|
|
0b07f1 |
Date: Sun Mar 5 23:37:54 2017 +0100
|
|
|
0b07f1 |
|
|
|
0b07f1 |
gas: Emit name, comp_dir and producer strings in .debug_str.
|
|
|
0b07f1 |
|
|
|
0b07f1 |
Putting the name, comp_dir and producer strings in the .debug_str section
|
|
|
0b07f1 |
makes it possible to share them across CUs. This saves a small amount of
|
|
|
0b07f1 |
space (about ~20K on a glibc libc.so.6 build with debuginfo). And makes
|
|
|
0b07f1 |
it easier for tools like rpm debugedit to adjust the source paths when
|
|
|
0b07f1 |
generating separate debuginfo files.
|
|
|
0b07f1 |
|
|
|
0b07f1 |
gas/
|
|
|
0b07f1 |
* dwarf2dbg.c (out_debug_abbrev): Use DW_FORM_strp instead of
|
|
|
0b07f1 |
DW_FORM_string for DW_AT_name, DW_AT_comp_dir and DW_AT_producer.
|
|
|
0b07f1 |
(out_debug_info): Accept symbols to name, comp_dir and producer
|
|
|
0b07f1 |
in the .debug_str section and emit those offsets not full strings.
|
|
|
0b07f1 |
(out_debug_str): New function that outputs the strings for name,
|
|
|
0b07f1 |
comp_dir and producer in .debug_str and generates symbols to
|
|
|
0b07f1 |
those strings.
|
|
|
0b07f1 |
(out_debug_line): Create a .debug_str section if necessary and
|
|
|
0b07f1 |
call out_debug_str before calling out_debug_info.
|
|
|
0b07f1 |
* testsuite/gas/aarch64/dwarf.d: Add extra section symbol to
|
|
|
0b07f1 |
expected output.
|
|
|
0b07f1 |
|
|
|
0b07f1 |
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
|
|
|
0b07f1 |
index 4bb658b..e02b6e8 100644
|
|
|
0b07f1 |
--- a/gas/dwarf2dbg.c
|
|
|
0b07f1 |
+++ b/gas/dwarf2dbg.c
|
|
|
0b07f1 |
@@ -1726,9 +1726,9 @@ out_debug_abbrev (segT abbrev_seg,
|
|
|
0b07f1 |
else
|
|
|
0b07f1 |
out_abbrev (DW_AT_ranges, DW_FORM_data8);
|
|
|
0b07f1 |
}
|
|
|
0b07f1 |
- out_abbrev (DW_AT_name, DW_FORM_string);
|
|
|
0b07f1 |
- out_abbrev (DW_AT_comp_dir, DW_FORM_string);
|
|
|
0b07f1 |
- out_abbrev (DW_AT_producer, DW_FORM_string);
|
|
|
0b07f1 |
+ out_abbrev (DW_AT_name, DW_FORM_strp);
|
|
|
0b07f1 |
+ out_abbrev (DW_AT_comp_dir, DW_FORM_strp);
|
|
|
0b07f1 |
+ out_abbrev (DW_AT_producer, DW_FORM_strp);
|
|
|
0b07f1 |
out_abbrev (DW_AT_language, DW_FORM_data2);
|
|
|
0b07f1 |
out_abbrev (0, 0);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
@@ -1739,15 +1739,11 @@ out_debug_abbrev (segT abbrev_seg,
|
|
|
0b07f1 |
/* Emit a description of this compilation unit for .debug_info. */
|
|
|
0b07f1 |
|
|
|
0b07f1 |
static void
|
|
|
0b07f1 |
-out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
|
|
|
0b07f1 |
+out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg,
|
|
|
0b07f1 |
+ symbolS *name_sym, symbolS *comp_dir_sym, symbolS *producer_sym)
|
|
|
0b07f1 |
{
|
|
|
0b07f1 |
- char producer[128];
|
|
|
0b07f1 |
- const char *comp_dir;
|
|
|
0b07f1 |
- const char *dirname;
|
|
|
0b07f1 |
expressionS exp;
|
|
|
0b07f1 |
symbolS *info_end;
|
|
|
0b07f1 |
- char *p;
|
|
|
0b07f1 |
- int len;
|
|
|
0b07f1 |
int sizeof_offset;
|
|
|
0b07f1 |
|
|
|
0b07f1 |
sizeof_offset = out_header (info_seg, &exp);
|
|
|
0b07f1 |
@@ -1798,10 +1794,38 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
|
|
|
0b07f1 |
TC_DWARF2_EMIT_OFFSET (section_symbol (ranges_seg), sizeof_offset);
|
|
|
0b07f1 |
}
|
|
|
0b07f1 |
|
|
|
0b07f1 |
+ /* DW_AT_name, DW_AT_comp_dir and DW_AT_producer. Symbols in .debug_str
|
|
|
0b07f1 |
+ setup in out_debug_str below. */
|
|
|
0b07f1 |
+ TC_DWARF2_EMIT_OFFSET (name_sym, sizeof_offset);
|
|
|
0b07f1 |
+ TC_DWARF2_EMIT_OFFSET (comp_dir_sym, sizeof_offset);
|
|
|
0b07f1 |
+ TC_DWARF2_EMIT_OFFSET (producer_sym, sizeof_offset);
|
|
|
0b07f1 |
+
|
|
|
0b07f1 |
+ /* DW_AT_language. Yes, this is probably not really MIPS, but the
|
|
|
0b07f1 |
+ dwarf2 draft has no standard code for assembler. */
|
|
|
0b07f1 |
+ out_two (DW_LANG_Mips_Assembler);
|
|
|
0b07f1 |
+
|
|
|
0b07f1 |
+ symbol_set_value_now (info_end);
|
|
|
0b07f1 |
+}
|
|
|
0b07f1 |
+
|
|
|
0b07f1 |
+/* Emit the three debug strings needed in .debug_str and setup symbols
|
|
|
0b07f1 |
+ to them for use in out_debug_info. */
|
|
|
0b07f1 |
+static void
|
|
|
0b07f1 |
+out_debug_str (segT str_seg, symbolS **name_sym, symbolS **comp_dir_sym,
|
|
|
0b07f1 |
+ symbolS **producer_sym)
|
|
|
0b07f1 |
+{
|
|
|
0b07f1 |
+ char producer[128];
|
|
|
0b07f1 |
+ const char *comp_dir;
|
|
|
0b07f1 |
+ const char *dirname;
|
|
|
0b07f1 |
+ char *p;
|
|
|
0b07f1 |
+ int len;
|
|
|
0b07f1 |
+
|
|
|
0b07f1 |
+ subseg_set (str_seg, 0);
|
|
|
0b07f1 |
+
|
|
|
0b07f1 |
/* DW_AT_name. We don't have the actual file name that was present
|
|
|
0b07f1 |
on the command line, so assume files[1] is the main input file.
|
|
|
0b07f1 |
We're not supposed to get called unless at least one line number
|
|
|
0b07f1 |
entry was emitted, so this should always be defined. */
|
|
|
0b07f1 |
+ *name_sym = symbol_temp_new_now ();
|
|
|
0b07f1 |
if (files_in_use == 0)
|
|
|
0b07f1 |
abort ();
|
|
|
0b07f1 |
if (files[1].dir)
|
|
|
0b07f1 |
@@ -1823,22 +1847,18 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
|
|
|
0b07f1 |
memcpy (p, files[1].filename, len);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
/* DW_AT_comp_dir */
|
|
|
0b07f1 |
+ *comp_dir_sym = symbol_temp_new_now ();
|
|
|
0b07f1 |
comp_dir = remap_debug_filename (getpwd ());
|
|
|
0b07f1 |
len = strlen (comp_dir) + 1;
|
|
|
0b07f1 |
p = frag_more (len);
|
|
|
0b07f1 |
memcpy (p, comp_dir, len);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
/* DW_AT_producer */
|
|
|
0b07f1 |
+ *producer_sym = symbol_temp_new_now ();
|
|
|
0b07f1 |
sprintf (producer, "GNU AS %s", VERSION);
|
|
|
0b07f1 |
len = strlen (producer) + 1;
|
|
|
0b07f1 |
p = frag_more (len);
|
|
|
0b07f1 |
memcpy (p, producer, len);
|
|
|
0b07f1 |
-
|
|
|
0b07f1 |
- /* DW_AT_language. Yes, this is probably not really MIPS, but the
|
|
|
0b07f1 |
- dwarf2 draft has no standard code for assembler. */
|
|
|
0b07f1 |
- out_two (DW_LANG_Mips_Assembler);
|
|
|
0b07f1 |
-
|
|
|
0b07f1 |
- symbol_set_value_now (info_end);
|
|
|
0b07f1 |
}
|
|
|
0b07f1 |
|
|
|
0b07f1 |
void
|
|
|
0b07f1 |
@@ -1907,19 +1927,22 @@ dwarf2_finish (void)
|
|
|
0b07f1 |
out_debug_line (line_seg);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
/* If this is assembler generated line info, and there is no
|
|
|
0b07f1 |
- debug_info already, we need .debug_info and .debug_abbrev
|
|
|
0b07f1 |
- sections as well. */
|
|
|
0b07f1 |
+ debug_info already, we need .debug_info, .debug_abbrev and
|
|
|
0b07f1 |
+ .debug_str sections as well. */
|
|
|
0b07f1 |
if (emit_other_sections)
|
|
|
0b07f1 |
{
|
|
|
0b07f1 |
segT abbrev_seg;
|
|
|
0b07f1 |
segT aranges_seg;
|
|
|
0b07f1 |
segT ranges_seg;
|
|
|
0b07f1 |
+ segT str_seg;
|
|
|
0b07f1 |
+ symbolS *name_sym, *comp_dir_sym, *producer_sym;
|
|
|
0b07f1 |
|
|
|
0b07f1 |
gas_assert (all_segs);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
info_seg = subseg_new (".debug_info", 0);
|
|
|
0b07f1 |
abbrev_seg = subseg_new (".debug_abbrev", 0);
|
|
|
0b07f1 |
aranges_seg = subseg_new (".debug_aranges", 0);
|
|
|
0b07f1 |
+ str_seg = subseg_new (".debug_str", 0);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
bfd_set_section_flags (stdoutput, info_seg,
|
|
|
0b07f1 |
SEC_READONLY | SEC_DEBUGGING);
|
|
|
0b07f1 |
@@ -1927,6 +1950,10 @@ dwarf2_finish (void)
|
|
|
0b07f1 |
SEC_READONLY | SEC_DEBUGGING);
|
|
|
0b07f1 |
bfd_set_section_flags (stdoutput, aranges_seg,
|
|
|
0b07f1 |
SEC_READONLY | SEC_DEBUGGING);
|
|
|
0b07f1 |
+ bfd_set_section_flags (stdoutput, str_seg,
|
|
|
0b07f1 |
+ (SEC_READONLY | SEC_DEBUGGING
|
|
|
0b07f1 |
+ | SEC_MERGE | SEC_STRINGS));
|
|
|
0b07f1 |
+ str_seg->entsize = 1;
|
|
|
0b07f1 |
|
|
|
0b07f1 |
record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1);
|
|
|
0b07f1 |
|
|
|
0b07f1 |
@@ -1943,6 +1970,8 @@ dwarf2_finish (void)
|
|
|
0b07f1 |
|
|
|
0b07f1 |
out_debug_aranges (aranges_seg, info_seg);
|
|
|
0b07f1 |
out_debug_abbrev (abbrev_seg, info_seg, line_seg);
|
|
|
0b07f1 |
- out_debug_info (info_seg, abbrev_seg, line_seg, ranges_seg);
|
|
|
0b07f1 |
+ out_debug_str (str_seg, &name_sym, &comp_dir_sym, &producer_sym);
|
|
|
0b07f1 |
+ out_debug_info (info_seg, abbrev_seg, line_seg, ranges_seg,
|
|
|
0b07f1 |
+ name_sym, comp_dir_sym, producer_sym);
|
|
|
0b07f1 |
}
|
|
|
0b07f1 |
}
|
|
|
0b07f1 |
diff --git a/gas/testsuite/gas/aarch64/dwarf.d b/gas/testsuite/gas/aarch64/dwarf.d
|
|
|
0b07f1 |
index 005f1d5..2a75e0b 100644
|
|
|
0b07f1 |
--- a/gas/testsuite/gas/aarch64/dwarf.d
|
|
|
0b07f1 |
+++ b/gas/testsuite/gas/aarch64/dwarf.d
|
|
|
0b07f1 |
@@ -1,7 +1,7 @@
|
|
|
0b07f1 |
#readelf: -s --debug-dump=aranges
|
|
|
0b07f1 |
#as: -g
|
|
|
0b07f1 |
|
|
|
0b07f1 |
-Symbol table '.symtab' contains 10 entries:
|
|
|
0b07f1 |
+Symbol table '.symtab' contains 11 entries:
|
|
|
0b07f1 |
Num:[ ]+Value[ ]+Size[ ]+Type[ ]+Bind[ ]+Vis[ ]+Ndx[ ]+Name
|
|
|
0b07f1 |
0: 0+ 0 NOTYPE LOCAL DEFAULT UND[ ]+
|
|
|
0b07f1 |
1: 0+ 0 SECTION LOCAL DEFAULT 1[ ]+
|
|
|
0b07f1 |
@@ -11,8 +11,9 @@ Symbol table '.symtab' contains 10 entries:
|
|
|
0b07f1 |
5: 0+ 0 SECTION LOCAL DEFAULT 6[ ]+
|
|
|
0b07f1 |
6: 0+ 0 SECTION LOCAL DEFAULT 8[ ]+
|
|
|
0b07f1 |
7: 0+ 0 SECTION LOCAL DEFAULT 4[ ]+
|
|
|
0b07f1 |
- 8: 0+ 0 SECTION LOCAL DEFAULT 9[ ]+
|
|
|
0b07f1 |
- 9: 0+ 8 FUNC GLOBAL DEFAULT 1 testfunc
|
|
|
0b07f1 |
+ 8: 0+ 0 SECTION LOCAL DEFAULT 11[ ]+
|
|
|
0b07f1 |
+ 9: 0+ 0 SECTION LOCAL DEFAULT 9[ ]+
|
|
|
0b07f1 |
+ 10: 0+ 8 FUNC GLOBAL DEFAULT 1 testfunc
|
|
|
0b07f1 |
Contents of the .debug_aranges section:
|
|
|
0b07f1 |
|
|
|
0b07f1 |
Length: (44|28)
|
|
|
0b07f1 |
--- binutils.orig/gas/config/tc-s390.c 2017-07-19 17:04:18.038524453 +0100
|
|
|
0b07f1 |
+++ binutils-2.28/gas/config/tc-s390.c 2017-07-19 17:04:46.117211159 +0100
|
|
|
0b07f1 |
@@ -2135,8 +2135,9 @@ md_pcrel_from_section (fixS *fixp, segT
|
|
|
0b07f1 |
int
|
|
|
0b07f1 |
tc_s390_fix_adjustable (fixS *fixP)
|
|
|
0b07f1 |
{
|
|
|
0b07f1 |
- /* Don't adjust references to merge sections. */
|
|
|
0b07f1 |
- if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
|
|
|
0b07f1 |
+ /* Don't adjust pc-relative references to merge sections. */
|
|
|
0b07f1 |
+ if (fixP->fx_pcrel
|
|
|
0b07f1 |
+ && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
|
|
|
0b07f1 |
return 0;
|
|
|
0b07f1 |
/* adjust_reloc_syms doesn't know about the GOT. */
|
|
|
0b07f1 |
if ( fixP->fx_r_type == BFD_RELOC_16_GOTOFF
|