/* Assorted BFD support routines, only used internally.
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 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 (size != (size_t) size)
+ if (ptr == NULL)
+ return bfd_malloc (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;
-
- 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);
+ void *ret = bfd_realloc (ptr, size);
- 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;
-
- 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;
+ void *ptr = bfd_malloc2 (nmemb, size);
- if (size != (size_t) size)
+ if (ptr != NULL)
{
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ size_t sz = nmemb * size;
- 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 (sz > 0)
+ memset (ptr, 0, sz);
}
return ptr;
.*/
/* Sign extension to bfd_signed_vma. */
-#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
-#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
-#define EIGHT_GAZILLION ((bfd_int64_t) 1 << 63)
+#define COERCE16(x) (((bfd_vma) (x) ^ 0x8000) - 0x8000)
+#define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000)
#define COERCE64(x) \
- (((bfd_int64_t) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
+ (((bfd_uint64_t) (x) ^ ((bfd_uint64_t) 1 << 63)) - ((bfd_uint64_t) 1 << 63))
bfd_vma
bfd_getb16 (const void *p)
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
+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
return result;
}
-bfd_boolean
-_bfd_generic_find_line (bfd *abfd ATTRIBUTE_UNUSED,
- asymbol **symbols ATTRIBUTE_UNUSED,
- asymbol *symbol ATTRIBUTE_UNUSED,
- const char **filename_ptr ATTRIBUTE_UNUSED,
- unsigned int *linenumber_ptr ATTRIBUTE_UNUSED)
-{
- return FALSE;
-}
-
-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,