Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: bfd/opncls.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bfd/mmo.c ('k') | bfd/pdp11.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bfd/opncls.c
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 7c1d2f99a5815990d97da36958079a91e8538946..3f09420bf735db821a88bc6395702b6f26c7e06d 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -1,7 +1,5 @@
/* opncls.c -- open and close a BFD.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -82,31 +80,18 @@ _bfd_new_bfd (void)
nbfd->arch_info = &bfd_default_arch_struct;
- nbfd->direction = no_direction;
- nbfd->iostream = NULL;
- nbfd->where = 0;
if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc,
- sizeof (struct section_hash_entry), 251))
+ sizeof (struct section_hash_entry), 13))
{
free (nbfd);
return NULL;
}
- nbfd->sections = NULL;
- nbfd->section_last = NULL;
- nbfd->format = bfd_unknown;
- nbfd->my_archive = NULL;
- nbfd->origin = 0;
- nbfd->opened_once = FALSE;
- nbfd->output_has_begun = FALSE;
- nbfd->section_count = 0;
- nbfd->usrdata = NULL;
- nbfd->cacheable = FALSE;
- nbfd->flags = BFD_NO_FLAGS;
- nbfd->mtime_set = FALSE;
return nbfd;
}
+static const struct bfd_iovec opncls_iovec;
+
/* Allocate a new BFD as a member of archive OBFD. */
bfd *
@@ -119,6 +104,8 @@ _bfd_new_bfd_contained_in (bfd *obfd)
return NULL;
nbfd->xvec = obfd->xvec;
nbfd->iovec = obfd->iovec;
+ if (obfd->iovec == &opncls_iovec)
+ nbfd->iostream = obfd->iostream;
nbfd->my_archive = obfd;
nbfd->direction = read_direction;
nbfd->target_defaulted = obfd->target_defaulted;
@@ -127,7 +114,7 @@ _bfd_new_bfd_contained_in (bfd *obfd)
/* Delete a BFD. */
-void
+static void
_bfd_delete_bfd (bfd *abfd)
{
if (abfd->memory)
@@ -135,6 +122,8 @@ _bfd_delete_bfd (bfd *abfd)
bfd_hash_table_free (&abfd->section_htab);
objalloc_free ((struct objalloc *) abfd->memory);
}
+
+ free (abfd->arelt_data);
free (abfd);
}
@@ -180,7 +169,7 @@ DESCRIPTION
Return a pointer to the created BFD. If @var{fd} is not -1,
then <<fdopen>> is used to open the file; otherwise, <<fopen>>
is used. @var{mode} is passed directly to <<fopen>> or
- <<fdopen>>.
+ <<fdopen>>.
Calls <<bfd_find_target>>, so @var{target} is interpreted as by
that function.
@@ -216,7 +205,7 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
_bfd_delete_bfd (nbfd);
return NULL;
}
-
+
#ifdef HAVE_FDOPEN
if (fd != -1)
nbfd->iostream = fdopen (fd, mode);
@@ -235,7 +224,7 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
/* Figure out whether the user is opening the file for reading,
writing, or both, by looking at the MODE argument. */
- if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a')
+ if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a')
&& mode[1] == '+')
nbfd->direction = both_direction;
else if (mode[0] == 'r')
@@ -249,12 +238,13 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
return NULL;
}
nbfd->opened_once = TRUE;
+
/* If we opened the file by name, mark it cacheable; we can close it
and reopen it later. However, if a file descriptor was provided,
then it may have been opened with special flags that make it
unsafe to close and reopen the file. */
if (fd == -1)
- bfd_set_cacheable (nbfd, TRUE);
+ (void) bfd_set_cacheable (nbfd, TRUE);
return nbfd;
}
@@ -707,8 +697,6 @@ bfd_boolean
bfd_close (bfd *abfd)
{
bfd_boolean ret;
- bfd *nbfd;
- bfd *next;
if (bfd_write_p (abfd))
{
@@ -716,17 +704,10 @@ bfd_close (bfd *abfd)
return FALSE;
}
- /* Close nested archives (if this bfd is a thin archive). */
- for (nbfd = abfd->nested_archives; nbfd; nbfd = next)
- {
- next = nbfd->archive_next;
- bfd_close (nbfd);
- }
-
if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
return FALSE;
- ret = abfd->iovec->bclose (abfd);
+ ret = abfd->iovec->bclose (abfd) == 0;
if (ret)
_maybe_make_executable (abfd);
@@ -1052,10 +1033,11 @@ bfd_release (bfd *abfd, void *block)
This facilitates "optional" provision of debugging information, without
having to provide two complete copies of every binary object (with and
- without debug symbols).
-*/
+ without debug symbols). */
+
+#define GNU_DEBUGLINK ".gnu_debuglink"
+#define GNU_DEBUGALTLINK ".gnu_debugaltlink"
-#define GNU_DEBUGLINK ".gnu_debuglink"
/*
FUNCTION
bfd_calc_gnu_debuglink_crc32
@@ -1138,25 +1120,27 @@ bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
crc = ~crc & 0xffffffff;
for (end = buf + len; buf < end; ++ buf)
crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
- return ~crc & 0xffffffff;;
+ return ~crc & 0xffffffff;
}
/*
-INTERNAL_FUNCTION
- get_debug_link_info
+FUNCTION
+ bfd_get_debug_link_info
SYNOPSIS
- char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+ char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
DESCRIPTION
fetch the filename and CRC32 value for any separate debuginfo
associated with @var{abfd}. Return NULL if no such info found,
- otherwise return filename and update @var{crc32_out}.
+ otherwise return filename and update @var{crc32_out}. The
+ returned filename is allocated with @code{malloc}; freeing it
+ is the responsibility of the caller.
*/
-static char *
-get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
+char *
+bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
{
asection *sect;
unsigned long crc32;
@@ -1191,6 +1175,60 @@ get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
}
/*
+FUNCTION
+ bfd_get_alt_debug_link_info
+
+SYNOPSIS
+ char *bfd_get_alt_debug_link_info (bfd * abfd,
+ bfd_size_type *buildid_len,
+ bfd_byte **buildid_out);
+
+DESCRIPTION
+ Fetch the filename and BuildID value for any alternate debuginfo
+ associated with @var{abfd}. Return NULL if no such info found,
+ otherwise return filename and update @var{buildid_len} and
+ @var{buildid_out}. The returned filename and build_id are
+ allocated with @code{malloc}; freeing them is the
+ responsibility of the caller.
+*/
+
+char *
+bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
+ bfd_byte **buildid_out)
+{
+ asection *sect;
+ bfd_byte *contents;
+ int buildid_offset;
+ char *name;
+
+ BFD_ASSERT (abfd);
+ BFD_ASSERT (buildid_len);
+ BFD_ASSERT (buildid_out);
+
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGALTLINK);
+
+ if (sect == NULL)
+ return NULL;
+
+ if (!bfd_malloc_and_get_section (abfd, sect, & contents))
+ {
+ if (contents != NULL)
+ free (contents);
+ return NULL;
+ }
+
+ /* BuildID value is stored after the filename. */
+ name = (char *) contents;
+ buildid_offset = strlen (name) + 1;
+
+ *buildid_len = bfd_get_section_size (sect) - buildid_offset;
+ *buildid_out = bfd_malloc (*buildid_len);
+ memcpy (*buildid_out, contents + buildid_offset, *buildid_len);
+
+ return name;
+}
+
+/*
INTERNAL_FUNCTION
separate_debug_file_exists
@@ -1225,6 +1263,37 @@ separate_debug_file_exists (const char *name, const unsigned long crc)
return crc == file_crc;
}
+/*
+INTERNAL_FUNCTION
+ separate_alt_debug_file_exists
+
+SYNOPSIS
+ bfd_boolean separate_alt_debug_file_exists
+ (char *name, unsigned long crc32);
+
+DESCRIPTION
+ Checks to see if @var{name} is a file and if its BuildID
+ matches @var{buildid}.
+*/
+
+static bfd_boolean
+separate_alt_debug_file_exists (const char *name,
+ const unsigned long buildid ATTRIBUTE_UNUSED)
+{
+ FILE *f;
+
+ BFD_ASSERT (name);
+
+ f = real_fopen (name, FOPEN_RB);
+ if (f == NULL)
+ return FALSE;
+
+ /* FIXME: Add code to check buildid. */
+
+ fclose (f);
+
+ return TRUE;
+}
/*
INTERNAL_FUNCTION
@@ -1234,16 +1303,24 @@ SYNOPSIS
char *find_separate_debug_file (bfd *abfd);
DESCRIPTION
- Searches @var{abfd} for a reference to separate debugging
- information, scans various locations in the filesystem, including
- the file tree rooted at @var{debug_file_directory}, and returns a
- filename of such debugging information if the file is found and has
- matching CRC32. Returns NULL if no reference to debugging file
- exists, or file cannot be found.
+ Searches @var{abfd} for a section called @var{section_name} which
+ is expected to contain a reference to a file containing separate
+ debugging information. The function scans various locations in
+ the filesystem, including the file tree rooted at
+ @var{debug_file_directory}, and returns the first matching
+ filename that it finds. If @var{check_crc} is TRUE then the
+ contents of the file must also match the CRC value contained in
+ @var{section_name}. Returns NULL if no valid file could be found.
*/
+typedef char * (* get_func_type) (bfd *, unsigned long *);
+typedef bfd_boolean (* check_func_type) (const char *, const unsigned long);
+
static char *
-find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
+find_separate_debug_file (bfd * abfd,
+ const char * debug_file_directory,
+ get_func_type get_func,
+ check_func_type check_func)
{
char *base;
char *dir;
@@ -1264,7 +1341,8 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
return NULL;
}
- base = get_debug_link_info (abfd, & crc32);
+ base = get_func (abfd, & crc32);
+
if (base == NULL)
return NULL;
@@ -1303,37 +1381,22 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
+ strlen (base)
+ 1);
if (debugfile == NULL)
- {
- free (base);
- free (dir);
- free (canon_dir);
- return NULL;
- }
+ goto found; /* Actually this returns NULL. */
/* First try in the same directory as the original file: */
strcpy (debugfile, dir);
strcat (debugfile, base);
- if (separate_debug_file_exists (debugfile, crc32))
- {
- free (base);
- free (dir);
- free (canon_dir);
- return debugfile;
- }
+ if (check_func (debugfile, crc32))
+ goto found;
/* Then try in a subdirectory called .debug. */
strcpy (debugfile, dir);
strcat (debugfile, ".debug/");
strcat (debugfile, base);
- if (separate_debug_file_exists (debugfile, crc32))
- {
- free (base);
- free (dir);
- free (canon_dir);
- return debugfile;
- }
+ if (check_func (debugfile, crc32))
+ goto found;
/* Then try in the global debugfile directory. */
strcpy (debugfile, debug_file_directory);
@@ -1345,19 +1408,18 @@ find_separate_debug_file (bfd *abfd, const char *debug_file_directory)
strcat (debugfile, canon_dir);
strcat (debugfile, base);
- if (separate_debug_file_exists (debugfile, crc32))
- {
- free (base);
- free (dir);
- free (canon_dir);
- return debugfile;
- }
+ if (check_func (debugfile, crc32))
+ goto found;
+ /* Failed to find the file. */
free (debugfile);
+ debugfile = NULL;
+
+ found:
free (base);
free (dir);
free (canon_dir);
- return NULL;
+ return debugfile;
}
@@ -1390,7 +1452,61 @@ RETURNS
char *
bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
{
- return find_separate_debug_file (abfd, dir);
+ return find_separate_debug_file (abfd, dir,
+ bfd_get_debug_link_info,
+ separate_debug_file_exists);
+}
+
+/* Helper for bfd_follow_gnu_debugaltlink. It just pretends to return
+ a CRC. .gnu_debugaltlink supplies a build-id, which is different,
+ but this is ok because separate_alt_debug_file_exists ignores the
+ CRC anyway. */
+
+static char *
+get_alt_debug_link_info_shim (bfd * abfd, unsigned long *crc32_out)
+{
+ bfd_size_type len;
+ bfd_byte *buildid = NULL;
+ char *result = bfd_get_alt_debug_link_info (abfd, &len, &buildid);
+
+ *crc32_out = 0;
+ free (buildid);
+
+ return result;
+}
+
+/*
+FUNCTION
+ bfd_follow_gnu_debugaltlink
+
+SYNOPSIS
+ char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
+
+DESCRIPTION
+
+ Takes a BFD and searches it for a .gnu_debugaltlink section. If this
+ section is found, it examines the section for the name of a file
+ containing auxiliary debugging information. It then searches the
+ filesystem for this file in a set of standard locations, including
+ the directory tree rooted at @var{dir}, and if found returns the
+ full filename.
+
+ If @var{dir} is NULL, it will search a default path configured into
+ libbfd at build time. [FIXME: This feature is not currently
+ implemented].
+
+RETURNS
+ <<NULL>> on any errors or failure to locate the debug file,
+ otherwise a pointer to a heap-allocated string containing the
+ filename. The caller is responsible for freeing this string.
+*/
+
+char *
+bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir)
+{
+ return find_separate_debug_file (abfd, dir,
+ get_alt_debug_link_info_shim,
+ separate_alt_debug_file_exists);
}
/*
« no previous file with comments | « bfd/mmo.c ('k') | bfd/pdp11.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698