mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
* elf32-m32r.c (m32r_elf_generic_reloc): new function. All
HOWTO references to bfd_elf_generic_reloc, that have partial_inplace == true, now use the new function. The function is based on the recent rewrite of m32r_elf_lo16_reloc(), and extends its fixes to the R_M32R_{16,24,32} relocs. The new logic in m32r_elf_lo16_reloc() has been removed, and it instead calls the new routine to obtain that functionality.
This commit is contained in:
parent
afb2cbbd21
commit
8b125cdefa
@ -1,3 +1,13 @@
|
||||
Wed Mar 30 15:28:00 2000 Donald Lindsay <dlindsay@cygnus.com>
|
||||
|
||||
* elf32-m32r.c (m32r_elf_generic_reloc): new function. All
|
||||
HOWTO references to bfd_elf_generic_reloc, that have
|
||||
partial_inplace == true, now use the new function. The function
|
||||
is based on the recent rewrite of m32r_elf_lo16_reloc(), and
|
||||
extends its fixes to the R_M32R_{16,24,32} relocs.
|
||||
The new logic in m32r_elf_lo16_reloc() has been removed, and
|
||||
it instead calls the new routine to obtain that functionality.
|
||||
|
||||
2000-03-27 Alan Modra <alan@linuxcare.com>
|
||||
|
||||
* elf32-avr.c (elf32_avr_gc_mark_hook, elf32_avr_gc_sweep_hook,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* M32R-specific support for 32-bit ELF.
|
||||
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
@ -35,6 +35,8 @@ static void m32r_elf_relocate_hi16
|
||||
bfd_byte *, bfd_vma));
|
||||
bfd_reloc_status_type m32r_elf_lo16_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
bfd_reloc_status_type m32r_elf_generic_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
static bfd_reloc_status_type m32r_elf_sda16_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||||
@ -105,7 +107,7 @@ static reloc_howto_type m32r_elf_howto_table[] =
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
m32r_elf_generic_reloc,/* special_function */
|
||||
"R_M32R_16", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffff, /* src_mask */
|
||||
@ -120,7 +122,7 @@ static reloc_howto_type m32r_elf_howto_table[] =
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
m32r_elf_generic_reloc,/* special_function */
|
||||
"R_M32R_32", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
@ -135,7 +137,7 @@ static reloc_howto_type m32r_elf_howto_table[] =
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_unsigned, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
m32r_elf_generic_reloc,/* special_function */
|
||||
"R_M32R_24", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffffff, /* src_mask */
|
||||
@ -508,10 +510,6 @@ m32r_elf_lo16_reloc (input_bfd, 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. */
|
||||
@ -564,6 +562,44 @@ m32r_elf_lo16_reloc (input_bfd, reloc_entry, symbol, data,
|
||||
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. */
|
||||
return m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
|
||||
input_section, output_bfd, error_message);
|
||||
}
|
||||
|
||||
/* Do generic partial_inplace relocation.
|
||||
This is a local replacement for bfd_elf_generic_reloc. */
|
||||
|
||||
bfd_reloc_status_type
|
||||
m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
|
||||
input_section, output_bfd, error_message)
|
||||
bfd *input_bfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
char **error_message;
|
||||
{
|
||||
bfd_reloc_status_type ret;
|
||||
bfd_vma relocation;
|
||||
bfd_byte *inplace_address;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Now do the the 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)
|
||||
@ -588,10 +624,32 @@ m32r_elf_lo16_reloc (input_bfd, reloc_entry, symbol, data,
|
||||
}
|
||||
|
||||
relocation += reloc_entry->addend;
|
||||
inplace_address = data + reloc_entry->address;
|
||||
|
||||
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);
|
||||
#define DOIT(x) \
|
||||
x = ( (x & ~reloc_entry->howto->dst_mask) | \
|
||||
(((x & reloc_entry->howto->src_mask) + relocation) & \
|
||||
reloc_entry->howto->dst_mask))
|
||||
|
||||
switch (reloc_entry->howto->size)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
short x = bfd_get_16 (input_bfd, inplace_address);
|
||||
DOIT (x);
|
||||
bfd_put_16 (input_bfd, x, inplace_address);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
unsigned long x = bfd_get_32 (input_bfd, inplace_address);
|
||||
DOIT (x);
|
||||
bfd_put_32 (input_bfd, x, inplace_address);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BFD_ASSERT (0);
|
||||
}
|
||||
|
||||
if (output_bfd != (bfd *) NULL)
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
|
Loading…
Reference in New Issue
Block a user