/* elfcomm.c -- common code for ELF format file.
- Copyright (C) 2010-2020 Free Software Foundation, Inc.
+ Copyright (C) 2010-2021 Free Software Foundation, Inc.
Originally developed by Eric Youngdale <eric@andante.jic.com>
Modifications by Nick Clifton <nickc@redhat.com>
#include "sysdep.h"
#include "libiberty.h"
+#include "bfd.h"
#include "filenames.h"
#include "aout/ar.h"
#include "elfcomm.h"
va_end (args);
}
-void (*byte_put) (unsigned char *, elf_vma, int);
+void (*byte_put) (unsigned char *, elf_vma, unsigned int);
void
-byte_put_little_endian (unsigned char * field, elf_vma value, int size)
+byte_put_little_endian (unsigned char * field, elf_vma value, unsigned int size)
{
- switch (size)
+ if (size > sizeof (elf_vma))
{
- case 8:
- field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
- field[6] = ((value >> 24) >> 24) & 0xff;
- field[5] = ((value >> 24) >> 16) & 0xff;
- field[4] = ((value >> 24) >> 8) & 0xff;
- /* Fall through. */
- case 4:
- field[3] = (value >> 24) & 0xff;
- /* Fall through. */
- case 3:
- field[2] = (value >> 16) & 0xff;
- /* Fall through. */
- case 2:
- field[1] = (value >> 8) & 0xff;
- /* Fall through. */
- case 1:
- field[0] = value & 0xff;
- break;
-
- default:
error (_("Unhandled data length: %d\n"), size);
abort ();
}
+ while (size--)
+ {
+ *field++ = value & 0xff;
+ value >>= 8;
+ }
}
void
-byte_put_big_endian (unsigned char * field, elf_vma value, int size)
+byte_put_big_endian (unsigned char * field, elf_vma value, unsigned int size)
{
- switch (size)
+ if (size > sizeof (elf_vma))
{
- case 8:
- field[7] = value & 0xff;
- field[6] = (value >> 8) & 0xff;
- field[5] = (value >> 16) & 0xff;
- field[4] = (value >> 24) & 0xff;
- value >>= 16;
- value >>= 16;
- /* Fall through. */
- case 4:
- field[3] = value & 0xff;
- value >>= 8;
- /* Fall through. */
- case 3:
- field[2] = value & 0xff;
- value >>= 8;
- /* Fall through. */
- case 2:
- field[1] = value & 0xff;
- value >>= 8;
- /* Fall through. */
- case 1:
- field[0] = value & 0xff;
- break;
-
- default:
error (_("Unhandled data length: %d\n"), size);
abort ();
}
+ while (size--)
+ {
+ field[size] = value & 0xff;
+ value >>= 8;
+ }
}
-elf_vma (*byte_get) (const unsigned char *, int);
+elf_vma (*byte_get) (const unsigned char *, unsigned int);
elf_vma
-byte_get_little_endian (const unsigned char *field, int size)
+byte_get_little_endian (const unsigned char *field, unsigned int size)
{
switch (size)
{
| (((unsigned long) (field[3])) << 24);
case 5:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[0]))
| (((elf_vma) (field[1])) << 8)
| (((elf_vma) (field[2])) << 16)
| (((elf_vma) (field[3])) << 24)
| (((elf_vma) (field[4])) << 32);
- else if (sizeof (elf_vma) == 4)
- /* We want to extract data from an 8 byte wide field and
- place it into a 4 byte wide field. Since this is a little
- endian source we can just use the 4 byte extraction code. */
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16)
- | (((unsigned long) (field[3])) << 24);
/* Fall through. */
case 6:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[0]))
| (((elf_vma) (field[1])) << 8)
| (((elf_vma) (field[2])) << 16)
| (((elf_vma) (field[3])) << 24)
| (((elf_vma) (field[4])) << 32)
| (((elf_vma) (field[5])) << 40);
- else if (sizeof (elf_vma) == 4)
- /* We want to extract data from an 8 byte wide field and
- place it into a 4 byte wide field. Since this is a little
- endian source we can just use the 4 byte extraction code. */
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16)
- | (((unsigned long) (field[3])) << 24);
/* Fall through. */
case 7:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[0]))
| (((elf_vma) (field[1])) << 8)
| (((elf_vma) (field[2])) << 16)
| (((elf_vma) (field[4])) << 32)
| (((elf_vma) (field[5])) << 40)
| (((elf_vma) (field[6])) << 48);
- else if (sizeof (elf_vma) == 4)
- /* We want to extract data from an 8 byte wide field and
- place it into a 4 byte wide field. Since this is a little
- endian source we can just use the 4 byte extraction code. */
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16)
- | (((unsigned long) (field[3])) << 24);
/* Fall through. */
case 8:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[0]))
| (((elf_vma) (field[1])) << 8)
| (((elf_vma) (field[2])) << 16)
| (((elf_vma) (field[5])) << 40)
| (((elf_vma) (field[6])) << 48)
| (((elf_vma) (field[7])) << 56);
- else if (sizeof (elf_vma) == 4)
- /* We want to extract data from an 8 byte wide field and
- place it into a 4 byte wide field. Since this is a little
- endian source we can just use the 4 byte extraction code. */
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16)
- | (((unsigned long) (field[3])) << 24);
/* Fall through. */
default:
}
elf_vma
-byte_get_big_endian (const unsigned char *field, int size)
+byte_get_big_endian (const unsigned char *field, unsigned int size)
{
switch (size)
{
| (((unsigned long) (field[0])) << 24);
case 5:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[4]))
| (((elf_vma) (field[3])) << 8)
| (((elf_vma) (field[2])) << 16)
| (((elf_vma) (field[1])) << 24)
| (((elf_vma) (field[0])) << 32);
- else if (sizeof (elf_vma) == 4)
- {
- /* Although we are extracting data from an 8 byte wide field,
- we are returning only 4 bytes of data. */
- field += 1;
- return ((unsigned long) (field[3]))
- | (((unsigned long) (field[2])) << 8)
- | (((unsigned long) (field[1])) << 16)
- | (((unsigned long) (field[0])) << 24);
- }
/* Fall through. */
case 6:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[5]))
| (((elf_vma) (field[4])) << 8)
| (((elf_vma) (field[3])) << 16)
| (((elf_vma) (field[2])) << 24)
| (((elf_vma) (field[1])) << 32)
| (((elf_vma) (field[0])) << 40);
- else if (sizeof (elf_vma) == 4)
- {
- /* Although we are extracting data from an 8 byte wide field,
- we are returning only 4 bytes of data. */
- field += 2;
- return ((unsigned long) (field[3]))
- | (((unsigned long) (field[2])) << 8)
- | (((unsigned long) (field[1])) << 16)
- | (((unsigned long) (field[0])) << 24);
- }
/* Fall through. */
case 7:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[6]))
| (((elf_vma) (field[5])) << 8)
| (((elf_vma) (field[4])) << 16)
| (((elf_vma) (field[2])) << 32)
| (((elf_vma) (field[1])) << 40)
| (((elf_vma) (field[0])) << 48);
- else if (sizeof (elf_vma) == 4)
- {
- /* Although we are extracting data from an 8 byte wide field,
- we are returning only 4 bytes of data. */
- field += 3;
- return ((unsigned long) (field[3]))
- | (((unsigned long) (field[2])) << 8)
- | (((unsigned long) (field[1])) << 16)
- | (((unsigned long) (field[0])) << 24);
- }
/* Fall through. */
case 8:
- if (sizeof (elf_vma) == 8)
+ if (sizeof (elf_vma) >= 8)
return ((elf_vma) (field[7]))
| (((elf_vma) (field[6])) << 8)
| (((elf_vma) (field[5])) << 16)
| (((elf_vma) (field[2])) << 40)
| (((elf_vma) (field[1])) << 48)
| (((elf_vma) (field[0])) << 56);
- else if (sizeof (elf_vma) == 4)
- {
- /* Although we are extracting data from an 8 byte wide field,
- we are returning only 4 bytes of data. */
- field += 4;
- return ((unsigned long) (field[3]))
- | (((unsigned long) (field[2])) << 8)
- | (((unsigned long) (field[1])) << 16)
- | (((unsigned long) (field[0])) << 24);
- }
/* Fall through. */
default:
}
elf_vma
-byte_get_signed (const unsigned char *field, int size)
+byte_get_signed (const unsigned char *field, unsigned int size)
{
elf_vma x = byte_get (field, size);
}
}
-/* Return the high-order 32-bits and the low-order 32-bits
- of an 8-byte value separately. */
-
-void
-byte_get_64 (const unsigned char *field, elf_vma *high, elf_vma *low)
-{
- if (byte_get == byte_get_big_endian)
- {
- *high = byte_get_big_endian (field, 4);
- *low = byte_get_big_endian (field + 4, 4);
- }
- else
- {
- *high = byte_get_little_endian (field + 4, 4);
- *low = byte_get_little_endian (field, 4);
- }
- return;
-}
-
/* Return the path name for a proxy entry in a thin archive, adjusted
relative to the path name of the thin archive itself if necessary.
Always returns a pointer to malloc'ed memory. */
}
/* See if this is the archive symbol table. */
- if (const_strneq (arch->arhdr.ar_name, "/ "))
+ if (startswith (arch->arhdr.ar_name, "/ "))
{
if (! process_archive_index_and_symbols (arch, 4, read_symbols))
return 1;
}
- else if (const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
+ else if (startswith (arch->arhdr.ar_name, "/SYM64/ "))
{
arch->uses_64bit_indices = 1;
if (! process_archive_index_and_symbols (arch, 8, read_symbols))
else if (read_symbols)
printf (_("%s has no archive index\n"), file_name);
- if (const_strneq (arch->arhdr.ar_name, "// "))
+ if (startswith (arch->arhdr.ar_name, "// "))
{
/* This is the archive string table holding long member names. */
char fmag_save = arch->arhdr.ar_fmag[0];
/* Close previous file and discard cached information. */
if (nested_arch->file != NULL)
- fclose (nested_arch->file);
+ {
+ fclose (nested_arch->file);
+ nested_arch->file = NULL;
+ }
release_archive (nested_arch);
member_file = fopen (member_file_name, "rb");
void
release_archive (struct archive_info * arch)
{
- if (arch->file_name != NULL)
- free (arch->file_name);
- if (arch->index_array != NULL)
- free (arch->index_array);
- if (arch->sym_table != NULL)
- free (arch->sym_table);
- if (arch->longnames != NULL)
- free (arch->longnames);
+ free (arch->file_name);
+ free (arch->index_array);
+ free (arch->sym_table);
+ free (arch->longnames);
+ arch->file_name = NULL;
+ arch->index_array = NULL;
+ arch->sym_table = NULL;
+ arch->longnames = NULL;
}
/* Get the name of an archive member from the current archive header.