static bfd_reloc_status_type
bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- void *data, asection *input_section,
- bfd *output_bfd ATTRIBUTE_UNUSED,
+ void *data, asection *input_section, bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
{
bfd_reloc_status_type status;
bfd_byte *where;
+ /* From bfd_elf_generic_reloc. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd == NULL
+ && !reloc_entry->howto->pc_relative
+ && (symbol->section->flags & SEC_DEBUGGING) != 0
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ reloc_entry->addend -= symbol->section->output_section->vma;
+
/* Sanity check that the address is in range. */
bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section);
bfd_size_type reloc_size;
|| end - reloc_entry->address < reloc_size)
return bfd_reloc_outofrange;
- /* Get the symbol value. */
- if (bfd_is_com_section (symbol->section))
- relocation = 0;
- else
- relocation = symbol->value;
+ /* Behave similarly to bfd_install_relocation with install_addend set.
+ That is, just install the addend and do not include the value of
+ the symbol. */
+ relocation = reloc_entry->addend;
if (symbol->flags & BSF_SECTION_SYM)
/* Relocation against a section symbol: add in the section base address. */
relocation += BASEADDR (symbol->section);
- relocation += reloc_entry->addend;
-
where = (bfd_byte *) data + reloc_entry->address;
status = bfd_check_overflow (reloc_entry->howto->complain_on_overflow,
where + reloc_entry->howto->bitpos / 8);
}
- reloc_entry->addend = relocation;
- reloc_entry->address += input_section->output_offset;
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}