|
|
f55871 |
diff -cp ../binutils-2.23.52.0.1.orig/bfd/bfd-in2.h bfd/bfd-in2.h
|
|
|
f55871 |
*** ../binutils-2.23.52.0.1.orig/bfd/bfd-in2.h 2013-06-04 15:26:45.127450022 +0100
|
|
|
f55871 |
--- bfd/bfd-in2.h 2013-06-04 15:47:45.160484950 +0100
|
|
|
f55871 |
*************** void *bfd_zalloc (bfd *abfd, bfd_size_ty
|
|
|
f55871 |
*** 1044,1051 ****
|
|
|
f55871 |
--- 1044,1055 ----
|
|
|
f55871 |
unsigned long bfd_calc_gnu_debuglink_crc32
|
|
|
f55871 |
(unsigned long crc, const unsigned char *buf, bfd_size_type len);
|
|
|
f55871 |
|
|
|
f55871 |
+ char *bfd_get_alt_debug_link_info (bfd *abfd, unsigned long *crc32_out);
|
|
|
f55871 |
+
|
|
|
f55871 |
char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
|
|
|
f55871 |
|
|
|
f55871 |
+ char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
|
|
|
f55871 |
+
|
|
|
f55871 |
struct bfd_section *bfd_create_gnu_debuglink_section
|
|
|
f55871 |
(bfd *abfd, const char *filename);
|
|
|
f55871 |
|
|
|
f55871 |
diff -cp ../binutils-2.23.52.0.1.orig/bfd/dwarf2.c bfd/dwarf2.c
|
|
|
f55871 |
*** ../binutils-2.23.52.0.1.orig/bfd/dwarf2.c 2013-06-04 15:26:44.556450006 +0100
|
|
|
f55871 |
--- bfd/dwarf2.c 2013-06-04 15:49:24.921487716 +0100
|
|
|
f55871 |
*************** struct dwarf2_debug
|
|
|
f55871 |
*** 108,113 ****
|
|
|
f55871 |
--- 108,123 ----
|
|
|
f55871 |
asection *sec;
|
|
|
f55871 |
bfd_byte *sec_info_ptr;
|
|
|
f55871 |
|
|
|
f55871 |
+ /* Support for alternate debug info sections created by the DWZ utility:
|
|
|
f55871 |
+ This includes a pointer to an alternate bfd which contains *extra*,
|
|
|
f55871 |
+ possibly duplicate debug sections, and pointers to the loaded
|
|
|
f55871 |
+ .debug_str and .debug_info sections from this bfd. */
|
|
|
f55871 |
+ bfd * alt_bfd_ptr;
|
|
|
f55871 |
+ bfd_byte * alt_dwarf_str_buffer;
|
|
|
f55871 |
+ bfd_size_type alt_dwarf_str_size;
|
|
|
f55871 |
+ bfd_byte * alt_dwarf_info_buffer;
|
|
|
f55871 |
+ bfd_size_type alt_dwarf_info_size;
|
|
|
f55871 |
+
|
|
|
f55871 |
/* A pointer to the memory block allocated for info_ptr. Neither
|
|
|
f55871 |
info_ptr nor sec_info_ptr are guaranteed to stay pointing to the
|
|
|
f55871 |
beginning of the malloc block. This is used only to free the
|
|
|
f55871 |
*************** const struct dwarf_debug_section dwarf_d
|
|
|
f55871 |
*** 290,295 ****
|
|
|
f55871 |
--- 300,306 ----
|
|
|
f55871 |
{ ".debug_aranges", ".zdebug_aranges" },
|
|
|
f55871 |
{ ".debug_frame", ".zdebug_frame" },
|
|
|
f55871 |
{ ".debug_info", ".zdebug_info" },
|
|
|
f55871 |
+ { ".debug_info", ".zdebug_info" },
|
|
|
f55871 |
{ ".debug_line", ".zdebug_line" },
|
|
|
f55871 |
{ ".debug_loc", ".zdebug_loc" },
|
|
|
f55871 |
{ ".debug_macinfo", ".zdebug_macinfo" },
|
|
|
f55871 |
*************** const struct dwarf_debug_section dwarf_d
|
|
|
f55871 |
*** 300,305 ****
|
|
|
f55871 |
--- 311,317 ----
|
|
|
f55871 |
{ ".debug_static_func", ".zdebug_static_func" },
|
|
|
f55871 |
{ ".debug_static_vars", ".zdebug_static_vars" },
|
|
|
f55871 |
{ ".debug_str", ".zdebug_str", },
|
|
|
f55871 |
+ { ".debug_str", ".zdebug_str", },
|
|
|
f55871 |
{ ".debug_types", ".zdebug_types" },
|
|
|
f55871 |
/* GNU DWARF 1 extensions */
|
|
|
f55871 |
{ ".debug_sfnames", ".zdebug_sfnames" },
|
|
|
f55871 |
*************** const struct dwarf_debug_section dwarf_d
|
|
|
f55871 |
*** 312,323 ****
|
|
|
f55871 |
--- 324,338 ----
|
|
|
f55871 |
{ NULL, NULL },
|
|
|
f55871 |
};
|
|
|
f55871 |
|
|
|
f55871 |
+ /* NB/ Numbers in this enum must match up with indicies
|
|
|
f55871 |
+ into the dwarf_debug_sections[] array above. */
|
|
|
f55871 |
enum dwarf_debug_section_enum
|
|
|
f55871 |
{
|
|
|
f55871 |
debug_abbrev = 0,
|
|
|
f55871 |
debug_aranges,
|
|
|
f55871 |
debug_frame,
|
|
|
f55871 |
debug_info,
|
|
|
f55871 |
+ debug_info_alt,
|
|
|
f55871 |
debug_line,
|
|
|
f55871 |
debug_loc,
|
|
|
f55871 |
debug_macinfo,
|
|
|
f55871 |
*************** enum dwarf_debug_section_enum
|
|
|
f55871 |
*** 328,333 ****
|
|
|
f55871 |
--- 343,349 ----
|
|
|
f55871 |
debug_static_func,
|
|
|
f55871 |
debug_static_vars,
|
|
|
f55871 |
debug_str,
|
|
|
f55871 |
+ debug_str_alt,
|
|
|
f55871 |
debug_types,
|
|
|
f55871 |
debug_sfnames,
|
|
|
f55871 |
debug_srcinfo,
|
|
|
f55871 |
*************** read_section (bfd * abfd,
|
|
|
f55871 |
*** 484,491 ****
|
|
|
f55871 |
asection *msec;
|
|
|
f55871 |
const char *section_name = sec->uncompressed_name;
|
|
|
f55871 |
|
|
|
f55871 |
! /* read_section is a noop if the section has already been read. */
|
|
|
f55871 |
! if (!*section_buffer)
|
|
|
f55871 |
{
|
|
|
f55871 |
msec = bfd_get_section_by_name (abfd, section_name);
|
|
|
f55871 |
if (! msec)
|
|
|
f55871 |
--- 500,507 ----
|
|
|
f55871 |
asection *msec;
|
|
|
f55871 |
const char *section_name = sec->uncompressed_name;
|
|
|
f55871 |
|
|
|
f55871 |
! /* The section may have already been read. */
|
|
|
f55871 |
! if (*section_buffer == NULL)
|
|
|
f55871 |
{
|
|
|
f55871 |
msec = bfd_get_section_by_name (abfd, section_name);
|
|
|
f55871 |
if (! msec)
|
|
|
f55871 |
*************** read_indirect_string (struct comp_unit *
|
|
|
f55871 |
*** 626,631 ****
|
|
|
f55871 |
--- 642,745 ----
|
|
|
f55871 |
return str;
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
+ /* Like read_indirect_string but uses a .debug_str located in
|
|
|
f55871 |
+ an alternate filepointed to by the .gnu_debuglink section.
|
|
|
f55871 |
+ Used to impement DW_FORM_GNU_strp_alt. */
|
|
|
f55871 |
+
|
|
|
f55871 |
+ static char *
|
|
|
f55871 |
+ read_alt_indirect_string (struct comp_unit * unit,
|
|
|
f55871 |
+ bfd_byte * buf,
|
|
|
f55871 |
+ unsigned int * bytes_read_ptr)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ bfd_uint64_t offset;
|
|
|
f55871 |
+ struct dwarf2_debug *stash = unit->stash;
|
|
|
f55871 |
+ char *str;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (unit->offset_size == 4)
|
|
|
f55871 |
+ offset = read_4_bytes (unit->abfd, buf);
|
|
|
f55871 |
+ else
|
|
|
f55871 |
+ offset = read_8_bytes (unit->abfd, buf);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ *bytes_read_ptr = unit->offset_size;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (stash->alt_bfd_ptr == NULL)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ bfd * debug_bfd;
|
|
|
f55871 |
+ char * debug_filename = bfd_follow_gnu_debugaltlink (unit->abfd, DEBUGDIR);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (debug_filename == NULL)
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
|
|
f55871 |
+ || ! bfd_check_format (debug_bfd, bfd_object))
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ if (debug_bfd)
|
|
|
f55871 |
+ bfd_close (debug_bfd);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ /* FIXME: Should we report our failure to follow the debuglink ? */
|
|
|
f55871 |
+ free (debug_filename);
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+ stash->alt_bfd_ptr = debug_bfd;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (! read_section (unit->stash->alt_bfd_ptr,
|
|
|
f55871 |
+ stash->debug_sections + debug_str_alt,
|
|
|
f55871 |
+ NULL, /* FIXME: Do we need to load alternate symbols ? */
|
|
|
f55871 |
+ offset,
|
|
|
f55871 |
+ &stash->alt_dwarf_str_buffer,
|
|
|
f55871 |
+ &stash->alt_dwarf_str_size))
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ str = (char *) stash->alt_dwarf_str_buffer + offset;
|
|
|
f55871 |
+ if (*str == '\0')
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ return str;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+
|
|
|
f55871 |
+ /* Resolve an alternate reference from UNIT at OFFSET.
|
|
|
f55871 |
+ Returns a pointer into the loaded alternate CU upon success
|
|
|
f55871 |
+ or NULL upon failure. */
|
|
|
f55871 |
+
|
|
|
f55871 |
+ static bfd_byte *
|
|
|
f55871 |
+ read_alt_indirect_ref (struct comp_unit * unit,
|
|
|
f55871 |
+ bfd_uint64_t offset)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ struct dwarf2_debug *stash = unit->stash;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (stash->alt_bfd_ptr == NULL)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ bfd * debug_bfd;
|
|
|
f55871 |
+ char * debug_filename = bfd_follow_gnu_debugaltlink (unit->abfd, DEBUGDIR);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (debug_filename == NULL)
|
|
|
f55871 |
+ return FALSE;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
|
|
f55871 |
+ || ! bfd_check_format (debug_bfd, bfd_object))
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ if (debug_bfd)
|
|
|
f55871 |
+ bfd_close (debug_bfd);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ /* FIXME: Should we report our failure to follow the debuglink ? */
|
|
|
f55871 |
+ free (debug_filename);
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+ stash->alt_bfd_ptr = debug_bfd;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (! read_section (unit->stash->alt_bfd_ptr,
|
|
|
f55871 |
+ stash->debug_sections + debug_info_alt,
|
|
|
f55871 |
+ NULL, /* FIXME: Do we need to load alternate symbols ? */
|
|
|
f55871 |
+ offset,
|
|
|
f55871 |
+ &stash->alt_dwarf_info_buffer,
|
|
|
f55871 |
+ &stash->alt_dwarf_info_size))
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ return stash->alt_dwarf_info_buffer + offset;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+
|
|
|
f55871 |
static bfd_uint64_t
|
|
|
f55871 |
read_address (struct comp_unit *unit, bfd_byte *buf)
|
|
|
f55871 |
{
|
|
|
f55871 |
*************** read_attribute_value (struct attribute *
|
|
|
f55871 |
*** 829,834 ****
|
|
|
f55871 |
--- 943,949 ----
|
|
|
f55871 |
attr->u.val = read_address (unit, info_ptr);
|
|
|
f55871 |
info_ptr += unit->addr_size;
|
|
|
f55871 |
break;
|
|
|
f55871 |
+ case DW_FORM_GNU_ref_alt:
|
|
|
f55871 |
case DW_FORM_sec_offset:
|
|
|
f55871 |
if (unit->offset_size == 4)
|
|
|
f55871 |
attr->u.val = read_4_bytes (unit->abfd, info_ptr);
|
|
|
f55871 |
*************** read_attribute_value (struct attribute *
|
|
|
f55871 |
*** 878,883 ****
|
|
|
f55871 |
--- 993,1002 ----
|
|
|
f55871 |
attr->u.str = read_indirect_string (unit, info_ptr, &bytes_read);
|
|
|
f55871 |
info_ptr += bytes_read;
|
|
|
f55871 |
break;
|
|
|
f55871 |
+ case DW_FORM_GNU_strp_alt:
|
|
|
f55871 |
+ attr->u.str = read_alt_indirect_string (unit, info_ptr, &bytes_read);
|
|
|
f55871 |
+ info_ptr += bytes_read;
|
|
|
f55871 |
+ break;
|
|
|
f55871 |
case DW_FORM_exprloc:
|
|
|
f55871 |
case DW_FORM_block:
|
|
|
f55871 |
amt = sizeof (struct dwarf_block);
|
|
|
f55871 |
*************** find_abstract_instance_name (struct comp
|
|
|
f55871 |
*** 2009,2014 ****
|
|
|
f55871 |
--- 2128,2144 ----
|
|
|
f55871 |
|
|
|
f55871 |
info_ptr = unit->sec_info_ptr + die_ref;
|
|
|
f55871 |
}
|
|
|
f55871 |
+ else if (attr_ptr->form == DW_FORM_GNU_ref_alt)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ info_ptr = read_alt_indirect_ref (unit, die_ref);
|
|
|
f55871 |
+ if (info_ptr == NULL)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ (*_bfd_error_handler)
|
|
|
f55871 |
+ (_("Dwarf Error: Unable to read alt ref %u."), die_ref);
|
|
|
f55871 |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
f55871 |
+ return name;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+ }
|
|
|
f55871 |
else
|
|
|
f55871 |
info_ptr = unit->info_ptr_unit + die_ref;
|
|
|
f55871 |
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
|
|
|
f55871 |
*************** _bfd_dwarf2_cleanup_debug_info (bfd *abf
|
|
|
f55871 |
*** 3692,3697 ****
|
|
|
f55871 |
--- 3822,3833 ----
|
|
|
f55871 |
free (stash->dwarf_ranges_buffer);
|
|
|
f55871 |
if (stash->info_ptr_memory)
|
|
|
f55871 |
free (stash->info_ptr_memory);
|
|
|
f55871 |
+ if (stash->alt_dwarf_str_buffer)
|
|
|
f55871 |
+ free (stash->alt_dwarf_str_buffer);
|
|
|
f55871 |
+ if (stash->alt_dwarf_info_buffer)
|
|
|
f55871 |
+ free (stash->alt_dwarf_info_buffer);
|
|
|
f55871 |
+ if (stash->alt_bfd_ptr)
|
|
|
f55871 |
+ bfd_close (stash->alt_bfd_ptr);
|
|
|
f55871 |
if (stash->close_on_cleanup)
|
|
|
f55871 |
bfd_close (stash->bfd_ptr);
|
|
|
f55871 |
}
|
|
|
f55871 |
diff -cp ../binutils-2.23.52.0.1.orig/bfd/opncls.c bfd/opncls.c
|
|
|
f55871 |
*** ../binutils-2.23.52.0.1.orig/bfd/opncls.c 2013-06-04 15:26:43.723449983 +0100
|
|
|
f55871 |
--- bfd/opncls.c 2013-06-04 15:47:45.183484951 +0100
|
|
|
f55871 |
*************** bfd_release (bfd *abfd, void *block)
|
|
|
f55871 |
*** 1049,1058 ****
|
|
|
f55871 |
|
|
|
f55871 |
This facilitates "optional" provision of debugging information, without
|
|
|
f55871 |
having to provide two complete copies of every binary object (with and
|
|
|
f55871 |
! without debug symbols).
|
|
|
f55871 |
! */
|
|
|
f55871 |
|
|
|
f55871 |
- #define GNU_DEBUGLINK ".gnu_debuglink"
|
|
|
f55871 |
/*
|
|
|
f55871 |
FUNCTION
|
|
|
f55871 |
bfd_calc_gnu_debuglink_crc32
|
|
|
f55871 |
--- 1049,1059 ----
|
|
|
f55871 |
|
|
|
f55871 |
This facilitates "optional" provision of debugging information, without
|
|
|
f55871 |
having to provide two complete copies of every binary object (with and
|
|
|
f55871 |
! without debug symbols). */
|
|
|
f55871 |
!
|
|
|
f55871 |
! #define GNU_DEBUGLINK ".gnu_debuglink"
|
|
|
f55871 |
! #define GNU_DEBUGALTLINK ".gnu_debugaltlink"
|
|
|
f55871 |
|
|
|
f55871 |
/*
|
|
|
f55871 |
FUNCTION
|
|
|
f55871 |
bfd_calc_gnu_debuglink_crc32
|
|
|
f55871 |
*************** get_debug_link_info (bfd *abfd, unsigned
|
|
|
f55871 |
*** 1188,1193 ****
|
|
|
f55871 |
--- 1189,1242 ----
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
/*
|
|
|
f55871 |
+ FUNCTION
|
|
|
f55871 |
+ bfd_get_alt_debug_link_info
|
|
|
f55871 |
+
|
|
|
f55871 |
+ SYNOPSIS
|
|
|
f55871 |
+ char *bfd_get_alt_debug_link_info (bfd *abfd, unsigned long *crc32_out);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ DESCRIPTION
|
|
|
f55871 |
+ Fetch the filename and BuildID value for any alternate debuginfo
|
|
|
f55871 |
+ associated with @var{abfd}. Return NULL if no such info found,
|
|
|
f55871 |
+ otherwise return filename and update @var{buildid_out}. The
|
|
|
f55871 |
+ returned filename is allocated with @code{malloc}; freeing it
|
|
|
f55871 |
+ is the responsibility of the caller.
|
|
|
f55871 |
+ */
|
|
|
f55871 |
+
|
|
|
f55871 |
+ char *
|
|
|
f55871 |
+ bfd_get_alt_debug_link_info (bfd * abfd, unsigned long * buildid_out)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ asection *sect;
|
|
|
f55871 |
+ bfd_byte *contents;
|
|
|
f55871 |
+ int buildid_offset;
|
|
|
f55871 |
+ char *name;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ BFD_ASSERT (abfd);
|
|
|
f55871 |
+ BFD_ASSERT (buildid_out);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGALTLINK);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (sect == NULL)
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ if (!bfd_malloc_and_get_section (abfd, sect, & contents))
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ if (contents != NULL)
|
|
|
f55871 |
+ free (contents);
|
|
|
f55871 |
+ return NULL;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+
|
|
|
f55871 |
+ /* BuildID value is stored after the filename, aligned up to 4 bytes. */
|
|
|
f55871 |
+ name = (char *) contents;
|
|
|
f55871 |
+ buildid_offset = strlen (name) + 1;
|
|
|
f55871 |
+ buildid_offset = (buildid_offset + 3) & ~3;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ * buildid_out = bfd_get_32 (abfd, contents + buildid_offset);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ return name;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
+
|
|
|
f55871 |
+ /*
|
|
|
f55871 |
INTERNAL_FUNCTION
|
|
|
f55871 |
separate_debug_file_exists
|
|
|
f55871 |
|
|
|
f55871 |
*************** separate_debug_file_exists (const char *
|
|
|
f55871 |
*** 1222,1227 ****
|
|
|
f55871 |
--- 1271,1307 ----
|
|
|
f55871 |
return crc == file_crc;
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
+ /*
|
|
|
f55871 |
+ INTERNAL_FUNCTION
|
|
|
f55871 |
+ separate_alt_debug_file_exists
|
|
|
f55871 |
+
|
|
|
f55871 |
+ SYNOPSIS
|
|
|
f55871 |
+ bfd_boolean separate_alt_debug_file_exists
|
|
|
f55871 |
+ (char *name, unsigned long crc32);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ DESCRIPTION
|
|
|
f55871 |
+ Checks to see if @var{name} is a file and if its BuildID
|
|
|
f55871 |
+ matches @var{buildid}.
|
|
|
f55871 |
+ */
|
|
|
f55871 |
+
|
|
|
f55871 |
+ static bfd_boolean
|
|
|
f55871 |
+ separate_alt_debug_file_exists (const char *name,
|
|
|
f55871 |
+ const unsigned long buildid ATTRIBUTE_UNUSED)
|
|
|
f55871 |
+ {
|
|
|
f55871 |
+ FILE *f;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ BFD_ASSERT (name);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ f = real_fopen (name, FOPEN_RB);
|
|
|
f55871 |
+ if (f == NULL)
|
|
|
f55871 |
+ return FALSE;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ /* FIXME: Add code to check buildid. */
|
|
|
f55871 |
+
|
|
|
f55871 |
+ fclose (f);
|
|
|
f55871 |
+
|
|
|
f55871 |
+ return TRUE;
|
|
|
f55871 |
+ }
|
|
|
f55871 |
|
|
|
f55871 |
/*
|
|
|
f55871 |
INTERNAL_FUNCTION
|
|
|
f55871 |
*************** SYNOPSIS
|
|
|
f55871 |
*** 1231,1246 ****
|
|
|
f55871 |
char *find_separate_debug_file (bfd *abfd);
|
|
|
f55871 |
|
|
|
f55871 |
DESCRIPTION
|
|
|
f55871 |
! Searches @var{abfd} for a reference to separate debugging
|
|
|
f55871 |
! information, scans various locations in the filesystem, including
|
|
|
f55871 |
! the file tree rooted at @var{debug_file_directory}, and returns a
|
|
|
f55871 |
! filename of such debugging information if the file is found and has
|
|
|
f55871 |
! matching CRC32. Returns NULL if no reference to debugging file
|
|
|
f55871 |
! exists, or file cannot be found.
|
|
|
f55871 |
*/
|
|
|
f55871 |
|
|
|
f55871 |
static char *
|
|
|
f55871 |
! find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
|
|
|
f55871 |
{
|
|
|
f55871 |
char *base;
|
|
|
f55871 |
char *dir;
|
|
|
f55871 |
--- 1311,1334 ----
|
|
|
f55871 |
char *find_separate_debug_file (bfd *abfd);
|
|
|
f55871 |
|
|
|
f55871 |
DESCRIPTION
|
|
|
f55871 |
! Searches @var{abfd} for a section called @var{section_name} which
|
|
|
f55871 |
! is expected to contain a reference to a file containing separate
|
|
|
f55871 |
! debugging information. The function scans various locations in
|
|
|
f55871 |
! the filesystem, including the file tree rooted at
|
|
|
f55871 |
! @var{debug_file_directory}, and returns the first matching
|
|
|
f55871 |
! filename that it finds. If @var{check_crc} is TRUE then the
|
|
|
f55871 |
! contents of the file must also match the CRC value contained in
|
|
|
f55871 |
! @var{section_name}. Returns NULL if no valid file could be found.
|
|
|
f55871 |
*/
|
|
|
f55871 |
|
|
|
f55871 |
+ typedef char * (* get_func_type) (bfd *, unsigned long *);
|
|
|
f55871 |
+ typedef bfd_boolean (* check_func_type) (const char *, const unsigned long);
|
|
|
f55871 |
+
|
|
|
f55871 |
static char *
|
|
|
f55871 |
! find_separate_debug_file (bfd * abfd,
|
|
|
f55871 |
! const char * debug_file_directory,
|
|
|
f55871 |
! get_func_type get_func,
|
|
|
f55871 |
! check_func_type check_func)
|
|
|
f55871 |
{
|
|
|
f55871 |
char *base;
|
|
|
f55871 |
char *dir;
|
|
|
f55871 |
*************** find_separate_debug_file (bfd *abfd, con
|
|
|
f55871 |
*** 1261,1267 ****
|
|
|
f55871 |
return NULL;
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
! base = get_debug_link_info (abfd, & crc32);
|
|
|
f55871 |
if (base == NULL)
|
|
|
f55871 |
return NULL;
|
|
|
f55871 |
|
|
|
f55871 |
--- 1349,1355 ----
|
|
|
f55871 |
return NULL;
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
! base = get_func (abfd, & crc32);
|
|
|
f55871 |
if (base == NULL)
|
|
|
f55871 |
return NULL;
|
|
|
f55871 |
|
|
|
f55871 |
*************** find_separate_debug_file (bfd *abfd, con
|
|
|
f55871 |
*** 1300,1336 ****
|
|
|
f55871 |
+ strlen (base)
|
|
|
f55871 |
+ 1);
|
|
|
f55871 |
if (debugfile == NULL)
|
|
|
f55871 |
! {
|
|
|
f55871 |
! free (base);
|
|
|
f55871 |
! free (dir);
|
|
|
f55871 |
! free (canon_dir);
|
|
|
f55871 |
! return NULL;
|
|
|
f55871 |
! }
|
|
|
f55871 |
|
|
|
f55871 |
/* First try in the same directory as the original file: */
|
|
|
f55871 |
strcpy (debugfile, dir);
|
|
|
f55871 |
strcat (debugfile, base);
|
|
|
f55871 |
|
|
|
f55871 |
! if (separate_debug_file_exists (debugfile, crc32))
|
|
|
f55871 |
! {
|
|
|
f55871 |
! free (base);
|
|
|
f55871 |
! free (dir);
|
|
|
f55871 |
! free (canon_dir);
|
|
|
f55871 |
! return debugfile;
|
|
|
f55871 |
! }
|
|
|
f55871 |
|
|
|
f55871 |
/* Then try in a subdirectory called .debug. */
|
|
|
f55871 |
strcpy (debugfile, dir);
|
|
|
f55871 |
strcat (debugfile, ".debug/");
|
|
|
f55871 |
strcat (debugfile, base);
|
|
|
f55871 |
|
|
|
f55871 |
! if (separate_debug_file_exists (debugfile, crc32))
|
|
|
f55871 |
! {
|
|
|
f55871 |
! free (base);
|
|
|
f55871 |
! free (dir);
|
|
|
f55871 |
! free (canon_dir);
|
|
|
f55871 |
! return debugfile;
|
|
|
f55871 |
! }
|
|
|
f55871 |
|
|
|
f55871 |
/* Then try in the global debugfile directory. */
|
|
|
f55871 |
strcpy (debugfile, debug_file_directory);
|
|
|
f55871 |
--- 1388,1409 ----
|
|
|
f55871 |
+ strlen (base)
|
|
|
f55871 |
+ 1);
|
|
|
f55871 |
if (debugfile == NULL)
|
|
|
f55871 |
! goto found; /* Actually this returns NULL. */
|
|
|
f55871 |
|
|
|
f55871 |
/* First try in the same directory as the original file: */
|
|
|
f55871 |
strcpy (debugfile, dir);
|
|
|
f55871 |
strcat (debugfile, base);
|
|
|
f55871 |
|
|
|
f55871 |
! if (check_func (debugfile, crc32))
|
|
|
f55871 |
! goto found;
|
|
|
f55871 |
|
|
|
f55871 |
/* Then try in a subdirectory called .debug. */
|
|
|
f55871 |
strcpy (debugfile, dir);
|
|
|
f55871 |
strcat (debugfile, ".debug/");
|
|
|
f55871 |
strcat (debugfile, base);
|
|
|
f55871 |
|
|
|
f55871 |
! if (check_func (debugfile, crc32))
|
|
|
f55871 |
! goto found;
|
|
|
f55871 |
|
|
|
f55871 |
/* Then try in the global debugfile directory. */
|
|
|
f55871 |
strcpy (debugfile, debug_file_directory);
|
|
|
f55871 |
*************** find_separate_debug_file (bfd *abfd, con
|
|
|
f55871 |
*** 1342,1360 ****
|
|
|
f55871 |
strcat (debugfile, canon_dir);
|
|
|
f55871 |
strcat (debugfile, base);
|
|
|
f55871 |
|
|
|
f55871 |
! if (separate_debug_file_exists (debugfile, crc32))
|
|
|
f55871 |
! {
|
|
|
f55871 |
! free (base);
|
|
|
f55871 |
! free (dir);
|
|
|
f55871 |
! free (canon_dir);
|
|
|
f55871 |
! return debugfile;
|
|
|
f55871 |
! }
|
|
|
f55871 |
|
|
|
f55871 |
free (debugfile);
|
|
|
f55871 |
free (base);
|
|
|
f55871 |
free (dir);
|
|
|
f55871 |
free (canon_dir);
|
|
|
f55871 |
! return NULL;
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
|
|
|
f55871 |
--- 1415,1432 ----
|
|
|
f55871 |
strcat (debugfile, canon_dir);
|
|
|
f55871 |
strcat (debugfile, base);
|
|
|
f55871 |
|
|
|
f55871 |
! if (check_func (debugfile, crc32))
|
|
|
f55871 |
! goto found;
|
|
|
f55871 |
|
|
|
f55871 |
+ /* Failed to find the file. */
|
|
|
f55871 |
free (debugfile);
|
|
|
f55871 |
+ debugfile = NULL;
|
|
|
f55871 |
+
|
|
|
f55871 |
+ found:
|
|
|
f55871 |
free (base);
|
|
|
f55871 |
free (dir);
|
|
|
f55871 |
free (canon_dir);
|
|
|
f55871 |
! return debugfile;
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
|
|
|
f55871 |
*************** RETURNS
|
|
|
f55871 |
*** 1387,1393 ****
|
|
|
f55871 |
char *
|
|
|
f55871 |
bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
|
|
|
f55871 |
{
|
|
|
f55871 |
! return find_separate_debug_file (abfd, dir);
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
/*
|
|
|
f55871 |
--- 1459,1501 ----
|
|
|
f55871 |
char *
|
|
|
f55871 |
bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
|
|
|
f55871 |
{
|
|
|
f55871 |
! return find_separate_debug_file (abfd, dir,
|
|
|
f55871 |
! get_debug_link_info,
|
|
|
f55871 |
! separate_debug_file_exists);
|
|
|
f55871 |
! }
|
|
|
f55871 |
!
|
|
|
f55871 |
! /*
|
|
|
f55871 |
! FUNCTION
|
|
|
f55871 |
! bfd_follow_gnu_debugaltlink
|
|
|
f55871 |
!
|
|
|
f55871 |
! SYNOPSIS
|
|
|
f55871 |
! char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
|
|
|
f55871 |
!
|
|
|
f55871 |
! DESCRIPTION
|
|
|
f55871 |
!
|
|
|
f55871 |
! Takes a BFD and searches it for a .gnu_debugaltlink section. If this
|
|
|
f55871 |
! section is found, it examines the section for the name of a file
|
|
|
f55871 |
! containing auxiliary debugging information. It then searches the
|
|
|
f55871 |
! filesystem for this file in a set of standard locations, including
|
|
|
f55871 |
! the directory tree rooted at @var{dir}, and if found returns the
|
|
|
f55871 |
! full filename.
|
|
|
f55871 |
!
|
|
|
f55871 |
! If @var{dir} is NULL, it will search a default path configured into
|
|
|
f55871 |
! libbfd at build time. [FIXME: This feature is not currently
|
|
|
f55871 |
! implemented].
|
|
|
f55871 |
!
|
|
|
f55871 |
! RETURNS
|
|
|
f55871 |
! <<NULL>> on any errors or failure to locate the debug file,
|
|
|
f55871 |
! otherwise a pointer to a heap-allocated string containing the
|
|
|
f55871 |
! filename. The caller is responsible for freeing this string.
|
|
|
f55871 |
! */
|
|
|
f55871 |
!
|
|
|
f55871 |
! char *
|
|
|
f55871 |
! bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir)
|
|
|
f55871 |
! {
|
|
|
f55871 |
! return find_separate_debug_file (abfd, dir,
|
|
|
f55871 |
! bfd_get_alt_debug_link_info,
|
|
|
f55871 |
! separate_alt_debug_file_exists);
|
|
|
f55871 |
}
|
|
|
f55871 |
|
|
|
f55871 |
/*
|