/* Display the contents of the relocation data found at the specified
offset. */
-static int
+static void
dump_relocations (FILE *file,
unsigned long rel_offset,
unsigned long rel_size,
if (is_rela)
{
if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
- return 0;
+ return;
}
else
{
if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
- return 0;
+ return;
}
if (is_32bit_elf)
}
free (rels);
-
- return 1;
}
static const char *
}
free (table);
- /* Third, apply any relocations to the unwind table: */
-
+ /* Third, apply any relocations to the unwind table: */
for (relsec = section_headers;
relsec < section_headers + elf_header.e_shnum;
++relsec)
free (table);
/* Third, apply any relocations to the unwind table. */
-
for (relsec = section_headers;
relsec < section_headers + elf_header.e_shnum;
++relsec)
{
switch (elf_header.e_machine)
{
+ case EM_386:
+ case EM_486:
+ return reloc_type == 1; /* R_386_32. */
case EM_68K:
return reloc_type == 1; /* R_68K_32. */
case EM_860:
return reloc_type == 1; /* R_860_32. */
case EM_ALPHA:
return reloc_type == 1; /* XXX Is this right ? */
+ case EM_ARC:
+ return reloc_type == 1; /* R_ARC_32. */
+ case EM_ARM:
+ return reloc_type == 2; /* R_ARM_ABS32 */
case EM_AVR_OLD:
case EM_AVR:
return reloc_type == 1;
return reloc_type == 15; /* R_CRX_NUM32. */
case EM_CYGNUS_FRV:
return reloc_type == 1;
+ case EM_CYGNUS_D10V:
+ case EM_D10V:
+ return reloc_type == 6; /* R_D10V_32. */
case EM_CYGNUS_D30V:
case EM_D30V:
return reloc_type == 12; /* R_D30V_32_NORMAL. */
+ case EM_DLX:
+ return reloc_type == 3; /* R_DLX_RELOC_32. */
case EM_CYGNUS_FR30:
case EM_FR30:
return reloc_type == 3; /* R_FR30_32. */
return reloc_type == 1; /* R_MSP43_32. */
case EM_MT:
return reloc_type == 2; /* R_MT_32. */
+ case EM_OPENRISC:
+ case EM_OR32:
+ return reloc_type == 1; /* R_OR32_32. */
case EM_PARISC:
return reloc_type == 1; /* R_PARISC_DIR32. */
case EM_PJ:
case EM_S390_OLD:
case EM_S390:
return reloc_type == 4; /* R_S390_32. */
+ case EM_SCORE:
+ return reloc_type == 8; /* R_SCORE_ABS32. */
case EM_SH:
return reloc_type == 1; /* R_SH_DIR32. */
case EM_SPARC32PLUS:
{
switch (elf_header.e_machine)
{
+ case EM_386:
+ case EM_486:
+ return reloc_type == 2; /* R_386_PC32. */
case EM_68K:
return reloc_type == 4; /* R_68K_PC32. */
case EM_ALPHA:
return reloc_type == 10; /* R_ALPHA_SREL32. */
+ case EM_ARM:
+ return reloc_type == 3; /* R_ARM_REL32 */
case EM_PARISC:
return reloc_type == 0; /* R_PARISC_NONE. *//* FIXME: This reloc is generated, but it may be a bug. */
case EM_PPC:
/* Do not abort or issue an error message here. Not all targets use
pc-relative 32-bit relocs in their DWARF debug information and we
have already tested for target coverage in is_32bit_abs_reloc. A
- more helpful warning message will be generated by debug_apply_rela_addends
- anyway, so just return. */
+ more helpful warning message will be generated by
+ debug_apply_relocations anyway, so just return. */
return FALSE;
}
}
case EM_AVR_OLD:
case EM_AVR:
return reloc_type == 4; /* R_AVR_16. */
+ case EM_CYGNUS_D10V:
+ case EM_D10V:
+ return reloc_type == 3; /* R_D10V_16. */
case EM_H8S:
case EM_H8_300:
case EM_H8_300H:
}
}
-/* Apply addends of RELA relocations. */
+/* Apply relocations to a debug section. */
-static int
-debug_apply_rela_addends (void *file,
- Elf_Internal_Shdr *section,
- unsigned char *start)
+static void
+debug_apply_relocations (void *file,
+ Elf_Internal_Shdr *section,
+ unsigned char *start)
{
Elf_Internal_Shdr *relsec;
unsigned char *end = start + section->sh_size;
- if (!is_relocatable)
- return 1;
-
- /* SH uses RELA but uses in place value instead of the addend field. */
- if (elf_header.e_machine == EM_SH)
- return 0;
+ if (elf_header.e_type != ET_REL)
+ return;
+ /* Find the reloc section associated with the debug section. */
for (relsec = section_headers;
relsec < section_headers + elf_header.e_shnum;
++relsec)
{
- unsigned long nrelas;
- Elf_Internal_Rela *rela, *rp;
+ bfd_boolean is_rela;
+ unsigned long num_relocs;
+ Elf_Internal_Rela *relocs, *rp;
Elf_Internal_Shdr *symsec;
Elf_Internal_Sym *symtab;
Elf_Internal_Sym *sym;
- if (relsec->sh_type != SHT_RELA
+ if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
|| SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != section
|| relsec->sh_size == 0
|| SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
continue;
- if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
- &rela, &nrelas))
- return 0;
+ is_rela = relsec->sh_type == SHT_RELA;
+
+ if (is_rela)
+ {
+ if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
+ & relocs, & num_relocs))
+ return;
+ }
+ else
+ {
+ if (!slurp_rel_relocs (file, relsec->sh_offset, relsec->sh_size,
+ & relocs, & num_relocs))
+ return;
+ }
+
+ /* SH uses RELA but uses in place value instead of the addend field. */
+ if (elf_header.e_machine == EM_SH)
+ is_rela = FALSE;
symsec = SECTION_HEADER (relsec->sh_link);
symtab = GET_ELF_SYMBOLS (file, symsec);
- for (rp = rela; rp < rela + nrelas; ++rp)
+ for (rp = relocs; rp < relocs + num_relocs; ++rp)
{
- unsigned int reloc_type;
- unsigned int reloc_size;
- unsigned char *loc;
+ bfd_vma addend;
+ unsigned int reloc_type;
+ unsigned int reloc_size;
+ unsigned char * loc;
/* In MIPS little-endian objects, r_info isn't really a
64-bit little-endian value: it has a 32-bit little-endian
| ((rp->r_info >> 24) & 0xff0000)
| ((rp->r_info >> 8) & 0xff000000));
- sym = symtab + get_reloc_symindex (rp->r_info);
reloc_type = get_reloc_type (rp->r_info);
+
if (is_32bit_abs_reloc (reloc_type)
|| is_32bit_pcrel_reloc (reloc_type))
reloc_size = 4;
reloc_size = 2;
else
{
- warn (_("skipping unsupported reloc type %d in section .rela%s\n"),
+ warn (_("unable to apply unsupported reloc type %d to section %s\n"),
reloc_type, SECTION_NAME (section));
continue;
}
continue;
}
+ sym = symtab + get_reloc_symindex (rp->r_info);
+
+ /* If the reloc has a symbol associated with it,
+ make sure that it is of an appropriate type. */
if (sym != symtab
&& ELF_ST_TYPE (sym->st_info) != STT_SECTION
/* Relocations against symbols without type can happen.
example of this see the _clz.o binary in libgcc.a. */
&& ELF_ST_TYPE (sym->st_info) != STT_OBJECT)
{
- warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
+ warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
get_symbol_type (ELF_ST_TYPE (sym->st_info)),
- SECTION_NAME (section));
+ rp - relocs,
+ SECTION_NAME (relsec));
continue;
}
- /* FIXME. We apply pcrel relocs as if they were absolute,
- ie. without subtracting the pc. This is to suit
- display_debug_frames which does not add the pc even
- though it ought to for DW_EH_PE_pcrel FDEs. Removing
- the hack in display_debug_frames will require that we
- apply rel relocs too. */
- byte_put (loc, rp->r_addend + sym->st_value, reloc_size);
+ addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
+
+ if (is_32bit_pcrel_reloc (reloc_type))
+ byte_put (loc, (addend + sym->st_value) - rp->r_offset,
+ reloc_size);
+ else
+ byte_put (loc, addend + sym->st_value, reloc_size);
}
free (symtab);
- free (rela);
+ free (relocs);
break;
}
- return 1;
}
int
sec->sh_size, buf);
if (debug_displays [debug].relocate)
- debug_apply_rela_addends (file, sec, section->start);
+ debug_apply_relocations (file, sec, section->start);
return section->start != NULL;
}
get_64bit_section_headers (file, 1);
}
- is_relocatable = elf_header.e_type == ET_REL;
-
return 1;
}