new file mode 100644
@@ -0,0 +1,7 @@
+{
+ "files.associations": {
+ "*.ejs": "html",
+ "C": ".c",
+ "p418.C": "cpp"
+ }
+}
\ No newline at end of file
@@ -418,6 +418,16 @@ struct fixed_point_type_info
struct { tree numerator; tree denominator; } arbitrary;
} scale_factor;
};
+/*Struct to hold compilation unit header need for .debug_info*/
+typedef struct dw_cu_header_struct
+{
+ uint32_t length;
+ uint16_t version;
+ uint8_t unit_type;
+ uint8_t address_size;
+ uint32_t debug_abbrev_offset;
+}
+dw_cu_header;
void dwarf2cfi_cc_finalize (void);
void dwarf2out_cc_finalize (void);
@@ -823,13 +823,6 @@ lhd_begin_section (const char *name)
if (flag_bypass_asm)
{
- static int initialized = false;
- if (!initialized)
- {
- gcc_assert (asm_out_file == NULL);
- lto_set_current_out_file (lto_obj_file_open (asm_file_name,
true));
- initialized = true;
- }
lto_obj_begin_section (name);
return;
}
--
2.42.0
From 284dc60ed2272eb60f7de1e188c92d1cac750d61 Mon Sep 17 00:00:00 2001
From: Rishi Raj <rishiraj45035@gmail.com>
Date: Mon, 23 Oct 2023 06:24:16 +0530
Subject: [PATCH 3/3] Extended dwarf2out.cc to output the .debug_line and
.debug_info relocations
Signed-off-by: Rishi Raj <rishiraj45035@gmail.com>
---
gcc/dwarf2out.cc | 1583 ++++++++++++++++++++++++++++++---------------
gcc/lto-object.cc | 2 +-
2 files changed, 1067 insertions(+), 518 deletions(-)
@@ -103,6 +103,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple.h"
#include "lto-streamer.h"
+#include "simple-object.h"
+
static void dwarf2out_source_line (unsigned int, unsigned int, const char
*,
int, bool);
@@ -2597,7 +2599,6 @@ output_loc_sequence (dw_loc_descr_ref loc, int
for_eh_or_skip)
/* Output location description stack opcode's operands (if any).
The output is single bytes on a line, suitable for .cfi_escape. */
-
static void
output_loc_operands_raw (dw_loc_descr_ref loc)
{
@@ -2652,7 +2653,7 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
offset = val1->v.val_loc->dw_loc_addr - (loc->dw_loc_addr + 3);
fputc (',', asm_out_file);
- dw2_asm_output_data_raw (2, offset);
+ dw2_asm_output_data_raw (2, offset);
}
break;
@@ -2774,7 +2775,7 @@ output_loc_sequence_raw (dw_loc_descr_ref loc)
gcc_assert (r <= 31);
opc = (enum dwarf_location_atom) (DW_OP_reg0 + r);
}
- /* Output the opcode. */
+ /* Output the opcode. */
fprintf (asm_out_file, "%#x", opc);
output_loc_operands_raw (loc);
@@ -4019,6 +4020,28 @@ static const char *comp_dir_string (void);
static void hash_loc_operands (dw_loc_descr_ref, inchash::hash &);
+/* object file output ( -fbypass-asm ) helper function */
+static size_t output_data_to_object_file(size_t size, unsigned
HOST_WIDE_INT value);
+static size_t output_data_uleb128_to_object_file(unsigned HOST_WIDE_INT
value);
+static size_t output_data_sleb128_to_object_file(HOST_WIDE_INT value);
+static size_t output_nstring_to_object_file(const char *str, size_t
orig_len);
+static size_t output_value_format_to_object_file (dw_attr_node *a);
+static void output_die_to_object_file (dw_die_ref die);
+static void output_die_abbrevs_to_object_file(unsigned long abbrev_id,
dw_die_ref abbrev);
+static void output_abbrev_section_to_object_file (void);
+static inline size_t output_discr_value_to_object_file (dw_discr_value
*discr_value, const char *name);
+static void output_compilation_unit_header_to_object_file(enum
dwarf_unit_type ut);
+static void output_comp_unit_to_object_file (dw_die_ref die, int
output_if_empty, const unsigned char *dwo_id);
+static void output_line_info_to_object_file (bool prologue_only);
+static void output_indirect_strings_to_object_file (void);
+static void output_line_string_to_object_file (enum dwarf_form form, const
char *str, const char *entry_kind, unsigned int idx);
+static void output_file_names_to_object_file (void);
+static void modify_buffer_of_object_file (unsigned long offset, size_t
size, HOST_WIDE_INT value)
+
+
+
+
+
/* enum for tracking thread-local variables whose address is really an
offset
relative to the TLS pointer, which will need link-time relocation, but
will
not need relocation by the DWARF consumer. */
@@ -10153,6 +10176,15 @@ output_value_format (dw_attr_node *a)
dw2_asm_output_data_uleb128 (form, "(%s)", dwarf_form_name (form));
}
+static size_t
+output_value_format_to_object_file (dw_attr_node *a)
+{
+ enum dwarf_form form = value_format (a);
+
+ return output_data_uleb128_to_object_file(form);
+
+}
+
/* Given a die and id, produce the appropriate abbreviations. */
static void
@@ -10192,6 +10224,44 @@ output_die_abbrevs (unsigned long abbrev_id,
dw_die_ref abbrev)
dw2_asm_output_data (1, 0, NULL);
}
+/* Given a die and id, produce the appropriate abbreviations
+ directly to lto object file */
+
+static void
+output_die_abbrevs_to_object_file(unsigned long abbrev_id, dw_die_ref
abbrev)
+{
+ unsigned ix;
+ dw_attr_node *a_attr;
+
+ output_data_uleb128_to_object_file(abbrev_id);
+ output_data_uleb128_to_object_file(abbrev->die_tag);
+
+
+ if (abbrev->die_child != NULL)
+ output_data_to_object_file(1,DW_children_yes);
+ else
+ output_data_to_object_file(1,DW_children_no);
+
+ for (ix = 0; vec_safe_iterate (abbrev->die_attr, ix, &a_attr); ix++)
+ {
+ output_data_uleb128_to_object_file(a_attr->dw_attr);
+ output_value_format_to_object_file(a_attr);
+ if (value_format (a_attr) == DW_FORM_implicit_const)
+ {
+ if (AT_class (a_attr) == dw_val_class_file_implicit)
+ {
+ int f = maybe_emit_file (a_attr->dw_attr_val.v.val_file);
+ output_data_sleb128_to_object_file(f);
+ }
+ else
+ output_data_sleb128_to_object_file(a_attr->dw_attr_val.v.val_int);
+ }
+ }
+
+ output_data_to_object_file (1, 0);
+ output_data_to_object_file (1, 0);
+}
+
/* Output the .debug_abbrev section which defines the DIE abbreviation
table. */
@@ -10211,28 +10281,58 @@ output_abbrev_section (void)
}
static void
-output_data_to_object_file(int size, unsigned HOST_WIDE_INT value)
+output_abbrev_section_to_object_file (void)
{
+ lto_obj_begin_section(".gnu.debuglto_.debug_abbrev");
+ unsigned int abbrev_id;
+ dw_die_ref abbrev;
+ FOR_EACH_VEC_SAFE_ELT (abbrev_die_table, abbrev_id, abbrev)
+ if (abbrev_id != 0)
+ output_die_abbrevs_to_object_file (abbrev_id, abbrev);
- char *buff=XNEWVEC(char,size);
+ /* Terminate the table. */
+ output_data_to_object_file (1, 0);
+ lto_obj_end_section();
- //handle little endian vs big endian. right now assuming little endian
- for(int i=size-1;i>=0;i--)
- {
- buff[i] = value & 0xFF;
- value >>= 8;
- }
+}
- void *v;
+/* Helper function to output a value of given size to object file */
+static size_t
+output_data_to_object_file(size_t size, unsigned HOST_WIDE_INT value)
+{
+ unsigned char bytes[8];
+ unsigned int i;
+ unsigned char *buff = XNEWVEC(unsigned char, size);
+ for (i = 0; i < 8; ++i)
+ {
+ bytes[i] = value & 0xff;
+ value >>= 8;
+ }
+ if (BYTES_BIG_ENDIAN)
+ {
+ for (i = size - 1; i >= 0; --i)
+ buff[i] = bytes[i];
+ }
+ else
+ {
+ for (i = 0; i <= size - 1; ++i)
+ buff[i] = bytes[i];
+ }
+
+ void *v = NULL;
lto_obj_append_data((const void *) buff, size, v);
+
+ return size;
}
-static void
+/* Helper function to output a uleb128 to object file */
+static size_t
output_data_uleb128_to_object_file(unsigned HOST_WIDE_INT value)
{
- int size=0, temp_value=value;
+ size_t size=0;
+ unsigned HOST_WIDE_INT temp_value=value;
//find the size of uleb128 data
while(temp_value)
@@ -10241,9 +10341,9 @@ output_data_uleb128_to_object_file(unsigned
HOST_WIDE_INT value)
size++;
}
- char *buff=XNEWVEC(char,size);
+ unsigned char *buff=XNEWVEC(unsigned char,size);
- for(int i=0;i<size;i++)
+ for(size_t i=0;i<size;i++)
{
int byte = (value & 0x7f);
value >>= 7;
@@ -10253,31 +10353,37 @@ output_data_uleb128_to_object_file(unsigned
HOST_WIDE_INT value)
buff[i]=byte;
}
- void *v;
+ void *v=NULL;
lto_obj_append_data((const void *) buff, size, v);
+ return size;
}
-static void
-output_data_sleb128_to_object_file(unsigned HOST_WIDE_INT value)
+ /* Helper function to output sleb128 to object file*/
+static size_t
+output_data_sleb128_to_object_file(HOST_WIDE_INT value)
{
- int size=0, temp_value=value,more;
+ size_t size=0;
+ HOST_WIDE_INT temp_value=value;
+ int byte, more;
//find the size of sleb128 data
while(1)
{
- int byte = (value & 0x7f);
- temp_value>>=7;
+ byte = (temp_value & 0x7f);
+ temp_value >>= 7;
size++;
- more = !((value == 0 && (byte & 0x40) == 0)
- || (value == -1 && (byte & 0x40) != 0));
+ more = !((temp_value == 0 && (byte & 0x40) == 0)
+ || (temp_value == -1 && (byte & 0x40) != 0));
+ if (more)
+ byte |= 0x80;
if(!more) break;
}
- char *buff=XNEWVEC(char,size);
+ unsigned char *buff=XNEWVEC(unsigned char,size);
- for(int i=0;i<size;i++)
+ for(size_t i=0;i<size;i++)
{
- int byte = (value & 0x7f);
+ byte = (value & 0x7f);
value >>= 7;
more = !((value == 0 && (byte & 0x40) == 0)
|| (value == -1 && (byte & 0x40) != 0));
@@ -10288,84 +10394,22 @@ output_data_sleb128_to_object_file(unsigned
HOST_WIDE_INT value)
buff[i]=byte;
}
- void *v;
+ void *v=NULL;
lto_obj_append_data((const void *) buff, size, v);
-}
-static void
-output_value_format_to_object_file (dw_attr_node *a)
-{
- enum dwarf_form form = value_format (a);
-
- output_data_uleb128_to_object_file(form);
- // dw2_asm_output_data_uleb128 (form, "(%s)", dwarf_form_name (form));
+ return size;
}
-/* Given a die and id, produce the appropriate abbreviations
-directly to lto object file */
-
-static void
-output_die_abbrevs_to_object_file(unsigned long abbrev_id, dw_die_ref
abbrev)
+static size_t
+output_nstring_to_object_file(const char *str, size_t orig_len )
{
- unsigned ix;
- dw_attr_node *a_attr;
-
- // dw2_asm_output_data_uleb128 (abbrev_id, "(abbrev code)");
- // dw2_asm_output_data_uleb128 (abbrev->die_tag, "(TAG: %s)",
- // dwarf_tag_name (abbrev->die_tag));
- output_data_uleb128_to_object_file(abbrev_id);
- output_data_uleb128_to_object_file(abbrev->die_tag);
-
-
- if (abbrev->die_child != NULL)
- output_data_to_object_file(1,DW_children_yes);
- // dw2_asm_output_data (1, DW_children_yes, "DW_children_yes");
- else
- output_data_to_object_file(1,DW_children_no);
- // dw2_asm_output_data (1, DW_children_no, "DW_children_no");
-
- for (ix = 0; vec_safe_iterate (abbrev->die_attr, ix, &a_attr); ix++)
- {
- // dw2_asm_output_data_uleb128 (a_attr->dw_attr, "(%s)",
- // dwarf_attr_name (a_attr->dw_attr));
- output_data_uleb128_to_object_file(a_attr->dw_attr);
- // output_value_format (a_attr);
- output_value_format_to_object_file(a_attr);
- if (value_format (a_attr) == DW_FORM_implicit_const)
- {
- if (AT_class (a_attr) == dw_val_class_file_implicit)
- {
- int f = maybe_emit_file (a_attr->dw_attr_val.v.val_file);
- // const char *filename = a_attr->dw_attr_val.v.val_file->filename;
- // dw2_asm_output_data_sleb128 (f, "(%s)", filename);
- output_data_sleb128_to_object_file(f);
- }
- else
- output_data_sleb128_to_object_file(a_attr->dw_attr_val.v.val_int);
- // dw2_asm_output_data_sleb128 (a_attr->dw_attr_val.v.val_int, NULL);
- }
- }
-
- output_data_to_object_file (1, 0);
- output_data_to_object_file (1, 0);
+ if(orig_len == (size_t) -1)
+ orig_len=strlen(str)+1;
+ void *v_=NULL;
+ lto_obj_append_data((const void *)str,orig_len,v_);
+ return orig_len;
}
-static void
-output_abbrev_section_to_object_file (void)
-{
- lto_obj_begin_section(".gnu.debuglto_.debug_abbrev");
- unsigned int abbrev_id;
- dw_die_ref abbrev;
- FOR_EACH_VEC_SAFE_ELT (abbrev_die_table, abbrev_id, abbrev)
- if (abbrev_id != 0)
- output_die_abbrevs_to_object_file (abbrev_id, abbrev);
-
- /* Terminate the table. */
- output_data_to_object_file (1, 0);
- lto_obj_end_section();
-
-}
-
/* Return a new location list, given the begin and end range, and the
expression. */
@@ -10930,6 +10974,14 @@ output_discr_value (dw_discr_value *discr_value,
const char *name)
else
dw2_asm_output_data_sleb128 (discr_value->v.sval, "%s", name);
}
+static inline size_t
+output_discr_value_to_object_file (dw_discr_value *discr_value, const char
*name)
+{
+ if (discr_value->pos)
+ return output_data_uleb128_to_object_file (discr_value->v.uval);
+ else
+ return output_data_sleb128_to_object_file (discr_value->v.sval);
+}
/* Output the DIE and its attributes. Called recursively to generate
the definitions of each child DIE. */
@@ -11472,62 +11524,63 @@ output_compilation_unit_header (dwo_id
}
}
+struct lto_simple_object
+{
+ /* The base information. */
+ lto_file base;
+
+ /* The system file descriptor. */
+ int fd;
+
+ /* The simple_object if we are reading the file. */
+ simple_object_read *sobj_r;
+
+ /* The simple_object if we are writing the file. */
+ simple_object_write *sobj_w;
+
+ /* The currently active section. */
+ simple_object_write_section *section;
+};
+
static void
output_die_to_object_file (dw_die_ref die)
{
+ struct lto_simple_object *lo = (struct lto_simple_object *)
lto_get_current_out_file ();
+ static uint64_t debug_info_offset = sizeof(dw_cu_header); /* current
offset into .debug_info section */
+ static uint64_t debug_str_offset=0; /* Current Offset into .debug_line
*/
+ static uint64_t debug_line_str_offset=0; /* Current offset into
.debug_line_str */
dw_attr_node *a;
dw_die_ref c;
- unsigned long size;
unsigned ix;
- // dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s)",
- // (unsigned long)die->die_offset,
- // dwarf_tag_name (die->die_tag));
- //this outputs the abbreviation code for this die
-
- output_data_uleb128_to_object_file(die->die_abbrev);
- return; //as I haven't handled all of the possible cases below output
the abbrev code and return
+ debug_info_offset+=output_data_uleb128_to_object_file(die->die_abbrev);
-
- //ouput each attribute of this die
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
{
const char *name = dwarf_attr_name (a->dw_attr);
switch (AT_class (a))
- {
+{
case dw_val_class_addr:
- //TO DO: will have to first read about rtx type
- // dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, AT_addr (a), "%s",
name);
+ gcc_unreachable();
break;
case dw_val_class_offset:
- dw2_asm_output_data (dwarf_offset_size, a->dw_attr_val.v.val_offset,
- "%s", name);
+
debug_info_offset+=output_data_to_object_file(dwarf_offset_size,a->dw_attr_val.v.val_offset);
break;
case dw_val_class_range_list:
- // handle it later as We have to output this into a different section
- // output_range_list_offset (a);
+ gcc_unreachable();
break;
case dw_val_class_loc:
- size = size_of_locs (AT_loc (a));
-
- /* Output the block length for this list of location operations. */
- if (dwarf_version >= 4)
- dw2_asm_output_data_uleb128 (size, "%s", name);
- else
- dw2_asm_output_data (constant_size (size), size, "%s", name);
-
- output_loc_sequence (AT_loc (a), -1);
- break;
+ gcc_unreachable();
case dw_val_class_const:
/* ??? It would be slightly more efficient to use a scheme like is
used for unsigned constants below, but gdb 4.x does not sign
extend. Gdb 5.x does sign extend. */
- dw2_asm_output_data_sleb128 (AT_int (a), "%s", name);
+ debug_info_offset+=output_data_sleb128_to_object_file (AT_int (a));
break;
case dw_val_class_unsigned_const:
@@ -11536,40 +11589,21 @@ output_die_to_object_file (dw_die_ref die)
if (dwarf_version == 3
&& a->dw_attr == DW_AT_data_member_location
&& csize >= 4)
- dw2_asm_output_data_uleb128 (AT_unsigned (a), "%s", name);
+
debug_info_offset+=output_data_uleb128_to_object_file(AT_unsigned(a));
else
- dw2_asm_output_data (csize, AT_unsigned (a), "%s", name);
+
debug_info_offset+=output_data_to_object_file(csize,AT_unsigned(a));
}
break;
case dw_val_class_symview:
- {
- int vsize;
- if (symview_upper_bound <= 0xff)
- vsize = 1;
- else if (symview_upper_bound <= 0xffff)
- vsize = 2;
- else if (symview_upper_bound <= 0xffffffff)
- vsize = 4;
- else
- vsize = 8;
- dw2_asm_output_addr (vsize, a->dw_attr_val.v.val_symbolic_view,
- "%s", name);
- }
+ gcc_unreachable();
break;
case dw_val_class_const_implicit:
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t\t\t%s %s ("
- HOST_WIDE_INT_PRINT_DEC ")\n",
- ASM_COMMENT_START, name, AT_int (a));
+ gcc_unreachable();
break;
case dw_val_class_unsigned_const_implicit:
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t\t\t%s %s ("
- HOST_WIDE_INT_PRINT_HEX ")\n",
- ASM_COMMENT_START, name, AT_unsigned (a));
break;
case dw_val_class_const_double:
@@ -11577,10 +11611,9 @@ output_die_to_object_file (dw_die_ref die)
unsigned HOST_WIDE_INT first, second;
if (HOST_BITS_PER_WIDE_INT >= DWARF_LARGEST_DATA_FORM_BITS)
- dw2_asm_output_data (1,
+ debug_info_offset+=output_data_to_object_file (1,
HOST_BITS_PER_DOUBLE_INT
- / HOST_BITS_PER_CHAR,
- NULL);
+ / HOST_BITS_PER_CHAR);
if (WORDS_BIG_ENDIAN)
{
@@ -11593,10 +11626,10 @@ output_die_to_object_file (dw_die_ref die)
second = a->dw_attr_val.v.val_double.high;
}
- dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
- first, "%s", name);
- dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
- second, NULL);
+ debug_info_offset+=output_data_to_object_file
(HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
+ first);
+ debug_info_offset+=output_data_to_object_file
(HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
+ second);
}
break;
@@ -11606,21 +11639,20 @@ output_die_to_object_file (dw_die_ref die)
int len = get_full_len (*a->dw_attr_val.v.val_wide);
int l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
if (len * HOST_BITS_PER_WIDE_INT > DWARF_LARGEST_DATA_FORM_BITS)
- dw2_asm_output_data (1, get_full_len (*a->dw_attr_val.v.val_wide)
- * l, NULL);
+ debug_info_offset+=output_data_to_object_file (1, get_full_len
(*a->dw_attr_val.v.val_wide)
+ * l);
+
if (WORDS_BIG_ENDIAN)
for (i = len - 1; i >= 0; --i)
{
- dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i),
- "%s", name);
+ debug_info_offset+=output_data_to_object_file (l,
a->dw_attr_val.v.val_wide->elt (i));
name = "";
}
else
for (i = 0; i < len; ++i)
{
- dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i),
- "%s", name);
+ debug_info_offset+=output_data_to_object_file (l,
a->dw_attr_val.v.val_wide->elt (i));
name = "";
}
}
@@ -11633,8 +11665,8 @@ output_die_to_object_file (dw_die_ref die)
unsigned int i;
unsigned char *p;
- dw2_asm_output_data (constant_size (len * elt_size),
- len * elt_size, "%s", name);
+ debug_info_offset+=output_data_to_object_file (constant_size (len *
elt_size),
+ len * elt_size);
if (elt_size > sizeof (HOST_WIDE_INT))
{
elt_size /= 2;
@@ -11643,8 +11675,7 @@ output_die_to_object_file (dw_die_ref die)
for (i = 0, p = (unsigned char *) a->dw_attr_val.v.val_vec.array;
i < len;
i++, p += elt_size)
- dw2_asm_output_data (elt_size, extract_int (p, elt_size),
- "fp or vector constant word %u", i);
+ debug_info_offset+=output_data_to_object_file (elt_size,
extract_int (p, elt_size));
break;
}
@@ -11658,145 +11689,91 @@ output_die_to_object_file (dw_die_ref die)
DW_FORM_flag_present if it is set to 1 in all DIEs using
the same abbrev entry. */
gcc_assert (AT_flag (a) == 1);
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t\t\t%s %s\n",
- ASM_COMMENT_START, name);
break;
}
- dw2_asm_output_data (1, AT_flag (a), "%s", name);
+ debug_info_offset+=output_data_to_object_file (1, AT_flag (a));
break;
case dw_val_class_loc_list:
- output_loc_list_offset (a);
+ gcc_unreachable();
break;
case dw_val_class_view_list:
- output_view_list_offset (a);
+ gcc_unreachable();
break;
- case dw_val_class_die_ref:
- if (AT_ref_external (a))
+ case dw_val_class_die_ref: // have to output this
+ if (AT_ref_external (a))
{
- if (AT_ref (a)->comdat_type_p)
- {
- comdat_type_node *type_node
- = AT_ref (a)->die_id.die_type_node;
-
- gcc_assert (type_node);
- output_signature (type_node->signature, name);
- }
- else
- {
- const char *sym = AT_ref (a)->die_id.die_symbol;
- int size;
-
- gcc_assert (sym);
- /* In DWARF2, DW_FORM_ref_addr is sized by target address
- length, whereas in DWARF3 it's always sized as an
- offset. */
- if (dwarf_version == 2)
- size = DWARF2_ADDR_SIZE;
- else
- size = dwarf_offset_size;
- /* ??? We cannot unconditionally output die_offset if
- non-zero - others might create references to those
- DIEs via symbols.
- And we do not clear its DIE offset after outputting it
- (and the label refers to the actual DIEs, not the
- DWARF CU unit header which is when using label + offset
- would be the correct thing to do).
- ??? This is the reason for the with_offset flag. */
- if (AT_ref (a)->with_offset)
- dw2_asm_output_offset (size, sym, AT_ref (a)->die_offset,
- debug_info_section, "%s", name);
- else
- dw2_asm_output_offset (size, sym, debug_info_section, "%s",
- name);
- }
+ gcc_unreachable();
}
else
{
gcc_assert (AT_ref (a)->die_offset);
- dw2_asm_output_data (dwarf_offset_size, AT_ref (a)->die_offset,
- "%s", name);
+ debug_info_offset+=output_data_to_object_file (dwarf_offset_size,
AT_ref (a)->die_offset);
}
break;
case dw_val_class_fde_ref:
- {
- char l1[MAX_ARTIFICIAL_LABEL_BYTES];
-
- ASM_GENERATE_INTERNAL_LABEL (l1, FDE_LABEL,
- a->dw_attr_val.v.val_fde_index * 2);
- dw2_asm_output_offset (dwarf_offset_size, l1, debug_frame_section,
- "%s", name);
- }
+ gcc_unreachable();
break;
case dw_val_class_vms_delta:
-#ifdef ASM_OUTPUT_DWARF_VMS_DELTA
- dw2_asm_output_vms_delta (dwarf_offset_size,
- AT_vms_delta2 (a), AT_vms_delta1 (a),
- "%s", name);
-#else
- dw2_asm_output_delta (dwarf_offset_size,
- AT_vms_delta2 (a), AT_vms_delta1 (a),
- "%s", name);
-#endif
- break;
+ gcc_unreachable();
case dw_val_class_lbl_id:
- output_attr_index_or_value (a);
+ gcc_unreachable();
break;
- case dw_val_class_lineptr:
- dw2_asm_output_offset (dwarf_offset_size, AT_lbl (a),
- debug_line_section, "%s", name);
+ case dw_val_class_lineptr:
+ simple_object_write_add_relocation(lo->section, debug_info_offset, 0,
+ ".gnu.debuglto_.debug_line", 3);
+ debug_info_offset += output_data_to_object_file(dwarf_offset_size,0);
break;
case dw_val_class_macptr:
- dw2_asm_output_offset (dwarf_offset_size, AT_lbl (a),
- debug_macinfo_section, "%s", name);
+ gcc_unreachable();
break;
case dw_val_class_loclistsptr:
- dw2_asm_output_offset (dwarf_offset_size, AT_lbl (a),
- debug_loc_section, "%s", name);
+ gcc_unreachable();
break;
case dw_val_class_str:
- if (a->dw_attr_val.v.val_str->form == DW_FORM_strp)
- dw2_asm_output_offset (dwarf_offset_size,
- a->dw_attr_val.v.val_str->label,
- debug_str_section,
- "%s: \"%s\"", name, AT_string (a));
- else if (a->dw_attr_val.v.val_str->form == DW_FORM_line_strp)
- dw2_asm_output_offset (dwarf_offset_size,
- a->dw_attr_val.v.val_str->label,
- debug_line_str_section,
- "%s: \"%s\"", name, AT_string (a));
- else if (a->dw_attr_val.v.val_str->form == dwarf_FORM (DW_FORM_strx))
- dw2_asm_output_data_uleb128 (AT_index (a),
- "%s: \"%s\"", name, AT_string (a));
- else
- dw2_asm_output_nstring (AT_string (a), -1, "%s", name);
- break;
+ {
+ if (a->dw_attr_val.v.val_str->form == DW_FORM_strp)
+ {
+ simple_object_write_add_relocation(lo->section, debug_info_offset,
+ debug_str_offset, ".gnu.debuglto_.debug_str", 4);
+ debug_info_offset += output_data_to_object_file(dwarf_offset_size,
0);
+ debug_str_offset += strlen(a->dw_attr_val.v.val_str->str)+1;
+
+ }
+ else if (a->dw_attr_val.v.val_str->form == DW_FORM_line_strp)
+ {
+ simple_object_write_add_relocation(lo->section, debug_info_offset,
+ debug_line_str_offset,
".gnu.debuglto_.debug_line_str", 5);
+ debug_info_offset += output_data_to_object_file(dwarf_offset_size,
0);
+ debug_line_str_offset += strlen(a->dw_attr_val.v.val_str->str)+1;
+
+ }
+
+ else if (a->dw_attr_val.v.val_str->form == dwarf_FORM (DW_FORM_strx))
+ debug_info_offset+=output_data_uleb128_to_object_file (AT_index
(a));
+ else
+ debug_info_offset+=output_nstring_to_object_file (AT_string (a),
-1);
+ break;
+ }
case dw_val_class_file:
{
int f = maybe_emit_file (a->dw_attr_val.v.val_file);
- dw2_asm_output_data (constant_size (f), f, "%s (%s)", name,
- a->dw_attr_val.v.val_file->filename);
+ debug_info_offset+=output_data_to_object_file (constant_size (f), f);
break;
}
case dw_val_class_file_implicit:
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t\t\t%s %s (%d, %s)\n",
- ASM_COMMENT_START, name,
- maybe_emit_file (a->dw_attr_val.v.val_file),
- a->dw_attr_val.v.val_file->filename);
break;
case dw_val_class_data8:
@@ -11804,18 +11781,16 @@ output_die_to_object_file (dw_die_ref die)
int i;
for (i = 0; i < 8; i++)
- dw2_asm_output_data (1, a->dw_attr_val.v.val_data8[i],
- i == 0 ? "%s" : NULL, name);
+ debug_info_offset+=output_data_to_object_file (1,
a->dw_attr_val.v.val_data8[i]);
break;
}
case dw_val_class_high_pc:
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, AT_lbl (a),
- get_AT_low_pc (die), "DW_AT_high_pc");
+ gcc_unreachable();
break;
case dw_val_class_discr_value:
- output_discr_value (&a->dw_attr_val.v.val_discr_value, name);
+ debug_info_offset+=output_discr_value_to_object_file
(&a->dw_attr_val.v.val_discr_value, name);
break;
case dw_val_class_discr_list:
@@ -11824,23 +11799,22 @@ output_die_to_object_file (dw_die_ref die)
const int size = size_of_discr_list (list);
/* This is a block, so output its length first. */
- dw2_asm_output_data (constant_size (size), size,
- "%s: block size", name);
+
+ debug_info_offset+=output_data_to_object_file (constant_size
(size), size);
for (; list != NULL; list = list->dw_discr_next)
{
/* One byte for the discriminant value descriptor, and then as
many LEB128 numbers as required. */
if (list->dw_discr_range)
- dw2_asm_output_data (1, DW_DSC_range,
- "%s: DW_DSC_range", name);
+ debug_info_offset+=output_data_to_object_file (1, DW_DSC_range);
else
- dw2_asm_output_data (1, DW_DSC_label,
- "%s: DW_DSC_label", name);
+ debug_info_offset+=output_data_to_object_file (1, DW_DSC_label);
- output_discr_value (&list->dw_discr_lower_bound, name);
+ debug_info_offset+=output_discr_value_to_object_file
(&list->dw_discr_lower_bound, name);
if (list->dw_discr_range)
- output_discr_value (&list->dw_discr_upper_bound, name);
+ debug_info_offset+=output_discr_value_to_object_file
(&list->dw_discr_upper_bound, name);
+
}
break;
}
@@ -11853,15 +11827,16 @@ output_die_to_object_file (dw_die_ref die)
FOR_EACH_CHILD (die, c, output_die_to_object_file (c));
/* Add null byte to terminate sibling list. */
- // if (die->die_child != NULL)
- // dw2_asm_output_data (1, 0, "end of children of DIE %#lx",
- // (unsigned long) die->die_offset);
+ if (die->die_child != NULL)
+ debug_info_offset+=output_data_to_object_file(1,0);
}
-
static void
output_compilation_unit_header_to_object_file(enum dwarf_unit_type ut)
{
+ struct lto_simple_object *lo = (struct lto_simple_object *)
lto_get_current_out_file ();
+
lto_obj_begin_section(".gnu.debuglto_.debug_info");
+
dw_cu_header *cu_header;
cu_header = XNEW(dw_cu_header);
cu_header->length = next_die_offset - DWARF_INITIAL_LENGTH_SIZE;
@@ -11869,7 +11844,10 @@ output_compilation_unit_header_to_object_file(enum
dwarf_unit_type ut)
cu_header->unit_type = ut;
cu_header->address_size = DWARF2_ADDR_SIZE;
cu_header->debug_abbrev_offset = 0x0;
- void *v;
+
+ simple_object_write_add_relocation(lo->section, 8, 0,
+ ".gnu.debuglto_.debug_abbrev", 2);
+ void *v = NULL;
lto_obj_append_data((const void *)cu_header,sizeof(dw_cu_header),v);
}
@@ -11878,9 +11856,8 @@ static void
output_comp_unit_to_object_file (dw_die_ref die, int output_if_empty,
const unsigned char *dwo_id)
{
- const char *secname, *oldsym;
- char *tmp;
-
+ const char *oldsym;
+
/* Unless we are outputting main CU, we may throw away empty ones. */
if (!output_if_empty && die->die_child == NULL)
return;
@@ -11914,6 +11891,14 @@ output_comp_unit_to_object_file (dw_die_ref die,
int output_if_empty,
oldsym = die->die_id.die_symbol;
+ /* For LTO cross unit DIE refs we want a symbol on the start of the
+ debuginfo section, not on the CU DIE. */
+ if ((flag_generate_lto || flag_generate_offload) && oldsym)
+ {
+ struct lto_simple_object *lo = (struct lto_simple_object *)
lto_get_current_out_file ();
+ simple_object_write_add_symbol(lo->sobj_w, oldsym, 0, 0, 2, 0, 1,
2);
+ }
+
output_compilation_unit_header_to_object_file(dwo_id
? DW_UT_split_compile : DW_UT_compile);
output_die_to_object_file(die);
@@ -13156,8 +13141,8 @@ output_line_string (enum dwarf_form form, const
char *str,
/* Output the directory table and the file name table. We try to minimize
the total amount of memory needed. A heuristic is used to avoid large
- slowdowns with many input files. */
-
+ slowdowns with many input files. */
+
static void
output_file_names (void)
{
@@ -13493,229 +13478,783 @@ output_file_names (void)
snprintf (filebuf, maxfilelen, "%s;%d",
files[file_idx].path + dirs[dir_idx].length, ver);
- output_line_string (str_form, filebuf, "File Entry", (unsigned) i +
1);
+ output_line_string (str_form, filebuf, "File Entry", (unsigned) i +
1);
+
+ /* Include directory index. */
+ if (dwarf_version >= 5 && idx_form != DW_FORM_udata)
+ dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
+ dir_idx + idx_offset, NULL);
+ else
+ dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL);
+
+ /* Modification time. */
+ dw2_asm_output_data_uleb128 ((vms_file_stats_name
(files[file_idx].path,
+ &cdt, 0, 0, 0) == 0)
+ ? cdt : 0, NULL);
+
+ /* File length in bytes. */
+ dw2_asm_output_data_uleb128 ((vms_file_stats_name
(files[file_idx].path,
+ 0, &siz, 0, 0) == 0)
+ ? siz : 0, NULL);
+#else
+ output_line_string (str_form,
+ files[file_idx].path + dirs[dir_idx].length,
+ "File Entry", (unsigned) i + 1);
+
+ /* Include directory index. */
+ if (dwarf_version >= 5 && idx_form != DW_FORM_udata)
+ dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
+ dir_idx + idx_offset, NULL);
+ else
+ dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL);
+
+ if (dwarf_version >= 5)
+ continue;
+
+ /* Modification time. */
+ dw2_asm_output_data_uleb128 (0, NULL);
+
+ /* File length in bytes. */
+ dw2_asm_output_data_uleb128 (0, NULL);
+#endif /* VMS_DEBUGGING_INFO */
+ }
+
+ if (dwarf_version < 5)
+ dw2_asm_output_data (1, 0, "End file name table");
+}
+
+/* Output one line number table into the .debug_line section. */
+
+static void
+output_one_line_info_table (dw_line_info_table *table)
+{
+ char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
+ unsigned int current_line = 1;
+ bool current_is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START;
+ dw_line_info_entry *ent, *prev_addr = NULL;
+ size_t i;
+ unsigned int view;
+
+ view = 0;
+
+ FOR_EACH_VEC_SAFE_ELT (table->entries, i, ent)
+ {
+ switch (ent->opcode)
+ {
+ case LI_set_address:
+ /* ??? Unfortunately, we have little choice here currently, and
+ must always use the most general form. GCC does not know the
+ address delta itself, so we can't use DW_LNS_advance_pc. Many
+ ports do have length attributes which will give an upper bound
+ on the address range. We could perhaps use length attributes
+ to determine when it is safe to use DW_LNS_fixed_advance_pc. */
+ ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val);
+
+ view = 0;
+
+ /* This can handle any delta. This takes
+ 4+DWARF2_ADDR_SIZE bytes. */
+ dw2_asm_output_data (1, 0, "set address %s%s", line_label,
+ debug_variable_location_views
+ ? ", reset view to 0" : "");
+ dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
+ dw2_asm_output_data (1, DW_LNE_set_address, NULL);
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL);
+
+ prev_addr = ent;
+ break;
+
+ case LI_adv_address:
+ {
+ ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val);
+ char prev_label[MAX_ARTIFICIAL_LABEL_BYTES];
+ ASM_GENERATE_INTERNAL_LABEL (prev_label, LINE_CODE_LABEL,
prev_addr->val);
+
+ view++;
+
+ dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, "fixed advance PC,
increment view to %i", view);
+ dw2_asm_output_delta (2, line_label, prev_label,
+ "from %s to %s", prev_label, line_label);
+
+ prev_addr = ent;
+ break;
+ }
+
+ case LI_set_line:
+ if (ent->val == current_line)
+ {
+ /* We still need to start a new row, so output a copy insn. */
+ dw2_asm_output_data (1, DW_LNS_copy,
+ "copy line %u", current_line);
+ }
+ else
+ {
+ int line_offset = ent->val - current_line;
+ int line_delta = line_offset - DWARF_LINE_BASE;
+
+ current_line = ent->val;
+ if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1))
+ {
+ /* This can handle deltas from -10 to 234, using the current
+ definitions of DWARF_LINE_BASE and DWARF_LINE_RANGE.
+ This takes 1 byte. */
+ dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE + line_delta,
+ "line %u", current_line);
+ }
+ else
+ {
+ /* This can handle any delta. This takes at least 4 bytes,
+ depending on the value being encoded. */
+ dw2_asm_output_data (1, DW_LNS_advance_line,
+ "advance to line %u", current_line);
+ dw2_asm_output_data_sleb128 (line_offset, NULL);
+ dw2_asm_output_data (1, DW_LNS_copy, NULL);
+ }
+ }
+ break;
+
+ case LI_set_file:
+ dw2_asm_output_data (1, DW_LNS_set_file, "set file %u", ent->val);
+ dw2_asm_output_data_uleb128 (ent->val, "%u", ent->val);
+ break;
+
+ case LI_set_column:
+ dw2_asm_output_data (1, DW_LNS_set_column, "column %u", ent->val);
+ dw2_asm_output_data_uleb128 (ent->val, "%u", ent->val);
+ break;
+
+ case LI_negate_stmt:
+ current_is_stmt = !current_is_stmt;
+ dw2_asm_output_data (1, DW_LNS_negate_stmt,
+ "is_stmt %d", current_is_stmt);
+ break;
+
+ case LI_set_prologue_end:
+ dw2_asm_output_data (1, DW_LNS_set_prologue_end,
+ "set prologue end");
+ break;
+
+ case LI_set_epilogue_begin:
+ dw2_asm_output_data (1, DW_LNS_set_epilogue_begin,
+ "set epilogue begin");
+ break;
+
+ case LI_set_discriminator:
+ dw2_asm_output_data (1, 0, "discriminator %u", ent->val);
+ dw2_asm_output_data_uleb128 (1 + size_of_uleb128 (ent->val), NULL);
+ dw2_asm_output_data (1, DW_LNE_set_discriminator, NULL);
+ dw2_asm_output_data_uleb128 (ent->val, NULL);
+ break;
+ }
+ }
+
+ /* Emit debug info for the address of the end of the table. */
+ dw2_asm_output_data (1, 0, "set address %s", table->end_label);
+ dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
+ dw2_asm_output_data (1, DW_LNE_set_address, NULL);
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, table->end_label, NULL);
+
+ dw2_asm_output_data (1, 0, "end sequence");
+ dw2_asm_output_data_uleb128 (1, NULL);
+ dw2_asm_output_data (1, DW_LNE_end_sequence, NULL);
+}
+
+static unsigned int output_line_info_generation;
+
+/* Output the source line number correspondence information. This
+ information goes into the .debug_line section. */
+
+static void
+output_line_info (bool prologue_only)
+{
+ char l1[MAX_ARTIFICIAL_LABEL_BYTES], l2[MAX_ARTIFICIAL_LABEL_BYTES];
+ char p1[MAX_ARTIFICIAL_LABEL_BYTES], p2[MAX_ARTIFICIAL_LABEL_BYTES];
+ bool saw_one = false;
+ int opc;
+
+ ASM_GENERATE_INTERNAL_LABEL (l1, LINE_NUMBER_BEGIN_LABEL,
+ output_line_info_generation);
+ ASM_GENERATE_INTERNAL_LABEL (l2, LINE_NUMBER_END_LABEL,
+ output_line_info_generation);
+ ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL,
+ output_line_info_generation);
+ ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL,
+ output_line_info_generation++);
+
+ if (!XCOFF_DEBUGGING_INFO )
+ {
+ if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
+ dw2_asm_output_delta (dwarf_offset_size, l2, l1,
+ "Length of Source Line Info");
+ }
+
+ ASM_OUTPUT_LABEL (asm_out_file, l1);
+
+ output_dwarf_version ();
+ if (dwarf_version >= 5)
+ {
+ dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size");
+ dw2_asm_output_data (1, 0, "Segment Size");
+ }
+ dw2_asm_output_delta (dwarf_offset_size, p2, p1, "Prolog Length");
+ ASM_OUTPUT_LABEL (asm_out_file, p1);
+
+ /* Define the architecture-dependent minimum instruction length (in
bytes).
+ In this implementation of DWARF, this field is used for information
+ purposes only. Since GCC generates assembly language, we have no
+ a priori knowledge of how many instruction bytes are generated for
each
+ source line, and therefore can use only the DW_LNE_set_address and
+ DW_LNS_fixed_advance_pc line information commands. Accordingly, we
fix
+ this as '1', which is "correct enough" for all architectures,
+ and don't let the target override. */
+ dw2_asm_output_data (1, 1, "Minimum Instruction Length");
+
+ if (dwarf_version >= 4)
+ dw2_asm_output_data (1, DWARF_LINE_DEFAULT_MAX_OPS_PER_INSN,
+ "Maximum Operations Per Instruction");
+ dw2_asm_output_data (1, DWARF_LINE_DEFAULT_IS_STMT_START,
+ "Default is_stmt_start flag");
+ dw2_asm_output_data (1, DWARF_LINE_BASE,
+ "Line Base Value (Special Opcodes)");
+ dw2_asm_output_data (1, DWARF_LINE_RANGE,
+ "Line Range Value (Special Opcodes)");
+ dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE,
+ "Special Opcode Base");
+
+ for (opc = 1; opc < DWARF_LINE_OPCODE_BASE; opc++)
+ {
+ int n_op_args;
+ switch (opc)
+ {
+ case DW_LNS_advance_pc:
+ case DW_LNS_advance_line:
+ case DW_LNS_set_file:
+ case DW_LNS_set_column:
+ case DW_LNS_fixed_advance_pc:
+ case DW_LNS_set_isa:
+ n_op_args = 1;
+ break;
+ default:
+ n_op_args = 0;
+ break;
+ }
+
+ dw2_asm_output_data (1, n_op_args, "opcode: %#x has %d args",
+ opc, n_op_args);
+ }
+
+ /* Write out the information about the files we use. */
+ output_file_names ();
+ ASM_OUTPUT_LABEL (asm_out_file, p2);
+ if (prologue_only)
+ {
+ /* Output the marker for the end of the line number info. */
+ ASM_OUTPUT_LABEL (asm_out_file, l2);
+ return;
+ }
+
+ if (separate_line_info)
+ {
+ dw_line_info_table *table;
+ size_t i;
+
+ FOR_EACH_VEC_ELT (*separate_line_info, i, table)
+ if (table->in_use)
+ {
+ output_one_line_info_table (table);
+ saw_one = true;
+ }
+ }
+ if (cold_text_section_line_info && cold_text_section_line_info->in_use)
+ {
+ output_one_line_info_table (cold_text_section_line_info);
+ saw_one = true;
+ }
+
+ /* ??? Some Darwin linkers crash on a .debug_line section with no
+ sequences. Further, merely a DW_LNE_end_sequence entry is not
+ sufficient -- the address column must also be initialized.
+ Make sure to output at least one set_address/end_sequence pair,
+ choosing .text since that section is always present. */
+ if (text_section_line_info->in_use || !saw_one)
+ output_one_line_info_table (text_section_line_info);
+
+ /* Output the marker for the end of the line number info. */
+ ASM_OUTPUT_LABEL (asm_out_file, l2);
+}
+
+unsigned long debug_line_offset=0;
+
+static void
+output_line_string_to_object_file (enum dwarf_form form, const char *str,
+ const char *entry_kind, unsigned int idx)
+{
+ static long debug_line_str_offset = 0;
+ struct lto_simple_object *lo = (struct lto_simple_object *)
lto_get_current_out_file ();
+ switch (form)
+ {
+ case DW_FORM_string:
+ debug_line_offset += output_nstring_to_object_file(str, -1);
+ break;
+ case DW_FORM_line_strp:
+ if (!debug_line_str_hash)
+ debug_line_str_hash
+ = hash_table<indirect_string_hasher>::create_ggc (10);
+
+ struct indirect_string_node *node;
+ node = find_AT_string_in_table (str, debug_line_str_hash);
+ set_indirect_string (node);
+ node->form = form;
+ simple_object_write_add_relocation(lo->section, debug_line_offset,
+ debug_line_str_offset,
".gnu.debuglto_.debug_line_str", 5);
+ debug_line_offset += output_data_to_object_file(dwarf_offset_size,
0);
+ debug_line_str_offset += strlen(node->str) + 1;
+ //Add relocations
+ // dw2_asm_output_offset (dwarf_offset_size, node->label,
+ // debug_line_str_section, "%s: %#x: \"%s\"",
+ // entry_kind, 0, node->str);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+static void
+output_file_names_to_object_file (void)
+{
+ struct file_name_acquire_data fnad;
+ int numfiles;
+ struct file_info *files;
+ struct dir_info *dirs;
+ int *saved;
+ int *savehere;
+ int *backmap;
+ int ndirs;
+ int idx_offset;
+ int i;
+
+ if (!last_emitted_file)
+ {
+ if (dwarf_version >= 5)
+ {
+ const char *comp_dir = comp_dir_string ();
+ if (comp_dir == NULL)
+ comp_dir = "";
+ debug_line_offset += output_data_to_object_file(1,1);
+ enum dwarf_form str_form = DW_FORM_string;
+ if (DWARF5_USE_DEBUG_LINE_STR)
+ str_form = DW_FORM_line_strp;
+ debug_line_offset += output_data_uleb128_to_object_file (DW_LNCT_path);
+ debug_line_offset += output_data_uleb128_to_object_file (str_form);
+ debug_line_offset += output_data_uleb128_to_object_file (1);
+ if (str_form == DW_FORM_string)
+ output_nstring_to_object_file(comp_dir, -1);
+ else
+ output_line_string_to_object_file (str_form, comp_dir, "Directory
Entry", 0);
+
+ const char *filename0 = get_AT_string (comp_unit_die (), DW_AT_name);
+ if (filename0 == NULL)
+ filename0 = "";
+#ifdef VMS_DEBUGGING_INFO
+ debug_line_offset += output_data_to_object_file(1, 4);
+#else
+ debug_line_offset += output_data_to_object_file(1, 2);
+#endif
+ debug_line_offset += output_data_uleb128_to_object_file(DW_LNCT_path);
+ debug_line_offset += output_data_uleb128_to_object_file(str_form);
+ debug_line_offset +=
output_data_uleb128_to_object_file(DW_LNCT_directory_index);
+ debug_line_offset += output_data_uleb128_to_object_file(DW_FORM_data1);
+
+#ifdef VMS_DEBUGGING_INFO
+ debug_line_offset +=
output_data_uleb128_to_object_file(DW_LNCT_timestamp);
+ debug_line_offset += output_data_uleb128_to_object_file(DW_FORM_udata);
+ debug_line_offset += output_data_uleb128_to_object_file(DW_LNCT_size);
+ debug_line_offset += output_data_uleb128_to_object_file(DW_FORM_udata);
+
+#endif
+ debug_line_offset += output_data_uleb128_to_object_file(1);
+ output_line_string_to_object_file(str_form, filename0, "File Entry",
0);
+ debug_line_offset += output_data_to_object_file(1, 0);
+
+#ifdef VMS_DEBUGGING_INFO
+ debug_line_offset += output_data_uleb128_to_object_file(0);
+ debug_line_offset += output_data_uleb128_to_object_file(0);
+
+#endif
+ }
+ else
+ {
+ debug_line_offset += output_data_to_object_file(1, 0);
+ debug_line_offset += output_data_to_object_file(1, 0);
+
+ }
+ return;
+ }
+
+ numfiles = last_emitted_file->emitted_number;
+
+ /* Allocate the various arrays we need. */
+ files = XALLOCAVEC (struct file_info, numfiles);
+ dirs = XALLOCAVEC (struct dir_info, numfiles);
+
+ fnad.files = files;
+ fnad.used_files = 0;
+ fnad.max_files = numfiles;
+ file_table->traverse<file_name_acquire_data *, file_name_acquire>
(&fnad);
+ gcc_assert (fnad.used_files == fnad.max_files);
+
+ qsort (files, numfiles, sizeof (files[0]), file_info_cmp);
+
+ /* Find all the different directories used. */
+ dirs[0].path = files[0].path;
+ dirs[0].length = files[0].fname - files[0].path;
+ dirs[0].prefix = -1;
+ dirs[0].count = 1;
+ dirs[0].dir_idx = 0;
+ files[0].dir_idx = 0;
+ ndirs = 1;
+
+ for (i = 1; i < numfiles; i++)
+ if (files[i].fname - files[i].path == dirs[ndirs - 1].length
+ && memcmp (dirs[ndirs - 1].path, files[i].path,
+ dirs[ndirs - 1].length) == 0)
+ {
+ /* Same directory as last entry. */
+ files[i].dir_idx = ndirs - 1;
+ ++dirs[ndirs - 1].count;
+ }
+ else
+ {
+ int j;
+
+ /* This is a new directory. */
+ dirs[ndirs].path = files[i].path;
+ dirs[ndirs].length = files[i].fname - files[i].path;
+ dirs[ndirs].count = 1;
+ dirs[ndirs].dir_idx = ndirs;
+ files[i].dir_idx = ndirs;
+
+ /* Search for a prefix. */
+ dirs[ndirs].prefix = -1;
+ for (j = 0; j < ndirs; j++)
+ if (dirs[j].length < dirs[ndirs].length
+ && dirs[j].length > 1
+ && (dirs[ndirs].prefix == -1
+ || dirs[j].length > dirs[dirs[ndirs].prefix].length)
+ && memcmp (dirs[j].path, dirs[ndirs].path, dirs[j].length) == 0)
+ dirs[ndirs].prefix = j;
+
+ ++ndirs;
+ }
+
+ /* Now to the actual work. We have to find a subset of the directories
which
+ allow expressing the file name using references to the directory table
+ with the least amount of characters. We do not do an exhaustive
search
+ where we would have to check out every combination of every single
+ possible prefix. Instead we use a heuristic which provides nearly
optimal
+ results in most cases and never is much off. */
+ saved = XALLOCAVEC (int, ndirs);
+ savehere = XALLOCAVEC (int, ndirs);
+
+ memset (saved, '\0', ndirs * sizeof (saved[0]));
+ for (i = 0; i < ndirs; i++)
+ {
+ int j;
+ int total;
+
+ /* We can always save some space for the current directory. But this
+ does not mean it will be enough to justify adding the directory. */
+ savehere[i] = dirs[i].length;
+ total = (savehere[i] - saved[i]) * dirs[i].count;
+
+ for (j = i + 1; j < ndirs; j++)
+ {
+ savehere[j] = 0;
+ if (saved[j] < dirs[i].length)
+ {
+ /* Determine whether the dirs[i] path is a prefix of the
+ dirs[j] path. */
+ int k;
+
+ k = dirs[j].prefix;
+ while (k != -1 && k != (int) i)
+ k = dirs[k].prefix;
+
+ if (k == (int) i)
+ {
+ /* Yes it is. We can possibly save some memory by
+ writing the filenames in dirs[j] relative to
+ dirs[i]. */
+ savehere[j] = dirs[i].length;
+ total += (savehere[j] - saved[j]) * dirs[j].count;
+ }
+ }
+ }
+
+ /* Check whether we can save enough to justify adding the dirs[i]
+ directory. */
+ if (total > dirs[i].length + 1)
+ {
+ /* It's worthwhile adding. */
+ for (j = i; j < ndirs; j++)
+ if (savehere[j] > 0)
+ {
+ /* Remember how much we saved for this directory so far. */
+ saved[j] = savehere[j];
+
+ /* Remember the prefix directory. */
+ dirs[j].dir_idx = i;
+ }
+ }
+ }
+
+ /* Emit the directory name table. */
+ idx_offset = dirs[0].length > 0 ? 1 : 0;
+ enum dwarf_form str_form = DW_FORM_string;
+ enum dwarf_form idx_form = DW_FORM_udata;
+ if (dwarf_version >= 5)
+ {
+ const char *comp_dir = comp_dir_string ();
+ if (comp_dir == NULL)
+ comp_dir = "";
+ debug_line_offset += output_data_to_object_file(1, 1);
+
+ if (DWARF5_USE_DEBUG_LINE_STR)
+ str_form = DW_FORM_line_strp;
+ debug_line_offset +=
output_data_uleb128_to_object_file(DW_LNCT_path);
+ debug_line_offset += output_data_uleb128_to_object_file(str_form);
+ debug_line_offset += output_data_uleb128_to_object_file(ndirs +
idx_offset);
+
+ if (str_form == DW_FORM_string)
+ {
+ output_nstring_to_object_file(comp_dir, -1);
+
+ for (i = 1 - idx_offset; i < ndirs; i++) //See this again
+ output_nstring_to_object_file(dirs[i].path,
+ dirs[i].length
+ - !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR);
+
+ }
+ else
+ {
+ output_line_string_to_object_file (str_form, comp_dir, "Directory
Entry", 0);
+
+ for (i = 1 - idx_offset; i < ndirs; i++)
+ {
+ const char *str
+ = ggc_alloc_string (dirs[i].path,
+ dirs[i].length
+ - !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR);
+ output_line_string_to_object_file (str_form, str, "Directory
Entry",
+ (unsigned) i + idx_offset);
+ }
+ }
+ }
+ else
+ {
+ for (i = 1 - idx_offset; i < ndirs; i++)
+ output_nstring_to_object_file(dirs[i].path,
+ dirs[i].length
+ - !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR);
+ debug_line_offset += output_data_to_object_file(1, 0);
+
+ }
+
+ /* We have to emit them in the order of emitted_number since that's
+ used in the debug info generation. To do this efficiently we
+ generate a back-mapping of the indices first. */
+ backmap = XALLOCAVEC (int, numfiles);
+ for (i = 0; i < numfiles; i++)
+ backmap[files[i].file_idx->emitted_number - 1] = i;
+
+ if (dwarf_version >= 5)
+ {
+ const char *filename0 = get_AT_string (comp_unit_die (), DW_AT_name);
+ if (filename0 == NULL)
+ filename0 = "";
+ /* DW_LNCT_directory_index can use DW_FORM_udata, DW_FORM_data1 and
+ DW_FORM_data2. Choose one based on the number of directories
+ and how much space would they occupy in each encoding.
+ If we have at most 256 directories, all indexes fit into
+ a single byte, so DW_FORM_data1 is most compact (if there
+ are at most 128 directories, DW_FORM_udata would be as
+ compact as that, but not shorter and slower to decode). */
+ if (ndirs + idx_offset <= 256)
+ idx_form = DW_FORM_data1;
+ /* If there are more than 65536 directories, we have to use
+ DW_FORM_udata, DW_FORM_data2 can't refer to them.
+ Otherwise, compute what space would occupy if all the indexes
+ used DW_FORM_udata - sum - and compare that to how large would
+ be DW_FORM_data2 encoding, and pick the more efficient one. */
+ else if (ndirs + idx_offset <= 65536)
+ {
+ unsigned HOST_WIDE_INT sum = 1;
+ for (i = 0; i < numfiles; i++)
+ {
+ int file_idx = backmap[i];
+ int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
+ sum += size_of_uleb128 (dir_idx);
+ }
+ if (sum >= HOST_WIDE_INT_UC (2) * (numfiles + 1))
+ idx_form = DW_FORM_data2;
+ }
+#ifdef VMS_DEBUGGING_INFO
+ debug_line_offset += output_data_to_object_file(1, 4);
+#else
+ debug_line_offset += output_data_to_object_file(1, 2);
+
+#endif
+ debug_line_offset +=
output_data_uleb128_to_object_file(DW_LNCT_path);
+ debug_line_offset += output_data_uleb128_to_object_file(str_form);
+ debug_line_offset +=
output_data_uleb128_to_object_file(DW_LNCT_directory_index);
+ debug_line_offset += output_data_uleb128_to_object_file(idx_form);
+
+#ifdef VMS_DEBUGGING_INFO
+ dw2_asm_output_data_uleb128 (DW_LNCT_timestamp);
+ dw2_asm_output_data_uleb128 (DW_FORM_udata);
+ dw2_asm_output_data_uleb128 (DW_LNCT_size);
+ dw2_asm_output_data_uleb128 (DW_FORM_udata);
+
+#endif
+ debug_line_offset += output_data_uleb128_to_object_file(numfiles +
1);
+
+
+ output_line_string_to_object_file (str_form, filename0, "File
Entry", 0);
+
+
+ /* Include directory index. */
+ if (idx_form != DW_FORM_udata)
+ debug_line_offset += output_data_to_object_file(idx_form ==
DW_FORM_data1 ? 1 : 2, 0);
+ else
+ debug_line_offset += output_data_uleb128_to_object_file(0);
+
+#ifdef VMS_DEBUGGING_INFO
+ debug_line_offset += output_data_uleb128_to_object_file(0);
+ debug_line_offset += output_data_uleb128_to_object_file(0);
+
+#endif
+ }
+
+ /* Now write all the file names. */
+ for (i = 0; i < numfiles; i++)
+ {
+ int file_idx = backmap[i];
+ int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
+
+#ifdef VMS_DEBUGGING_INFO
+#define MAX_VMS_VERSION_LEN 6 /* ";32768" */
+
+ /* Setting these fields can lead to debugger miscomparisons,
+ but VMS Debug requires them to be set correctly. */
+
+ int ver;
+ long long cdt;
+ long siz;
+ int maxfilelen = (strlen (files[file_idx].path)
+ + dirs[dir_idx].length
+ + MAX_VMS_VERSION_LEN + 1);
+ char *filebuf = XALLOCAVEC (char, maxfilelen);
+
+ vms_file_stats_name (files[file_idx].path, 0, 0, 0, &ver);
+ snprintf (filebuf, maxfilelen, "%s;%d",
+ files[file_idx].path + dirs[dir_idx].length, ver);
+
+ output_line_string_to_object_file (str_form, filebuf, "File Entry",
(unsigned) i + 1);
+
/* Include directory index. */
if (dwarf_version >= 5 && idx_form != DW_FORM_udata)
- dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
- dir_idx + idx_offset, NULL);
+ debug_line_offset += output_data_to_object_file(idx_form ==
DW_FORM_data1 ? 1 : 2, dir_idx_idx_offset);
+
else
- dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL);
+ debug_line_offset += output_data_uleb128_to_object_file(dir_idx +
idx_offset);
- /* Modification time. */
- dw2_asm_output_data_uleb128 ((vms_file_stats_name
(files[file_idx].path,
- &cdt, 0, 0, 0) == 0)
- ? cdt : 0, NULL);
+ /* Modification time. */
+ debug_line_offset +=
output_data_uleb128_to_object_file((vms_file_stats_name(files[file_idx].path,
&cdt, 0, 0, 0) == 0) ? cdt : 0);
+
+ /* File length in bytes. */
+ debug_line_offset +=
output_data_uleb128_to_object_file((vms_file_stats_name(files[file_idx].path,
0, &siz, 0, 0) == 0) ? siz : 0);
- /* File length in bytes. */
- dw2_asm_output_data_uleb128 ((vms_file_stats_name
(files[file_idx].path,
- 0, &siz, 0, 0) == 0)
- ? siz : 0, NULL);
#else
- output_line_string (str_form,
- files[file_idx].path + dirs[dir_idx].length,
- "File Entry", (unsigned) i + 1);
+ output_line_string_to_object_file (str_form,
+ files[file_idx].path + dirs[dir_idx].length,
+ "File Entry", (unsigned) i + 1);
/* Include directory index. */
if (dwarf_version >= 5 && idx_form != DW_FORM_udata)
- dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
- dir_idx + idx_offset, NULL);
+ debug_line_offset += output_data_to_object_file(idx_form ==
DW_FORM_data1 ? 1 : 2, dir_idx + idx_offset);
+
else
- dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL);
+ debug_line_offset += output_data_uleb128_to_object_file(dir_idx +
idx_offset);
if (dwarf_version >= 5)
continue;
/* Modification time. */
- dw2_asm_output_data_uleb128 (0, NULL);
+ debug_line_offset += output_data_uleb128_to_object_file(0);
/* File length in bytes. */
- dw2_asm_output_data_uleb128 (0, NULL);
+ debug_line_offset += output_data_uleb128_to_object_file(0);
+
#endif /* VMS_DEBUGGING_INFO */
}
if (dwarf_version < 5)
- dw2_asm_output_data (1, 0, "End file name table");
+ debug_line_offset += output_data_to_object_file(1, 0);
}
-
-
-/* Output one line number table into the .debug_line section. */
-
static void
-output_one_line_info_table (dw_line_info_table *table)
+modify_buffer_of_object_file (unsigned long offset, size_t size,
HOST_WIDE_INT value)
{
- char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
- unsigned int current_line = 1;
- bool current_is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START;
- dw_line_info_entry *ent, *prev_addr = NULL;
- size_t i;
- unsigned int view;
-
- view = 0;
-
- FOR_EACH_VEC_SAFE_ELT (table->entries, i, ent)
+ struct lto_simple_object *lo = (struct lto_simple_object *)
lto_get_current_out_file ();
+ unsigned char bytes[8];
+ unsigned int i;
+ unsigned char *buff = XNEWVEC(unsigned char, size);
+ for (i = 0; i < 8; ++i)
{
- switch (ent->opcode)
- {
- case LI_set_address:
- /* ??? Unfortunately, we have little choice here currently, and
- must always use the most general form. GCC does not know the
- address delta itself, so we can't use DW_LNS_advance_pc. Many
- ports do have length attributes which will give an upper bound
- on the address range. We could perhaps use length attributes
- to determine when it is safe to use DW_LNS_fixed_advance_pc. */
- ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val);
-
- view = 0;
-
- /* This can handle any delta. This takes
- 4+DWARF2_ADDR_SIZE bytes. */
- dw2_asm_output_data (1, 0, "set address %s%s", line_label,
- debug_variable_location_views
- ? ", reset view to 0" : "");
- dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
- dw2_asm_output_data (1, DW_LNE_set_address, NULL);
- dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL);
-
- prev_addr = ent;
- break;
-
- case LI_adv_address:
- {
- ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val);
- char prev_label[MAX_ARTIFICIAL_LABEL_BYTES];
- ASM_GENERATE_INTERNAL_LABEL (prev_label, LINE_CODE_LABEL,
prev_addr->val);
-
- view++;
-
- dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, "fixed advance PC,
increment view to %i", view);
- dw2_asm_output_delta (2, line_label, prev_label,
- "from %s to %s", prev_label, line_label);
-
- prev_addr = ent;
- break;
- }
-
- case LI_set_line:
- if (ent->val == current_line)
- {
- /* We still need to start a new row, so output a copy insn. */
- dw2_asm_output_data (1, DW_LNS_copy,
- "copy line %u", current_line);
- }
- else
- {
- int line_offset = ent->val - current_line;
- int line_delta = line_offset - DWARF_LINE_BASE;
-
- current_line = ent->val;
- if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1))
- {
- /* This can handle deltas from -10 to 234, using the current
- definitions of DWARF_LINE_BASE and DWARF_LINE_RANGE.
- This takes 1 byte. */
- dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE + line_delta,
- "line %u", current_line);
- }
- else
- {
- /* This can handle any delta. This takes at least 4 bytes,
- depending on the value being encoded. */
- dw2_asm_output_data (1, DW_LNS_advance_line,
- "advance to line %u", current_line);
- dw2_asm_output_data_sleb128 (line_offset, NULL);
- dw2_asm_output_data (1, DW_LNS_copy, NULL);
- }
- }
- break;
-
- case LI_set_file:
- dw2_asm_output_data (1, DW_LNS_set_file, "set file %u", ent->val);
- dw2_asm_output_data_uleb128 (ent->val, "%u", ent->val);
- break;
-
- case LI_set_column:
- dw2_asm_output_data (1, DW_LNS_set_column, "column %u", ent->val);
- dw2_asm_output_data_uleb128 (ent->val, "%u", ent->val);
- break;
-
- case LI_negate_stmt:
- current_is_stmt = !current_is_stmt;
- dw2_asm_output_data (1, DW_LNS_negate_stmt,
- "is_stmt %d", current_is_stmt);
- break;
-
- case LI_set_prologue_end:
- dw2_asm_output_data (1, DW_LNS_set_prologue_end,
- "set prologue end");
- break;
-
- case LI_set_epilogue_begin:
- dw2_asm_output_data (1, DW_LNS_set_epilogue_begin,
- "set epilogue begin");
- break;
-
- case LI_set_discriminator:
- dw2_asm_output_data (1, 0, "discriminator %u", ent->val);
- dw2_asm_output_data_uleb128 (1 + size_of_uleb128 (ent->val), NULL);
- dw2_asm_output_data (1, DW_LNE_set_discriminator, NULL);
- dw2_asm_output_data_uleb128 (ent->val, NULL);
- break;
- }
+ bytes[i] = value & 0xff;
+ value >>= 8;
}
-
- /* Emit debug info for the address of the end of the table. */
- dw2_asm_output_data (1, 0, "set address %s", table->end_label);
- dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
- dw2_asm_output_data (1, DW_LNE_set_address, NULL);
- dw2_asm_output_addr (DWARF2_ADDR_SIZE, table->end_label, NULL);
-
- dw2_asm_output_data (1, 0, "end sequence");
- dw2_asm_output_data_uleb128 (1, NULL);
- dw2_asm_output_data (1, DW_LNE_end_sequence, NULL);
+ if (BYTES_BIG_ENDIAN)
+ {
+ for (i = size - 1; i >= 0; --i)
+ buff[i] = bytes[i];
+ }
+ else
+ {
+ for (i = 0; i <= size - 1; ++i)
+ buff[i] = bytes[i];
+ }
+ simple_object_modify_buffer (lo->section, offset, buff, 1);
}
-static unsigned int output_line_info_generation;
-
-/* Output the source line number correspondence information. This
- information goes into the .debug_line section. */
-
static void
-output_line_info (bool prologue_only)
+output_line_info_to_object_file (bool prologue_only)
{
- char l1[MAX_ARTIFICIAL_LABEL_BYTES], l2[MAX_ARTIFICIAL_LABEL_BYTES];
- char p1[MAX_ARTIFICIAL_LABEL_BYTES], p2[MAX_ARTIFICIAL_LABEL_BYTES];
+ lto_obj_begin_section(".gnu.debuglto_.debug_line");
bool saw_one = false;
int opc;
- ASM_GENERATE_INTERNAL_LABEL (l1, LINE_NUMBER_BEGIN_LABEL,
- output_line_info_generation);
- ASM_GENERATE_INTERNAL_LABEL (l2, LINE_NUMBER_END_LABEL,
- output_line_info_generation);
- ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL,
- output_line_info_generation);
- ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL,
- output_line_info_generation++);
-
if (!XCOFF_DEBUGGING_INFO)
{
if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
- dw2_asm_output_data (4, 0xffffffff,
- "Initial length escape value indicating 64-bit DWARF extension");
- dw2_asm_output_delta (dwarf_offset_size, l2, l1,
- "Length of Source Line Info");
+ debug_line_offset += output_data_to_object_file (4, 0xffffffff);
+ // dw2_asm_output_delta (dwarf_offset_size, l2, l1,
+ // "Length of Source Line Info");
+ debug_line_offset += output_data_to_object_file(dwarf_offset_size,0);
+
}
- ASM_OUTPUT_LABEL (asm_out_file, l1);
+ debug_line_offset += output_data_to_object_file(2,dwarf_version); //
output dwarf version
- output_dwarf_version ();
if (dwarf_version >= 5)
{
- dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size");
- dw2_asm_output_data (1, 0, "Segment Size");
+ debug_line_offset += output_data_to_object_file (1,
DWARF2_ADDR_SIZE);
+ debug_line_offset += output_data_to_object_file (1, 0);
}
- dw2_asm_output_delta (dwarf_offset_size, p2, p1, "Prolog Length");
- ASM_OUTPUT_LABEL (asm_out_file, p1);
+ // dw2_asm_output_delta (dwarf_offset_size, p2, p1, "Prolog Length");
+ debug_line_offset += output_data_to_object_file(dwarf_offset_size,0);
/* Define the architecture-dependent minimum instruction length (in
bytes).
In this implementation of DWARF, this field is used for information
@@ -13725,19 +14264,13 @@ output_line_info (bool prologue_only)
DW_LNS_fixed_advance_pc line information commands. Accordingly, we
fix
this as '1', which is "correct enough" for all architectures,
and don't let the target override. */
- dw2_asm_output_data (1, 1, "Minimum Instruction Length");
-
+ debug_line_offset += output_data_to_object_file (1, 1);
if (dwarf_version >= 4)
- dw2_asm_output_data (1, DWARF_LINE_DEFAULT_MAX_OPS_PER_INSN,
- "Maximum Operations Per Instruction");
- dw2_asm_output_data (1, DWARF_LINE_DEFAULT_IS_STMT_START,
- "Default is_stmt_start flag");
- dw2_asm_output_data (1, DWARF_LINE_BASE,
- "Line Base Value (Special Opcodes)");
- dw2_asm_output_data (1, DWARF_LINE_RANGE,
- "Line Range Value (Special Opcodes)");
- dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE,
- "Special Opcode Base");
+ debug_line_offset += output_data_to_object_file (1,
DWARF_LINE_DEFAULT_MAX_OPS_PER_INSN);
+ debug_line_offset += output_data_to_object_file (1,
DWARF_LINE_DEFAULT_IS_STMT_START);
+ debug_line_offset += output_data_to_object_file (1, DWARF_LINE_BASE);
+ debug_line_offset += output_data_to_object_file (1, DWARF_LINE_RANGE);
+ debug_line_offset += output_data_to_object_file (1,
DWARF_LINE_OPCODE_BASE);
for (opc = 1; opc < DWARF_LINE_OPCODE_BASE; opc++)
{
@@ -13757,50 +14290,18 @@ output_line_info (bool prologue_only)
break;
}
- dw2_asm_output_data (1, n_op_args, "opcode: %#x has %d args",
- opc, n_op_args);
- }
-
- /* Write out the information about the files we use. */
- output_file_names ();
- ASM_OUTPUT_LABEL (asm_out_file, p2);
- if (prologue_only)
- {
- /* Output the marker for the end of the line number info. */
- ASM_OUTPUT_LABEL (asm_out_file, l2);
- return;
- }
+ debug_line_offset += output_data_to_object_file (1, n_op_args);
- if (separate_line_info)
- {
- dw_line_info_table *table;
- size_t i;
-
- FOR_EACH_VEC_ELT (*separate_line_info, i, table)
- if (table->in_use)
- {
- output_one_line_info_table (table);
- saw_one = true;
- }
- }
- if (cold_text_section_line_info && cold_text_section_line_info->in_use)
- {
- output_one_line_info_table (cold_text_section_line_info);
- saw_one = true;
}
- /* ??? Some Darwin linkers crash on a .debug_line section with no
- sequences. Further, merely a DW_LNE_end_sequence entry is not
- sufficient -- the address column must also be initialized.
- Make sure to output at least one set_address/end_sequence pair,
- choosing .text since that section is always present. */
- if (text_section_line_info->in_use || !saw_one)
- output_one_line_info_table (text_section_line_info);
-
- /* Output the marker for the end of the line number info. */
- ASM_OUTPUT_LABEL (asm_out_file, l2);
+ /* Write out the information about the files we use. */
+ output_file_names_to_object_file ();
+ /* Modify the write buffer so it holds the correct unit length */
+ modify_buffer_of_object_file (0, dwarf_offset_size, debug_line_offset -
4);
+ /* Modify the write buffer so it holds the correct header length */
+ modify_buffer_of_object_file (8, dwarf_offset_size, debug_line_offset
-12);
+ lto_obj_end_section();
}
-
/* Return true if DW_AT_endianity should be emitted according to REVERSE.
*/
static inline bool
@@ -30377,6 +30878,24 @@ output_indirect_string (indirect_string_node **h,
enum dwarf_form form)
return 1;
}
+/* A helper function for dwarf2out_finish called through
+ htab_traverse. Emit one queued .debug_str string directly to object
file. */
+
+int
+output_indirect_string_to_object_file (indirect_string_node **h, enum
dwarf_form form)
+{
+ struct indirect_string_node *node = *h;
+
+ node->form = find_string_form (node);
+ if (node->form == form && node->refcount > 0)
+ {
+ void *v = NULL;
+ lto_obj_append_data((const void *)node->str, strlen (node->str)+1,v);
+ }
+
+ return 1;
+}
+
/* Output the indexed string table. */
static void
@@ -30431,6 +30950,20 @@ output_indirect_strings (void)
}
}
+
+/* Output the indexed string table directly to object file. */
+
+static void
+output_indirect_strings_to_object_file (void)
+{
+ lto_obj_begin_section(".gnu.debuglto_.debug_str");
+ if (!dwarf_split_debug_info)
+ debug_str_hash->traverse<enum dwarf_form,
+ output_indirect_string_to_object_file> (DW_FORM_strp);
+ lto_obj_end_section();
+
+}
+
/* Callback for htab_traverse to assign an index to an entry in the
table, and to write that entry to the .debug_addr section. */
@@ -33872,7 +34405,23 @@ dwarf2out_early_finish (const char *filename)
else
{
output_comp_unit_to_object_file(comp_unit_die(), true, NULL);
- output_abbrev_section_to_object_file();
+ if (vec_safe_length (abbrev_die_table) != 1)
+ output_abbrev_section_to_object_file();
+
+ output_line_info_to_object_file (true);//.debug line section
+ /* If we emitted any indirect strings, output the string table too. */
+ if (debug_str_hash || skeleton_debug_str_hash)
+ output_indirect_strings_to_object_file (); //.debug_str
+ //.debug_line_str
+ if (debug_line_str_hash)
+ {
+ lto_obj_begin_section(".gnu.debuglto_.debug_line_str");
+
+ const enum dwarf_form form = DW_FORM_line_strp;
+ debug_line_str_hash->traverse<enum dwarf_form,
+ output_indirect_string_to_object_file> (form);
+ lto_obj_end_section();
+ }
}
}
@@ -189,7 +189,7 @@ lto_obj_file_close (lto_file *file)
gcc_assert (lo->base.offset == 0);
/*Add __gnu_lto_slim symbol*/
- simple_object_write_add_symbol (lo->sobj_w, "__gnu_lto_slim",1,1);
+ simple_object_write_add_symbol (lo->sobj_w,
"__gnu_lto_slim",1,1,1,1,-1,0);
errmsg = simple_object_write_to_file (lo->sobj_w, lo->fd, &err);
if (errmsg != NULL)