static unsigned int dirs_allocated = 0;
/* TRUE when we've seen a .loc directive recently. Used to avoid
- doing work when there's nothing to do. */
+ doing work when there's nothing to do. Will be reset by
+ dwarf2_consume_line_info. */
bfd_boolean dwarf2_loc_directive_seen;
+/* TRUE when we've seen any .loc directive at any time during parsing.
+ Indicates the user wants us to generate a .debug_line section.
+ Used in dwarf2_finish as sanity check. */
+static bfd_boolean dwarf2_any_loc_directive_seen;
+
/* TRUE when we're supposed to set the basic block mark whenever a
label is seen. */
bfd_boolean dwarf2_loc_mark_labels;
}
demand_empty_rest_of_line ();
- dwarf2_loc_directive_seen = TRUE;
+ dwarf2_any_loc_directive_seen = dwarf2_loc_directive_seen = TRUE;
debug_type = DEBUG_NONE;
/* If we were given a view id, emit the row right away. */
}
}
+/* Switch to LINE_STR_SEG and output the given STR. Return the
+ symbol pointing to the new string in the section. */
+
+static symbolS *
+add_line_strp (segT line_str_seg, const char *str)
+{
+ char *cp;
+ size_t size;
+ symbolS *sym;
+
+ subseg_set (line_str_seg, 0);
+
+ sym = symbol_temp_new_now_octets ();
+
+ size = strlen (str) + 1;
+ cp = frag_more (size);
+ memcpy (cp, str, size);
+
+ return sym;
+}
+
+
/* Emit the directory and file tables for .debug_line. */
static void
-out_dir_and_file_list (void)
+out_dir_and_file_list (segT line_seg, int sizeof_offset)
{
size_t size;
const char *dir;
bfd_boolean emit_md5 = FALSE;
bfd_boolean emit_timestamps = TRUE;
bfd_boolean emit_filesize = TRUE;
+ segT line_str_seg = NULL;
+ symbolS *line_strp;
/* Output the Directory Table. */
if (DWARF2_LINE_VERSION >= 5)
/* Describe the purpose and format of the column. */
out_uleb128 (DW_LNCT_path);
- /* FIXME: it would be better to store these strings in
- the .debug_line_str section and reference them here. */
- out_uleb128 (DW_FORM_string);
+ /* Store these strings in the .debug_line_str section so they
+ can be shared. */
+ out_uleb128 (DW_FORM_line_strp);
/* 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
/* Emit directory list. */
if (DWARF2_LINE_VERSION >= 5 && (dirs_in_use > 0 || files_in_use > 0))
{
+ line_str_seg = subseg_new (".debug_line_str", 0);
+ bfd_set_section_flags (line_str_seg,
+ SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS
+ | SEC_MERGE | SEC_STRINGS);
+ line_str_seg->entsize = 1;
+
/* 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.
else
dir = remap_debug_filename (getpwd ());
- size = strlen (dir) + 1;
- cp = frag_more (size);
- memcpy (cp, dir, size);
+ line_strp = add_line_strp (line_str_seg, dir);
+ subseg_set (line_seg, 0);
+ TC_DWARF2_EMIT_OFFSET (line_strp, sizeof_offset);
}
for (i = 1; i < dirs_in_use; ++i)
{
dir = remap_debug_filename (dirs[i]);
- size = strlen (dir) + 1;
- cp = frag_more (size);
- memcpy (cp, dir, size);
+ if (DWARF2_LINE_VERSION < 5)
+ {
+ size = strlen (dir) + 1;
+ cp = frag_more (size);
+ memcpy (cp, dir, size);
+ }
+ else
+ {
+ line_strp = add_line_strp (line_str_seg, dir);
+ subseg_set (line_seg, 0);
+ TC_DWARF2_EMIT_OFFSET (line_strp, sizeof_offset);
+ }
}
if (DWARF2_LINE_VERSION < 5)
out_byte (columns);
/* The format of the file name. */
out_uleb128 (DW_LNCT_path);
- /* FIXME: it would be better to store these strings in
- the .debug_line_str section and reference them here. */
- out_uleb128 (DW_FORM_string);
+ /* Store these strings in the .debug_line_str section so they
+ can be shared. */
+ out_uleb128 (DW_FORM_line_strp);
/* The format of the directory index. */
out_uleb128 (DW_LNCT_directory_index);
fullfilename = DWARF2_FILE_NAME (files[i].filename,
files[i].dir ? dirs [files [i].dir] : "");
- size = strlen (fullfilename) + 1;
- cp = frag_more (size);
- memcpy (cp, fullfilename, size);
+ if (DWARF2_LINE_VERSION < 5)
+ {
+ size = strlen (fullfilename) + 1;
+ cp = frag_more (size);
+ memcpy (cp, fullfilename, size);
+ }
+ else
+ {
+ line_strp = add_line_strp (line_str_seg, fullfilename);
+ subseg_set (line_seg, 0);
+ TC_DWARF2_EMIT_OFFSET (line_strp, sizeof_offset);
+ }
/* Directory number. */
out_uleb128 (files[i].dir);
matches up to the opcode base value we have been using. */
gas_assert (DWARF2_LINE_OPCODE_BASE == 13);
- out_dir_and_file_list ();
+ out_dir_and_file_list (line_seg, sizeof_offset);
symbol_set_value_now (prologue_end);
/* Finish the dwarf2 debug sections. We emit .debug.line if there
- were any .file/.loc directives, or --gdwarf2 was given, or if the
+ were any .file/.loc directives, or --gdwarf2 was given, and if the
file has a non-empty .debug_info section and an empty .debug_line
section. If we emit .debug_line, and the .debug_info section is
empty, we also emit .debug_info, .debug_aranges and .debug_abbrev.
empty_debug_line = line_seg == NULL || !seg_not_empty_p (line_seg);
/* We can't construct a new debug_line section if we already have one.
- Give an error. */
- if (all_segs && !empty_debug_line)
+ Give an error if we have seen any .loc, otherwise trust the user
+ knows what they are doing and want to generate the .debug_line
+ (and all other debug sections) themselves. */
+ if (all_segs && !empty_debug_line && dwarf2_any_loc_directive_seen)
as_fatal ("duplicate .debug_line sections");
if ((!all_segs && emit_other_sections)
sizeof_address = DWARF2_ADDR_SIZE (stdoutput);
/* Create and switch to the line number section. */
- line_seg = subseg_new (".debug_line", 0);
- bfd_set_section_flags (line_seg, SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS);
+ if (empty_debug_line)
+ {
+ line_seg = subseg_new (".debug_line", 0);
+ bfd_set_section_flags (line_seg,
+ SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS);
+ }
/* For each subsection, chain the debug entries together. */
for (s = all_segs; s; s = s->next)
}
}
- out_debug_line (line_seg);
+ if (empty_debug_line)
+ out_debug_line (line_seg);
/* If this is assembler generated line info, and there is no
debug_info already, we need .debug_info, .debug_abbrev and