/* dwarf2dbg.c - DWARF2 debug support
- Copyright (C) 1999-2020 Free Software Foundation, Inc.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of GAS, the GNU Assembler.
#include "as.h"
#include "safe-ctype.h"
-
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#else
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifndef INT_MAX
-#define INT_MAX (int) (((unsigned) (-1)) >> 1)
-#endif
-#endif
-
#include "dwarf2dbg.h"
#include <filenames.h>
/* TRUE when we've seen a .loc directive recently. Used to avoid
doing work when there's nothing to do. Will be reset by
dwarf2_consume_line_info. */
-bfd_boolean dwarf2_loc_directive_seen;
+bool 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;
+static bool 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;
+bool dwarf2_loc_mark_labels;
/* Current location as indicated by the most recent .loc directive. */
static struct dwarf2_line_info current =
/* Find or create (if CREATE_P) an entry for SEG+SUBSEG in ALL_SEGS. */
static struct line_subseg *
-get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
+get_line_subseg (segT seg, subsegT subseg, bool create_p)
{
struct line_seg *s = seg_info (seg)->dwarf2_line_seg;
struct line_subseg **pss, *lss;
{
struct line_subseg *lss;
struct line_entry *e;
+ flagword need_flags = SEC_LOAD | SEC_CODE;
+
+ /* PR 26850: Do not record LOCs in non-executable or non-loaded
+ sections. SEC_ALLOC isn't tested for non-ELF because obj-coff.c
+ obj_coff_section is careless in setting SEC_ALLOC. */
+ if (IS_ELF)
+ need_flags |= SEC_ALLOC;
+ if ((now_seg->flags & need_flags) != need_flags)
+ {
+ /* FIXME: Add code to suppress multiple warnings ? */
+ if (debug_type != DEBUG_DWARF2)
+ as_warn ("dwarf line number information for %s ignored",
+ segment_name (now_seg));
+ return;
+ }
e = XNEW (struct line_entry);
e->next = NULL;
e->label = label;
e->loc = *loc;
- lss = get_line_subseg (now_seg, now_subseg, TRUE);
+ lss = get_line_subseg (now_seg, now_subseg, true);
/* Subseg heads are chained to previous subsegs in
dwarf2_finish. */
/* Early out for as-yet incomplete location information. */
if (loc->line == 0)
return;
- if (loc->filenum == 0 && DWARF2_LINE_VERSION < 5)
- return;
+ if (loc->filenum == 0)
+ {
+ if (dwarf_level < 5)
+ dwarf_level = 5;
+ if (DWARF2_LINE_VERSION < 5)
+ return;
+ }
/* Don't emit sequences of line symbols for the same line when the
symbols apply to assembler code. It is necessary to emit
}
static unsigned int
-get_directory_table_entry (const char * dirname,
- size_t dirlen,
- bfd_boolean can_use_zero)
+get_directory_table_entry (const char *dirname,
+ size_t dirlen,
+ bool can_use_zero)
{
unsigned int d;
return d;
}
-static bfd_boolean
+static bool
assign_file_to_slot (unsigned long i, const char *file, unsigned int dir)
{
if (i >= files_allocated)
if (files_allocated <= old)
{
as_bad (_("file number %lu is too big"), (unsigned long) i);
- return FALSE;
+ return false;
}
files = XRESIZEVEC (struct file_entry, files, files_allocated);
if (files_in_use < i + 1)
files_in_use = i + 1;
- return TRUE;
+ return true;
}
/* Get a .debug_line file number for PATHNAME. If there is a
file = get_basename (pathname);
dir_len = file - pathname;
- dir = get_directory_table_entry (pathname, dir_len, FALSE);
+ dir = get_directory_table_entry (pathname, dir_len, false);
/* Do not use slot-0. That is specifically reserved for use by
the '.file 0 "name"' directive. */
if WITH_MD5 is TRUE then there is a md5 value in generic_bignum.
Returns TRUE if allocation succeeded, FALSE otherwise. */
-static bfd_boolean
-allocate_filename_to_slot (const char * dirname,
- const char * filename,
- unsigned int num,
- bfd_boolean with_md5)
+static bool
+allocate_filename_to_slot (const char *dirname,
+ const char *filename,
+ unsigned int num,
+ bool with_md5)
{
const char *file;
size_t dirlen;
{
const char * dir = NULL;
- if (dirs)
+ if (dirs != NULL)
dir = dirs[files[num].dir];
if (with_md5
/* If the filenames match, but the directory table entry was
empty, then fill it with the provided directory name. */
if (dir == NULL)
- dirs[files[num].dir] = xmemdup0 (dirname, strlen (dirname));
+ {
+ if (dirs == NULL)
+ {
+ dirs_allocated = files[num].dir + 32;
+ dirs = XCNEWVEC (char *, dirs_allocated);
+ }
+
+ dirs[files[num].dir] = xmemdup0 (dirname, strlen (dirname));
+ }
- return TRUE;
+ return true;
}
else if (dir != NULL)
{
if (filename_ncmp (filename, dir, dirlen) == 0
&& IS_DIR_SEPARATOR (filename [dirlen])
&& filename_cmp (filename + dirlen + 1, files[num].filename) == 0)
- return TRUE;
+ return true;
}
else /* dir == NULL */
{
file = get_basename (filename);
if (filename_cmp (file, files[num].filename) == 0)
{
+ /* The filenames match, but the directory table entry is empty.
+ Fill it with the provided directory name. */
if (file > filename)
- /* The filenames match, but the directory table entry is empty.
- Fill it with the provided directory name. */
- dirs[files[num].dir] = xmemdup0 (filename, file - filename);
- return TRUE;
+ {
+ if (dirs == NULL)
+ {
+ dirs_allocated = files[num].dir + 32;
+ dirs = XCNEWVEC (char *, dirs_allocated);
+ }
+
+ dirs[files[num].dir] = xmemdup0 (filename, file - filename);
+ }
+ return true;
}
}
dirname == NULL ? "" : dirname,
dirname == NULL ? "" : "/",
filename);
- return FALSE;
+ return false;
}
if (dirname == NULL)
i = num;
if (! assign_file_to_slot (i, file, d))
- return FALSE;
+ return false;
if (with_md5)
{
else
memset (files[i].md5, 0, NUM_MD5_BYTES);
- return TRUE;
+ return true;
}
/* Returns the current source information. If .file directives have
if (delta == 0)
return;
- lss = get_line_subseg (now_seg, now_subseg, FALSE);
+ lss = get_line_subseg (now_seg, now_subseg, false);
if (!lss)
return;
{
/* Unless we generate DWARF2 debugging information for each
assembler line, we only emit one line symbol for one LOC. */
- dwarf2_loc_directive_seen = FALSE;
+ dwarf2_loc_directive_seen = false;
current.flags &= ~(DWARF2_FLAG_BASIC_BLOCK
| DWARF2_FLAG_PROLOGUE_END
char *
dwarf2_directive_filename (void)
{
- bfd_boolean with_md5 = FALSE;
+ bool with_md5 = false;
valueT num;
char *filename;
const char * dirname = NULL;
num = get_absolute_expression ();
- if ((offsetT) num < 1 && DWARF2_LINE_VERSION < 5)
+ if ((offsetT) num < 1)
{
- as_bad (_("file number less than one"));
- ignore_rest_of_line ();
- return NULL;
+ if (num == 0 && dwarf_level < 5)
+ dwarf_level = 5;
+ if ((offsetT) num < 0 || DWARF2_LINE_VERSION < 5)
+ {
+ as_bad (_("file number less than one"));
+ ignore_rest_of_line ();
+ return NULL;
+ }
}
/* FIXME: Should we allow ".file <N>\n" as an expression meaning
SKIP_WHITESPACE ();
}
- if (strncmp (input_line_pointer, "md5", 3) == 0)
+ if (startswith (input_line_pointer, "md5"))
{
input_line_pointer += 3;
SKIP_WHITESPACE ();
if (exp.X_op != O_big)
as_bad (_("md5 value too small or not a constant"));
else
- with_md5 = TRUE;
+ with_md5 = true;
}
}
if (filenum < 1)
{
- if (filenum != 0 || DWARF2_LINE_VERSION < 5)
+ if (filenum == 0 && dwarf_level < 5)
+ dwarf_level = 5;
+ if (filenum < 0 || DWARF2_LINE_VERSION < 5)
{
as_bad (_("file number less than one"));
return;
}
}
- if (filenum >= (int) files_in_use || files[filenum].filename == NULL)
+ if ((valueT) filenum >= files_in_use || files[filenum].filename == NULL)
{
as_bad (_("unassigned file number %ld"), (long) filenum);
return;
if (ISDIGIT (*input_line_pointer)
|| *input_line_pointer == '-')
{
- bfd_boolean force_reset = *input_line_pointer == '-';
+ bool force_reset = *input_line_pointer == '-';
value = get_absolute_expression ();
if (value != 0)
}
demand_empty_rest_of_line ();
- dwarf2_any_loc_directive_seen = 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. */
if (strcmp (sec_name, ".text") != 0)
{
name = concat (".debug_line", sec_name, (char *) NULL);
- subseg_set (subseg_get (name, FALSE), 0);
+ subseg_set (subseg_get (name, false), 0);
}
else
/* Don't create a .debug_line.text section -
that is redundant. Instead just switch back to the
normal .debug_line section. */
- subseg_set (subseg_get (".debug_line", FALSE), 0);
+ subseg_set (subseg_get (".debug_line", false), 0);
}
do
const char *dir;
char *cp;
unsigned int i;
- bfd_boolean emit_md5 = FALSE;
- bfd_boolean emit_timestamps = TRUE;
- bfd_boolean emit_filesize = TRUE;
+ bool emit_md5 = false;
+ bool emit_timestamps = true;
+ bool emit_filesize = true;
segT line_str_seg = NULL;
symbolS *line_strp;
if (((unsigned long) DWARF2_FILE_TIME_NAME ("", "")) == -1UL)
{
- emit_timestamps = FALSE;
+ emit_timestamps = false;
-- columns;
}
if (DWARF2_FILE_SIZE_NAME ("", "") == -1)
{
- emit_filesize = FALSE;
+ emit_filesize = false;
-- columns;
}
break;
if (i < files_in_use)
{
- emit_md5 = TRUE;
+ emit_md5 = true;
++ columns;
}
/* For each section, emit a statement program. */
for (s = all_segs; s; s = s->next)
+ /* Paranoia - this check should have already have
+ been handled in dwarf2_gen_line_info_1(). */
if (SEG_NORMAL (s->seg))
process_entries (s->seg, s->head->head);
- else
- as_warn ("dwarf line number information for %s ignored",
- segment_name (s->seg));
if (flag_dwarf_sections)
/* We have to switch to the special .debug_line_end section
This section contains the line_end symbol which is used to
compute the size of the linked .debug_line section, as seen
in the DWARF Line Number header. */
- subseg_set (subseg_get (".debug_line_end", FALSE), 0);
+ subseg_set (subseg_get (".debug_line_end", false), 0);
symbol_set_value_now (line_end);
}
flag_dwarf_cie_version = 1;
}
-
/* Finish the dwarf2 debug sections. We emit .debug.line if there
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