Better coping with different reloc types.
This commit is contained in:
parent
633fd09f3c
commit
9c19a80986
2 changed files with 131 additions and 72 deletions
|
@ -1,3 +1,13 @@
|
|||
1999-05-28 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* readelf.c (dump_relocations): Add extra parameter: is_rela to
|
||||
specify the kind of relocations to be dumped. Call guess_is_rela
|
||||
if this parameter has a value of UNKNOWN.
|
||||
(guess_is_rela): New function: Guess the kind of reloc being used
|
||||
baced on the machine number.
|
||||
(process_relocs): Determine type of reloc before calling
|
||||
dump_relocations.
|
||||
|
||||
1999-05-28 Ian Lance Taylor <ian@zembu.com>
|
||||
|
||||
* readelf.c: Include "elf/i960.h".
|
||||
|
|
|
@ -118,7 +118,7 @@ unsigned int num_dump_sects = 0;
|
|||
static unsigned long (* byte_get) PARAMS ((unsigned char *, int));
|
||||
static const char * get_mips_dynamic_type PARAMS ((unsigned long type));
|
||||
static const char * get_dynamic_type PARAMS ((unsigned long type));
|
||||
static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *));
|
||||
static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *, int));
|
||||
static char * get_file_type PARAMS ((unsigned e_type));
|
||||
static char * get_machine_name PARAMS ((unsigned e_machine));
|
||||
static char * get_machine_data PARAMS ((unsigned e_data));
|
||||
|
@ -174,9 +174,16 @@ static void request_dump PARAMS ((unsigned int, char));
|
|||
static const char * get_elf_class PARAMS ((unsigned char));
|
||||
static const char * get_data_encoding PARAMS ((unsigned char));
|
||||
static const char * get_osabi_name PARAMS ((unsigned char));
|
||||
static int guess_is_rela PARAMS ((unsigned long));
|
||||
|
||||
typedef int Elf32_Word;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#define UNKNOWN -1
|
||||
|
||||
#define SECTION_NAME(X) (string_table + (X)->sh_name)
|
||||
|
||||
#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
|
||||
|
@ -329,24 +336,12 @@ byte_get_big_endian (field, size)
|
|||
}
|
||||
|
||||
|
||||
/* Display the contents of the relocation data
|
||||
found at the specified offset. */
|
||||
/* Guess the relocation sized based on the sized commonly used by the specific machine. */
|
||||
static int
|
||||
dump_relocations (file, rel_offset, rel_size, symtab, strtab)
|
||||
FILE * file;
|
||||
unsigned long rel_offset;
|
||||
unsigned long rel_size;
|
||||
Elf_Internal_Sym * symtab;
|
||||
char * strtab;
|
||||
guess_is_rela (e_machine)
|
||||
unsigned long e_machine;
|
||||
{
|
||||
unsigned int i;
|
||||
int is_rela;
|
||||
Elf_Internal_Rel * rels;
|
||||
Elf_Internal_Rela * relas;
|
||||
|
||||
|
||||
/* Compute number of relocations and read them in. */
|
||||
switch (elf_header.e_machine)
|
||||
switch (e_machine)
|
||||
{
|
||||
/* Targets that use REL relocations. */
|
||||
case EM_ARM:
|
||||
|
@ -357,30 +352,8 @@ dump_relocations (file, rel_offset, rel_size, symtab, strtab)
|
|||
case EM_CYGNUS_D10V:
|
||||
case EM_MIPS:
|
||||
case EM_MIPS_RS4_BE:
|
||||
{
|
||||
Elf32_External_Rel * erels;
|
||||
|
||||
GET_DATA_ALLOC (rel_offset, rel_size, erels,
|
||||
Elf32_External_Rel *, "relocs");
|
||||
|
||||
rel_size = rel_size / sizeof (Elf32_External_Rel);
|
||||
|
||||
rels = (Elf_Internal_Rel *) malloc (rel_size *
|
||||
sizeof (Elf_Internal_Rel));
|
||||
|
||||
for (i = 0; i < rel_size; i++)
|
||||
{
|
||||
rels[i].r_offset = BYTE_GET (erels[i].r_offset);
|
||||
rels[i].r_info = BYTE_GET (erels[i].r_info);
|
||||
}
|
||||
|
||||
free (erels);
|
||||
|
||||
is_rela = 0;
|
||||
relas = (Elf_Internal_Rela *) rels;
|
||||
}
|
||||
break;
|
||||
|
||||
return FALSE;
|
||||
|
||||
/* Targets that use RELA relocations. */
|
||||
case EM_68K:
|
||||
case EM_SPARC:
|
||||
|
@ -390,37 +363,95 @@ dump_relocations (file, rel_offset, rel_size, symtab, strtab)
|
|||
case EM_CYGNUS_MN10200:
|
||||
case EM_CYGNUS_MN10300:
|
||||
case EM_CYGNUS_FR30:
|
||||
/* start-sanitize-venus */
|
||||
case EM_CYGNUS_VENUS:
|
||||
/* end-sanitize-venus */
|
||||
case EM_SH:
|
||||
case EM_ALPHA:
|
||||
case EM_MCORE:
|
||||
{
|
||||
Elf32_External_Rela * erelas;
|
||||
|
||||
GET_DATA_ALLOC (rel_offset, rel_size, erelas,
|
||||
Elf32_External_Rela *, "relocs");
|
||||
|
||||
rel_size = rel_size / sizeof (Elf32_External_Rela);
|
||||
|
||||
relas = (Elf_Internal_Rela *) malloc (rel_size *
|
||||
sizeof (Elf_Internal_Rela));
|
||||
|
||||
for (i = 0; i < rel_size; i++)
|
||||
{
|
||||
relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
|
||||
relas[i].r_info = BYTE_GET (erelas[i].r_info);
|
||||
relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
|
||||
}
|
||||
|
||||
free (erelas);
|
||||
|
||||
is_rela = 1;
|
||||
rels = (Elf_Internal_Rel *) relas;
|
||||
}
|
||||
break;
|
||||
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
warn (_("Don't know about relocations on this machine architecture\n"));
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display the contents of the relocation data
|
||||
found at the specified offset. */
|
||||
static int
|
||||
dump_relocations (file, rel_offset, rel_size, symtab, strtabm, is_rela)
|
||||
FILE * file;
|
||||
unsigned long rel_offset;
|
||||
unsigned long rel_size;
|
||||
Elf_Internal_Sym * symtab;
|
||||
char * strtab;
|
||||
int is_rela;
|
||||
{
|
||||
unsigned int i;
|
||||
Elf_Internal_Rel * rels;
|
||||
Elf_Internal_Rela * relas;
|
||||
|
||||
|
||||
if (is_rela == UNKNOWN)
|
||||
is_rela = guess_is_rela (elf_header.e_machine);
|
||||
|
||||
if (is_rela)
|
||||
{
|
||||
Elf32_External_Rela * erelas;
|
||||
|
||||
GET_DATA_ALLOC (rel_offset, rel_size, erelas,
|
||||
Elf32_External_Rela *, "relocs");
|
||||
|
||||
rel_size = rel_size / sizeof (Elf32_External_Rela);
|
||||
|
||||
relas = (Elf_Internal_Rela *) malloc (rel_size *
|
||||
sizeof (Elf_Internal_Rela));
|
||||
|
||||
if (relas == NULL)
|
||||
{
|
||||
error(_("out of memory parsing relocs"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < rel_size; i++)
|
||||
{
|
||||
relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
|
||||
relas[i].r_info = BYTE_GET (erelas[i].r_info);
|
||||
relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
|
||||
}
|
||||
|
||||
free (erelas);
|
||||
|
||||
rels = (Elf_Internal_Rel *) relas;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf32_External_Rel * erels;
|
||||
unsigned long saved_rel_size = rel_size;
|
||||
|
||||
GET_DATA_ALLOC (rel_offset, rel_size, erels,
|
||||
Elf32_External_Rel *, "relocs");
|
||||
|
||||
rel_size = rel_size / sizeof (Elf32_External_Rel);
|
||||
|
||||
rels = (Elf_Internal_Rel *) malloc (rel_size *
|
||||
sizeof (Elf_Internal_Rel));
|
||||
if (rels == NULL)
|
||||
{
|
||||
error(_("out of memory parsing relocs"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < rel_size; i++)
|
||||
{
|
||||
rels[i].r_offset = BYTE_GET (erels[i].r_offset);
|
||||
rels[i].r_info = BYTE_GET (erels[i].r_info);
|
||||
}
|
||||
|
||||
free (erels);
|
||||
|
||||
relas = (Elf_Internal_Rela *) rels;
|
||||
}
|
||||
|
||||
if (is_rela)
|
||||
|
@ -1827,6 +1858,8 @@ process_relocs (file)
|
|||
|
||||
if (do_using_dynamic)
|
||||
{
|
||||
int is_rela;
|
||||
|
||||
rel_size = 0;
|
||||
rel_offset = 0;
|
||||
|
||||
|
@ -1834,16 +1867,19 @@ process_relocs (file)
|
|||
{
|
||||
rel_offset = dynamic_info[DT_REL];
|
||||
rel_size = dynamic_info[DT_RELSZ];
|
||||
is_rela = FALSE;
|
||||
}
|
||||
else if (dynamic_info [DT_RELA])
|
||||
{
|
||||
rel_offset = dynamic_info[DT_RELA];
|
||||
rel_size = dynamic_info[DT_RELASZ];
|
||||
is_rela = TRUE;
|
||||
}
|
||||
else if (dynamic_info[DT_JMPREL])
|
||||
{
|
||||
rel_offset = dynamic_info[DT_JMPREL];
|
||||
rel_size = dynamic_info[DT_PLTRELSZ];
|
||||
is_rela = UNKNOWN;
|
||||
}
|
||||
|
||||
if (rel_size)
|
||||
|
@ -1853,7 +1889,7 @@ process_relocs (file)
|
|||
rel_offset, rel_size);
|
||||
|
||||
dump_relocations (file, rel_offset - loadaddr, rel_size,
|
||||
dynamic_symbols, dynamic_strings);
|
||||
dynamic_symbols, dynamic_strings, is_rela);
|
||||
}
|
||||
else
|
||||
printf (_("\nThere are no dynamic relocations in this file.\n"));
|
||||
|
@ -1881,13 +1917,26 @@ process_relocs (file)
|
|||
Elf32_Internal_Shdr * symsec;
|
||||
Elf_Internal_Sym * symtab;
|
||||
char * strtab;
|
||||
|
||||
int is_rela;
|
||||
|
||||
printf (_("\nRelocation section "));
|
||||
|
||||
if (string_table == NULL)
|
||||
printf ("%d", section->sh_name);
|
||||
{
|
||||
printf ("%d", section->sh_name);
|
||||
is_rela = UNKNOWN;
|
||||
}
|
||||
else
|
||||
printf ("'%s'", SECTION_NAME (section));
|
||||
{
|
||||
printf ("'%s'", SECTION_NAME (section));
|
||||
|
||||
if (strncmp (".rela.", SECTION_NAME (section), 6) == 0)
|
||||
is_rela = TRUE;
|
||||
else if (strncmp (".rel.", SECTION_NAME (section), 5) == 0)
|
||||
is_rela = FALSE;
|
||||
else
|
||||
is_rela = UNKNOWN;
|
||||
}
|
||||
|
||||
printf (_(" at offset 0x%lx contains %lu entries:\n"),
|
||||
rel_offset, (unsigned long) (rel_size / section->sh_entsize));
|
||||
|
@ -1905,7 +1954,7 @@ process_relocs (file)
|
|||
GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
|
||||
char *, "string table");
|
||||
|
||||
dump_relocations (file, rel_offset, rel_size, symtab, strtab);
|
||||
dump_relocations (file, rel_offset, rel_size, symtab, strtab, is_rela);
|
||||
|
||||
free (strtab);
|
||||
free (symtab);
|
||||
|
|
Loading…
Reference in a new issue