/* opncls.c -- open and close a BFD.
- Copyright (C) 1990-2017 Free Software Foundation, Inc.
+ Copyright (C) 1990-2020 Free Software Foundation, Inc.
Written by Cygnus Support.
SYNOPSIS
bfd *bfd_fopen (const char *filename, const char *target,
- const char *mode, int fd);
+ const char *mode, int fd);
DESCRIPTION
Open the file @var{filename} with the target @var{target}.
if (nbfd->iostream == NULL)
{
bfd_set_error (bfd_error_system_call);
+ if (fd != -1)
+ close (fd);
_bfd_delete_bfd (nbfd);
return NULL;
}
/* PR 11983: Do not cache the original filename, but
rather make a copy - the original might go away. */
- nbfd->filename = xstrdup (filename);
+ nbfd->filename = bfd_strdup (filename);
+ if (nbfd->filename == NULL)
+ {
+ fclose (nbfd->iostream);
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
/* Figure out whether the user is opening the file for reading,
writing, or both, by looking at the MODE argument. */
else
nbfd->direction = write_direction;
- if (! bfd_cache_init (nbfd))
+ if (!bfd_cache_init (nbfd))
{
+ fclose (nbfd->iostream);
_bfd_delete_bfd (nbfd);
return NULL;
}
SYNOPSIS
bfd *bfd_openstreamr (const char * filename, const char * target,
- void * stream);
+ void * stream);
DESCRIPTION
Open a BFD for read access on an existing stdio stream. When
nbfd->iostream = stream;
/* PR 11983: Do not cache the original filename, but
rather make a copy - the original might go away. */
- nbfd->filename = xstrdup (filename);
+ nbfd->filename = bfd_strdup (filename);
+ if (nbfd->filename == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
nbfd->direction = read_direction;
if (! bfd_cache_init (nbfd))
bfd_openr_iovec
SYNOPSIS
- bfd *bfd_openr_iovec (const char *filename, const char *target,
- void *(*open_func) (struct bfd *nbfd,
- void *open_closure),
- void *open_closure,
- file_ptr (*pread_func) (struct bfd *nbfd,
- void *stream,
- void *buf,
- file_ptr nbytes,
- file_ptr offset),
- int (*close_func) (struct bfd *nbfd,
- void *stream),
+ bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open_func) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread_func) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close_func) (struct bfd *nbfd,
+ void *stream),
int (*stat_func) (struct bfd *abfd,
- void *stream,
- struct stat *sb));
+ void *stream,
+ 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}.
+ 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}.
Calls <<bfd_find_target>>, so @var{target} is interpreted as by
that function.
int prot ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED,
file_ptr offset ATTRIBUTE_UNUSED,
- void **map_addr ATTRIBUTE_UNUSED,
- bfd_size_type *map_len ATTRIBUTE_UNUSED)
+ void **map_addr ATTRIBUTE_UNUSED,
+ bfd_size_type *map_len ATTRIBUTE_UNUSED)
{
return (void *) -1;
}
/* PR 11983: Do not cache the original filename, but
rather make a copy - the original might go away. */
- nbfd->filename = xstrdup (filename);
+ nbfd->filename = bfd_strdup (filename);
+ if (nbfd->filename == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
nbfd->direction = read_direction;
/* `open_p (...)' would get expanded by an the open(2) syscall macro. */
/* PR 11983: Do not cache the original filename, but
rather make a copy - the original might go away. */
- nbfd->filename = xstrdup (filename);
+ nbfd->filename = bfd_strdup (filename);
+ if (nbfd->filename == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
nbfd->direction = write_direction;
if (bfd_open_file (nbfd) == NULL)
bfd_boolean
bfd_close (bfd *abfd)
{
- bfd_boolean ret;
-
if (bfd_write_p (abfd))
{
if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
return FALSE;
}
- if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
- return FALSE;
-
- ret = abfd->iovec->bclose (abfd) == 0;
-
- if (ret)
- _maybe_make_executable (abfd);
-
- _bfd_delete_bfd (abfd);
-
- return ret;
+ return bfd_close_all_done (abfd);
}
/*
{
bfd_boolean ret;
- ret = bfd_cache_close (abfd);
-
if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
return FALSE;
+ ret = abfd->iovec->bclose (abfd) == 0;
+
if (ret)
_maybe_make_executable (abfd);
return NULL;
/* PR 11983: Do not cache the original filename, but
rather make a copy - the original might go away. */
- nbfd->filename = xstrdup (filename);
+ nbfd->filename = bfd_strdup (filename);
+ if (nbfd->filename == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
if (templ)
nbfd->xvec = templ->xvec;
nbfd->direction = no_direction;
bfd_byte *contents;
unsigned int crc_offset;
char *name;
+ bfd_size_type size;
BFD_ASSERT (abfd);
BFD_ASSERT (crc32_out);
if (sect == NULL)
return NULL;
+ size = bfd_section_size (sect);
+
+ /* PR 22794: Make sure that the section has a reasonable size. */
+ if (size < 8 || size >= bfd_get_size (abfd))
+ return NULL;
+
if (!bfd_malloc_and_get_section (abfd, sect, &contents))
{
if (contents != NULL)
/* CRC value is stored after the filename, aligned up to 4 bytes. */
name = (char *) contents;
- /* PR 17597: avoid reading off the end of the buffer. */
- crc_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
+ /* PR 17597: Avoid reading off the end of the buffer. */
+ crc_offset = strnlen (name, size) + 1;
crc_offset = (crc_offset + 3) & ~3;
- if (crc_offset >= bfd_get_section_size (sect))
+ if (crc_offset + 4 > size)
return NULL;
*crc32 = bfd_get_32 (abfd, contents + crc_offset);
SYNOPSIS
char *bfd_get_alt_debug_link_info (bfd * abfd,
bfd_size_type *buildid_len,
- bfd_byte **buildid_out);
+ bfd_byte **buildid_out);
DESCRIPTION
Fetch the filename and BuildID value for any alternate debuginfo
bfd_byte *contents;
unsigned int buildid_offset;
char *name;
+ bfd_size_type size;
BFD_ASSERT (abfd);
BFD_ASSERT (buildid_len);
if (sect == NULL)
return NULL;
+ size = bfd_section_size (sect);
+ if (size < 8 || size >= bfd_get_size (abfd))
+ return NULL;
+
if (!bfd_malloc_and_get_section (abfd, sect, & contents))
{
if (contents != NULL)
/* BuildID value is stored after the filename. */
name = (char *) contents;
- buildid_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
- if (buildid_offset >= bfd_get_section_size (sect))
+ buildid_offset = strnlen (name, size) + 1;
+ if (buildid_offset >= bfd_section_size (sect))
return NULL;
- *buildid_len = bfd_get_section_size (sect) - buildid_offset;
+ *buildid_len = size - buildid_offset;
*buildid_out = bfd_malloc (*buildid_len);
memcpy (*buildid_out, contents + buildid_offset, *buildid_len);
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,
+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,
- void * func_data)
+ void * func_data)
{
char *base;
char *dir;
debugfile = (char *)
bfd_malloc (strlen (debug_file_directory) + 1
- + (canon_dirlen > dirlen ? canon_dirlen : dirlen)
- + strlen (".debug/")
+ + (canon_dirlen > dirlen ? canon_dirlen : dirlen)
+ + strlen (".debug/")
#ifdef EXTRA_DEBUG_ROOT1
+ strlen (EXTRA_DEBUG_ROOT1)
#endif
#ifdef EXTRA_DEBUG_ROOT2
+ strlen (EXTRA_DEBUG_ROOT2)
#endif
- + strlen (base)
- + 1);
+ + strlen (base)
+ + 1);
if (debugfile == NULL)
goto found; /* Actually this returns NULL. */
debuglink_size &= ~3;
debuglink_size += 4;
- if (! bfd_set_section_size (abfd, sect, debuglink_size))
+ if (!bfd_set_section_size (sect, debuglink_size))
/* XXX Should we delete the section from the bfd ? */
return NULL;
/* PR 21193: Ensure that the section has 4-byte alignment for the CRC.
Note - despite the name of the function being called, we are
setting an alignment power, not a byte alignment value. */
- bfd_set_section_alignment (abfd, sect, 2);
+ bfd_set_section_alignment (sect, 2);
return sect;
}
return NULL;
}
- size = bfd_get_section_size (sect);
+ size = bfd_section_size (sect);
/* FIXME: Should we support smaller build-id notes ? */
if (size < 0x24)
{
/* FIXME: Paranoia - allow for compressed build-id sections.
Maybe we should complain if this size is different from
the one obtained above... */
- size = bfd_get_section_size (sect);
+ size = bfd_section_size (sect);
if (size < sizeof (Elf_External_Note))
{
bfd_set_error (bfd_error_invalid_operation);
inote.descdata = inote.namedata + BFD_ALIGN (inote.namesz, 4);
/* FIXME: Should we check for extra notes in this section ? */
- if (inote.descsz == 0
+ if (inote.descsz <= 0
|| inote.type != NT_GNU_BUILD_ID
|| inote.namesz != 4 /* sizeof "GNU" */
|| strncmp (inote.namedata, "GNU", 4) != 0
+ || inote.descsz > 0x7ffffffe
|| size < (12 + BFD_ALIGN (inote.namesz, 4) + inote.descsz))
{
free (contents);
get_build_id_name,
check_build_id_file, &build_id);
}
+
+/*
+FUNCTION
+ bfd_set_filename
+
+SYNOPSIS
+ void bfd_set_filename (bfd *abfd, char *filename);
+
+DESCRIPTION
+ Set the filename of @var{abfd}. The old filename, if any, is freed.
+ @var{filename} must be allocated using @code{xmalloc}. After
+ this call, it is owned @var{abfd}.
+*/
+
+void
+bfd_set_filename (bfd *abfd, char *filename)
+{
+ free ((char *) abfd->filename);
+ abfd->filename = filename;
+}