/* Assorted BFD support routines, only used internally.
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2017 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
bfd_malloc (bfd_size_type size)
{
void *ptr;
+ size_t sz = (size_t) size;
- if (size != (size_t) size)
+ if (size != sz
+ /* This is to pacify memory checkers like valgrind. */
+ || ((signed long) sz) < 0)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
- ptr = malloc ((size_t) size);
- if (ptr == NULL && (size_t) size != 0)
+ ptr = malloc (sz);
+ if (ptr == NULL && sz != 0)
bfd_set_error (bfd_error_no_memory);
return ptr;
void *
bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
{
- void *ptr;
-
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
return NULL;
}
- size *= nmemb;
-
- if (size != (size_t) size)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
-
- ptr = malloc ((size_t) size);
- if (ptr == NULL && (size_t) size != 0)
- bfd_set_error (bfd_error_no_memory);
-
- return ptr;
+ return bfd_malloc (size * nmemb);
}
/* Reallocate memory using realloc. */
bfd_realloc (void *ptr, bfd_size_type size)
{
void *ret;
+ size_t sz = (size_t) size;
+
+ if (ptr == NULL)
+ return bfd_malloc (size);
- if (size != (size_t) size)
+ if (size != sz
+ /* This is to pacify memory checkers like valgrind. */
+ || ((signed long) sz) < 0)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
- if (ptr == NULL)
- ret = malloc ((size_t) size);
- else
- ret = realloc (ptr, (size_t) size);
+ ret = realloc (ptr, sz);
- if (ret == NULL && (size_t) size != 0)
+ if (ret == NULL && sz != 0)
bfd_set_error (bfd_error_no_memory);
return ret;
void *
bfd_realloc2 (void *ptr, 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 != (size_t) size)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
-
- if (ptr == NULL)
- ret = malloc ((size_t) size);
- else
- ret = realloc (ptr, (size_t) size);
-
- if (ret == NULL && (size_t) size != 0)
- bfd_set_error (bfd_error_no_memory);
-
- return ret;
+ return bfd_realloc (ptr, size * nmemb);
}
/* Reallocate memory using realloc.
void *
bfd_realloc_or_free (void *ptr, bfd_size_type size)
{
- size_t amount = (size_t) size;
- void *ret;
+ void *ret = bfd_realloc (ptr, size);
- if (size != amount)
- ret = NULL;
- else if (ptr == NULL)
- ret = malloc (amount);
- else
- ret = realloc (ptr, amount);
-
- if (ret == NULL)
- {
- if (amount > 0)
- bfd_set_error (bfd_error_no_memory);
-
- if (ptr != NULL)
- free (ptr);
- }
+ if (ret == NULL && ptr != NULL)
+ free (ptr);
return ret;
}
void *
bfd_zmalloc (bfd_size_type size)
{
- void *ptr;
+ void *ptr = bfd_malloc (size);
- if (size != (size_t) size)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
-
- ptr = malloc ((size_t) size);
-
- if ((size_t) size != 0)
- {
- if (ptr == NULL)
- bfd_set_error (bfd_error_no_memory);
- else
- memset (ptr, 0, (size_t) size);
- }
+ if (ptr != NULL && size > 0)
+ memset (ptr, 0, (size_t) size);
return ptr;
}
void *
bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
{
- void *ptr;
+ void *ptr = bfd_malloc2 (nmemb, size);
- if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
- && size != 0
- && nmemb > ~(bfd_size_type) 0 / size)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
-
- size *= nmemb;
-
- if (size != (size_t) size)
+ if (ptr != NULL)
{
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
-
- ptr = malloc ((size_t) size);
+ size_t sz = nmemb * size;
- if ((size_t) size != 0)
- {
- if (ptr == NULL)
- bfd_set_error (bfd_error_no_memory);
- else
- memset (ptr, 0, (size_t) size);
+ if (sz > 0)
+ memset (ptr, 0, sz);
}
return ptr;
if (section->compress_status != COMPRESS_SECTION_NONE)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unable to get decompressed section %A"),
abfd, section);
bfd_set_error (bfd_error_invalid_operation);
return name[0] == locals_prefix;
}
-/* Can be used from / for bfd_merge_private_bfd_data to check that
- endianness matches between input and output file. Returns
- TRUE for a match, otherwise returns FALSE and emits an error. */
-bfd_boolean
-_bfd_generic_verify_endian_match (bfd *ibfd, bfd *obfd)
-{
- if (ibfd->xvec->byteorder != obfd->xvec->byteorder
- && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
- && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
- {
- const char *msg;
-
- if (bfd_big_endian (ibfd))
- msg = _("%B: compiled for a big endian system and target is little endian");
- else
- msg = _("%B: compiled for a little endian system and target is big endian");
-
- (*_bfd_error_handler) (msg, ibfd);
-
- bfd_set_error (bfd_error_wrong_format);
- return FALSE;
- }
-
- return TRUE;
-}
-
/* Give a warning at runtime if someone compiles code which calls
old routines. */
void
-warn_deprecated (const char *what,
- const char *file,
- int line,
- const char *func)
+_bfd_warn_deprecated (const char *what,
+ const char *file,
+ int line,
+ const char *func)
{
/* Poor man's tracking of functions we've already warned about. */
static size_t mask = 0;
/* Note: separate sentences in order to allow
for translation into other languages. */
if (func)
+ /* xgettext:c-format */
fprintf (stderr, _("Deprecated %s called at %s line %d in %s\n"),
what, file, line, func);
else
/* Helper function for reading uleb128 encoded data. */
bfd_vma
-read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
- bfd_byte *buf,
- unsigned int *bytes_read_ptr)
+_bfd_read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *buf,
+ unsigned int *bytes_read_ptr)
{
bfd_vma result;
unsigned int num_read;
return result;
}
+/* Read in a LEB128 encoded value from ABFD starting at DATA.
+ If SIGN is true, return a signed LEB128 value.
+ If LENGTH_RETURN is not NULL, return in it the number of bytes read.
+ No bytes will be read at address END or beyond. */
+
+bfd_vma
+_bfd_safe_read_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *data,
+ unsigned int *length_return,
+ bfd_boolean sign,
+ const bfd_byte * const end)
+{
+ bfd_vma result = 0;
+ unsigned int num_read = 0;
+ unsigned int shift = 0;
+ unsigned char byte = 0;
+
+ while (data < end)
+ {
+ byte = bfd_get_8 (abfd, data);
+ data++;
+ num_read++;
+
+ result |= ((bfd_vma) (byte & 0x7f)) << shift;
+
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+
+ if (length_return != NULL)
+ *length_return = num_read;
+
+ if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+ result |= -((bfd_vma) 1 << shift);
+
+ return result;
+}
+
/* Helper function for reading sleb128 encoded data. */
bfd_signed_vma
-read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
- bfd_byte *buf,
- unsigned int *bytes_read_ptr)
+_bfd_read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *buf,
+ unsigned int *bytes_read_ptr)
{
bfd_vma result;
unsigned int shift;
return result;
}
-bfd_boolean
-_bfd_generic_find_nearest_line_discriminator (bfd *abfd ATTRIBUTE_UNUSED,
- asection *section ATTRIBUTE_UNUSED,
- asymbol **symbols ATTRIBUTE_UNUSED,
- bfd_vma offset ATTRIBUTE_UNUSED,
- const char **filename_ptr ATTRIBUTE_UNUSED,
- const char **functionname_ptr ATTRIBUTE_UNUSED,
- unsigned int *line_ptr ATTRIBUTE_UNUSED,
- unsigned int *discriminator_ptr ATTRIBUTE_UNUSED)
-{
- return FALSE;
-}
-
bfd_boolean
_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
asection *isec ATTRIBUTE_UNUSED,