aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-04-07 14:51:42 +0100
committerNick Clifton <nickc@redhat.com>2017-04-07 14:51:42 +0100
commit49f4617bf4b86a0b057f3477d57ffbf7c998b229 (patch)
treefe8740141ff5a97c6ce3a8c328867bd851957b36 /bfd/opncls.c
parentFix failure in x86_64 linker tests when compiling with a PIE enabled compiler. (diff)
downloadbinutils-gdb-49f4617bf4b86a0b057f3477d57ffbf7c998b229.tar.gz
binutils-gdb-49f4617bf4b86a0b057f3477d57ffbf7c998b229.tar.bz2
binutils-gdb-49f4617bf4b86a0b057f3477d57ffbf7c998b229.zip
Fix building the BFD library for Win64 by reqorking the find_separate_debug_file interface.
* opncls.c (bfd_get_debug_link_info): Rename to... (bfd_get_debug_link_info_1): ... this. Change type of second parameter to void pointer. Adjust. (bfd_get_debug_link_info): Reimplement on top of bfd_get_debug_link_info_1. (separate_debug_file_exists, separate_alt_debug_file_exists): Change type of second parameter to void pointer. Adjust. (get_func_type, check_func_type): Change type of second parameter to void pointer. (find_separate_debug_file): Add 'func_data' parameter. Pass it to the callback functions instead of passing the address of a local. (bfd_follow_gnu_debuglink): Pass address of unsigned long local to find_separate_debug_file. (get_alt_debug_link_info_shim): Change type of second parameter to void pointer. Adjust. (bfd_follow_gnu_debugaltlink): Adjust to pass NULL to find_separate_debug_file. (get_build_id_name, bfd_boolean check_build_id_file): Change type of second parameter to void pointer. Adjust. (bfd_follow_build_id_debuglink): Pass address of bfd_build_id pointer local to find_separate_debug_file.
Diffstat (limited to 'bfd/opncls.c')
-rw-r--r--bfd/opncls.c231
1 files changed, 138 insertions, 93 deletions
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 4137a3bdcdb..994b950ba32 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -366,10 +366,10 @@ FUNCTION
bfd_openstreamr
SYNOPSIS
- bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
+ bfd *bfd_openstreamr (const char * filename, const char * target,
+ void * stream);
DESCRIPTION
-
Open a BFD for read access on an existing stdio stream. When
the BFD is passed to <<bfd_close>>, the stream will be closed.
@@ -431,7 +431,6 @@ SYNOPSIS
struct stat *sb));
DESCRIPTION
-
Create and return a BFD backed by a read-only @var{stream}.
The @var{stream} is created using @var{open_func}, accessed using
@var{pread_func} and destroyed using @var{close_func}.
@@ -502,6 +501,7 @@ opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
{
struct opncls *vec = (struct opncls *) abfd->iostream;
file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where);
+
if (nread < 0)
return nread;
vec->where += nread;
@@ -523,6 +523,7 @@ opncls_bclose (struct bfd *abfd)
/* Since the VEC's memory is bound to the bfd deleting the bfd will
free it. */
int status = 0;
+
if (vec->close != NULL)
status = (vec->close) (abfd, vec->stream);
abfd->iostream = NULL;
@@ -560,7 +561,8 @@ opncls_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
return (void *) -1;
}
-static const struct bfd_iovec opncls_iovec = {
+static const struct bfd_iovec opncls_iovec =
+{
&opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
&opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap
};
@@ -700,7 +702,6 @@ _maybe_make_executable (bfd * abfd)
}
/*
-
FUNCTION
bfd_close
@@ -708,7 +709,6 @@ SYNOPSIS
bfd_boolean bfd_close (bfd *abfd);
DESCRIPTION
-
Close a BFD. If the BFD was open for writing, then pending
operations are completed and the file written out and closed.
If the created file is executable, then <<chmod>> is called
@@ -723,7 +723,6 @@ RETURNS
<<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
*/
-
bfd_boolean
bfd_close (bfd *abfd)
{
@@ -1157,25 +1156,35 @@ bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
/*
-FUNCTION
- bfd_get_debug_link_info
+INTERNAL_FUNCTION
+ bfd_get_debug_link_info_1
SYNOPSIS
- char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+ char *bfd_get_debug_link_info_1 (bfd *abfd, void *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}. The
- returned filename is allocated with @code{malloc}; freeing it
- is the responsibility of the caller.
+ Extracts the filename and CRC32 value for any separate debug
+ information file associated with @var{abfd}.
+
+ The @var{crc32_out} parameter is an untyped pointer because
+ this routine is used as a @code{get_func_type} function, but it
+ is expected to be an unsigned long pointer.
+
+RETURNS
+ The filename of the associated debug information file, or NULL
+ if there is no such file. If the filename was found then the
+ contents of @var{crc32_out} are updated to hold the corresponding
+ CRC32 value for the file.
+
+ The returned filename is allocated with @code{malloc}; freeing
+ it is the responsibility of the caller.
*/
-char *
-bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
+static char *
+bfd_get_debug_link_info_1 (bfd *abfd, void *crc32_out)
{
asection *sect;
- unsigned long crc32;
+ unsigned long *crc32 = (unsigned long *) crc32_out;
bfd_byte *contents;
unsigned int crc_offset;
char *name;
@@ -1203,12 +1212,38 @@ bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
if (crc_offset >= bfd_get_section_size (sect))
return NULL;
- crc32 = bfd_get_32 (abfd, contents + crc_offset);
-
- *crc32_out = crc32;
+ *crc32 = bfd_get_32 (abfd, contents + crc_offset);
return name;
}
+
+/*
+FUNCTION
+ bfd_get_debug_link_info
+
+SYNOPSIS
+ char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+
+DESCRIPTION
+ Extracts the filename and CRC32 value for any separate debug
+ information file associated with @var{abfd}.
+
+RETURNS
+ The filename of the associated debug information file, or NULL
+ if there is no such file. If the filename was found then the
+ contents of @var{crc32_out} are updated to hold the corresponding
+ CRC32 value for the file.
+
+ The returned filename is allocated with @code{malloc}; freeing
+ it is the responsibility of the caller.
+*/
+
+char *
+bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
+{
+ return bfd_get_debug_link_info_1 (abfd, crc32_out);
+}
+
/*
FUNCTION
bfd_get_alt_debug_link_info
@@ -1223,8 +1258,8 @@ DESCRIPTION
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.
+ allocated with @code{malloc}; freeing them is the responsibility
+ of the caller.
*/
char *
@@ -1271,22 +1306,30 @@ INTERNAL_FUNCTION
SYNOPSIS
bfd_boolean separate_debug_file_exists
- (char *name, unsigned long crc32);
+ (char *name, void *crc32_p);
DESCRIPTION
Checks to see if @var{name} is a file and if its contents
- match @var{crc32}.
+ match @var{crc32}, which is a pointer to an @code{unsigned
+ long} containing a CRC32.
+
+ The @var{crc32_p} parameter is an untyped pointer because
+ this routine is used as a @code{check_func_type} function.
*/
static bfd_boolean
-separate_debug_file_exists (const char *name, const unsigned long crc)
+separate_debug_file_exists (const char *name, void *crc32_p)
{
static unsigned char buffer [8 * 1024];
unsigned long file_crc = 0;
FILE *f;
bfd_size_type count;
+ unsigned long crc;
BFD_ASSERT (name);
+ BFD_ASSERT (crc32_p);
+
+ crc = *(unsigned long *) crc32_p;
f = _bfd_real_fopen (name, FOPEN_RB);
if (f == NULL)
@@ -1306,16 +1349,14 @@ INTERNAL_FUNCTION
SYNOPSIS
bfd_boolean separate_alt_debug_file_exists
- (char *name, unsigned long buildid);
+ (char *name, void *unused);
DESCRIPTION
- Checks to see if @var{name} is a file and if its BuildID
- matches @var{buildid}.
+ Checks to see if @var{name} is a file.
*/
static bfd_boolean
-separate_alt_debug_file_exists (const char *name,
- const unsigned long buildid ATTRIBUTE_UNUSED)
+separate_alt_debug_file_exists (const char *name, void *unused ATTRIBUTE_UNUSED)
{
FILE *f;
@@ -1325,8 +1366,6 @@ separate_alt_debug_file_exists (const char *name,
if (f == NULL)
return FALSE;
- /* FIXME: Add code to check buildid. */
-
fclose (f);
return TRUE;
@@ -1339,36 +1378,43 @@ INTERNAL_FUNCTION
SYNOPSIS
char *find_separate_debug_file
(bfd *abfd, const char *dir, bfd_boolean include_dirs,
- get_func_type get, check_func_type check);
+ get_func_type get, check_func_type check, void *data);
DESCRIPTION
Searches for a debug information file corresponding to @var{abfd}.
- The name of the separate debug info file is returned by the @var{get}
- function. This function scans various fixed locations in the
- filesystem, including the file tree rooted at @var{dir}. If the
- @var{include_dirs} parameter is true then the directory components of
- @var{abfd}'s filename will be included in the searched locations.
-
- Returns the filename of the first file to be found which receives a
- TRUE result from the @var{check} function. Returns NULL if no valid
- file could be found.
+
+ The name of the separate debug info file is returned by the
+ @var{get} function. This function scans various fixed locations
+ in the filesystem, including the file tree rooted at @var{dir}.
+ If the @var{include_dirs} parameter is true then the directory
+ components of @var{abfd}'s filename will be included in the
+ searched locations.
+
+ @var{data} is passed unmodified to the @var{get} and @var{check}
+ functions. It is generally used to implement build-id-like
+ matching in the callback functions.
+
+RETURNS
+ Returns the filename of the first file to be found which
+ receives a TRUE result from the @var{check} function.
+ 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);
+typedef char * (* get_func_type) (bfd *, void *);
+typedef bfd_boolean (* check_func_type) (const char *, void *);
static char *
find_separate_debug_file (bfd * abfd,
const char * debug_file_directory,
bfd_boolean include_dirs,
get_func_type get_func,
- check_func_type check_func)
+ check_func_type check_func,
+ void * func_data)
{
char *base;
char *dir;
char *debugfile;
char *canon_dir;
- unsigned long crc32;
size_t dirlen;
size_t canon_dirlen;
@@ -1383,7 +1429,7 @@ find_separate_debug_file (bfd * abfd,
return NULL;
}
- base = get_func (abfd, & crc32);
+ base = get_func (abfd, func_data);
if (base == NULL)
return NULL;
@@ -1430,7 +1476,7 @@ find_separate_debug_file (bfd * abfd,
#endif
#ifndef EXTRA_DEBUG_ROOT2
#define EXTRA_DEBUG_ROOT2 "/usr/lib/debug/usr"
-#endif
+#endif
debugfile = (char *)
bfd_malloc (strlen (debug_file_directory) + 1
@@ -1457,19 +1503,19 @@ find_separate_debug_file (bfd * abfd,
a file into the root filesystem. (See binutils/testsuite/
binutils-all/objdump.exp for the test). */
sprintf (debugfile, "%s%s", dir, base);
- if (check_func (debugfile, crc32))
+ if (check_func (debugfile, func_data))
goto found;
/* Then try in a subdirectory called .debug. */
sprintf (debugfile, "%s.debug/%s", dir, base);
- if (check_func (debugfile, crc32))
+ if (check_func (debugfile, func_data))
goto found;
#ifdef EXTRA_DEBUG_ROOT1
/* Try the first extra debug file root. */
sprintf (debugfile, "%s%s%s", EXTRA_DEBUG_ROOT1,
include_dirs ? canon_dir : "/", base);
- if (check_func (debugfile, crc32))
+ if (check_func (debugfile, func_data))
goto found;
#endif
@@ -1477,10 +1523,10 @@ find_separate_debug_file (bfd * abfd,
/* Try the second extra debug file root. */
sprintf (debugfile, "%s%s%s", EXTRA_DEBUG_ROOT2,
include_dirs ? canon_dir : "/", base);
- if (check_func (debugfile, crc32))
+ if (check_func (debugfile, func_data))
goto found;
#endif
-
+
/* Then try in the global debugfile directory. */
strcpy (debugfile, debug_file_directory);
dirlen = strlen (debug_file_directory) - 1;
@@ -1499,7 +1545,7 @@ find_separate_debug_file (bfd * abfd,
}
strcat (debugfile, base);
- if (check_func (debugfile, crc32))
+ if (check_func (debugfile, func_data))
goto found;
/* Failed to find the file. */
@@ -1513,7 +1559,6 @@ find_separate_debug_file (bfd * abfd,
return debugfile;
}
-
/*
FUNCTION
bfd_follow_gnu_debuglink
@@ -1522,7 +1567,6 @@ SYNOPSIS
char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
DESCRIPTION
-
Takes a BFD and searches it for a .gnu_debuglink section. If this
section is found, it examines the section for the name and checksum
of a '.debug' file containing auxiliary debugging information. It
@@ -1542,24 +1586,23 @@ RETURNS
char *
bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
{
+ unsigned long crc32;
+
return find_separate_debug_file (abfd, dir, TRUE,
- bfd_get_debug_link_info,
- separate_debug_file_exists);
+ bfd_get_debug_link_info_1,
+ separate_debug_file_exists, &crc32);
}
-/* 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. */
+/* Helper for bfd_follow_gnu_debugaltlink. It just returns the name
+ of the separate debug file. */
static char *
-get_alt_debug_link_info_shim (bfd * abfd, unsigned long *crc32_out)
+get_alt_debug_link_info_shim (bfd * abfd, void *unused ATTRIBUTE_UNUSED)
{
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;
@@ -1573,7 +1616,6 @@ 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
@@ -1595,7 +1637,8 @@ bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir)
{
return find_separate_debug_file (abfd, dir, TRUE,
get_alt_debug_link_info_shim,
- separate_alt_debug_file_exists);
+ separate_alt_debug_file_exists,
+ NULL);
}
/*
@@ -1607,13 +1650,13 @@ SYNOPSIS
(bfd *abfd, const char *filename);
DESCRIPTION
-
- Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized
- to be big enough to contain a link to the specified @var{filename}.
+ Takes a @var{BFD} and adds a .gnu_debuglink section to it. The
+ section is sized to be big enough to contain a link to the specified
+ @var{filename}.
RETURNS
- A pointer to the new section is returned if all is ok. Otherwise <<NULL>> is
- returned and bfd_error is set.
+ A pointer to the new section is returned if all is ok. Otherwise
+ <<NULL>> is returned and bfd_error is set.
*/
asection *
@@ -1674,7 +1717,6 @@ SYNOPSIS
(bfd *abfd, struct bfd_section *sect, const char *filename);
DESCRIPTION
-
Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
and fills in the contents of the section to contain a link to the
specified @var{filename}. The filename should be relative to the
@@ -1761,8 +1803,7 @@ INTERNAL_FUNCTION
get_build_id
SYNOPSIS
- struct bfd_build_id * get_build_id
- (bfd *abfd);
+ struct bfd_build_id * get_build_id (bfd *abfd);
DESCRIPTION
Finds the build-id associated with @var{abfd}. If the build-id is
@@ -1770,6 +1811,7 @@ DESCRIPTION
for it, using memory allocated to @var{abfd}, and this is then
attached to the @var{abfd}.
+RETURNS
Returns a pointer to the build-id structure if a build-id could be
found. If no build-id is found NULL is returned and error code is
set.
@@ -1818,7 +1860,7 @@ get_build_id (bfd *abfd)
inote.descsz = H_GET_32 (abfd, enote->descsz);
inote.descdata = inote.namedata + BFD_ALIGN (inote.namesz, 4);
/* FIXME: Should we check for extra notes in this section ? */
-
+
if (inote.descsz == 0
|| inote.type != NT_GNU_BUILD_ID
|| inote.namesz != 4 /* sizeof "GNU" */
@@ -1849,24 +1891,26 @@ INTERNAL_FUNCTION
get_build_id_name
SYNOPSIS
- char * get_build_id_name
- (bfd *abfd, unsigned long *build_id_out)
+ char * get_build_id_name (bfd *abfd, void *build_id_out_p)
DESCRIPTION
Searches @var{abfd} for a build-id, and then constructs a pathname
from it. The path is computed as .build-id/NN/NN+NN.debug where
NNNN+NN is the build-id value as a hexadecimal string.
+RETURNS
Returns the constructed filename or NULL upon error.
It is the caller's responsibility to free the memory used to hold the
filename.
- If a filename is returned then the @var{build_id_out} parameter is
- set to a pointer to the build_id structure.
+ If a filename is returned then the @var{build_id_out_p}
+ parameter (which points to a @code{struct bfd_build_id}
+ pointer) is set to a pointer to the build_id structure.
*/
static char *
-get_build_id_name (bfd *abfd, unsigned long *build_id_out)
+get_build_id_name (bfd *abfd, void *build_id_out_p)
{
+ struct bfd_build_id **build_id_out = build_id_out_p;
struct bfd_build_id *build_id;
char *name;
char *n;
@@ -1901,7 +1945,7 @@ get_build_id_name (bfd *abfd, unsigned long *build_id_out)
n += sprintf (n, "%02x", (unsigned) *d++);
n += sprintf (n, ".debug");
- * build_id_out = (unsigned long) build_id;
+ *build_id_out = build_id;
return name;
}
@@ -1910,20 +1954,20 @@ INTERNAL_FUNCTION
check_build_id_file
SYNOPSIS
- bfd_boolean check_build_id_file
- (char *name, unsigned long buildid);
+ bfd_boolean check_build_id_file (char *name, void *buildid_p);
DESCRIPTION
Checks to see if @var{name} is a readable file and if its build-id
matches @var{buildid}.
- Returns TRUE if the file exists, is readable, and contains a build-id
- which matches @var{build-id}.
+RETURNS
+ Returns TRUE if the file exists, is readable, and contains a
+ build-id which matches the build-id pointed at by
+ @var{build_id_p} (which is really a @code{struct bfd_build_id **}).
*/
static bfd_boolean
-check_build_id_file (const char *name,
- const unsigned long buildid)
+check_build_id_file (const char *name, void *buildid_p)
{
struct bfd_build_id *orig_build_id;
struct bfd_build_id *build_id;
@@ -1931,7 +1975,7 @@ check_build_id_file (const char *name,
bfd_boolean result;
BFD_ASSERT (name);
- BFD_ASSERT (buildid);
+ BFD_ASSERT (buildid_p);
file = bfd_openr (name, NULL);
if (file == NULL)
@@ -1943,7 +1987,7 @@ check_build_id_file (const char *name,
bfd_close (file);
return FALSE;
}
-
+
build_id = get_build_id (file);
if (build_id == NULL)
{
@@ -1951,7 +1995,7 @@ check_build_id_file (const char *name,
return FALSE;
}
- orig_build_id = (struct bfd_build_id *) buildid;
+ orig_build_id = *(struct bfd_build_id **) buildid_p;
result = build_id->size == orig_build_id->size
&& memcmp (build_id->data, orig_build_id->data, build_id->size) == 0;
@@ -1969,7 +2013,6 @@ SYNOPSIS
char *bfd_follow_build_id_debuglink (bfd *abfd, const char *dir);
DESCRIPTION
-
Takes @var{abfd} and searches it for a .note.gnu.build-id section.
If this section is found, it extracts the value of the NT_GNU_BUILD_ID
note, which should be a hexadecimal value @var{NNNN+NN} (for
@@ -1993,7 +2036,9 @@ RETURNS
char *
bfd_follow_build_id_debuglink (bfd *abfd, const char *dir)
{
+ struct bfd_build_id *build_id;
+
return find_separate_debug_file (abfd, dir, FALSE,
get_build_id_name,
- check_build_id_file);
+ check_build_id_file, &build_id);
}