aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorCatherine Moore <clm@redhat.com>2000-03-14 18:16:05 +0000
committerCatherine Moore <clm@redhat.com>2000-03-14 18:16:05 +0000
commit4c72e23a26d7b4f5575eba00a9d4c5ee05c03a9b (patch)
treed859ed81671f770b59ef6f0d3fb46cc31e7a95a0 /bfd
parentc4d5c859ba8a93e51316459fe336137b32766364 (diff)
downloadgdb-4c72e23a26d7b4f5575eba00a9d4c5ee05c03a9b.zip
gdb-4c72e23a26d7b4f5575eba00a9d4c5ee05c03a9b.tar.gz
gdb-4c72e23a26d7b4f5575eba00a9d4c5ee05c03a9b.tar.bz2
* elf32-m32r.c (m32r_elf_lo16_reloc): Rewrite.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/elf32-m32r.c66
2 files changed, 62 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e931e32..eba4c2d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,7 @@
+2000-03-14 Doug Evans <dje@casey.transmeta.com>
+
+ * elf32-m32r.c (m32r_elf_lo16_reloc): Rewrite.
+
2000-03-14 Kazu Hirata <kazu@hxi.com>
* reloc16.c (bfd_coff_reloc16_relax_section): Count the total number
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index be6af6c..84666b6 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -498,9 +498,9 @@ m32r_elf_relocate_hi16 (input_bfd, type, relhi, rello, contents, addend)
R_M32R_HI16_[SU]LO relocation described above. */
bfd_reloc_status_type
-m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
+m32r_elf_lo16_reloc (input_bfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message)
- bfd *abfd;
+ bfd *input_bfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
@@ -508,6 +508,21 @@ m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
bfd *output_bfd;
char **error_message;
{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ unsigned long insn;
+
+ /* This part is from bfd_elf_generic_reloc.
+ If we're relocating, and this an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
if (m32r_hi16_list != NULL)
{
struct m32r_hi16 *l;
@@ -523,8 +538,8 @@ m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
/* Do the HI16 relocation. Note that we actually don't need
to know anything about the LO16 itself, except where to
find the low 16 bits of the addend needed by the LO16. */
- insn = bfd_get_32 (abfd, l->addr);
- vallo = ((bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
+ insn = bfd_get_32 (input_bfd, l->addr);
+ vallo = ((bfd_get_32 (input_bfd, (bfd_byte *) data + reloc_entry->address)
& 0xffff) ^ 0x8000) - 0x8000;
val = ((insn & 0xffff) << 16) + vallo;
val += l->addend;
@@ -534,7 +549,7 @@ m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
val += 0x10000;
insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
- bfd_put_32 (abfd, insn, l->addr);
+ bfd_put_32 (input_bfd, insn, l->addr);
next = l->next;
free (l);
@@ -544,9 +559,44 @@ m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
m32r_hi16_list = NULL;
}
- /* Now do the LO16 reloc in the usual way. */
- return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
- input_section, output_bfd, error_message);
+ /* Now do the LO16 reloc in the usual way.
+ ??? It would be nice to call bfd_elf_generic_reloc here,
+ but we have partial_inplace == TRUE. bfd_elf_generic_reloc will
+ pass the handling back to bfd_install_relocation which will install
+ a section relative addend which is wrong. */
+
+ /* Sanity check the address (offset in section). */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ ret = bfd_reloc_ok;
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ ret = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section)
+ || output_bfd != (bfd *) NULL)
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ /* Only do this for a final link. */
+ if (output_bfd == (bfd *) NULL)
+ {
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ }
+
+ relocation += reloc_entry->addend;
+
+ insn = bfd_get_32 (input_bfd, data + reloc_entry->address);
+ insn = (insn & 0xffff0000) | (relocation & 0xffff);
+ bfd_put_32 (input_bfd, insn, data + reloc_entry->address);
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
}
/* Handle the R_M32R_SDA16 reloc.