/* dwarf.c -- display DWARF contents of a BFD binary file
- Copyright (C) 2005-2020 Free Software Foundation, Inc.
+ Copyright (C) 2005-2021 Free Software Foundation, Inc.
This file is part of GNU Binutils.
#include "sysdep.h"
#include "libiberty.h"
#include "bfd.h"
-#include "bfd_stdint.h"
+#include <stdint.h>
#include "bucomm.h"
#include "elfcomm.h"
#include "elf/common.h"
#include <elfutils/debuginfod.h>
#endif
+#include <limits.h>
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef ENABLE_CHECKING
+#define ENABLE_CHECKING 0
+#endif
+
#undef MAX
#undef MIN
#define MAX(a, b) ((a) > (b) ? (a) : (b))
{
dwo_type type;
const char * value;
+ dwarf_vma cu_offset;
struct dwo_info * next;
} dwo_info;
-static dwo_info * first_dwo_info = NULL;
-static bfd_boolean need_dwo_info;
+static dwo_info *first_dwo_info = NULL;
+static bool need_dwo_info;
separate_info * first_separate_info = NULL;
int do_debug_cu_index;
int do_wide;
int do_debug_links;
-int do_follow_links;
-bfd_boolean do_checks;
+int do_follow_links = DEFAULT_FOR_FOLLOW_LINKS;
+bool do_checks;
int dwarf_cutoff_level = -1;
unsigned long dwarf_start_die;
static struct cu_tu_set *cu_sets = NULL;
static struct cu_tu_set *tu_sets = NULL;
-static bfd_boolean load_cu_tu_indexes (void *);
+static bool load_cu_tu_indexes (void *);
/* An array that indicates for a given level of CU nesting whether
the latest DW_AT_type seen for that level was a signed type or
an unsigned type. */
#define MAX_CU_NESTING (1 << 8)
-static bfd_boolean level_type_signed[MAX_CU_NESTING];
+static bool level_type_signed[MAX_CU_NESTING];
/* Values for do_debug_lines. */
#define FLAG_DEBUG_LINES_RAW 1
unsigned int size = size_of_encoded_value (encoding);
dwarf_vma val;
- if (data + size >= end)
+ if (data >= end || size > (size_t) (end - data))
{
warn (_("Encoded value extends past end of section\n"));
* pdata = end;
return val;
}
-#if defined HAVE_LONG_LONG && SIZEOF_LONG_LONG > SIZEOF_LONG
+#if SIZEOF_LONG_LONG > SIZEOF_LONG
# ifndef __MINGW32__
# define DWARF_VMA_FMT "ll"
# define DWARF_VMA_FMT_LONG "%16.16llx"
printf ("%*s", len + 1, "");
}
-/* Format a 64-bit value, given as two 32-bit values, in hex.
- For reentrancy, this uses a buffer provided by the caller. */
-
-static const char *
-dwarf_vmatoa64 (dwarf_vma hvalue, dwarf_vma lvalue, char *buf,
- unsigned int buf_len)
-{
- int len = 0;
-
- if (hvalue == 0)
- snprintf (buf, buf_len, "%" DWARF_VMA_FMT "x", lvalue);
- else
- {
- len = snprintf (buf, buf_len, "%" DWARF_VMA_FMT "x", hvalue);
- snprintf (buf + len, buf_len - len,
- "%08" DWARF_VMA_FMT "x", lvalue);
- }
-
- return buf;
-}
-
/* Read in a LEB128 encoded value starting at address DATA.
If SIGN is true, return a signed LEB128 value.
If LENGTH_RETURN is not NULL, return in it the number of bytes read.
- If STATUS_RETURN in not NULL, return with bit 0 (LSB) set if the
+ If STATUS_RETURN is not NULL, return with bit 0 (LSB) set if the
terminating byte was not found and with bit 1 set if the value
overflows a dwarf_vma.
No bytes will be read at address END or beyond. */
dwarf_vma
read_leb128 (unsigned char *data,
const unsigned char *const end,
- bfd_boolean sign,
+ bool sign,
unsigned int *length_return,
int *status_return)
{
while (data < end)
{
unsigned char byte = *data++;
- bfd_boolean cont = (byte & 0x80) ? TRUE : FALSE;
+ unsigned char lost, mask;
- byte &= 0x7f;
num_read++;
- if (shift < sizeof (result) * 8)
+ if (shift < CHAR_BIT * sizeof (result))
{
- result |= ((dwarf_vma) byte) << shift;
- if (sign)
- {
- if ((((dwarf_signed_vma) result >> shift) & 0x7f) != byte)
- /* Overflow. */
- status |= 2;
- }
- else if ((result >> shift) != byte)
- {
- /* Overflow. */
- status |= 2;
- }
-
+ result |= ((dwarf_vma) (byte & 0x7f)) << shift;
+ /* These bits overflowed. */
+ lost = byte ^ (result >> shift);
+ /* And this is the mask of possible overflow bits. */
+ mask = 0x7f ^ ((dwarf_vma) 0x7f << shift >> shift);
shift += 7;
}
- else if (byte != 0)
+ else
{
- status |= 2;
+ lost = byte;
+ mask = 0x7f;
}
+ if ((lost & mask) != (sign && (dwarf_signed_vma) result < 0 ? mask : 0))
+ status |= 2;
- if (!cont)
+ if ((byte & 0x80) == 0)
{
status &= ~1;
- if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+ if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
result |= -((dwarf_vma) 1 << shift);
break;
}
return result;
}
-/* Read AMOUNT bytes from PTR and store them in VAL as an unsigned value.
- Checks to make sure that the read will not reach or pass END
- and that VAL is big enough to hold AMOUNT bytes. */
-#define SAFE_BYTE_GET(VAL, PTR, AMOUNT, END) \
- do \
- { \
- unsigned int amount = (AMOUNT); \
- if (sizeof (VAL) < amount) \
- { \
+/* Read AMOUNT bytes from PTR and store them in VAL.
+ Checks to make sure that the read will not reach or pass END.
+ FUNC chooses whether the value read is unsigned or signed, and may
+ be either byte_get or byte_get_signed. If INC is true, PTR is
+ incremented after reading the value.
+ This macro cannot protect against PTR values derived from user input.
+ The C standard sections 6.5.6 and 6.5.8 say attempts to do so using
+ pointers is undefined behaviour. */
+#define SAFE_BYTE_GET_INTERNAL(VAL, PTR, AMOUNT, END, FUNC, INC) \
+ do \
+ { \
+ size_t amount = (AMOUNT); \
+ if (sizeof (VAL) < amount) \
+ { \
error (ngettext ("internal error: attempt to read %d byte " \
"of data in to %d sized variable", \
"internal error: attempt to read %d bytes " \
"of data in to %d sized variable", \
amount), \
- amount, (int) sizeof (VAL)); \
- amount = sizeof (VAL); \
- } \
- if (((PTR) + amount) >= (END)) \
- { \
- if ((PTR) < (END)) \
- amount = (END) - (PTR); \
- else \
- amount = 0; \
- } \
- if (amount == 0 || amount > 8) \
- VAL = 0; \
- else \
- VAL = byte_get ((PTR), amount); \
- } \
+ (int) amount, (int) sizeof (VAL)); \
+ amount = sizeof (VAL); \
+ } \
+ if (ENABLE_CHECKING) \
+ assert ((PTR) <= (END)); \
+ size_t avail = (END) - (PTR); \
+ if ((PTR) > (END)) \
+ avail = 0; \
+ if (amount > avail) \
+ amount = avail; \
+ if (amount == 0) \
+ (VAL) = 0; \
+ else \
+ (VAL) = (FUNC) ((PTR), amount); \
+ if (INC) \
+ (PTR) += amount; \
+ } \
while (0)
-/* Like SAFE_BYTE_GET, but also increments PTR by AMOUNT. */
+#define SAFE_BYTE_GET(VAL, PTR, AMOUNT, END) \
+ SAFE_BYTE_GET_INTERNAL (VAL, PTR, AMOUNT, END, byte_get, false)
+
#define SAFE_BYTE_GET_AND_INC(VAL, PTR, AMOUNT, END) \
- do \
- { \
- SAFE_BYTE_GET (VAL, PTR, AMOUNT, END); \
- PTR += AMOUNT; \
- } \
- while (0)
+ SAFE_BYTE_GET_INTERNAL (VAL, PTR, AMOUNT, END, byte_get, true)
-/* Like SAFE_BYTE_GET, but reads a signed value. */
#define SAFE_SIGNED_BYTE_GET(VAL, PTR, AMOUNT, END) \
- do \
- { \
- unsigned int amount = (AMOUNT); \
- if (((PTR) + amount) >= (END)) \
- { \
- if ((PTR) < (END)) \
- amount = (END) - (PTR); \
- else \
- amount = 0; \
- } \
- if (amount) \
- VAL = byte_get_signed ((PTR), amount); \
- else \
- VAL = 0; \
- } \
- while (0)
+ SAFE_BYTE_GET_INTERNAL (VAL, PTR, AMOUNT, END, byte_get_signed, false)
-/* Like SAFE_SIGNED_BYTE_GET, but also increments PTR by AMOUNT. */
#define SAFE_SIGNED_BYTE_GET_AND_INC(VAL, PTR, AMOUNT, END) \
- do \
- { \
- SAFE_SIGNED_BYTE_GET (VAL, PTR, AMOUNT, END); \
- PTR += AMOUNT; \
- } \
- while (0)
-
-#define SAFE_BYTE_GET64(PTR, HIGH, LOW, END) \
- do \
- { \
- if (((PTR) + 8) <= (END)) \
- { \
- byte_get_64 ((PTR), (HIGH), (LOW)); \
- } \
- else \
- { \
- * (LOW) = * (HIGH) = 0; \
- } \
- } \
- while (0)
+ SAFE_BYTE_GET_INTERNAL (VAL, PTR, AMOUNT, END, byte_get_signed, true)
typedef struct State_Machine_Registers
{
READ_ULEB (len, data, end);
header_len = data - orig_data;
- if (len == 0 || data == end || len > (size_t) (end - data))
+ if (len == 0 || data >= end || len > (size_t) (end - data))
{
warn (_("Badly formed extended line op encountered!\n"));
return header_len;
name = data;
l = strnlen ((char *) data, end - data);
- data += l + 1;
+ data += l;
+ if (data < end)
+ data++;
READ_ULEB (val, data, end);
printf ("%s\t", dwarf_vmatoa ("u", val));
READ_ULEB (val, data, end);
printf ("%.*s\n\n", (int) l, name);
}
- if (((size_t) (data - orig_data) != len + header_len) || data == end)
+ if (((size_t) (data - orig_data) != len + header_len) || data >= end)
warn (_("DW_LNE_define_file: Bad opcode length\n"));
break;
if (offset >= section->size)
{
- warn (_("DW_FORM_strp offset too big: %s\n"),
+ warn (_("DW_FORM_strp offset too big: 0x%s\n"),
dwarf_vmatoa ("x", offset));
return (const unsigned char *) _("<offset is too big>");
}
ret = (const unsigned char *)
_("<no NUL byte at end of .debug_str section>");
- return ret;
+ return ret;
}
static const unsigned char *
if (offset >= section->size)
{
- warn (_("DW_FORM_line_strp offset too big: %s\n"),
+ warn (_("DW_FORM_line_strp offset too big: 0x%s\n"),
dwarf_vmatoa ("x", offset));
return (const unsigned char *) _("<offset is too big>");
}
static const char *
fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
- dwarf_vma offset_size, bfd_boolean dwo)
+ dwarf_vma offset_size, bool dwo)
{
enum dwarf_section_display_enum str_sec_idx = dwo ? str_dwo : str;
enum dwarf_section_display_enum idx_sec_idx = dwo ? str_index_dwo : str_index;
dwarf_vma str_offset;
const char * ret;
unsigned char *curr = index_section->start;
- const unsigned char *end = curr + index_section->size;
+ unsigned char *end = curr + index_section->size;
dwarf_vma length;
if (index_section->start == NULL)
{
/* Skip the version and padding bytes.
We assume that they are correct. */
- curr += 4;
+ if (end - curr >= 4)
+ curr += 4;
+ else
+ curr = end;
+ if (length >= 4)
+ length -= 4;
+ else
+ length = 0;
+
+ if (this_set != NULL
+ && this_set->section_sizes[DW_SECT_STR_OFFSETS] < length)
+ length = this_set->section_sizes[DW_SECT_STR_OFFSETS];
- /* FIXME: The code below assumes that there is only one table
- in the .debug_str_offsets section, so check that now. */
- if ((offset_size == 4 && curr + length < (end - 8))
- || (offset_size == 8 && curr + length < (end - 16)))
+ if (length > (dwarf_vma) (end - curr))
{
- warn (_("index table size is too small %s vs %s\n"),
+ warn (_("index table size too large for section %s vs %s\n"),
dwarf_vmatoa ("x", length),
dwarf_vmatoa ("x", index_section->size));
+ length = end - curr;
+ }
+
+ if (length < offset_size)
+ {
+ warn (_("index table size %s is too small\n"),
+ dwarf_vmatoa ("x", length));
return _("<table too small>");
}
}
index_offset = idx * offset_size;
-
+
if (this_set != NULL)
index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS];
- if (index_offset >= length)
+ if (index_offset >= length
+ || length - index_offset < offset_size)
{
- warn (_("DW_FORM_GNU_str_index offset too big: %s vs %s\n"),
+ warn (_("DW_FORM_GNU_str_index offset too big: 0x%s vs 0x%s\n"),
dwarf_vmatoa ("x", index_offset),
dwarf_vmatoa ("x", length));
return _("<index offset is too big>");
str_offset -= str_section->address;
if (str_offset >= str_section->size)
{
- warn (_("DW_FORM_GNU_str_index indirect offset too big: %s\n"),
+ warn (_("DW_FORM_GNU_str_index indirect offset too big: 0x%s\n"),
dwarf_vmatoa ("x", str_offset));
return _("<indirect index offset is too big>");
}
if (offset + bytes > section->size)
{
- warn (_("Offset into section %s too big: %s\n"),
+ warn (_("Offset into section %s too big: 0x%s\n"),
section->name, dwarf_vmatoa ("x", offset));
return "<offset too big>";
}
{
unsigned long attribute;
unsigned long form;
- bfd_signed_vma implicit_const;
+ dwarf_signed_vma implicit_const;
struct abbrev_attr * next;
}
abbrev_attr;
}
static void
-add_abbrev_attr (unsigned long attribute,
- unsigned long form,
- bfd_signed_vma implicit_const,
- abbrev_list * list)
+add_abbrev_attr (unsigned long attribute,
+ unsigned long form,
+ dwarf_signed_vma implicit_const,
+ abbrev_list * list)
{
abbrev_attr *attr;
attr = (abbrev_attr *) xmalloc (sizeof (*attr));
- attr->attribute = attribute;
- attr->form = form;
+ attr->attribute = attribute;
+ attr->form = form;
attr->implicit_const = implicit_const;
- attr->next = NULL;
+ attr->next = NULL;
assert (list != NULL && list->last_abbrev != NULL);
an abbreviation set was found. */
static unsigned char *
-process_abbrev_set (unsigned char * start,
- const unsigned char * end,
- abbrev_list * list)
+process_abbrev_set (struct dwarf_section *section,
+ dwarf_vma abbrev_base,
+ dwarf_vma abbrev_size,
+ dwarf_vma abbrev_offset,
+ abbrev_list *list)
{
+ if (abbrev_base >= section->size
+ || abbrev_size > section->size - abbrev_base)
+ {
+ /* PR 17531: file:4bcd9ce9. */
+ warn (_("Debug info is corrupted, abbrev size (%lx) is larger than "
+ "abbrev section size (%lx)\n"),
+ (unsigned long) (abbrev_base + abbrev_size),
+ (unsigned long) section->size);
+ return NULL;
+ }
+ if (abbrev_offset >= abbrev_size)
+ {
+ warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than "
+ "abbrev section size (%lx)\n"),
+ (unsigned long) abbrev_offset,
+ (unsigned long) abbrev_size);
+ return NULL;
+ }
+
+ unsigned char *start = section->start + abbrev_base;
+ unsigned char *end = start + abbrev_size;
+ start += abbrev_offset;
while (start < end)
{
unsigned long entry;
{
unsigned long form;
/* Initialize it due to a false compiler warning. */
- bfd_signed_vma implicit_const = -1;
+ dwarf_signed_vma implicit_const = -1;
READ_ULEB (attribute, start, end);
if (start == end)
need_frame_base = 1;
putchar (')');
data += uvalue;
- if (data > end)
- data = end;
break;
case DW_OP_const_type:
case DW_OP_GNU_const_type:
return NULL;
}
-/* Add INC to HIGH_BITS:LOW_BITS. */
-static void
-add64 (dwarf_vma * high_bits, dwarf_vma * low_bits, dwarf_vma inc)
-{
- dwarf_vma tmp = * low_bits;
-
- tmp += inc;
-
- /* FIXME: There is probably a better way of handling this:
-
- We need to cope with dwarf_vma being a 32-bit or 64-bit
- type. Plus regardless of its size LOW_BITS is meant to
- only hold 32-bits, so if there is overflow or wrap around
- we must propagate into HIGH_BITS. */
- if (tmp < * low_bits)
- {
- ++ * high_bits;
- }
- else if (sizeof (tmp) > 8
- && (tmp >> 31) > 1)
- {
- ++ * high_bits;
- tmp &= 0xFFFFFFFF;
- }
-
- * low_bits = tmp;
-}
-
static const char *
fetch_alt_indirect_string (dwarf_vma offset)
{
return ret;
}
-
+
warn (_("DW_FORM_GNU_strp_alt offset (%s) too big or no string sections available\n"),
dwarf_vmatoa ("x", offset));
return _("<offset is too big>");
}
static void
-add_dwo_info (const char * field, dwo_type type)
+add_dwo_info (const char * value, dwarf_vma cu_offset, dwo_type type)
{
dwo_info * dwinfo = xmalloc (sizeof * dwinfo);
- dwinfo->type = type;
- dwinfo->value = field;
- dwinfo->next = first_dwo_info;
+ dwinfo->type = type;
+ dwinfo->value = value;
+ dwinfo->cu_offset = cu_offset;
+ dwinfo->next = first_dwo_info;
first_dwo_info = dwinfo;
}
static void
-add_dwo_name (const char * name)
+add_dwo_name (const char * name, dwarf_vma cu_offset)
{
- add_dwo_info (name, DWO_NAME);
+ add_dwo_info (name, cu_offset, DWO_NAME);
}
static void
-add_dwo_dir (const char * dir)
+add_dwo_dir (const char * dir, dwarf_vma cu_offset)
{
- add_dwo_info (dir, DWO_DIR);
+ add_dwo_info (dir, cu_offset, DWO_DIR);
}
static void
-add_dwo_id (const char * id)
+add_dwo_id (const char * id, dwarf_vma cu_offset)
{
- add_dwo_info (id, DWO_ID);
+ add_dwo_info (id, cu_offset, DWO_ID);
}
static void
}
static unsigned char *
-skip_attr_bytes (unsigned long form,
- unsigned char * data,
- unsigned const char * end,
- dwarf_vma pointer_size,
- dwarf_vma offset_size,
- int dwarf_version,
- dwarf_vma * value_return)
+skip_attr_bytes (unsigned long form,
+ unsigned char *data,
+ unsigned char *end,
+ dwarf_vma pointer_size,
+ dwarf_vma offset_size,
+ int dwarf_version,
+ dwarf_vma *value_return)
{
dwarf_signed_vma svalue;
dwarf_vma uvalue = 0;
+ dwarf_vma inc = 0;
* value_return = 0;
case DW_FORM_ref1:
case DW_FORM_flag:
case DW_FORM_data1:
+ case DW_FORM_strx1:
+ case DW_FORM_addrx1:
SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
break;
+ case DW_FORM_strx3:
+ case DW_FORM_addrx3:
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 3, end);
+ break;
+
case DW_FORM_ref2:
case DW_FORM_data2:
+ case DW_FORM_strx2:
+ case DW_FORM_addrx2:
SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
break;
case DW_FORM_ref4:
case DW_FORM_data4:
+ case DW_FORM_strx4:
+ case DW_FORM_addrx4:
SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
break;
case DW_FORM_ref_udata:
case DW_FORM_udata:
case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
case DW_FORM_GNU_addr_index:
+ case DW_FORM_addrx:
READ_ULEB (uvalue, data, end);
break;
case DW_FORM_ref8:
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 8, end);
+ break;
+
case DW_FORM_data8:
case DW_FORM_ref_sig8:
- data += 8;
+ inc = 8;
break;
case DW_FORM_data16:
- data += 16;
+ inc = 16;
break;
case DW_FORM_string:
- data += strnlen ((char *) data, end - data) + 1;
+ inc = strnlen ((char *) data, end - data) + 1;
break;
case DW_FORM_block:
case DW_FORM_exprloc:
READ_ULEB (uvalue, data, end);
- data += uvalue;
+ inc = uvalue;
break;
case DW_FORM_block1:
- SAFE_BYTE_GET (uvalue, data, 1, end);
- data += 1 + uvalue;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ inc = uvalue;
break;
case DW_FORM_block2:
- SAFE_BYTE_GET (uvalue, data, 2, end);
- data += 2 + uvalue;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
+ inc = uvalue;
break;
case DW_FORM_block4:
- SAFE_BYTE_GET (uvalue, data, 4, end);
- data += 4 + uvalue;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+ inc = uvalue;
break;
case DW_FORM_indirect:
READ_ULEB (form, data, end);
if (form == DW_FORM_implicit_const)
SKIP_ULEB (data, end);
- return skip_attr_bytes (form, data, end, pointer_size, offset_size, dwarf_version, value_return);
+ return skip_attr_bytes (form, data, end, pointer_size, offset_size,
+ dwarf_version, value_return);
default:
return NULL;
}
* value_return = uvalue;
- if (data > end)
- data = (unsigned char *) end;
+ if (inc <= (dwarf_vma) (end - data))
+ data += inc;
+ else
+ data = end;
return data;
}
associated with it. */
static abbrev_entry *
-get_type_abbrev_from_form (unsigned long form,
- unsigned long uvalue,
- dwarf_vma cu_offset,
- const struct dwarf_section * section,
- unsigned long * abbrev_num_return,
- unsigned char ** data_return,
- unsigned long * cu_offset_return)
+get_type_abbrev_from_form (unsigned long form,
+ unsigned long uvalue,
+ dwarf_vma cu_offset,
+ unsigned char *cu_end,
+ const struct dwarf_section *section,
+ unsigned long *abbrev_num_return,
+ unsigned char **data_return,
+ abbrev_map **map_return)
{
unsigned long abbrev_number;
abbrev_map * map;
switch (form)
{
case DW_FORM_GNU_ref_alt:
+ case DW_FORM_ref_sig8:
/* FIXME: We are unable to handle this form at the moment. */
return NULL;
}
break;
+ case DW_FORM_ref_sup4:
+ case DW_FORM_ref_sup8:
+ break;
+
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
+ case DW_FORM_ref8:
case DW_FORM_ref_udata:
- if (uvalue + cu_offset > section->size)
+ if (uvalue + cu_offset > (size_t) (cu_end - section->start))
{
- warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > section size %lx\n"),
- uvalue, (long) cu_offset, (long) section->size);
+ warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"),
+ uvalue, (long) cu_offset, (long) (cu_end - section->start));
return NULL;
}
uvalue += cu_offset;
data = (unsigned char *) section->start + uvalue;
map = find_abbrev_map_by_offset (uvalue);
-
+
if (map == NULL)
{
warn (_("Unable to find abbreviations for CU offset %#lx\n"), uvalue);
return NULL;
}
- if (cu_offset_return != NULL)
+ if (map_return != NULL)
{
if (form == DW_FORM_ref_addr)
- * cu_offset_return = map->start;
+ *map_return = map;
else
- * cu_offset_return = cu_offset;
+ *map_return = NULL;
}
READ_ULEB (abbrev_number, data, section->start + section->size);
for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next)
if (entry->number == abbrev_number)
break;
-
+
if (abbrev_num_return != NULL)
* abbrev_num_return = abbrev_number;
found starting at DATA. */
static void
-get_type_signedness (abbrev_entry * entry,
- const struct dwarf_section * section,
- unsigned char * data,
- unsigned const char * end,
- dwarf_vma cu_offset,
- dwarf_vma pointer_size,
- dwarf_vma offset_size,
- int dwarf_version,
- bfd_boolean * is_signed,
- unsigned int nesting)
+get_type_signedness (abbrev_entry *entry,
+ const struct dwarf_section *section,
+ unsigned char *data,
+ unsigned char *end,
+ dwarf_vma cu_offset,
+ dwarf_vma pointer_size,
+ dwarf_vma offset_size,
+ int dwarf_version,
+ bool *is_signed,
+ unsigned int nesting)
{
abbrev_attr * attr;
- * is_signed = FALSE;
+ * is_signed = false;
#define MAX_NESTING 20
if (nesting > MAX_NESTING)
if (attr->form == DW_FORM_strp)
printf (", %s", fetch_indirect_string (uvalue));
else if (attr->form == DW_FORM_string)
- printf (", %s", orig_data);
+ printf (", %.*s", (int) (end - orig_data), orig_data);
}
break;
case DW_AT_type:
/* Recurse. */
{
- abbrev_entry * type_abbrev;
- unsigned char * type_data;
- unsigned long type_cu_offset;
+ abbrev_entry *type_abbrev;
+ unsigned char *type_data;
+ abbrev_map *map;
type_abbrev = get_type_abbrev_from_form (attr->form,
uvalue,
cu_offset,
+ end,
section,
NULL /* abbrev num return */,
- & type_data,
- & type_cu_offset);
+ &type_data,
+ &map);
if (type_abbrev == NULL)
break;
- get_type_signedness (type_abbrev, section, type_data, end, type_cu_offset,
+ get_type_signedness (type_abbrev, section, type_data,
+ map ? section->start + map->end : end,
+ map ? map->start : cu_offset,
pointer_size, offset_size, dwarf_version,
is_signed, nesting + 1);
}
case DW_ATE_unsigned:
case DW_ATE_unsigned_char:
case DW_ATE_unsigned_fixed:
- * is_signed = FALSE;
+ * is_signed = false;
break;
default:
case DW_ATE_imaginary_float:
case DW_ATE_decimal_float:
case DW_ATE_signed_fixed:
- * is_signed = TRUE;
+ * is_signed = true;
break;
}
break;
}
static void
-read_and_print_leb128 (unsigned char * data,
- unsigned int * bytes_read,
- unsigned const char * end,
- bfd_boolean is_signed)
+read_and_print_leb128 (unsigned char *data,
+ unsigned int *bytes_read,
+ unsigned const char *end,
+ bool is_signed)
{
int status;
dwarf_vma val = read_leb128 (data, end, is_signed, bytes_read, &status);
if (status != 0)
- report_leb_status (status, __FILE__, __LINE__);
+ report_leb_status (status);
else
printf ("%s", dwarf_vmatoa (is_signed ? "d" : "u", val));
}
display_discr_list (unsigned long form,
dwarf_vma uvalue,
unsigned char * data,
- unsigned const char * end,
int level)
{
+ unsigned char *end = data;
+
if (uvalue == 0)
{
printf ("[default]");
return;
}
-
+
switch (form)
{
case DW_FORM_block:
return;
}
- bfd_boolean is_signed =
- (level > 0 && level <= MAX_CU_NESTING)
- ? level_type_signed [level - 1] : FALSE;
-
+ bool is_signed = (level > 0 && level <= MAX_CU_NESTING
+ ? level_type_signed [level - 1] : false);
+
printf ("(");
- while (uvalue)
+ while (data < end)
{
unsigned char discriminant;
unsigned int bytes_read;
- SAFE_BYTE_GET (discriminant, data, 1, end);
- -- uvalue;
- data ++;
+ SAFE_BYTE_GET_AND_INC (discriminant, data, 1, end);
- assert (uvalue > 0);
switch (discriminant)
{
case DW_DSC_label:
printf ("label ");
read_and_print_leb128 (data, & bytes_read, end, is_signed);
- assert (bytes_read <= uvalue && bytes_read > 0);
- uvalue -= bytes_read;
data += bytes_read;
break;
case DW_DSC_range:
printf ("range ");
read_and_print_leb128 (data, & bytes_read, end, is_signed);
- assert (bytes_read <= uvalue && bytes_read > 0);
- uvalue -= bytes_read;
data += bytes_read;
printf ("..");
read_and_print_leb128 (data, & bytes_read, end, is_signed);
- assert (bytes_read <= uvalue && bytes_read > 0);
- uvalue -= bytes_read;
data += bytes_read;
break;
default:
printf ("<corrupt>\n");
- warn (_("corrupt discr_list - unrecognised discriminant byte %#x\n"),
+ warn (_("corrupt discr_list - unrecognized discriminant byte %#x\n"),
discriminant);
return;
}
- if (uvalue)
+ if (data < end)
printf (", ");
}
int level)
{
dwarf_signed_vma svalue;
- dwarf_vma uvalue = 0;
- unsigned char * block_start = NULL;
- unsigned char * orig_data = data;
+ dwarf_vma uvalue = 0;
+ dwarf_vma uvalue_hi = 0;
+ unsigned char *block_start = NULL;
+ unsigned char *orig_data = data;
if (data > end || (data == end && form != DW_FORM_flag_present))
{
return data;
}
+ if (do_wide && ! do_loc)
+ {
+ /* PR 26847: Display the name of the form. */
+ const char * name = get_FORM_name (form);
+
+ /* For convenience we skip the DW_FORM_ prefix to the name. */
+ if (name[0] == 'D')
+ name += 8; /* strlen ("DW_FORM_") */
+ printf ("%c(%s)", delimiter, name);
+ }
+
switch (form)
{
default:
SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
break;
+ case DW_FORM_strp_sup:
case DW_FORM_strp:
case DW_FORM_line_strp:
case DW_FORM_sec_offset:
case DW_FORM_ref1:
case DW_FORM_flag:
case DW_FORM_data1:
+ case DW_FORM_strx1:
+ case DW_FORM_addrx1:
SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
break;
case DW_FORM_ref2:
case DW_FORM_data2:
+ case DW_FORM_strx2:
+ case DW_FORM_addrx2:
SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
break;
+ case DW_FORM_strx3:
+ case DW_FORM_addrx3:
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 3, end);
+ break;
+
+ case DW_FORM_ref_sup4:
case DW_FORM_ref4:
case DW_FORM_data4:
+ case DW_FORM_strx4:
+ case DW_FORM_addrx4:
SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
break;
+ case DW_FORM_ref_sup8:
+ case DW_FORM_ref8:
+ case DW_FORM_data8:
+ case DW_FORM_ref_sig8:
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 8, end);
+ break;
+
+ case DW_FORM_data16:
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 8, end);
+ SAFE_BYTE_GET_AND_INC (uvalue_hi, data, 8, end);
+ if (byte_get != byte_get_little_endian)
+ {
+ dwarf_vma utmp = uvalue;
+ uvalue = uvalue_hi;
+ uvalue_hi = utmp;
+ }
+ break;
+
case DW_FORM_sdata:
READ_SLEB (svalue, data, end);
uvalue = svalue;
break;
case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
case DW_FORM_ref_udata:
case DW_FORM_udata:
case DW_FORM_GNU_addr_index:
+ case DW_FORM_addrx:
READ_ULEB (uvalue, data, end);
break;
offset_size, dwarf_version,
debug_info_p, do_loc,
section, this_set, delimiter, level);
+
+ case DW_FORM_implicit_const:
+ uvalue = implicit_const;
+ break;
}
switch (form)
case DW_FORM_GNU_ref_alt:
if (!do_loc)
- printf ("%c<alt 0x%s>", delimiter, dwarf_vmatoa ("x", uvalue));
+ {
+ if (do_wide)
+ /* We have already printed the form name. */
+ printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue));
+ else
+ printf ("%c<alt 0x%s>", delimiter, dwarf_vmatoa ("x", uvalue));
+ }
/* FIXME: Follow the reference... */
break;
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
+ case DW_FORM_ref_sup4:
case DW_FORM_ref_udata:
if (!do_loc)
printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
printf ("%c%s", delimiter, dwarf_vmatoa ("d", implicit_const));
break;
+ case DW_FORM_ref_sup8:
case DW_FORM_ref8:
case DW_FORM_data8:
if (!do_loc)
{
- dwarf_vma high_bits;
- dwarf_vma utmp;
- char buf[64];
-
- SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
- utmp = uvalue;
+ dwarf_vma utmp = uvalue;
if (form == DW_FORM_ref8)
- add64 (& high_bits, & utmp, cu_offset);
- printf ("%c0x%s", delimiter,
- dwarf_vmatoa64 (high_bits, utmp, buf, sizeof (buf)));
+ utmp += cu_offset;
+ printf ("%c0x%s", delimiter, dwarf_vmatoa ("x", utmp));
}
-
- if ((do_loc || do_debug_loc || do_debug_ranges)
- && num_debug_info_entries == 0)
- {
- if (sizeof (uvalue) == 8)
- SAFE_BYTE_GET (uvalue, data, 8, end);
- else
- error (_("DW_FORM_data8 is unsupported when sizeof (dwarf_vma) != 8\n"));
- }
-
- data += 8;
break;
case DW_FORM_data16:
if (!do_loc)
- {
- dwarf_vma left_high_bits, left_low_bits;
- dwarf_vma right_high_bits, right_low_bits;
-
- SAFE_BYTE_GET64 (data, &left_high_bits, &left_low_bits, end);
- SAFE_BYTE_GET64 (data + 8, &right_high_bits, &right_low_bits, end);
- if (byte_get == byte_get_little_endian)
- {
- /* Swap them. */
- left_high_bits ^= right_high_bits;
- right_high_bits ^= left_high_bits;
- left_high_bits ^= right_high_bits;
- left_low_bits ^= right_low_bits;
- right_low_bits ^= left_low_bits;
- left_low_bits ^= right_low_bits;
- }
- printf (" 0x%08" DWARF_VMA_FMT "x%08" DWARF_VMA_FMT "x"
- "%08" DWARF_VMA_FMT "x%08" DWARF_VMA_FMT "x",
- left_high_bits, left_low_bits, right_high_bits,
- right_low_bits);
- }
- data += 16;
+ printf (" 0x%s%s",
+ uvalue_hi == 0 ? "" : dwarf_vmatoa ("x", uvalue_hi),
+ dwarf_vmatoa_1 ("x", uvalue, uvalue_hi == 0 ? 0 : 8));
break;
case DW_FORM_string:
if (!do_loc)
printf ("%c%.*s", delimiter, (int) (end - data), data);
- data += strnlen ((char *) data, end - data) + 1;
+ data += strnlen ((char *) data, end - data);
+ if (data < end)
+ data++;
break;
case DW_FORM_block:
case DW_FORM_strp:
if (!do_loc)
- printf (_("%c(indirect string, offset: 0x%s): %s"), delimiter,
- dwarf_vmatoa ("x", uvalue),
- fetch_indirect_string (uvalue));
+ {
+ if (do_wide)
+ /* We have already displayed the form name. */
+ printf (_("%c(offset: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indirect_string (uvalue));
+ else
+ printf (_("%c(indirect string, offset: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indirect_string (uvalue));
+ }
break;
case DW_FORM_line_strp:
if (!do_loc)
- printf (_("%c(indirect line string, offset: 0x%s): %s"), delimiter,
- dwarf_vmatoa ("x", uvalue),
- fetch_indirect_line_string (uvalue));
+ {
+ if (do_wide)
+ /* We have already displayed the form name. */
+ printf (_("%c(offset: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indirect_line_string (uvalue));
+ else
+ printf (_("%c(indirect line string, offset: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indirect_line_string (uvalue));
+ }
break;
case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
if (!do_loc)
{
- const char * suffix = strrchr (section->name, '.');
- bfd_boolean dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? TRUE : FALSE;
+ const char *suffix = strrchr (section->name, '.');
+ bool dwo = suffix && strcmp (suffix, ".dwo") == 0;
- printf (_("%c(indexed string: 0x%s): %s"), delimiter,
- dwarf_vmatoa ("x", uvalue),
- fetch_indexed_string (uvalue, this_set, offset_size, dwo));
+ if (do_wide)
+ /* We have already displayed the form name. */
+ printf (_("%c(offset: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indexed_string (uvalue, this_set, offset_size, dwo));
+ else
+ printf (_("%c(indexed string: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indexed_string (uvalue, this_set, offset_size, dwo));
}
break;
case DW_FORM_GNU_strp_alt:
if (!do_loc)
{
- printf (_("%c(alt indirect string, offset: 0x%s) %s"), delimiter,
- dwarf_vmatoa ("x", uvalue),
- fetch_alt_indirect_string (uvalue));
+ if (do_wide)
+ /* We have already displayed the form name. */
+ printf (_("%c(offset: 0x%s) %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_alt_indirect_string (uvalue));
+ else
+ printf (_("%c(alt indirect string, offset: 0x%s) %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_alt_indirect_string (uvalue));
}
break;
break;
case DW_FORM_ref_sig8:
+ if (!do_loc)
+ printf ("%c%s: 0x%s", delimiter, do_wide ? "" : "signature",
+ dwarf_vmatoa ("x", uvalue));
+ break;
+
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_addrx:
+ case DW_FORM_addrx1:
+ case DW_FORM_addrx2:
+ case DW_FORM_addrx3:
+ case DW_FORM_addrx4:
if (!do_loc)
{
- dwarf_vma high_bits;
- char buf[64];
+ dwarf_vma base;
+ dwarf_vma offset;
+
+ if (debug_info_p == NULL)
+ base = 0;
+ else if (debug_info_p->addr_base == DEBUG_INFO_UNAVAILABLE)
+ base = 0;
+ else
+ base = debug_info_p->addr_base;
- SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
- printf ("%csignature: 0x%s", delimiter,
- dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
+ offset = base + uvalue * pointer_size;
+
+ if (do_wide)
+ /* We have already displayed the form name. */
+ printf (_("%c(index: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indexed_value (offset, pointer_size));
+ else
+ printf (_("%c(addr_index: 0x%s): %s"), delimiter,
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indexed_value (offset, pointer_size));
}
- data += 8;
break;
- case DW_FORM_GNU_addr_index:
+ case DW_FORM_strp_sup:
if (!do_loc)
- printf (_("%c(addr_index: 0x%s): %s"), delimiter,
- dwarf_vmatoa ("x", uvalue),
- fetch_indexed_value (uvalue * pointer_size, pointer_size));
+ printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
break;
-
+
default:
- warn (_("Unrecognized form: %lu\n"), form);
+ warn (_("Unrecognized form: 0x%lx\n"), form);
+ /* What to do? Consume a byte maybe? */
+ ++data;
break;
}
break;
case DW_AT_GNU_addr_base:
+ case DW_AT_addr_base:
debug_info_p->addr_base = uvalue;
break;
switch (form)
{
case DW_FORM_strp:
- add_dwo_name ((const char *) fetch_indirect_string (uvalue));
+ add_dwo_name ((const char *) fetch_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_strp_alt:
- add_dwo_name ((const char *) fetch_alt_indirect_string (uvalue));
+ add_dwo_name ((const char *) fetch_alt_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_str_index:
- add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, FALSE));
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
+ add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false), cu_offset);
break;
case DW_FORM_string:
- add_dwo_name ((const char *) orig_data);
+ add_dwo_name ((const char *) orig_data, cu_offset);
break;
default:
warn (_("Unsupported form (%s) for attribute %s\n"),
break;
}
break;
-
+
case DW_AT_comp_dir:
/* FIXME: Also extract a build-id in a CU/TU. */
if (need_dwo_info)
switch (form)
{
case DW_FORM_strp:
- add_dwo_dir ((const char *) fetch_indirect_string (uvalue));
+ add_dwo_dir ((const char *) fetch_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_strp_alt:
- add_dwo_dir (fetch_alt_indirect_string (uvalue));
+ add_dwo_dir (fetch_alt_indirect_string (uvalue), cu_offset);
break;
case DW_FORM_line_strp:
- add_dwo_dir ((const char *) fetch_indirect_line_string (uvalue));
+ add_dwo_dir ((const char *) fetch_indirect_line_string (uvalue), cu_offset);
break;
case DW_FORM_GNU_str_index:
- add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, FALSE));
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
+ add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false), cu_offset);
break;
case DW_FORM_string:
- add_dwo_dir ((const char *) orig_data);
+ add_dwo_dir ((const char *) orig_data, cu_offset);
break;
default:
warn (_("Unsupported form (%s) for attribute %s\n"),
break;
}
break;
-
+
case DW_AT_GNU_dwo_id:
if (need_dwo_info)
switch (form)
{
case DW_FORM_data8:
/* FIXME: Record the length of the ID as well ? */
- add_dwo_id ((const char *) (data - 8));
+ add_dwo_id ((const char *) (data - 8), cu_offset);
break;
default:
warn (_("Unsupported form (%s) for attribute %s\n"),
break;
}
break;
-
+
default:
break;
}
if (level >= 0 && level < MAX_CU_NESTING
&& uvalue < (size_t) (end - start))
{
- bfd_boolean is_signed = FALSE;
- abbrev_entry * type_abbrev;
- unsigned char * type_data;
- unsigned long type_cu_offset;
-
- type_abbrev = get_type_abbrev_from_form (form, uvalue, cu_offset,
- section, NULL, & type_data, & type_cu_offset);
+ bool is_signed = false;
+ abbrev_entry *type_abbrev;
+ unsigned char *type_data;
+ abbrev_map *map;
+
+ type_abbrev = get_type_abbrev_from_form (form, uvalue,
+ cu_offset, end,
+ section, NULL,
+ &type_data, &map);
if (type_abbrev != NULL)
{
- get_type_signedness (type_abbrev, section, type_data, end, type_cu_offset,
+ get_type_signedness (type_abbrev, section, type_data,
+ map ? section->start + map->end : end,
+ map ? map->start : cu_offset,
pointer_size, offset_size, dwarf_version,
& is_signed, 0);
}
level_type_signed[level] = is_signed;
}
break;
-
+
case DW_AT_inline:
printf ("\t");
switch (uvalue)
case DW_AT_discr_list:
printf ("\t");
- display_discr_list (form, uvalue, data, end, level);
+ display_discr_list (form, uvalue, data, level);
break;
-
+
case DW_AT_frame_base:
have_frame_base = 1;
/* Fall through. */
unsigned long abbrev_number;
abbrev_entry *entry;
- entry = get_type_abbrev_from_form (form, uvalue, cu_offset,
+ entry = get_type_abbrev_from_form (form, uvalue, cu_offset, end,
section, & abbrev_number, NULL, NULL);
if (entry == NULL)
{
following debug links, then attempt to load the requested section
from one of the separate debug info files. */
-static bfd_boolean
+static bool
load_debug_section_with_follow (enum dwarf_section_display_enum sec_enum,
void * handle)
{
}
}
- return TRUE;
+ return true;
}
if (do_follow_links)
/* FIXME: We should check to see if any of the remaining debug info
files also contain this section, and, umm, do something about it. */
- return TRUE;
+ return true;
}
}
}
- return FALSE;
+ return false;
}
static void
-introduce (struct dwarf_section * section, bfd_boolean raw)
+introduce (struct dwarf_section * section, bool raw)
{
if (raw)
{
printf (_("Contents of the %s section:\n\n"), section->name);
}
}
-
+
/* Process the contents of a .debug_info section.
If do_loc is TRUE then we are scanning for location lists and dwo tags
and we do not want to display anything to the user.
Returns TRUE upon success. Otherwise an error or warning message is
printed and FALSE is returned. */
-static bfd_boolean
-process_debug_info (struct dwarf_section * section,
- void * file,
- enum dwarf_section_display_enum abbrev_sec,
- bfd_boolean do_loc,
- bfd_boolean do_types)
+static bool
+process_debug_info (struct dwarf_section * section,
+ void *file,
+ enum dwarf_section_display_enum abbrev_sec,
+ bool do_loc,
+ bool do_types)
{
unsigned char *start = section->start;
unsigned char *end = start + section->size;
unsigned int unit;
unsigned int num_units = 0;
- if ((do_loc || do_debug_loc || do_debug_ranges)
- && num_debug_info_entries == 0
- && ! do_types)
+ /* First scan the section to get the number of comp units.
+ Length sanity checks are done here. */
+ for (section_begin = start, num_units = 0; section_begin < end;
+ num_units ++)
{
dwarf_vma length;
- /* First scan the section to get the number of comp units. */
- for (section_begin = start, num_units = 0; section_begin < end;
- num_units ++)
- {
- /* Read the first 4 bytes. For a 32-bit DWARF section, this
- will be the length. For a 64-bit DWARF section, it'll be
- the escape code 0xffffffff followed by an 8 byte length. */
- SAFE_BYTE_GET (length, section_begin, 4, end);
-
- if (length == 0xffffffff)
- {
- SAFE_BYTE_GET (length, section_begin + 4, 8, end);
- section_begin += length + 12;
- }
- else if (length >= 0xfffffff0 && length < 0xffffffff)
- {
- warn (_("Reserved length value (0x%s) found in section %s\n"),
- dwarf_vmatoa ("x", length), section->name);
- return FALSE;
- }
- else
- section_begin += length + 4;
+ /* Read the first 4 bytes. For a 32-bit DWARF section, this
+ will be the length. For a 64-bit DWARF section, it'll be
+ the escape code 0xffffffff followed by an 8 byte length. */
+ SAFE_BYTE_GET_AND_INC (length, section_begin, 4, end);
- /* Negative values are illegal, they may even cause infinite
- looping. This can happen if we can't accurately apply
- relocations to an object file, or if the file is corrupt. */
- if ((signed long) length <= 0 || section_begin < start)
- {
- warn (_("Corrupt unit length (0x%s) found in section %s\n"),
- dwarf_vmatoa ("x", length), section->name);
- return FALSE;
- }
+ if (length == 0xffffffff)
+ SAFE_BYTE_GET_AND_INC (length, section_begin, 8, end);
+ else if (length >= 0xfffffff0 && length < 0xffffffff)
+ {
+ warn (_("Reserved length value (0x%s) found in section %s\n"),
+ dwarf_vmatoa ("x", length), section->name);
+ return false;
}
- if (num_units == 0)
+ /* Negative values are illegal, they may even cause infinite
+ looping. This can happen if we can't accurately apply
+ relocations to an object file, or if the file is corrupt. */
+ if (length > (size_t) (end - section_begin))
{
- error (_("No comp units in %s section ?\n"), section->name);
- return FALSE;
+ warn (_("Corrupt unit length (got 0x%s expected at most 0x%s) in section %s\n"),
+ dwarf_vmatoa ("x", length),
+ dwarf_vmatoa ("x", end - section_begin),
+ section->name);
+ return false;
}
+ section_begin += length;
+ }
+
+ if (num_units == 0)
+ {
+ error (_("No comp units in %s section ?\n"), section->name);
+ return false;
+ }
+
+ if ((do_loc || do_debug_loc || do_debug_ranges)
+ && num_debug_info_entries == 0
+ && ! do_types)
+ {
/* Then allocate an array to hold the information. */
debug_information = (debug_info *) cmalloc (num_units,
error (_("Not enough memory for a debug info array of %u entries\n"),
num_units);
alloc_num_debug_info_entries = num_debug_info_entries = 0;
- return FALSE;
+ return false;
}
/* PR 17531: file: 92ca3797.
load_debug_section_with_follow (str_index_dwo, file);
load_debug_section_with_follow (debug_addr, file);
}
-
+
load_debug_section_with_follow (abbrev_sec, file);
if (debug_displays [abbrev_sec].section.start == NULL)
{
warn (_("Unable to locate %s section!\n"),
debug_displays [abbrev_sec].section.uncompressed_name);
- return FALSE;
+ return false;
}
if (!do_loc && dwarf_start_die == 0)
- introduce (section, FALSE);
+ introduce (section, false);
free_all_abbrevs ();
free (cu_abbrev_map);
cu_abbrev_map = NULL;
next_free_abbrev_map_entry = 0;
-
+
/* In order to be able to resolve DW_FORM_ref_attr forms we need
to load *all* of the abbrevs for all CUs in this .debug_info
section. This does effectively mean that we (partially) read
size_t abbrev_size;
dwarf_vma cu_offset;
unsigned int offset_size;
- unsigned int initial_length_size;
struct cu_tu_set * this_set;
abbrev_list * list;
+ unsigned char *end_cu;
hdrptr = start;
+ cu_offset = start - section_begin;
SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 4, end);
{
SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 8, end);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
-
- SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end);
+ offset_size = 4;
+ end_cu = hdrptr + compunit.cu_length;
- cu_offset = start - section_begin;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end_cu);
this_set = find_cu_tu_set_v2 (cu_offset, do_types);
}
else
{
- SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end_cu);
do_types = (compunit.cu_unit_type == DW_UT_type);
- SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu);
}
- SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size,
+ end_cu);
+
+ if (compunit.cu_unit_type == DW_UT_split_compile
+ || compunit.cu_unit_type == DW_UT_skeleton)
+ {
+ uint64_t dwo_id;
+ SAFE_BYTE_GET_AND_INC (dwo_id, hdrptr, 8, end_cu);
+ }
if (this_set == NULL)
{
list = new_abbrev_list (abbrev_base,
compunit.cu_abbrev_offset);
- next = process_abbrev_set
- (((unsigned char *) debug_displays [abbrev_sec].section.start
- + abbrev_base + compunit.cu_abbrev_offset),
- ((unsigned char *) debug_displays [abbrev_sec].section.start
- + abbrev_base + abbrev_size),
- list);
+ next = process_abbrev_set (&debug_displays[abbrev_sec].section,
+ abbrev_base, abbrev_size,
+ compunit.cu_abbrev_offset, list);
list->start_of_next_abbrevs = next;
}
-
- start = section_begin + cu_offset + compunit.cu_length
- + initial_length_size;
+
+ start = end_cu;
record_abbrev_list_for_cu (cu_offset, start - section_begin, list);
}
unsigned char *tags;
int level, last_level, saved_level;
dwarf_vma cu_offset;
- unsigned long sec_off;
unsigned int offset_size;
- unsigned int initial_length_size;
- dwarf_vma signature_high = 0;
- dwarf_vma signature_low = 0;
+ dwarf_vma signature = 0;
dwarf_vma type_offset = 0;
struct cu_tu_set *this_set;
dwarf_vma abbrev_base;
size_t abbrev_size;
abbrev_list * list = NULL;
+ unsigned char *end_cu;
hdrptr = start;
+ cu_offset = start - section_begin;
SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 4, end);
{
SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 8, end);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
+ offset_size = 4;
+ end_cu = hdrptr + compunit.cu_length;
- SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end);
-
- cu_offset = start - section_begin;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end_cu);
this_set = find_cu_tu_set_v2 (cu_offset, do_types);
}
else
{
- SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end_cu);
do_types = (compunit.cu_unit_type == DW_UT_type);
- SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu);
}
- SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end_cu);
if (this_set == NULL)
{
}
if (compunit.cu_version < 5)
- SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu);
+
+ bool do_dwo_id = false;
+ uint64_t dwo_id = 0;
+ if (compunit.cu_unit_type == DW_UT_split_compile
+ || compunit.cu_unit_type == DW_UT_skeleton)
+ {
+ SAFE_BYTE_GET_AND_INC (dwo_id, hdrptr, 8, end_cu);
+ do_dwo_id = true;
+ }
/* PR 17512: file: 001-108546-0.001:0.1. */
if (compunit.cu_pointer_size < 2 || compunit.cu_pointer_size > 8)
if (do_types)
{
- SAFE_BYTE_GET64 (hdrptr, &signature_high, &signature_low, end);
- hdrptr += 8;
- SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (signature, hdrptr, 8, end_cu);
+ SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end_cu);
}
- if (dwarf_start_die > (cu_offset + compunit.cu_length
- + initial_length_size))
+ if (dwarf_start_die >= (size_t) (end_cu - section_begin))
{
- start = section_begin + cu_offset + compunit.cu_length
- + initial_length_size;
+ start = end_cu;
continue;
}
offset_size == 8 ? "64-bit" : "32-bit");
printf (_(" Version: %d\n"), compunit.cu_version);
if (compunit.cu_version >= 5)
- printf (_(" Unit Type: %s (%x)\n"),
- get_DW_UT_name (compunit.cu_unit_type) ?: "???",
- compunit.cu_unit_type);
+ {
+ const char *name = get_DW_UT_name (compunit.cu_unit_type);
+
+ printf (_(" Unit Type: %s (%x)\n"),
+ name ? name : "???",
+ compunit.cu_unit_type);
+ }
printf (_(" Abbrev Offset: 0x%s\n"),
dwarf_vmatoa ("x", compunit.cu_abbrev_offset));
printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
if (do_types)
{
- char buf[64];
-
printf (_(" Signature: 0x%s\n"),
- dwarf_vmatoa64 (signature_high, signature_low,
- buf, sizeof (buf)));
+ dwarf_vmatoa ("x", signature));
printf (_(" Type Offset: 0x%s\n"),
dwarf_vmatoa ("x", type_offset));
}
+ if (do_dwo_id)
+ printf (_(" DWO ID: 0x%s\n"), dwarf_vmatoa ("x", dwo_id));
if (this_set != NULL)
{
dwarf_vma *offsets = this_set->section_offsets;
}
}
- sec_off = cu_offset + initial_length_size;
- if (sec_off + compunit.cu_length < sec_off
- || sec_off + compunit.cu_length > section->size)
- {
- warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
- section->name,
- (unsigned long) cu_offset,
- dwarf_vmatoa ("x", compunit.cu_length));
- num_units = unit;
- break;
- }
-
tags = hdrptr;
- start += compunit.cu_length + initial_length_size;
+ start = end_cu;
if (compunit.cu_version < 2 || compunit.cu_version > 5)
{
if (compunit.cu_unit_type != DW_UT_compile
&& compunit.cu_unit_type != DW_UT_partial
- && compunit.cu_unit_type != DW_UT_type)
+ && compunit.cu_unit_type != DW_UT_type
+ && compunit.cu_unit_type != DW_UT_split_compile
+ && compunit.cu_unit_type != DW_UT_skeleton)
{
warn (_("CU at offset %s contains corrupt or "
"unsupported unit type: %d.\n"),
}
/* Process the abbrevs used by this compilation unit. */
- if (compunit.cu_abbrev_offset >= abbrev_size)
- warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"),
- (unsigned long) compunit.cu_abbrev_offset,
- (unsigned long) abbrev_size);
- /* PR 17531: file:4bcd9ce9. */
- else if ((abbrev_base + abbrev_size)
- > debug_displays [abbrev_sec].section.size)
- warn (_("Debug info is corrupted, abbrev size (%lx) is larger than abbrev section size (%lx)\n"),
- (unsigned long) abbrev_base + abbrev_size,
- (unsigned long) debug_displays [abbrev_sec].section.size);
- else
+ list = find_abbrev_list_by_abbrev_offset (abbrev_base,
+ compunit.cu_abbrev_offset);
+ if (list == NULL)
{
- list = find_abbrev_list_by_abbrev_offset (abbrev_base,
- compunit.cu_abbrev_offset);
- if (list == NULL)
- {
- unsigned char * next;
-
- list = new_abbrev_list (abbrev_base,
- compunit.cu_abbrev_offset);
- next = process_abbrev_set
- (((unsigned char *) debug_displays [abbrev_sec].section.start
- + abbrev_base + compunit.cu_abbrev_offset),
- ((unsigned char *) debug_displays [abbrev_sec].section.start
- + abbrev_base + abbrev_size),
- list);
- list->start_of_next_abbrevs = next;
- }
+ unsigned char *next;
+
+ list = new_abbrev_list (abbrev_base,
+ compunit.cu_abbrev_offset);
+ next = process_abbrev_set (&debug_displays[abbrev_sec].section,
+ abbrev_base, abbrev_size,
+ compunit.cu_abbrev_offset, list);
+ list->start_of_next_abbrevs = next;
}
level = 0;
}
}
if (dwarf_start_die != 0 && level < saved_level)
- return TRUE;
+ return true;
continue;
}
}
warn (_("DIE at offset 0x%lx refers to abbreviation number %lu which does not exist\n"),
die_offset, abbrev_number);
- return FALSE;
+ return false;
}
if (!do_loc && do_printing)
attr->implicit_const,
section_begin,
tags,
- end,
+ start,
cu_offset,
compunit.cu_pointer_size,
offset_size,
if (!do_loc)
printf ("\n");
- return TRUE;
+ return true;
}
/* Locate and scan the .debug_info section in the file and record the pointer
(void) load_cu_tu_indexes (file);
if (load_debug_section_with_follow (info, file)
- && process_debug_info (&debug_displays [info].section, file, abbrev, TRUE, FALSE))
+ && process_debug_info (&debug_displays [info].section, file, abbrev, true, false))
return num_debug_info_entries;
if (load_debug_section_with_follow (info_dwo, file)
&& process_debug_info (&debug_displays [info_dwo].section, file,
- abbrev_dwo, TRUE, FALSE))
+ abbrev_dwo, true, false))
return num_debug_info_entries;
num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
unsigned char ** end_of_sequence)
{
unsigned char *hdrptr;
- unsigned int initial_length_size;
/* Extract information from the Line Number Program Header.
(section 6.2.4 in the Dwarf3 doc). */
/* This section is 64-bit DWARF 3. */
SAFE_BYTE_GET_AND_INC (linfo->li_length, hdrptr, 8, end);
linfo->li_offset_size = 8;
- initial_length_size = 12;
}
else
- {
- linfo->li_offset_size = 4;
- initial_length_size = 4;
- }
+ linfo->li_offset_size = 4;
- if (linfo->li_length + initial_length_size > section->size)
+ if (linfo->li_length > (size_t) (end - hdrptr))
{
/* If the length field has a relocation against it, then we should
not complain if it is inaccurate (and probably negative). This
is used to compute the correct length once that is done. */
if (reloc_at (section, (hdrptr - section->start) - linfo->li_offset_size))
{
- linfo->li_length = (end - data) - initial_length_size;
+ linfo->li_length = end - hdrptr;
}
else
{
return NULL;
}
}
+ end = hdrptr + linfo->li_length;
/* Get and check the version number. */
SAFE_BYTE_GET_AND_INC (linfo->li_version, hdrptr, 2, end);
SAFE_BYTE_GET_AND_INC (linfo->li_line_range, hdrptr, 1, end);
SAFE_BYTE_GET_AND_INC (linfo->li_opcode_base, hdrptr, 1, end);
- * end_of_sequence = data + linfo->li_length + initial_length_size;
- /* PR 17512: file:002-117414-0.004. */
- if (* end_of_sequence > end)
- {
- warn (_("Line length %s extends beyond end of section\n"),
- dwarf_vmatoa ("u", linfo->li_length));
- * end_of_sequence = end;
- return NULL;
- }
-
+ *end_of_sequence = end;
return hdrptr;
}
static unsigned char *
-display_formatted_table (unsigned char * data,
- unsigned char * start,
- unsigned char * end,
- const DWARF2_Internal_LineInfo * linfo,
- struct dwarf_section * section,
- bfd_boolean is_dir)
+display_formatted_table (unsigned char *data,
+ unsigned char *start,
+ unsigned char *end,
+ const DWARF2_Internal_LineInfo *linfo,
+ struct dwarf_section *section,
+ bool is_dir)
{
unsigned char *format_start, format_count, *format, formati;
dwarf_vma data_count, datai;
unsigned int namepass, last_entry = 0;
const char * table_name = is_dir ? N_("Directory Table") : N_("File Name Table");
-
+
SAFE_BYTE_GET_AND_INC (format_count, data, 1, end);
if (do_checks && format_count > 5)
warn (_("Unexpectedly large number of columns in the %s (%u)\n"),
{
SKIP_ULEB (data, end);
SKIP_ULEB (data, end);
- if (data == end)
+ if (data >= end)
{
warn (_("%s: Corrupt format description entry\n"), table_name);
return data;
printf (_("\n The %s is empty.\n"), table_name);
return data;
}
- else if (data == end)
+ else if (data >= end)
{
warn (_("%s: Corrupt entry count - expected %s but none found\n"),
table_name, dwarf_vmatoa ("x", data_count));
format_count);
printf (_(" Entry"));
- /* Delay displaying name as the last entry for better screen layout. */
+ /* Delay displaying name as the last entry for better screen layout. */
for (namepass = 0; namepass < 2; namepass++)
{
format = format_start;
unsigned char *datapass = data;
printf (" %d", last_entry++);
- /* Delay displaying name as the last entry for better screen layout. */
+ /* Delay displaying name as the last entry for better screen layout. */
for (namepass = 0; namepass < 2; namepass++)
{
format = format_start;
}
}
- if (data == end && (datai < data_count - 1))
+ if (data >= end && (datai < data_count - 1))
{
warn (_("\n%s: Corrupt entries list\n"), table_name);
return data;
}
putchar ('\n');
}
- return data;
+ return data;
+}
+
+static int
+display_debug_sup (struct dwarf_section * section,
+ void * file ATTRIBUTE_UNUSED)
+{
+ unsigned char * start = section->start;
+ unsigned char * end = section->start + section->size;
+ unsigned int version;
+ char is_supplementary;
+ const unsigned char * sup_filename;
+ size_t sup_filename_len;
+ unsigned int num_read;
+ int status;
+ dwarf_vma checksum_len;
+
+
+ introduce (section, true);
+ if (section->size < 4)
+ {
+ error (_("corrupt .debug_sup section: size is too small\n"));
+ return 0;
+ }
+
+ /* Read the data. */
+ SAFE_BYTE_GET_AND_INC (version, start, 2, end);
+ if (version < 5)
+ warn (_("corrupt .debug_sup section: version < 5"));
+
+ SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end);
+ if (is_supplementary != 0 && is_supplementary != 1)
+ warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
+
+ sup_filename = start;
+ if (is_supplementary && sup_filename[0] != 0)
+ warn (_("corrupt .debug_sup section: filename not empty in supplementary section\n"));
+
+ sup_filename_len = strnlen ((const char *) start, end - start);
+ if (sup_filename_len == (size_t) (end - start))
+ {
+ error (_("corrupt .debug_sup section: filename is not NUL terminated\n"));
+ return 0;
+ }
+ start += sup_filename_len + 1;
+
+ checksum_len = read_leb128 (start, end, false /* unsigned */, & num_read, & status);
+ if (status)
+ {
+ error (_("corrupt .debug_sup section: bad LEB128 field for checksum length\n"));
+ checksum_len = 0;
+ }
+ start += num_read;
+ if (checksum_len > (dwarf_vma) (end - start))
+ {
+ error (_("corrupt .debug_sup section: checksum length is longer than the remaining section length\n"));
+ checksum_len = end - start;
+ }
+ else if (checksum_len < (dwarf_vma) (end - start))
+ {
+ warn (_("corrupt .debug_sup section: there are 0x%lx extra, unused bytes at the end of the section\n"),
+ (long) ((end - start) - checksum_len));
+ }
+
+ printf (_(" Version: %u\n"), version);
+ printf (_(" Is Supp: %u\n"), is_supplementary);
+ printf (_(" Filename: %s\n"), sup_filename);
+ printf (_(" Checksum Len: %lu\n"), (long) checksum_len);
+ if (checksum_len > 0)
+ {
+ printf (_(" Checksum: "));
+ while (checksum_len--)
+ printf ("0x%x ", * start++ );
+ printf ("\n");
+ }
+ return 1;
}
static int
unsigned char *start = section->start;
int verbose_view = 0;
- introduce (section, TRUE);
+ introduce (section, true);
while (data < end)
{
unsigned char *end_of_sequence;
int i;
- if (const_strneq (section->name, ".debug_line.")
+ if (startswith (section->name, ".debug_line.")
/* Note: the following does not apply to .debug_line.dwo sections.
These are full debug_line sections. */
&& strcmp (section->name, ".debug_line.dwo") != 0)
load_debug_section_with_follow (line_str, file);
data = display_formatted_table (data, start, end, &linfo, section,
- TRUE);
+ true);
data = display_formatted_table (data, start, end, &linfo, section,
- FALSE);
+ false);
}
else
{
{
printf (" %d\t%.*s\n", ++last_dir_entry, (int) (end - data), data);
- data += strnlen ((char *) data, end - data) + 1;
+ data += strnlen ((char *) data, end - data);
+ if (data < end)
+ data++;
}
/* PR 17512: file: 002-132094-0.004. */
}
/* Skip the NUL at the end of the table. */
- data++;
+ if (data < end)
+ data++;
/* Display the contents of the File Name table. */
- if (*data == 0)
+ if (data >= end || *data == 0)
printf (_("\n The File Name Table is empty.\n"));
else
{
printf (" %d\t", ++state_machine_regs.last_file_entry);
name = data;
- data += strnlen ((char *) data, end - data) + 1;
+ data += strnlen ((char *) data, end - data);
+ if (data < end)
+ data++;
READ_ULEB (val, data, end);
printf ("%s\t", dwarf_vmatoa ("u", val));
printf ("%s\t", dwarf_vmatoa ("u", val));
printf ("%.*s\n", (int)(end - name), name);
- if (data == end)
+ if (data >= end)
{
warn (_("Corrupt file name table entry\n"));
break;
}
/* Skip the NUL at the end of the table. */
- data++;
+ if (data < end)
+ data++;
}
putchar ('\n');
{
static DWARF2_Internal_LineInfo saved_linfo;
- introduce (section, FALSE);
+ introduce (section, false);
while (data < end)
{
unsigned char **directory_table = NULL;
dwarf_vma n_directories = 0;
- if (const_strneq (section->name, ".debug_line.")
+ if (startswith (section->name, ".debug_line.")
/* Note: the following does not apply to .debug_line.dwo sections.
These are full debug_line sections. */
&& strcmp (section->name, ".debug_line.dwo") != 0)
}
READ_ULEB (n_directories, data, end);
- if (data == end)
+ if (data >= end)
{
warn (_("Corrupt directories list\n"));
break;
READ_ULEB (content_type, format, end);
READ_ULEB (form, format, end);
- if (data == end)
+ if (data >= end)
{
warn (_("Corrupt directories list\n"));
break;
NULL, 1, section,
NULL, '\t', -1);
}
- if (data == end)
+ if (data >= end)
{
warn (_("Corrupt directories list\n"));
break;
}
READ_ULEB (n_files, data, end);
- if (data == end && n_files > 0)
+ if (data >= end && n_files > 0)
{
warn (_("Corrupt file name list\n"));
break;
READ_ULEB (content_type, format, end);
READ_ULEB (form, format, end);
- if (data == end)
+ if (data >= end)
{
warn (_("Corrupt file name list\n"));
break;
NULL, 1, section,
NULL, '\t', -1);
}
- if (data == end)
+ if (data >= end)
{
warn (_("Corrupt file name list\n"));
break;
while (data < end && *data != 0)
{
- data += strnlen ((char *) data, end - data) + 1;
+ data += strnlen ((char *) data, end - data);
+ if (data < end)
+ data++;
n_directories++;
}
while (*ptr_directory_table != 0)
{
directory_table[i] = ptr_directory_table;
- ptr_directory_table += strnlen ((char *) ptr_directory_table,
- ptr_directory_table - end) + 1;
+ ptr_directory_table
+ += strlen ((char *) ptr_directory_table) + 1;
i++;
}
}
{
/* Skip Name, directory index, last modification
time and length of file. */
- data += strnlen ((char *) data, end - data) + 1;
+ data += strnlen ((char *) data, end - data);
+ if (data < end)
+ data++;
SKIP_ULEB (data, end);
SKIP_ULEB (data, end);
SKIP_ULEB (data, end);
while (*ptr_file_name_table != 0)
{
file_table[i].name = ptr_file_name_table;
- ptr_file_name_table += strnlen ((char *) ptr_file_name_table,
- end - ptr_file_name_table) + 1;
+ ptr_file_name_table
+ += strlen ((char *) ptr_file_name_table) + 1;
/* We are not interested in directory, time or size. */
READ_ULEB (file_table[i].directory_index,
state_machine_regs.file = uladv;
{
- unsigned file = state_machine_regs.file - 1;
+ unsigned file = state_machine_regs.file;
unsigned dir;
+ if (linfo.li_version < 5)
+ --file;
if (file_table == NULL || n_files == 0)
printf (_("\n [Use file table entry %d]\n"), file);
/* PR 20439 */
else if (file >= n_files)
{
- warn (_("file index %u > number of files %u\n"), file + 1, n_files);
+ warn (_("file index %u > number of files %u\n"), file, n_files);
printf (_("\n <over large file table index %u>"), file);
}
else if ((dir = file_table[file].directory_index) == 0)
if (file_table)
{
- unsigned indx = state_machine_regs.file - 1;
+ unsigned indx = state_machine_regs.file;
+
+ if (linfo.li_version < 5)
+ --indx;
/* PR 20439 */
if (indx >= n_files)
{
fileName = _("<unknown>");
fileNameLength = strlen (fileName);
-
- if ((fileNameLength > MAX_FILENAME_LENGTH) && (!do_wide))
+ newFileName = fileName;
+ if (fileNameLength > MAX_FILENAME_LENGTH && !do_wide)
{
newFileName = (char *) xmalloc (MAX_FILENAME_LENGTH + 1);
/* Truncate file name */
- strncpy (newFileName,
- fileName + fileNameLength - MAX_FILENAME_LENGTH,
- MAX_FILENAME_LENGTH + 1);
- /* FIXME: This is to pacify gcc-10 which can warn that the
- strncpy above might leave a non-NUL terminated string
- in newFileName. It won't, but gcc's analysis doesn't
- quite go far enough to discover this. */
+ memcpy (newFileName,
+ fileName + fileNameLength - MAX_FILENAME_LENGTH,
+ MAX_FILENAME_LENGTH);
newFileName[MAX_FILENAME_LENGTH] = 0;
}
- else
- {
- newFileName = (char *) xmalloc (fileNameLength + 1);
- strncpy (newFileName, fileName, fileNameLength + 1);
- }
/* A row with end_seq set to true has a meaningful address, but
the other information in the same row is not significant.
In such a row, print line as "-", and don't print
view/is_stmt. */
- if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
+ if (!do_wide || fileNameLength <= MAX_FILENAME_LENGTH)
{
if (linfo.li_max_ops_per_insn == 1)
{
putchar ('\n');
}
- free (newFileName);
+ if (newFileName != fileName)
+ free (newFileName);
}
}
}
static debug_info *
-find_debug_info_for_offset (unsigned long offset)
+find_debug_info_for_offset (dwarf_vma offset)
{
unsigned int i;
we test for that later on. */
load_debug_info (file);
- introduce (section, FALSE);
+ introduce (section, false);
while (start < end)
{
unsigned char *data;
- unsigned long sec_off;
- unsigned int offset_size, initial_length_size;
+ unsigned long sec_off = start - section->start;
+ unsigned int offset_size;
SAFE_BYTE_GET_AND_INC (names.pn_length, start, 4, end);
if (names.pn_length == 0xffffffff)
{
SAFE_BYTE_GET_AND_INC (names.pn_length, start, 8, end);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
+ offset_size = 4;
- sec_off = start - section->start;
- if (sec_off + names.pn_length < sec_off
- || sec_off + names.pn_length > section->size)
+ if (names.pn_length > (size_t) (end - start))
{
warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
section->name,
- sec_off - initial_length_size,
+ sec_off,
dwarf_vmatoa ("x", names.pn_length));
break;
}
data = start;
start += names.pn_length;
- SAFE_BYTE_GET_AND_INC (names.pn_version, data, 2, end);
- SAFE_BYTE_GET_AND_INC (names.pn_offset, data, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (names.pn_version, data, 2, start);
+ SAFE_BYTE_GET_AND_INC (names.pn_offset, data, offset_size, start);
if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
&& num_debug_info_entries > 0
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
(unsigned long) names.pn_offset, section->name);
- SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, start);
printf (_(" Length: %ld\n"),
(long) names.pn_length);
bfd_size_type maxprint;
dwarf_vma offset;
- SAFE_BYTE_GET (offset, data, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (offset, data, offset_size, start);
if (offset == 0)
break;
- data += offset_size;
- if (data >= end)
+ if (data >= start)
break;
- maxprint = (end - data) - 1;
+ maxprint = (start - data) - 1;
if (is_gnu)
{
const char *kind_name;
int is_static;
- SAFE_BYTE_GET (kind_data, data, 1, end);
- data++;
+ SAFE_BYTE_GET_AND_INC (kind_data, data, 1, start);
maxprint --;
/* GCC computes the kind as the upper byte in the CU index
word, and then right shifts it by the CU index size.
printf (" %-6lx\t%.*s\n",
(unsigned long) offset, (int) maxprint, data);
- data += strnlen ((char *) data, maxprint) + 1;
- if (data >= end)
+ data += strnlen ((char *) data, maxprint);
+ if (data < start)
+ data++;
+ if (data >= start)
break;
}
}
unsigned char *curr = start;
enum dwarf_macinfo_record_type op;
- introduce (section, FALSE);
+ introduce (section, false);
while (curr < end)
{
case DW_MACINFO_define:
READ_ULEB (lineno, curr, end);
string = curr;
- curr += strnlen ((char *) string, end - string) + 1;
- printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
- lineno, string);
+ curr += strnlen ((char *) string, end - string);
+ printf (_(" DW_MACINFO_define - lineno : %d macro : %*s\n"),
+ lineno, (int) (curr - string), string);
+ if (curr < end)
+ curr++;
break;
case DW_MACINFO_undef:
READ_ULEB (lineno, curr, end);
string = curr;
- curr += strnlen ((char *) string, end - string) + 1;
- printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
- lineno, string);
+ curr += strnlen ((char *) string, end - string);
+ printf (_(" DW_MACINFO_undef - lineno : %d macro : %*s\n"),
+ lineno, (int) (curr - string), string);
+ if (curr < end)
+ curr++;
break;
case DW_MACINFO_vendor_ext:
READ_ULEB (constant, curr, end);
string = curr;
- curr += strnlen ((char *) string, end - string) + 1;
- printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
- constant, string);
+ curr += strnlen ((char *) string, end - string);
+ printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %*s\n"),
+ constant, (int) (curr - string), string);
+ if (curr < end)
+ curr++;
}
break;
}
{
struct dwarf_section *section = &debug_displays [line].section;
unsigned char *hdrptr, *dirtable, *file_name;
- unsigned int offset_size, initial_length_size;
+ unsigned int offset_size;
unsigned int version, opcode_base;
dwarf_vma length, diridx;
const unsigned char * end;
/* This section is 64-bit DWARF 3. */
SAFE_BYTE_GET_AND_INC (length, hdrptr, 8, end);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
- if (length + initial_length_size < length
- || length + initial_length_size > section->size)
+ offset_size = 4;
+
+ if (length > (size_t) (end - hdrptr)
+ || length < 2 + offset_size + 1 + 3 + 1)
return NULL;
+ end = hdrptr + length;
SAFE_BYTE_GET_AND_INC (version, hdrptr, 2, end);
if (version != 2 && version != 3 && version != 4)
hdrptr += 3; /* Skip default_is_stmt, line_base, line_range. */
SAFE_BYTE_GET_AND_INC (opcode_base, hdrptr, 1, end);
- if (opcode_base == 0)
+ if (opcode_base == 0
+ || opcode_base - 1 >= (size_t) (end - hdrptr))
return NULL;
hdrptr += opcode_base - 1;
- if (hdrptr >= end)
- return NULL;
dirtable = hdrptr;
/* Skip over dirname table. */
while (*hdrptr != '\0')
{
- hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
+ hdrptr += strnlen ((char *) hdrptr, end - hdrptr);
+ if (hdrptr < end)
+ hdrptr++;
if (hdrptr >= end)
return NULL;
}
/* Now skip over preceding filename table entries. */
for (; hdrptr < end && *hdrptr != '\0' && fileidx > 1; fileidx--)
{
- hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
+ hdrptr += strnlen ((char *) hdrptr, end - hdrptr);
+ if (hdrptr < end)
+ hdrptr++;
SKIP_ULEB (hdrptr, end);
SKIP_ULEB (hdrptr, end);
SKIP_ULEB (hdrptr, end);
return NULL;
file_name = hdrptr;
- hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
+ hdrptr += strnlen ((char *) hdrptr, end - hdrptr);
+ if (hdrptr < end)
+ hdrptr++;
if (hdrptr >= end)
return NULL;
READ_ULEB (diridx, hdrptr, end);
if (diridx == 0)
return file_name;
for (; dirtable < end && *dirtable != '\0' && diridx > 1; diridx--)
- dirtable += strnlen ((char *) dirtable, end - dirtable) + 1;
+ {
+ dirtable += strnlen ((char *) dirtable, end - dirtable);
+ if (dirtable < end)
+ dirtable++;
+ }
if (dirtable >= end || *dirtable == '\0')
return NULL;
*dir_name = dirtable;
unsigned char *end = start + section->size;
unsigned char *curr = start;
unsigned char *extended_op_buf[256];
+ bool is_dwo = false;
+ const char *suffix = strrchr (section->name, '.');
+
+ if (suffix && strcmp (suffix, ".dwo") == 0)
+ is_dwo = true;
load_debug_section_with_follow (str, file);
load_debug_section_with_follow (line, file);
load_debug_section_with_follow (str_index, file);
-
- introduce (section, FALSE);
+
+ introduce (section, false);
while (curr < end)
{
unsigned int lineno, version, flags;
- unsigned int offset_size = 4;
+ unsigned int offset_size;
const unsigned char *string;
dwarf_vma line_offset = 0, sec_offset = curr - start, offset;
unsigned char **extended_ops = NULL;
SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
if (version != 4 && version != 5)
{
- error (_("Only GNU extension to DWARF 4 or 5 of %s is currently supported.\n"),
- section->name);
+ error (_("Expected to find a version number of 4 or 5 in section %s but found %d instead\n"),
+ section->name, version);
return 0;
}
SAFE_BYTE_GET_AND_INC (flags, curr, 1, end);
- if (flags & 1)
- offset_size = 8;
+ offset_size = (flags & 1) ? 8 : 4;
printf (_(" Offset: 0x%lx\n"),
(unsigned long) sec_offset);
printf (_(" Version: %d\n"), version);
case DW_MACRO_define:
READ_ULEB (lineno, curr, end);
string = curr;
- curr += strnlen ((char *) string, end - string) + 1;
- printf (_(" DW_MACRO_define - lineno : %d macro : %s\n"),
- lineno, string);
+ curr += strnlen ((char *) string, end - string);
+ printf (_(" DW_MACRO_define - lineno : %d macro : %*s\n"),
+ lineno, (int) (curr - string), string);
+ if (curr < end)
+ curr++;
break;
case DW_MACRO_undef:
READ_ULEB (lineno, curr, end);
string = curr;
- curr += strnlen ((char *) string, end - string) + 1;
- printf (_(" DW_MACRO_undef - lineno : %d macro : %s\n"),
- lineno, string);
+ curr += strnlen ((char *) string, end - string);
+ printf (_(" DW_MACRO_undef - lineno : %d macro : %*s\n"),
+ lineno, (int) (curr - string), string);
+ if (curr < end)
+ curr++;
break;
case DW_MACRO_start_file:
case DW_MACRO_define_strp:
READ_ULEB (lineno, curr, end);
- SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
+ if (version == 4 && is_dwo)
+ READ_ULEB (offset, curr, end);
+ else
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
string = fetch_indirect_string (offset);
printf (_(" DW_MACRO_define_strp - lineno : %d macro : %s\n"),
lineno, string);
case DW_MACRO_undef_strp:
READ_ULEB (lineno, curr, end);
- SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
+ if (version == 4 && is_dwo)
+ READ_ULEB (offset, curr, end);
+ else
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
string = fetch_indirect_string (offset);
printf (_(" DW_MACRO_undef_strp - lineno : %d macro : %s\n"),
lineno, string);
READ_ULEB (lineno, curr, end);
READ_ULEB (offset, curr, end);
string = (const unsigned char *)
- fetch_indexed_string (offset, NULL, offset_size, FALSE);
+ fetch_indexed_string (offset, NULL, offset_size, false);
if (op == DW_MACRO_define_strx)
printf (" DW_MACRO_define_strx ");
else
{
abbrev_entry *entry;
unsigned char *start = section->start;
- const unsigned char *end = start + section->size;
- introduce (section, FALSE);
+ introduce (section, false);
do
{
if (list == NULL)
{
list = new_abbrev_list (0, offset);
- start = process_abbrev_set (start, end, list);
+ start = process_abbrev_set (section, 0, section->size, offset, list);
list->start_of_next_abbrevs = start;
}
else
get_AT_name (attr->attribute),
get_FORM_name (attr->form));
if (attr->form == DW_FORM_implicit_const)
- printf (": %" BFD_VMA_FMT "d", attr->implicit_const);
+ printf (": %s", dwarf_vmatoa ("d", attr->implicit_const));
putchar ('\n');
}
}
/* Return true when ADDR is the maximum address, when addresses are
POINTER_SIZE bytes long. */
-static bfd_boolean
+static bool
is_max_address (dwarf_vma addr, unsigned int pointer_size)
{
dwarf_vma mask = ~(~(dwarf_vma) 1 << (pointer_size * 8 - 1));
{
unsigned char *start = *start_ptr, *vstart = *vstart_ptr;
unsigned char *section_end = section->start + section->size;
- unsigned long cu_offset;
+ dwarf_vma cu_offset;
unsigned int pointer_size;
unsigned int offset_size;
int dwarf_version;
-
dwarf_vma begin;
dwarf_vma end;
unsigned short length;
dwarf_vma off = offset + (start - *start_ptr);
dwarf_vma vbegin = vm1, vend = vm1;
- if (start + 2 * pointer_size > section_end)
+ if (2 * pointer_size > (size_t) (section_end - start))
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
(unsigned long) offset);
break;
}
- printf (" %8.8lx ", (unsigned long) off);
+ printf (" ");
+ print_dwarf_vma (off, 4);
SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end);
SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end);
(unsigned long) off, 8, "");
}
- if (start + 2 > section_end)
+ if (2 > (size_t) (section_end - start))
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
(unsigned long) offset);
SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
- if (start + length > section_end)
+ if (length > (size_t) (section_end - start))
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
(unsigned long) offset);
{
unsigned char *start = *start_ptr, *vstart = *vstart_ptr;
unsigned char *section_end = section->start + section->size;
- unsigned long cu_offset;
+ dwarf_vma cu_offset;
unsigned int pointer_size;
unsigned int offset_size;
int dwarf_version;
break;
}
- printf (" %8.8lx ", (unsigned long) off);
+ printf (" ");
+ print_dwarf_vma (off, 4);
SAFE_BYTE_GET_AND_INC (llet, start, 1, section_end);
&& llet != DW_LLE_start_length)
continue;
- if (start + 2 > section_end)
+ if (start == section_end)
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
(unsigned long) offset);
break;
}
-
READ_ULEB (length, start, section_end);
+ if (length > (size_t) (section_end - start))
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ (unsigned long) offset);
+ break;
+ }
+
print_dwarf_vma (begin, pointer_size);
print_dwarf_vma (end, pointer_size);
{
unsigned char *start = *start_ptr, *vstart = *vstart_ptr;
unsigned char *section_end = section->start + section->size;
- unsigned long cu_offset;
+ dwarf_vma cu_offset;
unsigned int pointer_size;
unsigned int offset_size;
int dwarf_version;
while (1)
{
- printf (" %8.8lx ", (unsigned long) (offset + (start - *start_ptr)));
+ printf (" ");
+ print_dwarf_vma (offset + (start - *start_ptr), 4);
if (start >= section_end)
{
return;
}
- if (start + 2 > section_end)
+ if (2 > (size_t) (section_end - start))
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
(unsigned long) offset);
}
SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
- if (start + length > section_end)
+ if (length > (size_t) (section_end - start))
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
(unsigned long) offset);
display_debug_loc (struct dwarf_section *section, void *file)
{
unsigned char *start = section->start, *vstart = NULL;
- unsigned long bytes;
+ dwarf_vma bytes;
unsigned char *section_begin = start;
unsigned int num_loc_list = 0;
- unsigned long last_offset = 0;
- unsigned long last_view = 0;
+ dwarf_vma last_offset = 0;
+ dwarf_vma last_view = 0;
unsigned int first = 0;
unsigned int i;
unsigned int j;
unsigned char *next = start, *vnext = vstart;
unsigned int *array = NULL;
const char *suffix = strrchr (section->name, '.');
- bfd_boolean is_dwo = FALSE;
+ bool is_dwo = false;
int is_loclists = strstr (section->name, "debug_loclists") != NULL;
dwarf_vma expected_start = 0;
if (suffix && strcmp (suffix, ".dwo") == 0)
- is_dwo = TRUE;
+ is_dwo = true;
bytes = section->size;
if (!locs_sorted)
array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int));
- introduce (section, FALSE);
+ introduce (section, false);
if (reloc_at (section, 0))
printf (_(" Warning: This section has relocations - addresses seen here may not be accurate.\n\n"));
else
{
if (start < next)
- warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
+ warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
(unsigned long) (start - section_begin),
- (unsigned long) offset);
+ (unsigned long) offset,
+ section->name);
else if (start > next)
- warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
+ warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
(unsigned long) (start - section_begin),
- (unsigned long) offset);
+ (unsigned long) offset,
+ section->name);
}
start = next;
vstart = vnext;
if (offset >= bytes)
{
- warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"),
- (unsigned long) offset);
+ warn (_("Offset 0x%lx is bigger than %s section size.\n"),
+ (unsigned long) offset,
+ section->name);
continue;
}
if (vnext && voffset >= bytes)
{
- warn (_("View Offset 0x%lx is bigger than .debug_loc section size.\n"),
- (unsigned long) voffset);
+ warn (_("View Offset 0x%lx is bigger than %s section size.\n"),
+ (unsigned long) voffset,
+ section->name);
continue;
}
void *file ATTRIBUTE_UNUSED)
{
unsigned char *start = section->start;
- unsigned long bytes = section->size;
+ dwarf_vma bytes = section->size;
dwarf_vma addr = section->address;
if (bytes == 0)
return 0;
}
- introduce (section, FALSE);
+ introduce (section, false);
while (bytes)
{
static int
display_debug_info (struct dwarf_section *section, void *file)
{
- return process_debug_info (section, file, section->abbrev_sec, FALSE, FALSE);
+ return process_debug_info (section, file, section->abbrev_sec, false, false);
}
static int
display_debug_types (struct dwarf_section *section, void *file)
{
- return process_debug_info (section, file, section->abbrev_sec, FALSE, TRUE);
+ return process_debug_info (section, file, section->abbrev_sec, false, true);
}
static int
display_trace_info (struct dwarf_section *section, void *file)
{
- return process_debug_info (section, file, section->abbrev_sec, FALSE, TRUE);
+ return process_debug_info (section, file, section->abbrev_sec, false, true);
}
static int
unsigned char *start = section->start;
unsigned char *end = start + section->size;
- introduce (section, FALSE);
+ introduce (section, false);
/* It does not matter if this load fails,
we test for that later on. */
unsigned char *addr_ranges;
dwarf_vma length;
dwarf_vma address;
- unsigned long sec_off;
+ dwarf_vma sec_off;
unsigned char address_size;
- int excess;
- unsigned int offset_size;
- unsigned int initial_length_size;
+ unsigned int offset_size;
+ unsigned char *end_ranges;
hdrptr = start;
+ sec_off = hdrptr - section->start;
SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 4, end);
if (arange.ar_length == 0xffffffff)
{
SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 8, end);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
+ offset_size = 4;
- sec_off = hdrptr - section->start;
- if (sec_off + arange.ar_length < sec_off
- || sec_off + arange.ar_length > section->size)
+ if (arange.ar_length > (size_t) (end - hdrptr))
{
warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
section->name,
- sec_off - initial_length_size,
+ (unsigned long) sec_off,
dwarf_vmatoa ("x", arange.ar_length));
break;
}
+ end_ranges = hdrptr + arange.ar_length;
- SAFE_BYTE_GET_AND_INC (arange.ar_version, hdrptr, 2, end);
- SAFE_BYTE_GET_AND_INC (arange.ar_info_offset, hdrptr, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (arange.ar_version, hdrptr, 2, end_ranges);
+ SAFE_BYTE_GET_AND_INC (arange.ar_info_offset, hdrptr, offset_size,
+ end_ranges);
if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
&& num_debug_info_entries > 0
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
(unsigned long) arange.ar_info_offset, section->name);
- SAFE_BYTE_GET_AND_INC (arange.ar_pointer_size, hdrptr, 1, end);
- SAFE_BYTE_GET_AND_INC (arange.ar_segment_size, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (arange.ar_pointer_size, hdrptr, 1, end_ranges);
+ SAFE_BYTE_GET_AND_INC (arange.ar_segment_size, hdrptr, 1, end_ranges);
if (arange.ar_version != 2 && arange.ar_version != 3)
{
addr_ranges = hdrptr;
/* Must pad to an alignment boundary that is twice the address size. */
- excess = (hdrptr - start) % (2 * address_size);
- if (excess)
- addr_ranges += (2 * address_size) - excess;
-
- start += arange.ar_length + initial_length_size;
+ addr_ranges += (2 * address_size - 1
+ - (hdrptr - start - 1) % (2 * address_size));
- while (addr_ranges + 2 * address_size <= start)
+ while (2 * address_size <= end_ranges - addr_ranges)
{
- SAFE_BYTE_GET_AND_INC (address, addr_ranges, address_size, end);
- SAFE_BYTE_GET_AND_INC (length, addr_ranges, address_size, end);
-
+ SAFE_BYTE_GET_AND_INC (address, addr_ranges, address_size,
+ end_ranges);
+ SAFE_BYTE_GET_AND_INC (length, addr_ranges, address_size,
+ end_ranges);
printf (" ");
print_dwarf_vma (address, address_size);
print_dwarf_vma (length, address_size);
putchar ('\n');
}
+
+ start = end_ranges;
}
printf ("\n");
unsigned char *end;
unsigned int i;
unsigned int count;
+ unsigned char * header;
if (section->size == 0)
{
return 0;
}
- introduce (section, FALSE);
+ introduce (section, false);
/* PR 17531: file: cf38d01b.
We use xcalloc because a corrupt file may not have initialised all of the
debug_addr_info [count]->addr_base = section->size;
qsort (debug_addr_info, count, sizeof (debug_info *), comp_addr_base);
+ header = section->start;
for (i = 0; i < count; i++)
{
unsigned int idx;
printf (_("\tIndex\tAddress\n"));
entry = section->start + debug_addr_info [i]->addr_base;
- end = section->start + debug_addr_info [i + 1]->addr_base;
+ if (debug_addr_info [i]->dwarf_version >= 5)
+ {
+ size_t header_size = entry - header;
+ unsigned char * curr_header = header;
+ dwarf_vma length;
+ int version;
+ int segment_selector_size;
+
+ if (header_size != 8 && header_size != 16)
+ {
+ warn (_("Corrupt %s section: expecting header size of 8 or 16, but found %ld instead\n"),
+ section->name, (long) header_size);
+ return 0;
+ }
+
+ SAFE_BYTE_GET_AND_INC (length, curr_header, 4, entry);
+ if (length == 0xffffffff)
+ SAFE_BYTE_GET_AND_INC (length, curr_header, 8, entry);
+ end = curr_header + length;
+
+ SAFE_BYTE_GET_AND_INC (version, curr_header, 2, entry);
+ if (version != 5)
+ warn (_("Corrupt %s section: expecting version number 5 in header but found %d instead\n"),
+ section->name, version);
+
+ SAFE_BYTE_GET_AND_INC (address_size, curr_header, 1, entry);
+ SAFE_BYTE_GET_AND_INC (segment_selector_size, curr_header, 1, entry);
+ address_size += segment_selector_size;
+ }
+ else
+ end = section->start + debug_addr_info [i + 1]->addr_base;
+ header = end;
idx = 0;
while (entry < end)
{
unsigned char *end = start + section->size;
unsigned char *curr = start;
- const char * suffix = strrchr (section->name, '.');
- bfd_boolean dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? TRUE : FALSE;
+ const char *suffix = strrchr (section->name, '.');
+ bool dwo = suffix && strcmp (suffix, ".dwo") == 0;
if (dwo)
load_debug_section_with_follow (str_dwo, file);
else
load_debug_section_with_follow (str, file);
- introduce (section, FALSE);
+ introduce (section, false);
while (curr < end)
{
/* FIXME: We assume that this means 64-bit DWARF is being used. */
if (length == 0xffffffff)
{
- SAFE_BYTE_GET (length, curr, 8, end);
+ SAFE_BYTE_GET_AND_INC (length, curr, 8, end);
entry_length = 8;
}
else
entry_length = 4;
+ unsigned char *entries_end;
if (length == 0)
{
/* This is probably an old style .debug_str_offset section which
just contains offsets and no header (and the first offset is 0). */
length = section->size;
curr = section->start;
+ entries_end = end;
printf (_(" Length: %#lx\n"), (unsigned long) length);
printf (_(" Index Offset [String]\n"));
}
else
{
+ if (length <= (dwarf_vma) (end - curr))
+ entries_end = curr + length;
+ else
+ {
+ warn (_("Section %s is too small %#lx\n"),
+ section->name, (unsigned long) section->size);
+ entries_end = end;
+ }
+
int version;
- SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
+ SAFE_BYTE_GET_AND_INC (version, curr, 2, entries_end);
if (version != 5)
warn (_("Unexpected version number in str_offset header: %#x\n"), version);
int padding;
- SAFE_BYTE_GET_AND_INC (padding, curr, 2, end);
+ SAFE_BYTE_GET_AND_INC (padding, curr, 2, entries_end);
if (padding != 0)
warn (_("Unexpected value in str_offset header's padding field: %#x\n"), padding);
printf (_(" Index Offset [String]\n"));
}
- for (idx = 0; length >= entry_length && curr < end; idx++)
+ for (idx = 0; curr < entries_end; idx++)
{
dwarf_vma offset;
const unsigned char * string;
- SAFE_BYTE_GET_AND_INC (offset, curr, entry_length, end);
+ if ((dwarf_vma) (entries_end - curr) < entry_length)
+ /* Not enough space to read one entry_length, give up. */
+ return 0;
+
+ SAFE_BYTE_GET_AND_INC (offset, curr, entry_length, entries_end);
if (dwo)
string = (const unsigned char *)
fetch_indexed_string (idx, NULL, entry_length, dwo);
}
static void
-display_debug_ranges_list (unsigned char *start, unsigned char *finish,
- unsigned int pointer_size, unsigned long offset,
- unsigned long base_address)
+display_debug_ranges_list (unsigned char * start,
+ unsigned char * finish,
+ unsigned int pointer_size,
+ dwarf_vma offset,
+ dwarf_vma base_address)
{
while (start < finish)
{
break;
SAFE_SIGNED_BYTE_GET_AND_INC (end, start, pointer_size, finish);
-
- printf (" %8.8lx ", offset);
+ printf (" ");
+ print_dwarf_vma (offset, 4);
if (begin == 0 && end == 0)
{
}
static void
-display_debug_rnglists_list (unsigned char *start, unsigned char *finish,
- unsigned int pointer_size, unsigned long offset,
- unsigned long base_address)
+display_debug_rnglists_list (unsigned char * start,
+ unsigned char * finish,
+ unsigned int pointer_size,
+ dwarf_vma offset,
+ dwarf_vma base_address)
{
unsigned char *next = start;
while (1)
{
- unsigned long off = offset + (start - next);
+ dwarf_vma off = offset + (start - next);
enum dwarf_range_list_entry rlet;
/* Initialize it due to a false compiler warning. */
dwarf_vma begin = -1, length, end = -1;
- if (start + 1 > finish)
+ if (start >= finish)
{
- warn (_("Range list starting at offset 0x%lx is not terminated.\n"),
- offset);
+ warn (_("Range list starting at offset 0x%s is not terminated.\n"),
+ dwarf_vmatoa ("x", offset));
break;
}
- printf (" %8.8lx ", off);
+ printf (" ");
+ print_dwarf_vma (off, 4);
SAFE_BYTE_GET_AND_INC (rlet, start, 1, finish);
if (rlet == DW_RLE_base_address)
continue;
- print_dwarf_vma (begin + base_address, pointer_size);
- print_dwarf_vma (end + base_address, pointer_size);
+ /* Only a DW_RLE_offset_pair needs the base address added. */
+ if (rlet == DW_RLE_offset_pair)
+ {
+ begin += base_address;
+ end += base_address;
+ }
+
+ print_dwarf_vma (begin, pointer_size);
+ print_dwarf_vma (end, pointer_size);
if (begin == end)
fputs (_("(start == end)"), stdout);
display_debug_ranges (struct dwarf_section *section,
void *file ATTRIBUTE_UNUSED)
{
- unsigned char *start = section->start;
- unsigned char *last_start = start;
- unsigned long bytes = section->size;
- unsigned char *section_begin = start;
- unsigned char *finish = start + bytes;
- unsigned int num_range_list, i;
- struct range_entry *range_entries, *range_entry_fill;
- int is_rnglists = strstr (section->name, "debug_rnglists") != NULL;
+ unsigned char * start = section->start;
+ unsigned char * last_start = start;
+ dwarf_vma bytes = section->size;
+ unsigned char * section_begin = start;
+ unsigned char * finish = start + bytes;
+ unsigned int num_range_list, i;
+ struct range_entry * range_entries;
+ struct range_entry * range_entry_fill;
+ int is_rnglists = strstr (section->name, "debug_rnglists") != NULL;
/* Initialize it due to a false compiler warning. */
- unsigned char address_size = 0;
- dwarf_vma last_offset = 0;
+ unsigned char address_size = 0;
+ dwarf_vma last_offset = 0;
if (bytes == 0)
{
if (is_rnglists)
{
dwarf_vma initial_length;
- unsigned int initial_length_size;
unsigned char segment_selector_size;
unsigned int offset_size, offset_entry_count;
unsigned short version;
/* This section is 64-bit DWARF 3. */
SAFE_BYTE_GET_AND_INC (initial_length, start, 8, finish);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
+ offset_size = 4;
- if (initial_length + initial_length_size > section->size)
+ if (initial_length > (size_t) (finish - start))
{
/* If the length field has a relocation against it, then we should
not complain if it is inaccurate (and probably negative).
It is copied from .debug_line handling code. */
if (reloc_at (section, (start - section->start) - offset_size))
{
- initial_length = (finish - start) - initial_length_size;
+ initial_length = finish - start;
}
else
{
num_range_list = 0;
for (i = 0; i < num_debug_info_entries; i++)
- num_range_list += debug_information [i].num_range_lists;
+ {
+ if (debug_information [i].dwarf_version < 5 && is_rnglists)
+ /* Skip .debug_rnglists reference. */
+ continue;
+ if (debug_information [i].dwarf_version >= 5 && !is_rnglists)
+ /* Skip .debug_range reference. */
+ continue;
+ num_range_list += debug_information [i].num_range_lists;
+ }
if (num_range_list == 0)
{
debug_info *debug_info_p = &debug_information[i];
unsigned int j;
+ if (debug_information [i].dwarf_version < 5 && is_rnglists)
+ /* Skip .debug_rnglists reference. */
+ continue;
+ if (debug_information [i].dwarf_version >= 5 && !is_rnglists)
+ /* Skip .debug_range reference. */
+ continue;
+
for (j = 0; j < debug_info_p->num_range_lists; j++)
{
range_entry_fill->ranges_offset = debug_info_p->range_lists[j];
warn (_("Range lists in %s section start at 0x%lx\n"),
section->name, (unsigned long) range_entries[0].ranges_offset);
- introduce (section, FALSE);
+ introduce (section, false);
printf (_(" Offset Begin End\n"));
pointer_size = (is_rnglists ? address_size : debug_info_p->pointer_size);
offset = range_entry->ranges_offset;
- next = section_begin + offset;
base_address = debug_info_p->base_address;
/* PR 17512: file: 001-101485-0.001:0.1. */
continue;
}
- if (next < section_begin || next >= finish)
+ if (offset > (size_t) (finish - section_begin))
{
warn (_("Corrupt offset (%#8.8lx) in range entry %u\n"),
(unsigned long) offset, i);
continue;
}
+ next = section_begin + offset;
/* If multiple DWARF entities reference the same range then we will
have multiple entries in the `range_entries' list for the same
if (*need_col_headers)
{
- static const char *sloc = " LOC";
-
*need_col_headers = 0;
- printf ("%-*s CFA ", eh_addr_size * 2, sloc);
+ printf ("%-*s CFA ", eh_addr_size * 2, " LOC");
for (r = 0; r < *max_regs; r++)
if (fc->col_type[r] != DW_CFA_unreferenced)
}
if (strcmp (fc->augmentation, "eh") == 0)
- start += eh_addr_size;
+ {
+ if (eh_addr_size > (size_t) (end - start))
+ goto fail;
+ start += eh_addr_size;
+ }
if (version >= 4)
{
+ if (2 > (size_t) (end - start))
+ goto fail;
GET (fc->ptr_size, 1);
if (fc->ptr_size < 1 || fc->ptr_size > 8)
{
READ_ULEB (fc->code_factor, start, end);
READ_SLEB (fc->data_factor, start, end);
+ if (start >= end)
+ goto fail;
+
if (version == 1)
{
GET (fc->ra, 1);
if (fc->augmentation[0] == 'z')
{
+ if (start >= end)
+ goto fail;
READ_ULEB (augmentation_data_len, start, end);
augmentation_data = start;
/* PR 17512: file: 11042-2589-0.004. */
Frame_Chunk *chunks = NULL, *forward_refs = NULL;
Frame_Chunk *remembered_state = NULL;
Frame_Chunk *rs;
- bfd_boolean is_eh = strcmp (section->name, ".eh_frame") == 0;
+ bool is_eh = strcmp (section->name, ".eh_frame") == 0;
unsigned int max_regs = 0;
const char *bad_reg = _("bad register: ");
unsigned int saved_eh_addr_size = eh_addr_size;
- introduce (section, FALSE);
+ introduce (section, false);
while (start < end)
{
bfd_size_type augmentation_data_len = 0;
unsigned int encoded_ptr_size = saved_eh_addr_size;
unsigned int offset_size;
- unsigned int initial_length_size;
- bfd_boolean all_nops;
+ bool all_nops;
static Frame_Chunk fde_fc;
saved_start = start;
{
SAFE_BYTE_GET_AND_INC (length, start, 8, end);
offset_size = 8;
- initial_length_size = 12;
}
else
- {
- offset_size = 4;
- initial_length_size = 4;
- }
+ offset_size = 4;
- block_end = saved_start + length + initial_length_size;
- if (block_end > end || block_end < start)
+ if (length > (size_t) (end - start))
{
warn ("Invalid length 0x%s in FDE at %#08lx\n",
dwarf_vmatoa_1 (NULL, length, offset_size),
(unsigned long) (saved_start - section_start));
block_end = end;
}
+ else
+ block_end = start + length;
- SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, block_end);
if (is_eh ? (cie_id == 0) : ((offset_size == 4 && cie_id == DW_CIE_ID)
|| (offset_size == 8 && cie_id == DW64_CIE_ID)))
int version;
unsigned int mreg;
- start = read_cie (start, end, &cie, &version,
+ start = read_cie (start, block_end, &cie, &version,
&augmentation_data_len, &augmentation_data);
/* PR 17512: file: 027-135133-0.005. */
if (cie == NULL)
{
unsigned char *look_for;
unsigned long segment_selector;
+ dwarf_vma cie_off;
+ cie_off = cie_id;
if (is_eh)
{
dwarf_vma sign = (dwarf_vma) 1 << (offset_size * 8 - 1);
- look_for = start - 4 - ((cie_id ^ sign) - sign);
+ cie_off = (cie_off ^ sign) - sign;
+ cie_off = start - 4 - section_start - cie_off;
}
- else
- look_for = section_start + cie_id;
- if (look_for <= saved_start)
+ look_for = section_start + cie_off;
+ if (cie_off <= (dwarf_vma) (saved_start - section_start))
{
for (cie = chunks; cie ; cie = cie->next)
if (cie->chunk_start == look_for)
break;
}
+ else if (cie_off >= section->size)
+ cie = NULL;
else
{
for (cie = forward_refs; cie ; cie = cie->next)
SAFE_BYTE_GET_AND_INC (length, cie_scan, 8, end);
off_size = 8;
}
- if (length != 0)
+ if (length != 0 && length <= (size_t) (end - cie_scan))
{
dwarf_vma c_id;
+ unsigned char *cie_end = cie_scan + length;
- SAFE_BYTE_GET_AND_INC (c_id, cie_scan, off_size, end);
+ SAFE_BYTE_GET_AND_INC (c_id, cie_scan, off_size,
+ cie_end);
if (is_eh
? c_id == 0
: ((off_size == 4 && c_id == DW_CIE_ID)
int version;
unsigned int mreg;
- read_cie (cie_scan, end, &cie, &version,
+ read_cie (cie_scan, cie_end, &cie, &version,
&augmentation_data_len, &augmentation_data);
/* PR 17512: file: 3450-2098-0.004. */
if (cie == NULL)
if (!cie)
{
- warn ("Invalid CIE pointer 0x%s in FDE at %#08lx\n",
- dwarf_vmatoa_1 (NULL, cie_id, offset_size),
- (unsigned long) (saved_start - section_start));
fc->ncols = 0;
fc->col_type = (short int *) xmalloc (sizeof (short int));
fc->col_offset = (int *) xmalloc (sizeof (int));
warn (_("Probably corrupt segment size: %d - using 4 instead\n"), fc->segment_size);
fc->segment_size = 4;
}
- SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
+ SAFE_BYTE_GET_AND_INC (segment_selector, start,
+ fc->segment_size, block_end);
}
- fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section, end);
+ fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section,
+ block_end);
/* FIXME: It appears that sometimes the final pc_range value is
encoded in less than encoded_ptr_size bytes. See the x86_64
run of the "objcopy on compressed debug sections" test for an
example of this. */
- SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size, end);
+ SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size,
+ block_end);
if (cie->augmentation[0] == 'z')
{
- READ_ULEB (augmentation_data_len, start, end);
+ READ_ULEB (augmentation_data_len, start, block_end);
augmentation_data = start;
/* PR 17512 file: 722-8446-0.004 and PR 22386. */
- if (augmentation_data_len > (bfd_size_type) (end - start))
+ if (augmentation_data_len > (bfd_size_type) (block_end - start))
{
warn (_("Augmentation data too long: 0x%s, "
"expected at most %#lx\n"),
dwarf_vmatoa ("x", augmentation_data_len),
- (unsigned long) (end - start));
- start = end;
+ (unsigned long) (block_end - start));
+ start = block_end;
augmentation_data = NULL;
augmentation_data_len = 0;
}
start += augmentation_data_len;
}
- printf ("\n%08lx %s %s FDE cie=%08lx pc=",
+ printf ("\n%08lx %s %s FDE ",
(unsigned long)(saved_start - section_start),
dwarf_vmatoa_1 (NULL, length, fc->ptr_size),
- dwarf_vmatoa_1 (NULL, cie_id, offset_size),
- (unsigned long)(cie->chunk_start - section_start));
+ dwarf_vmatoa_1 (NULL, cie_id, offset_size));
+
+ if (cie->chunk_start)
+ printf ("cie=%08lx",
+ (unsigned long) (cie->chunk_start - section_start));
+ else
+ /* Ideally translate "invalid " to 8 chars, trailing space
+ is optional. */
+ printf (_("cie=invalid "));
+ printf (" pc=");
if (fc->segment_size)
printf ("%04lx:", segment_selector);
{
unsigned int reg, op, opa;
unsigned long temp;
- unsigned char * new_start;
op = *start++;
opa = op & 0x3f;
case DW_CFA_advance_loc:
break;
case DW_CFA_offset:
- SKIP_ULEB (start, end);
+ SKIP_ULEB (start, block_end);
if (frame_need_space (fc, opa) >= 0)
fc->col_type[opa] = DW_CFA_undefined;
break;
fc->col_type[opa] = DW_CFA_undefined;
break;
case DW_CFA_set_loc:
- start += encoded_ptr_size;
+ if ((size_t) (block_end - start) < encoded_ptr_size)
+ start = block_end;
+ else
+ start += encoded_ptr_size;
break;
case DW_CFA_advance_loc1:
- start += 1;
+ if ((size_t) (block_end - start) < 1)
+ start = block_end;
+ else
+ start += 1;
break;
case DW_CFA_advance_loc2:
- start += 2;
+ if ((size_t) (block_end - start) < 2)
+ start = block_end;
+ else
+ start += 2;
break;
case DW_CFA_advance_loc4:
- start += 4;
+ if ((size_t) (block_end - start) < 4)
+ start = block_end;
+ else
+ start += 4;
break;
case DW_CFA_offset_extended:
case DW_CFA_val_offset:
- READ_ULEB (reg, start, end);
- SKIP_ULEB (start, end);
+ READ_ULEB (reg, start, block_end);
+ SKIP_ULEB (start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_restore_extended:
- READ_ULEB (reg, start, end);
+ READ_ULEB (reg, start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_undefined:
- READ_ULEB (reg, start, end);
+ READ_ULEB (reg, start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_same_value:
- READ_ULEB (reg, start, end);
+ READ_ULEB (reg, start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_register:
- READ_ULEB (reg, start, end);
- SKIP_ULEB (start, end);
+ READ_ULEB (reg, start, block_end);
+ SKIP_ULEB (start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_def_cfa:
- SKIP_ULEB (start, end);
- SKIP_ULEB (start, end);
+ SKIP_ULEB (start, block_end);
+ SKIP_ULEB (start, block_end);
break;
case DW_CFA_def_cfa_register:
- SKIP_ULEB (start, end);
+ SKIP_ULEB (start, block_end);
break;
case DW_CFA_def_cfa_offset:
- SKIP_ULEB (start, end);
+ SKIP_ULEB (start, block_end);
break;
case DW_CFA_def_cfa_expression:
- READ_ULEB (temp, start, end);
- new_start = start + temp;
- if (new_start < start)
- {
- warn (_("Corrupt CFA_def expression value: %lu\n"), temp);
- start = block_end;
- }
+ READ_ULEB (temp, start, block_end);
+ if ((size_t) (block_end - start) < temp)
+ start = block_end;
else
- start = new_start;
+ start += temp;
break;
case DW_CFA_expression:
case DW_CFA_val_expression:
- READ_ULEB (reg, start, end);
- READ_ULEB (temp, start, end);
- new_start = start + temp;
- if (new_start < start)
- {
- /* PR 17512: file:306-192417-0.005. */
- warn (_("Corrupt CFA expression value: %lu\n"), temp);
- start = block_end;
- }
+ READ_ULEB (reg, start, block_end);
+ READ_ULEB (temp, start, block_end);
+ if ((size_t) (block_end - start) < temp)
+ start = block_end;
else
- start = new_start;
+ start += temp;
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_offset_extended_sf:
case DW_CFA_val_offset_sf:
- READ_ULEB (reg, start, end);
- SKIP_SLEB (start, end);
+ READ_ULEB (reg, start, block_end);
+ SKIP_SLEB (start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_def_cfa_sf:
- SKIP_ULEB (start, end);
- SKIP_SLEB (start, end);
+ SKIP_ULEB (start, block_end);
+ SKIP_SLEB (start, block_end);
break;
case DW_CFA_def_cfa_offset_sf:
- SKIP_SLEB (start, end);
+ SKIP_SLEB (start, block_end);
break;
case DW_CFA_MIPS_advance_loc8:
- start += 8;
+ if ((size_t) (block_end - start) < 8)
+ start = block_end;
+ else
+ start += 8;
break;
case DW_CFA_GNU_args_size:
- SKIP_ULEB (start, end);
+ SKIP_ULEB (start, block_end);
break;
case DW_CFA_GNU_negative_offset_extended:
- READ_ULEB (reg, start, end);
- SKIP_ULEB (start, end);
+ READ_ULEB (reg, start, block_end);
+ SKIP_ULEB (start, block_end);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
start = tmp;
}
- all_nops = TRUE;
+ all_nops = true;
/* Now we know what registers are used, make a second pass over
the chunk, this time actually printing out the info. */
while (start < block_end)
{
- unsigned char * tmp;
unsigned op, opa;
unsigned long ul, roffs;
/* Note: It is tempting to use an unsigned long for 'reg' but there
/* Make a note if something other than DW_CFA_nop happens. */
if (op != DW_CFA_nop)
- all_nops = FALSE;
+ all_nops = false;
/* Warning: if you add any more cases to this switch, be
sure to add them to the corresponding switch above. */
break;
case DW_CFA_offset:
- READ_ULEB (roffs, start, end);
+ READ_ULEB (roffs, start, block_end);
if (opa >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_set_loc:
- vma = get_encoded_value (&start, fc->fde_encoding, section, block_end);
+ vma = get_encoded_value (&start, fc->fde_encoding, section,
+ block_end);
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
else
break;
case DW_CFA_advance_loc1:
- SAFE_BYTE_GET_AND_INC (ofs, start, 1, end);
+ SAFE_BYTE_GET_AND_INC (ofs, start, 1, block_end);
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
else
break;
case DW_CFA_offset_extended:
- READ_ULEB (reg, start, end);
- READ_ULEB (roffs, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_ULEB (roffs, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_val_offset:
- READ_ULEB (reg, start, end);
- READ_ULEB (roffs, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_ULEB (roffs, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_restore_extended:
- READ_ULEB (reg, start, end);
+ READ_ULEB (reg, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_undefined:
- READ_ULEB (reg, start, end);
+ READ_ULEB (reg, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_same_value:
- READ_ULEB (reg, start, end);
+ READ_ULEB (reg, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_register:
- READ_ULEB (reg, start, end);
- READ_ULEB (roffs, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_ULEB (roffs, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_def_cfa:
- READ_ULEB (fc->cfa_reg, start, end);
- READ_ULEB (fc->cfa_offset, start, end);
+ READ_ULEB (fc->cfa_reg, start, block_end);
+ READ_ULEB (fc->cfa_offset, start, block_end);
fc->cfa_exp = 0;
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa: %s ofs %d\n",
break;
case DW_CFA_def_cfa_register:
- READ_ULEB (fc->cfa_reg, start, end);
+ READ_ULEB (fc->cfa_reg, start, block_end);
fc->cfa_exp = 0;
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa_register: %s\n",
break;
case DW_CFA_def_cfa_offset:
- READ_ULEB (fc->cfa_offset, start, end);
+ READ_ULEB (fc->cfa_offset, start, block_end);
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
break;
break;
case DW_CFA_def_cfa_expression:
- READ_ULEB (ul, start, end);
- if (start >= block_end || ul > (unsigned long) (block_end - start))
+ READ_ULEB (ul, start, block_end);
+ if (ul > (size_t) (block_end - start))
{
printf (_(" DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
break;
break;
case DW_CFA_expression:
- READ_ULEB (reg, start, end);
- READ_ULEB (ul, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_ULEB (ul, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
/* PR 17512: file: 069-133014-0.006. */
/* PR 17512: file: 98c02eb4. */
- tmp = start + ul;
- if (start >= block_end || tmp > block_end || tmp < start)
+ if (ul > (size_t) (block_end - start))
{
printf (_(" DW_CFA_expression: <corrupt len %lu>\n"), ul);
break;
}
if (*reg_prefix == '\0')
fc->col_type[reg] = DW_CFA_expression;
- start = tmp;
+ start += ul;
break;
case DW_CFA_val_expression:
- READ_ULEB (reg, start, end);
- READ_ULEB (ul, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_ULEB (ul, start, block_end);
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
- tmp = start + ul;
- if (start >= block_end || tmp > block_end || tmp < start)
+ if (ul > (size_t) (block_end - start))
{
printf (" DW_CFA_val_expression: <corrupt len %lu>\n", ul);
break;
}
if (*reg_prefix == '\0')
fc->col_type[reg] = DW_CFA_val_expression;
- start = tmp;
+ start += ul;
break;
case DW_CFA_offset_extended_sf:
- READ_ULEB (reg, start, end);
- READ_SLEB (l, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_SLEB (l, start, block_end);
if (frame_need_space (fc, reg) < 0)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_val_offset_sf:
- READ_ULEB (reg, start, end);
- READ_SLEB (l, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_SLEB (l, start, block_end);
if (frame_need_space (fc, reg) < 0)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
break;
case DW_CFA_def_cfa_sf:
- READ_ULEB (fc->cfa_reg, start, end);
- READ_ULEB (fc->cfa_offset, start, end);
- fc->cfa_offset = fc->cfa_offset * fc->data_factor;
+ READ_ULEB (fc->cfa_reg, start, block_end);
+ READ_SLEB (l, start, block_end);
+ l *= fc->data_factor;
+ fc->cfa_offset = l;
fc->cfa_exp = 0;
if (! do_debug_frames_interp)
- printf (" DW_CFA_def_cfa_sf: %s ofs %d\n",
- regname (fc->cfa_reg, 0), (int) fc->cfa_offset);
+ printf (" DW_CFA_def_cfa_sf: %s ofs %ld\n",
+ regname (fc->cfa_reg, 0), (long) l);
break;
case DW_CFA_def_cfa_offset_sf:
- READ_ULEB (fc->cfa_offset, start, end);
- fc->cfa_offset *= fc->data_factor;
+ READ_SLEB (l, start, block_end);
+ l *= fc->data_factor;
+ fc->cfa_offset = l;
if (! do_debug_frames_interp)
- printf (" DW_CFA_def_cfa_offset_sf: %d\n", (int) fc->cfa_offset);
+ printf (" DW_CFA_def_cfa_offset_sf: %ld\n", (long) l);
break;
case DW_CFA_MIPS_advance_loc8:
break;
case DW_CFA_GNU_args_size:
- READ_ULEB (ul, start, end);
+ READ_ULEB (ul, start, block_end);
if (! do_debug_frames_interp)
printf (" DW_CFA_GNU_args_size: %ld\n", ul);
break;
case DW_CFA_GNU_negative_offset_extended:
- READ_ULEB (reg, start, end);
- READ_SLEB (l, start, end);
+ READ_ULEB (reg, start, block_end);
+ READ_SLEB (l, start, block_end);
l = - l;
if (frame_need_space (fc, reg) < 0)
reg_prefix = bad_reg;
const unsigned char *const section_end = section->start + section->size;
unsigned char *unit_end;
- introduce (section, FALSE);
+ introduce (section, false);
load_debug_section_with_follow (str, file);
unsigned int offset_size;
uint16_t dwarf_version, padding;
uint32_t comp_unit_count, local_type_unit_count, foreign_type_unit_count;
- uint32_t bucket_count, name_count, abbrev_table_size;
+ uint64_t bucket_count, name_count, abbrev_table_size;
uint32_t augmentation_string_size;
unsigned int i;
- unsigned long sec_off;
- bfd_boolean augmentation_printable;
+ bool augmentation_printable;
const char *augmentation_string;
+ size_t total;
unit_start = hdrptr;
}
else
offset_size = 4;
- unit_end = hdrptr + unit_length;
- sec_off = hdrptr - section->start;
- if (sec_off + unit_length < sec_off
- || sec_off + unit_length > section->size)
+ if (unit_length > (size_t) (section_end - hdrptr)
+ || unit_length < 2 + 2 + 4 * 7)
{
+ too_short:
warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
section->name,
(unsigned long) (unit_start - section->start),
dwarf_vmatoa ("x", unit_length));
return 0;
}
+ unit_end = hdrptr + unit_length;
/* Get and check the version number. */
SAFE_BYTE_GET_AND_INC (dwarf_version, hdrptr, 2, unit_end);
augmentation_string_size);
augmentation_string_size += (-augmentation_string_size) & 3;
}
+ if (augmentation_string_size > (size_t) (unit_end - hdrptr))
+ goto too_short;
printf (_("Augmentation string:"));
- augmentation_printable = TRUE;
+ augmentation_printable = true;
augmentation_string = (const char *) hdrptr;
for (i = 0; i < augmentation_string_size; i++)
printf (" %02x", uc);
if (uc != 0 && !ISPRINT (uc))
- augmentation_printable = FALSE;
+ augmentation_printable = false;
}
if (augmentation_printable)
putchar ('\n');
printf (_("CU table:\n"));
+ if (_mul_overflow (comp_unit_count, offset_size, &total)
+ || total > (size_t) (unit_end - hdrptr))
+ goto too_short;
for (i = 0; i < comp_unit_count; i++)
{
uint64_t cu_offset;
putchar ('\n');
printf (_("TU table:\n"));
+ if (_mul_overflow (local_type_unit_count, offset_size, &total)
+ || total > (size_t) (unit_end - hdrptr))
+ goto too_short;
for (i = 0; i < local_type_unit_count; i++)
{
uint64_t tu_offset;
putchar ('\n');
printf (_("Foreign TU table:\n"));
+ if (_mul_overflow (foreign_type_unit_count, 8, &total)
+ || total > (size_t) (unit_end - hdrptr))
+ goto too_short;
for (i = 0; i < foreign_type_unit_count; i++)
{
uint64_t signature;
}
putchar ('\n');
+ uint64_t xtra = (bucket_count * sizeof (uint32_t)
+ + name_count * (sizeof (uint32_t) + 2 * offset_size)
+ + abbrev_table_size);
+ if (xtra > (size_t) (unit_end - hdrptr))
+ {
+ warn (_("Entry pool offset (0x%lx) exceeds unit size 0x%lx "
+ "for unit 0x%lx in the debug_names\n"),
+ (long) xtra,
+ (long) (unit_end - unit_start),
+ (long) (unit_start - section->start));
+ return 0;
+ }
const uint32_t *const hash_table_buckets = (uint32_t *) hdrptr;
hdrptr += bucket_count * sizeof (uint32_t);
const uint32_t *const hash_table_hashes = (uint32_t *) hdrptr;
hdrptr += abbrev_table_size;
const unsigned char *const abbrev_table_end = hdrptr;
unsigned char *const entry_pool = hdrptr;
- if (hdrptr > unit_end)
- {
- warn (_("Entry pool offset (0x%lx) exceeds unit size 0x%lx "
- "for unit 0x%lx in the debug_names\n"),
- (long) (hdrptr - section->start),
- (long) (unit_end - section->start),
- (long) (unit_start - section->start));
- return 0;
- }
size_t buckets_filled = 0;
size_t bucketi;
for (namei = 0; namei < name_count; ++namei)
{
uint64_t string_offset, entry_offset;
+ unsigned char *p;
- SAFE_BYTE_GET (string_offset,
- name_table_string_offsets + namei * offset_size,
- offset_size, unit_end);
- SAFE_BYTE_GET (entry_offset,
- name_table_entry_offsets + namei * offset_size,
- offset_size, unit_end);
+ p = name_table_string_offsets + namei * offset_size;
+ SAFE_BYTE_GET (string_offset, p, offset_size, unit_end);
+ p = name_table_entry_offsets + namei * offset_size;
+ SAFE_BYTE_GET (entry_offset, p, offset_size, unit_end);
printf ("[%3u] #%08x %s:", namei, hash_table_hashes[namei],
fetch_indirect_string (string_offset));
const unsigned char * filename;
unsigned int filelen;
- introduce (section, FALSE);
+ introduce (section, false);
/* The .gnu_debuglink section is formatted as:
(c-string) Filename.
The .gun_debugaltlink section is formatted as:
(c-string) Filename.
(binary) Build-ID. */
-
+
filename = section->start;
filelen = strnlen ((const char *) filename, section->size);
if (filelen == section->size)
printf (_(" Separate debug info file: %s\n"), filename);
- if (const_strneq (section->name, ".gnu_debuglink"))
+ if (startswith (section->name, ".gnu_debuglink"))
{
unsigned int crc32;
unsigned int crc_offset;
return 0;
}
}
- else /* const_strneq (section->name, ".gnu_debugaltlink") */
+ else /* startswith (section->name, ".gnu_debugaltlink") */
{
const unsigned char * build_id = section->start + filelen + 1;
bfd_size_type build_id_len = section->size - (filelen + 1);
/* The documentation for the format of this file is in gdb/dwarf2read.c. */
- introduce (section, FALSE);
+ introduce (section, false);
if (section->size < 6 * sizeof (uint32_t))
{
symbol_table = start + symbol_table_offset;
constant_pool = start + constant_pool_offset;
- if (address_table + address_table_size > section->start + section->size)
+ if (address_table_offset + address_table_size > section->size)
{
warn (_("Address table extends beyond end of section.\n"));
return 0;
|| cu_vector_offset != 0)
{
unsigned int j;
- unsigned char * adr;
- adr = constant_pool + name_offset;
/* PR 17531: file: 5b7b07ad. */
- if (adr < constant_pool || adr >= section->start + section->size)
+ if (name_offset >= section->size - constant_pool_offset)
{
printf (_("[%3u] <corrupt offset: %x>"), i, name_offset);
warn (_("Corrupt name offset of 0x%x found for symbol table slot %d\n"),
(int) (section->size - (constant_pool_offset + name_offset)),
constant_pool + name_offset);
- adr = constant_pool + cu_vector_offset;
- if (adr < constant_pool || adr >= section->start + section->size - 3)
+ if (section->size - constant_pool_offset < 4
+ || cu_vector_offset > section->size - constant_pool_offset - 4)
{
printf (_("<invalid CU vector offset: %x>\n"), cu_vector_offset);
warn (_("Corrupt CU vector offset of 0x%x found for symbol table slot %d\n"),
continue;
}
- num_cus = byte_get_little_endian (adr, 4);
+ num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
- adr = constant_pool + cu_vector_offset + 4 + num_cus * 4;
- if (num_cus * 4 < num_cus
- || adr >= section->start + section->size
- || adr < constant_pool)
+ if ((uint64_t) num_cus * 4 > section->size - (constant_pool_offset
+ + cu_vector_offset + 4))
{
printf ("<invalid number of CUs: %d>\n", num_cus);
warn (_("Invalid number of CUs (0x%x) for symbol table slot %d\n"),
unsigned int nslots;
unsigned int i;
unsigned int j;
- dwarf_vma signature_high;
- dwarf_vma signature_low;
- char buf[64];
+ dwarf_vma signature;
+ size_t total;
/* PR 17512: file: 002-168123-0.004. */
if (phdr == NULL)
return 0;
}
- SAFE_BYTE_GET (version, phdr, 4, limit);
+ phash = phdr;
+ SAFE_BYTE_GET_AND_INC (version, phash, 4, limit);
if (version >= 2)
- SAFE_BYTE_GET (ncols, phdr + 4, 4, limit);
- SAFE_BYTE_GET (nused, phdr + 8, 4, limit);
- SAFE_BYTE_GET (nslots, phdr + 12, 4, limit);
+ SAFE_BYTE_GET_AND_INC (ncols, phash, 4, limit);
+ SAFE_BYTE_GET_AND_INC (nused, phash, 4, limit);
+ SAFE_BYTE_GET_AND_INC (nslots, phash, 4, limit);
- phash = phdr + 16;
pindex = phash + (size_t) nslots * 8;
ppool = pindex + (size_t) nslots * 4;
if (do_display)
{
- introduce (section, FALSE);
+ introduce (section, false);
printf (_(" Version: %u\n"), version);
if (version >= 2)
}
/* PR 17531: file: 45d69832. */
- if ((size_t) nslots * 8 / 8 != nslots
- || phash < phdr || phash > limit
- || pindex < phash || pindex > limit
- || ppool < pindex || ppool > limit)
+ if (_mul_overflow ((size_t) nslots, 12, &total)
+ || total > (size_t) (limit - phash))
{
warn (ngettext ("Section %s is too small for %u slot\n",
"Section %s is too small for %u slots\n",
unsigned char *shndx_list;
unsigned int shndx;
- SAFE_BYTE_GET64 (phash, &signature_high, &signature_low, limit);
- if (signature_high != 0 || signature_low != 0)
+ SAFE_BYTE_GET (signature, phash, 8, limit);
+ if (signature != 0)
{
SAFE_BYTE_GET (j, pindex, 4, limit);
shndx_list = ppool + j * 4;
if (do_display)
printf (_(" [%3d] Signature: 0x%s Sections: "),
- i, dwarf_vmatoa64 (signature_high, signature_low,
- buf, sizeof (buf)));
+ i, dwarf_vmatoa ("x", signature));
for (;;)
{
if (shndx_list >= limit)
unsigned char *pi = pindex;
unsigned char *poffsets = ppool + (size_t) ncols * 4;
unsigned char *psizes = poffsets + (size_t) nused * ncols * 4;
- unsigned char *pend = psizes + (size_t) nused * ncols * 4;
- bfd_boolean is_tu_index;
+ bool is_tu_index;
struct cu_tu_set *this_set = NULL;
unsigned int row;
unsigned char *prow;
+ size_t temp;
is_tu_index = strcmp (section->name, ".debug_tu_index") == 0;
/* PR 17531: file: 0dd159bf.
Check for integer overflow (can occur when size_t is 32-bit)
with overlarge ncols or nused values. */
- if (ncols > 0
- && ((size_t) ncols * 4 / 4 != ncols
- || (size_t) nused * ncols * 4 / ((size_t) ncols * 4) != nused
- || poffsets < ppool || poffsets > limit
- || psizes < poffsets || psizes > limit
- || pend < psizes || pend > limit))
+ if (nused == -1u
+ || _mul_overflow ((size_t) ncols, 4, &temp)
+ || _mul_overflow ((size_t) nused + 1, temp, &total)
+ || total > (size_t) (limit - ppool))
{
warn (_("Section %s too small for offset and size tables\n"),
section->name);
{
for (j = 0; j < ncols; j++)
{
- SAFE_BYTE_GET (dw_sect, ppool + j * 4, 4, limit);
+ unsigned char *p = ppool + j * 4;
+ SAFE_BYTE_GET (dw_sect, p, 4, limit);
printf (" %8s", get_DW_SECT_short_name (dw_sect));
}
printf ("\n");
for (i = 0; i < nslots; i++)
{
- SAFE_BYTE_GET64 (ph, &signature_high, &signature_low, limit);
+ SAFE_BYTE_GET (signature, ph, 8, limit);
SAFE_BYTE_GET (row, pi, 4, limit);
if (row != 0)
{
size_t num_copy = sizeof (uint64_t);
- /* PR 23064: Beware of buffer overflow. */
- if (ph + num_copy < limit)
- memcpy (&this_set[row - 1].signature, ph, num_copy);
- else
- {
- warn (_("Signature (%p) extends beyond end of space in section\n"), ph);
- return 0;
- }
+ memcpy (&this_set[row - 1].signature, ph, num_copy);
}
prow = poffsets + (row - 1) * ncols * 4;
- /* PR 17531: file: b8ce60a8. */
- if (prow < poffsets || prow > limit)
- {
- warn (_("Row index (%u) * num columns (%u) > space remaining in section\n"),
- row, ncols);
- return 0;
- }
-
if (do_display)
printf (_(" [%3d] 0x%s"),
- i, dwarf_vmatoa64 (signature_high, signature_low,
- buf, sizeof (buf)));
+ i, dwarf_vmatoa ("x", signature));
for (j = 0; j < ncols; j++)
{
- SAFE_BYTE_GET (val, prow + j * 4, 4, limit);
+ unsigned char *p = prow + j * 4;
+ SAFE_BYTE_GET (val, p, 4, limit);
if (do_display)
printf (" %8d", val);
else
{
- SAFE_BYTE_GET (dw_sect, ppool + j * 4, 4, limit);
+ p = ppool + j * 4;
+ SAFE_BYTE_GET (dw_sect, p, 4, limit);
/* PR 17531: file: 10796eb3. */
if (dw_sect >= DW_SECT_MAX)
for (j = 0; j < ncols; j++)
{
- SAFE_BYTE_GET (val, ppool + j * 4, 4, limit);
+ unsigned char *p = ppool + j * 4;
+ SAFE_BYTE_GET (val, p, 4, limit);
if (do_display)
printf (" %8s", get_DW_SECT_short_name (val));
}
for (i = 0; i < nslots; i++)
{
- SAFE_BYTE_GET64 (ph, &signature_high, &signature_low, limit);
+ SAFE_BYTE_GET (signature, ph, 8, limit);
SAFE_BYTE_GET (row, pi, 4, limit);
if (row != 0)
if (do_display)
printf (_(" [%3d] 0x%s"),
- i, dwarf_vmatoa64 (signature_high, signature_low,
- buf, sizeof (buf)));
+ i, dwarf_vmatoa ("x", signature));
for (j = 0; j < ncols; j++)
{
- SAFE_BYTE_GET (val, prow + j * 4, 4, limit);
+ unsigned char *p = prow + j * 4;
+ SAFE_BYTE_GET (val, p, 4, limit);
if (do_display)
printf (" %8d", val);
else
{
- SAFE_BYTE_GET (dw_sect, ppool + j * 4, 4, limit);
+ p = ppool + j * 4;
+ SAFE_BYTE_GET (dw_sect, p, 4, limit);
if (dw_sect >= DW_SECT_MAX)
warn (_("Overlarge Dwarf section index detected: %u\n"), dw_sect);
else
return 1;
}
+static int cu_tu_indexes_read = -1; /* Tri-state variable. */
+
/* Load the CU and TU indexes if present. This will build a list of
section sets that we can use to associate a .debug_info.dwo section
with its associated .debug_abbrev.dwo section in a .dwp file. */
-static bfd_boolean
+static bool
load_cu_tu_indexes (void *file)
{
- static int cu_tu_indexes_read = -1; /* Tri-state variable. */
-
/* If we have already loaded (or tried to load) the CU and TU indexes
then do not bother to repeat the task. */
if (cu_tu_indexes_read == -1)
{
- cu_tu_indexes_read = TRUE;
-
+ cu_tu_indexes_read = true;
+
if (load_debug_section_with_follow (dwp_cu_index, file))
if (! process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0))
- cu_tu_indexes_read = FALSE;
+ cu_tu_indexes_read = false;
if (load_debug_section_with_follow (dwp_tu_index, file))
if (! process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0))
- cu_tu_indexes_read = FALSE;
+ cu_tu_indexes_read = false;
}
- return (bfd_boolean) cu_tu_indexes_read;
+ return (bool) cu_tu_indexes_read;
}
/* Find the set of sections that includes section SHNDX. */
return ~crc & 0xffffffff;
}
-typedef bfd_boolean (* check_func_type) (const char *, void *);
-typedef const char * (* parse_func_type) (struct dwarf_section *, void *);
+typedef bool (*check_func_type) (const char *, void *);
+typedef const char *(* parse_func_type) (struct dwarf_section *, void *);
-static bfd_boolean
+static bool
check_gnu_debuglink (const char * pathname, void * crc_pointer)
{
static unsigned char buffer [8 * 1024];
sep_data = open_debug_file (pathname);
if (sep_data == NULL)
- return FALSE;
+ return false;
/* Yes - we are opening the file twice... */
f = fopen (pathname, "rb");
/* Paranoia: This should never happen. */
close_debug_file (sep_data);
warn (_("Unable to reopen separate debug info file: %s\n"), pathname);
- return FALSE;
+ return false;
}
while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0)
close_debug_file (sep_data);
warn (_("Separate debug info file %s found, but CRC does not match - ignoring\n"),
pathname);
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static const char *
The CRC value is stored after the filename, aligned up to 4 bytes. */
name = (const char *) section->start;
-
crc_offset = strnlen (name, section->size) + 1;
+ if (crc_offset == 1)
+ return NULL;
crc_offset = (crc_offset + 3) & ~3;
if (crc_offset + 4 > section->size)
return NULL;
return name;
}
-static bfd_boolean
+static bool
check_gnu_debugaltlink (const char * filename, void * data ATTRIBUTE_UNUSED)
{
void * sep_data = open_debug_file (filename);
if (sep_data == NULL)
- return FALSE;
+ return false;
/* FIXME: We should now extract the build-id in the separate file
and check it... */
- return TRUE;
+ return true;
}
typedef struct build_id_data
name = (const char *) section->start;
namelen = strnlen (name, section->size) + 1;
+ if (namelen == 1)
+ return NULL;
if (namelen >= section->size)
return NULL;
file. If successful, store the path of the file in filename and
return TRUE, otherwise return FALSE. */
-static bfd_boolean
+static bool
debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
char ** filename,
void * file)
filelen = strnlen ((const char *)section->start, section->size);
if (filelen == section->size)
/* Corrupt debugaltlink. */
- return FALSE;
+ return false;
build_id = section->start + filelen + 1;
build_id_len = section->size - (filelen + 1);
if (build_id_len == 0)
- return FALSE;
+ return false;
}
else
- return FALSE;
+ return false;
if (build_id)
{
client = debuginfod_begin ();
if (client == NULL)
- return FALSE;
+ return false;
/* Query debuginfod servers for the target file. If found its path
will be stored in filename. */
/* File successfully retrieved. Close fd since we want to
use open_debug_file () on filename instead. */
close (fd);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
#endif
xlink->name ? xlink->name : xlink->uncompressed_name);
return NULL;
}
-
+
/* Attempt to locate the separate file.
This should duplicate the logic in bfd/opncls.c:find_separate_debug_file(). */
canon_dir = lrealpath (main_filename);
-
+
for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--)
if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1]))
break;
}
#endif
- /* Failed to find the file. */
- warn (_("could not find separate debug file '%s'\n"), separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ if (do_debug_links)
+ {
+ /* Failed to find the file. */
+ warn (_("could not find separate debug file '%s'\n"),
+ separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
#ifdef EXTRA_DEBUG_ROOT2
- sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT2, separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT2,
+ separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
#endif
#ifdef EXTRA_DEBUG_ROOT1
- sprintf (debug_filename, "%s/%s/%s", EXTRA_DEBUG_ROOT1, canon_dir, separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, "%s/%s/%s", EXTRA_DEBUG_ROOT1,
+ canon_dir, separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
- sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT1, separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT1,
+ separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
#endif
- sprintf (debug_filename, "%s.debug/%s", canon_dir, separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, "%s.debug/%s", canon_dir,
+ separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
- sprintf (debug_filename, "%s%s", canon_dir, separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, "%s%s", canon_dir, separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
- sprintf (debug_filename, ".debug/%s", separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, ".debug/%s", separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
- sprintf (debug_filename, "%s", separate_filename);
- warn (_("tried: %s\n"), debug_filename);
+ sprintf (debug_filename, "%s", separate_filename);
+ warn (_("tried: %s\n"), debug_filename);
#if HAVE_LIBDEBUGINFOD
- {
- char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
- if (urls == NULL)
- urls = "";
+ {
+ char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
+ if (urls == NULL)
+ urls = "";
- warn (_("tried: DEBUGINFOD_URLS=%s\n"), urls);
- }
+ warn (_("tried: DEBUGINFOD_URLS=%s\n"), urls);
+ }
#endif
+ }
free (canon_dir);
free (debug_filename);
/* FIXME: We do not check to see if there are any other separate debug info
files that would also match. */
- printf (_("%s: Found separate debug info file: %s\n\n"), main_filename, debug_filename);
+ if (do_debug_links)
+ printf (_("\n%s: Found separate debug info file: %s\n"), main_filename, debug_filename);
add_separate_debug_file (debug_filename, debug_handle);
/* Do not free debug_filename - it might be referenced inside
char * separate_filename;
void * separate_handle;
- /* FIXME: Skip adding / if dwo_dir ends in /. */
- separate_filename = concat (dir, "/", name, NULL);
+ if (IS_ABSOLUTE_PATH (name))
+ separate_filename = strdup (name);
+ else
+ /* FIXME: Skip adding / if dwo_dir ends in /. */
+ separate_filename = concat (dir, "/", name, NULL);
if (separate_filename == NULL)
{
warn (_("Out of memory allocating dwo filename\n"));
/* FIXME: We should check the dwo_id. */
printf (_("%s: Found separate debug object file: %s\n\n"), main_filename, separate_filename);
+
add_separate_debug_file (separate_filename, separate_handle);
/* Note - separate_filename will be freed in free_debug_memory(). */
return separate_handle;
}
+static void
+load_debug_sup_file (const char * main_filename, void * file)
+{
+ if (! load_debug_section (debug_sup, file))
+ return; /* No .debug_sup section. */
+
+ struct dwarf_section * section;
+ section = & debug_displays [debug_sup].section;
+ assert (section != NULL);
+
+ if (section->start == NULL || section->size < 5)
+ {
+ warn (_(".debug_sup section is corrupt/empty\n"));
+ return;
+ }
+
+ if (section->start[2] != 0)
+ return; /* This is a supplementary file. */
+
+ const char * filename = (const char *) section->start + 3;
+ if (strnlen (filename, section->size - 3) == section->size - 3)
+ {
+ warn (_("filename in .debug_sup section is corrupt\n"));
+ return;
+ }
+
+ if (filename[0] != '/' && strchr (main_filename, '/'))
+ {
+ char * new_name;
+ int new_len;
+
+ new_len = asprintf (& new_name, "%.*s/%s",
+ (int) (strrchr (main_filename, '/') - main_filename),
+ main_filename,
+ filename);
+ if (new_len < 3)
+ {
+ warn (_("unable to construct path for supplementary debug file"));
+ if (new_len > -1)
+ free (new_name);
+ return;
+ }
+ filename = new_name;
+ }
+ else
+ {
+ /* PR 27796: Make sure that we pass a filename that can be free'd to
+ add_separate_debug_file(). */
+ filename = strdup (filename);
+ if (filename == NULL)
+ {
+ warn (_("out of memory constructing filename for .debug_sup link\n"));
+ return;
+ }
+ }
+
+ void * handle = open_debug_file (filename);
+ if (handle == NULL)
+ {
+ warn (_("unable to open file '%s' referenced from .debug_sup section\n"), filename);
+ free ((void *) filename);
+ return;
+ }
+
+ printf (_("%s: Found supplementary debug file: %s\n\n"), main_filename, filename);
+
+ /* FIXME: Compare the checksums, if present. */
+ add_separate_debug_file (filename, handle);
+}
+
/* Load a debuglink section and/or a debugaltlink section, if either are present.
Recursively check the loaded files for more of these sections.
- FIXME: Should also check for DWO_* entries in the newlu loaded files. */
+ Also follow any links in .debug_sup sections.
+ FIXME: Should also check for DWO_* entries in the newly loaded files. */
static void
check_for_and_load_links (void * file, const char * filename)
first_separate_info->filename);
}
}
+
+ load_debug_sup_file (filename, file);
}
/* Load the separate debug info file(s) attached to FILE, if any exist.
If TRUE is returned then the linked list starting at first_separate_info
will be populated with open file handles. */
-bfd_boolean
+bool
load_separate_debug_files (void * file, const char * filename)
{
/* Skip this operation if we are not interested in debug links. */
if (! do_follow_links && ! do_debug_links)
- return FALSE;
+ return false;
/* See if there are any dwo links. */
if (load_debug_section (str, file)
{
free_dwo_info ();
- if (process_debug_info (& debug_displays[info].section, file, abbrev, TRUE, FALSE))
+ if (process_debug_info (& debug_displays[info].section, file, abbrev,
+ true, false))
{
- bfd_boolean introduced = FALSE;
- dwo_info * dwinfo;
- const char * dir = NULL;
- const char * id = NULL;
+ bool introduced = false;
+ dwo_info *dwinfo;
+ const char *dir = NULL;
+ const char *id = NULL;
+ const char *name = NULL;
for (dwinfo = first_dwo_info; dwinfo != NULL; dwinfo = dwinfo->next)
{
+ /* Accumulate NAME, DIR and ID fields. */
switch (dwinfo->type)
{
case DWO_NAME:
+ if (name != NULL)
+ warn (_("Multiple DWO_NAMEs encountered for the same CU\n"));
+ name = dwinfo->value;
+ break;
+
+ case DWO_DIR:
+ /* There can be multiple DW_AT_comp_dir entries in a CU,
+ so do not complain. */
+ dir = dwinfo->value;
+ break;
+
+ case DWO_ID:
+ if (id != NULL)
+ warn (_("multiple DWO_IDs encountered for the same CU\n"));
+ id = dwinfo->value;
+ break;
+
+ default:
+ error (_("Unexpected DWO INFO type"));
+ break;
+ }
+
+ /* If we have reached the end of our list, or we are changing
+ CUs, then display the information that we have accumulated
+ so far. */
+ if (name != NULL
+ && (dwinfo->next == NULL
+ || dwinfo->next->cu_offset != dwinfo->cu_offset))
+ {
if (do_debug_links)
{
if (! introduced)
{
printf (_("The %s section contains link(s) to dwo file(s):\n\n"),
debug_displays [info].section.uncompressed_name);
- introduced = TRUE;
+ introduced = true;
}
- printf (_(" Name: %s\n"), dwinfo->value);
+ printf (_(" Name: %s\n"), name);
printf (_(" Directory: %s\n"), dir ? dir : _("<not-found>"));
if (id != NULL)
display_data (printf (_(" ID: ")), (unsigned char *) id, 8);
else
- printf (_(" ID: <unknown>\n"));
+ printf (_(" ID: <not specified>\n"));
printf ("\n\n");
}
if (do_follow_links)
- load_dwo_file (filename, dwinfo->value, dir, id);
- break;
-
- case DWO_DIR:
- dir = dwinfo->value;
- break;
-
- case DWO_ID:
- id = dwinfo->value;
- break;
+ load_dwo_file (filename, name, dir, id);
- default:
- error (_("Unexpected DWO INFO type"));
- break;
+ name = dir = id = NULL;
}
}
}
if (! do_follow_links)
/* The other debug links will be displayed by display_debug_links()
so we do not need to do any further processing here. */
- return FALSE;
+ return false;
/* FIXME: We do not check for the presence of both link sections in the same file. */
/* FIXME: We do not check for the presence of multiple, same-name debuglink sections. */
check_for_and_load_links (file, filename);
if (first_separate_info != NULL)
- return TRUE;
+ return true;
do_follow_links = 0;
- return FALSE;
-}
+ return false;
+}
void
free_debug_memory (void)
free (cu_abbrev_map);
cu_abbrev_map = NULL;
next_free_abbrev_map_entry = 0;
-
+
+ free (shndx_pool);
+ shndx_pool = NULL;
+ shndx_pool_size = 0;
+ shndx_pool_used = 0;
+ free (cu_sets);
+ cu_sets = NULL;
+ cu_count = 0;
+ free (tu_sets);
+ tu_sets = NULL;
+ tu_count = 0;
+
+ memset (level_type_signed, 0, sizeof level_type_signed);
+ cu_tu_indexes_read = -1;
+
for (i = 0; i < max; i++)
free_debug_section ((enum dwarf_section_display_enum) i);
free ((void *) d);
}
first_separate_info = NULL;
-
+
free_dwo_info ();
}
{ "links", & do_debug_links, 1 },
{ "loc", & do_debug_loc, 1 },
{ "macro", & do_debug_macinfo, 1 },
+ { "no-follow-links", & do_follow_links, 0 },
{ "pubnames", & do_debug_pubnames, 1 },
{ "pubtypes", & do_debug_pubtypes, 1 },
/* This entry is for compatibility
if (strncmp (p, entry->option, len) == 0
&& (p[len] == ',' || p[len] == '\0'))
{
- * entry->variable |= entry->val;
+ * entry->variable = entry->val;
/* The --debug-dump=frames-interp option also
enables the --debug-dump=frames option. */
case 'g': do_gdb_index = 1; break;
case 'i': do_debug_info = 1; break;
case 'K': do_follow_links = 1; break;
+ case 'N': do_follow_links = 0; break;
case 'k': do_debug_links = 1; break;
case 'l': do_debug_lines |= FLAG_DEBUG_LINES_RAW; break;
case 'L': do_debug_lines |= FLAG_DEBUG_LINES_DECODED; break;
do_debug_str_offsets = 1;
}
-#define NO_ABBREVS NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL
-#define ABBREV(N) NULL, NULL, NULL, 0, 0, N, NULL, 0, NULL
+#define NO_ABBREVS NULL, NULL, NULL, 0, 0, 0, NULL, 0
+#define ABBREV(N) NULL, NULL, NULL, 0, 0, N, NULL, 0
/* N.B. The order here must match the order in section_display_enum. */
struct dwarf_section_display debug_displays[] =
{
- { { ".debug_abbrev", ".zdebug_abbrev", NO_ABBREVS }, display_debug_abbrev, &do_debug_abbrevs, FALSE },
- { { ".debug_aranges", ".zdebug_aranges", NO_ABBREVS }, display_debug_aranges, &do_debug_aranges, TRUE },
- { { ".debug_frame", ".zdebug_frame", NO_ABBREVS }, display_debug_frames, &do_debug_frames, TRUE },
- { { ".debug_info", ".zdebug_info", ABBREV (abbrev)}, display_debug_info, &do_debug_info, TRUE },
- { { ".debug_line", ".zdebug_line", NO_ABBREVS }, display_debug_lines, &do_debug_lines, TRUE },
- { { ".debug_pubnames", ".zdebug_pubnames", NO_ABBREVS }, display_debug_pubnames, &do_debug_pubnames, FALSE },
- { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubnames, FALSE },
- { { ".eh_frame", "", NO_ABBREVS }, display_debug_frames, &do_debug_frames, TRUE },
- { { ".debug_macinfo", ".zdebug_macinfo", NO_ABBREVS }, display_debug_macinfo, &do_debug_macinfo, FALSE },
- { { ".debug_macro", ".zdebug_macro", NO_ABBREVS }, display_debug_macro, &do_debug_macinfo, TRUE },
- { { ".debug_str", ".zdebug_str", NO_ABBREVS }, display_debug_str, &do_debug_str, FALSE },
- { { ".debug_line_str", ".zdebug_line_str", NO_ABBREVS }, display_debug_str, &do_debug_str, FALSE },
- { { ".debug_loc", ".zdebug_loc", NO_ABBREVS }, display_debug_loc, &do_debug_loc, TRUE },
- { { ".debug_loclists", ".zdebug_loclists", NO_ABBREVS }, display_debug_loc, &do_debug_loc, TRUE },
- { { ".debug_pubtypes", ".zdebug_pubtypes", NO_ABBREVS }, display_debug_pubnames, &do_debug_pubtypes, FALSE },
- { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubtypes, FALSE },
- { { ".debug_ranges", ".zdebug_ranges", NO_ABBREVS }, display_debug_ranges, &do_debug_ranges, TRUE },
- { { ".debug_rnglists", ".zdebug_rnglists", NO_ABBREVS }, display_debug_ranges, &do_debug_ranges, TRUE },
- { { ".debug_static_func", ".zdebug_static_func", NO_ABBREVS }, display_debug_not_supported, NULL, FALSE },
- { { ".debug_static_vars", ".zdebug_static_vars", NO_ABBREVS }, display_debug_not_supported, NULL, FALSE },
- { { ".debug_types", ".zdebug_types", ABBREV (abbrev) }, display_debug_types, &do_debug_info, TRUE },
- { { ".debug_weaknames", ".zdebug_weaknames", NO_ABBREVS }, display_debug_not_supported, NULL, FALSE },
- { { ".gdb_index", "", NO_ABBREVS }, display_gdb_index, &do_gdb_index, FALSE },
- { { ".debug_names", "", NO_ABBREVS }, display_debug_names, &do_gdb_index, FALSE },
- { { ".trace_info", "", ABBREV (trace_abbrev) }, display_trace_info, &do_trace_info, TRUE },
- { { ".trace_abbrev", "", NO_ABBREVS }, display_debug_abbrev, &do_trace_abbrevs, FALSE },
- { { ".trace_aranges", "", NO_ABBREVS }, display_debug_aranges, &do_trace_aranges, FALSE },
- { { ".debug_info.dwo", ".zdebug_info.dwo", ABBREV (abbrev_dwo) }, display_debug_info, &do_debug_info, TRUE },
- { { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo", NO_ABBREVS }, display_debug_abbrev, &do_debug_abbrevs, FALSE },
- { { ".debug_types.dwo", ".zdebug_types.dwo", ABBREV (abbrev_dwo) }, display_debug_types, &do_debug_info, TRUE },
- { { ".debug_line.dwo", ".zdebug_line.dwo", NO_ABBREVS }, display_debug_lines, &do_debug_lines, TRUE },
- { { ".debug_loc.dwo", ".zdebug_loc.dwo", NO_ABBREVS }, display_debug_loc, &do_debug_loc, TRUE },
- { { ".debug_macro.dwo", ".zdebug_macro.dwo", NO_ABBREVS }, display_debug_macro, &do_debug_macinfo, TRUE },
- { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NO_ABBREVS }, display_debug_macinfo, &do_debug_macinfo, FALSE },
- { { ".debug_str.dwo", ".zdebug_str.dwo", NO_ABBREVS }, display_debug_str, &do_debug_str, TRUE },
- { { ".debug_str_offsets", ".zdebug_str_offsets", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, TRUE },
- { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, TRUE },
- { { ".debug_addr", ".zdebug_addr", NO_ABBREVS }, display_debug_addr, &do_debug_addr, TRUE },
- { { ".debug_cu_index", "", NO_ABBREVS }, display_cu_index, &do_debug_cu_index, FALSE },
- { { ".debug_tu_index", "", NO_ABBREVS }, display_cu_index, &do_debug_cu_index, FALSE },
- { { ".gnu_debuglink", "", NO_ABBREVS }, display_debug_links, &do_debug_links, FALSE },
- { { ".gnu_debugaltlink", "", NO_ABBREVS }, display_debug_links, &do_debug_links, FALSE },
+ { { ".debug_abbrev", ".zdebug_abbrev", ".dwabrev", NO_ABBREVS }, display_debug_abbrev, &do_debug_abbrevs, false },
+ { { ".debug_aranges", ".zdebug_aranges", ".dwarnge", NO_ABBREVS }, display_debug_aranges, &do_debug_aranges, true },
+ { { ".debug_frame", ".zdebug_frame", ".dwframe", NO_ABBREVS }, display_debug_frames, &do_debug_frames, true },
+ { { ".debug_info", ".zdebug_info", ".dwinfo", ABBREV (abbrev)}, display_debug_info, &do_debug_info, true },
+ { { ".debug_line", ".zdebug_line", ".dwline", NO_ABBREVS }, display_debug_lines, &do_debug_lines, true },
+ { { ".debug_pubnames", ".zdebug_pubnames", ".dwpbnms", NO_ABBREVS }, display_debug_pubnames, &do_debug_pubnames, false },
+ { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", "", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubnames, false },
+ { { ".eh_frame", "", "", NO_ABBREVS }, display_debug_frames, &do_debug_frames, true },
+ { { ".debug_macinfo", ".zdebug_macinfo", "", NO_ABBREVS }, display_debug_macinfo, &do_debug_macinfo, false },
+ { { ".debug_macro", ".zdebug_macro", ".dwmac", NO_ABBREVS }, display_debug_macro, &do_debug_macinfo, true },
+ { { ".debug_str", ".zdebug_str", ".dwstr", NO_ABBREVS }, display_debug_str, &do_debug_str, false },
+ { { ".debug_line_str", ".zdebug_line_str", "", NO_ABBREVS }, display_debug_str, &do_debug_str, false },
+ { { ".debug_loc", ".zdebug_loc", ".dwloc", NO_ABBREVS }, display_debug_loc, &do_debug_loc, true },
+ { { ".debug_loclists", ".zdebug_loclists", "", NO_ABBREVS }, display_debug_loc, &do_debug_loc, true },
+ { { ".debug_pubtypes", ".zdebug_pubtypes", ".dwpbtyp", NO_ABBREVS }, display_debug_pubnames, &do_debug_pubtypes, false },
+ { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", "", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubtypes, false },
+ { { ".debug_ranges", ".zdebug_ranges", ".dwrnges", NO_ABBREVS }, display_debug_ranges, &do_debug_ranges, true },
+ { { ".debug_rnglists", ".zdebug_rnglists", "", NO_ABBREVS }, display_debug_ranges, &do_debug_ranges, true },
+ { { ".debug_static_func", ".zdebug_static_func", "", NO_ABBREVS }, display_debug_not_supported, NULL, false },
+ { { ".debug_static_vars", ".zdebug_static_vars", "", NO_ABBREVS }, display_debug_not_supported, NULL, false },
+ { { ".debug_types", ".zdebug_types", "", ABBREV (abbrev) }, display_debug_types, &do_debug_info, true },
+ { { ".debug_weaknames", ".zdebug_weaknames", "", NO_ABBREVS }, display_debug_not_supported, NULL, false },
+ { { ".gdb_index", "", "", NO_ABBREVS }, display_gdb_index, &do_gdb_index, false },
+ { { ".debug_names", "", "", NO_ABBREVS }, display_debug_names, &do_gdb_index, false },
+ { { ".trace_info", "", "", ABBREV (trace_abbrev) }, display_trace_info, &do_trace_info, true },
+ { { ".trace_abbrev", "", "", NO_ABBREVS }, display_debug_abbrev, &do_trace_abbrevs, false },
+ { { ".trace_aranges", "", "", NO_ABBREVS }, display_debug_aranges, &do_trace_aranges, false },
+ { { ".debug_info.dwo", ".zdebug_info.dwo", "", ABBREV (abbrev_dwo) }, display_debug_info, &do_debug_info, true },
+ { { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo", "", NO_ABBREVS }, display_debug_abbrev, &do_debug_abbrevs, false },
+ { { ".debug_types.dwo", ".zdebug_types.dwo", "", ABBREV (abbrev_dwo) }, display_debug_types, &do_debug_info, true },
+ { { ".debug_line.dwo", ".zdebug_line.dwo", "", NO_ABBREVS }, display_debug_lines, &do_debug_lines, true },
+ { { ".debug_loc.dwo", ".zdebug_loc.dwo", "", NO_ABBREVS }, display_debug_loc, &do_debug_loc, true },
+ { { ".debug_macro.dwo", ".zdebug_macro.dwo", "", NO_ABBREVS }, display_debug_macro, &do_debug_macinfo, true },
+ { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", "", NO_ABBREVS }, display_debug_macinfo, &do_debug_macinfo, false },
+ { { ".debug_str.dwo", ".zdebug_str.dwo", "", NO_ABBREVS }, display_debug_str, &do_debug_str, true },
+ { { ".debug_str_offsets", ".zdebug_str_offsets", "", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, true },
+ { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", "", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, true },
+ { { ".debug_addr", ".zdebug_addr", "", NO_ABBREVS }, display_debug_addr, &do_debug_addr, true },
+ { { ".debug_cu_index", "", "", NO_ABBREVS }, display_cu_index, &do_debug_cu_index, false },
+ { { ".debug_tu_index", "", "", NO_ABBREVS }, display_cu_index, &do_debug_cu_index, false },
+ { { ".gnu_debuglink", "", "", NO_ABBREVS }, display_debug_links, &do_debug_links, false },
+ { { ".gnu_debugaltlink", "", "", NO_ABBREVS }, display_debug_links, &do_debug_links, false },
+ { { ".debug_sup", "", "", NO_ABBREVS }, display_debug_sup, &do_debug_links, false },
/* Separate debug info files can containt their own .debug_str section,
and this might be in *addition* to a .debug_str section already present
- in the main file. Hence we need to have two entries for .debug_str. */
- { { ".debug_str", ".zdebug_str", NO_ABBREVS }, display_debug_str, &do_debug_str, FALSE },
+ in the main file. Hence we need to have two entries for .debug_str. */
+ { { ".debug_str", ".zdebug_str", "", NO_ABBREVS }, display_debug_str, &do_debug_str, false },
};
/* A static assertion. */