/* opncls.c -- open and close a BFD.
- Copyright 1990-2013 Free Software Foundation, Inc.
+ Copyright (C) 1990-2016 Free Software Foundation, Inc.
Written by Cygnus Support.
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), 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;
}
nbfd->my_archive = obfd;
nbfd->direction = read_direction;
nbfd->target_defaulted = obfd->target_defaulted;
+ nbfd->lto_output = obfd->lto_output;
+ nbfd->no_export = obfd->no_export;
return nbfd;
}
objalloc_free ((struct objalloc *) abfd->memory);
}
+ if (abfd->filename)
+ free ((char *) abfd->filename);
free (abfd->arelt_data);
free (abfd);
}
<<system_call>> error.
On error, @var{fd} is always closed.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
bfd *
}
/* OK, put everything where it belongs. */
- nbfd->filename = filename;
+
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
/* Figure out whether the user is opening the file for reading,
writing, or both, by looking at the MODE argument. */
If <<NULL>> is returned then an error has occured. Possible errors
are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
<<system_call>> error.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
bfd *
<<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
On error, @var{fd} is closed.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
bfd *
bfd_openstreamr
SYNOPSIS
- bfd *bfd_openstreamr (const char *, const char *, void *);
+ 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.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
bfd *
}
nbfd->iostream = stream;
- nbfd->filename = filename;
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
nbfd->direction = read_direction;
if (! bfd_cache_init (nbfd))
occurred. Possible errors are <<bfd_error_no_memory>>,
<<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
struct opncls
return NULL;
}
- nbfd->filename = filename;
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
nbfd->direction = read_direction;
/* `open_p (...)' would get expanded by an the open(2) syscall macro. */
Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
<<bfd_error_invalid_target>>.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
bfd *
return NULL;
}
- nbfd->filename = filename;
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
nbfd->direction = write_direction;
if (bfd_open_file (nbfd) == NULL)
Create a new BFD in the manner of <<bfd_openw>>, but without
opening a file. The new BFD takes the target from the target
used by @var{templ}. The format is always set to <<bfd_object>>.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
*/
bfd *
nbfd = _bfd_new_bfd ();
if (nbfd == NULL)
return NULL;
- nbfd->filename = filename;
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
if (templ)
nbfd->xvec = templ->xvec;
nbfd->direction = no_direction;
bfd_alloc (bfd *abfd, bfd_size_type size)
{
void *ret;
-
- if (size != (unsigned long) size)
+ unsigned long ul_size = (unsigned long) size;
+
+ if (size != ul_size
+ /* Note - although objalloc_alloc takes an unsigned long as its
+ argument, internally the size is treated as a signed long. This can
+ lead to problems where, for example, a request to allocate -1 bytes
+ can result in just 1 byte being allocated, rather than
+ ((unsigned long) -1) bytes. Also memory checkers will often
+ complain about attempts to allocate a negative amount of memory.
+ So to stop these problems we fail if the size is negative. */
+ || ((signed long) ul_size) < 0)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
- ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size);
+ ret = objalloc_alloc ((struct objalloc *) abfd->memory, ul_size);
if (ret == NULL)
bfd_set_error (bfd_error_no_memory);
return ret;
void *
bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
{
- void *ret;
-
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
return NULL;
}
- size *= nmemb;
-
- if (size != (unsigned long) size)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
-
- ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size);
- if (ret == NULL)
- bfd_set_error (bfd_error_no_memory);
- return ret;
+ return bfd_alloc (abfd, size * nmemb);
}
/*
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,
+ 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.
asection *sect;
unsigned long crc32;
bfd_byte *contents;
- int crc_offset;
+ unsigned int crc_offset;
char *name;
BFD_ASSERT (abfd);
return NULL;
}
- /* Crc value is stored after the filename, aligned up to 4 bytes. */
+ /* CRC value is stored after the filename, aligned up to 4 bytes. */
name = (char *) contents;
- crc_offset = strlen (name) + 1;
+ /* PR 17597: avoid reading off the end of the buffer. */
+ crc_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
crc_offset = (crc_offset + 3) & ~3;
+ if (crc_offset >= bfd_get_section_size (sect))
+ return NULL;
crc32 = bfd_get_32 (abfd, contents + crc_offset);
{
asection *sect;
bfd_byte *contents;
- int buildid_offset;
+ unsigned int buildid_offset;
char *name;
BFD_ASSERT (abfd);
/* BuildID value is stored after the filename. */
name = (char *) contents;
- buildid_offset = strlen (name) + 1;
+ buildid_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
+ if (buildid_offset >= bfd_get_section_size (sect))
+ return NULL;
*buildid_len = bfd_get_section_size (sect) - buildid_offset;
*buildid_out = bfd_malloc (*buildid_len);
}
base = get_func (abfd, & crc32);
-
+
if (base == NULL)
return NULL;