Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/gnu/dist/toolchain Pull up changes from binutils master sources
details: https://anonhg.NetBSD.org/src/rev/8928d2847a3b
branches: trunk
changeset: 542824:8928d2847a3b
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Sat Feb 08 17:09:35 2003 +0000
description:
Pull up changes from binutils master sources
<http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/?cvsroot=src>
to fix relocation problem on linking startup routines for sh3:
src/bfd/elf32-sh.c revision 1.36:
> * elf32-sh.c (sh_elf_howto_table, R_SH_REL32): Make
> partial_inplace, matching assembler output. Set src_mask to
> all ones.
> (sh_elf_relocate_section): Delete misplaced comment.
> For relocatable linking against section symbol, call
> _bfd_relocate_contents for partial_inplace relocs and adjust
> rel->r_addend for others.
> <case R_SH_DIR32, R_SH_REL32>: Fetch partial_inplace addend with
> bfd_get_32, not at rel->r_addend.
src/gas/config/tc-sh.c revision 1.43:
> * config/tc-sh.c (md_pcrel_from_section): Transformed from
> md_pcrel_from. Handle pc-relativeness against link-time
> symbol. Handle relativeness to elsewhere than the fixup.
src/gas/config/tc-sh.h revision 1.14:
> * config/tc-sh.h (MD_PCREL_FROM_SECTION): Define.
> (md_pcrel_from_section): Prototype.
Thanks to Kaz Kojima and Jason R Thorpe for their comments.
diffstat:
gnu/dist/toolchain/bfd/elf32-sh.c | 51 ++++++++++++++++++++++++++++------
gnu/dist/toolchain/gas/config/tc-sh.c | 16 ++++++++++-
gnu/dist/toolchain/gas/config/tc-sh.h | 3 ++
3 files changed, 60 insertions(+), 10 deletions(-)
diffs (150 lines):
diff -r 09088cfa9d54 -r 8928d2847a3b gnu/dist/toolchain/bfd/elf32-sh.c
--- a/gnu/dist/toolchain/bfd/elf32-sh.c Sat Feb 08 12:06:13 2003 +0000
+++ b/gnu/dist/toolchain/bfd/elf32-sh.c Sat Feb 08 17:09:35 2003 +0000
@@ -121,8 +121,8 @@
complain_overflow_signed, /* complain_on_overflow */
sh_elf_ignore_reloc, /* special_function */
"R_SH_REL32", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
true), /* pcrel_offset */
@@ -2918,7 +2918,11 @@
howto = sh_elf_howto_table + r_type;
- /* This is a final link. */
+ /* For relocs that aren't partial_inplace, we get the addend from
+ the relocation. */
+ if (! howto->partial_inplace)
+ addend = rel->r_addend;
+
h = NULL;
sym = NULL;
sec = NULL;
@@ -2938,7 +2942,32 @@
section symbol winds up in the output section. */
sym = local_syms + r_symndx;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
- goto final_link_relocate;
+ {
+ if (! howto->partial_inplace)
+ {
+ /* For relocations with the addend in the
+ relocation, we need just to update the addend.
+ All real relocs are of type partial_inplace; this
+ code is mostly for completeness. */
+ rel->r_addend += sec->output_offset + sym->st_value;
+
+ continue;
+ }
+
+ /* Relocs of type partial_inplace need to pick up the
+ contents in the contents and add the offset resulting
+ from the changed location of the section symbol.
+ Using _bfd_final_link_relocate (e.g. goto
+ final_link_relocate) here would be wrong, because
+ relocations marked pc_relative would get the current
+ location subtracted, and we must only do that at the
+ final link. */
+ r = _bfd_relocate_contents (howto, input_bfd,
+ sec->output_offset
+ + sym->st_value,
+ contents + rel->r_offset);
+ goto relocation_done;
+ }
continue;
}
@@ -3111,7 +3140,8 @@
BFD_ASSERT (h != NULL && h->dynindx != -1);
relocate = false;
outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32);
- outrel.r_addend = rel->r_addend;
+ outrel.r_addend
+ = bfd_get_32 (input_bfd, contents + rel->r_offset);
}
else
{
@@ -3124,14 +3154,18 @@
{
relocate = true;
outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
- outrel.r_addend = relocation + rel->r_addend;
+ outrel.r_addend
+ = relocation + bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
}
else
{
BFD_ASSERT (h->dynindx != -1);
relocate = false;
outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32);
- outrel.r_addend = relocation + rel->r_addend;
+ outrel.r_addend
+ = relocation + bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
}
}
@@ -3148,8 +3182,6 @@
if (! relocate)
continue;
}
- else if (r_type == R_SH_DIR32)
- addend = rel->r_addend;
goto final_link_relocate;
case R_SH_GOT32:
@@ -3329,6 +3361,7 @@
}
}
+ relocation_done:
if (r != bfd_reloc_ok)
{
switch (r)
diff -r 09088cfa9d54 -r 8928d2847a3b gnu/dist/toolchain/gas/config/tc-sh.c
--- a/gnu/dist/toolchain/gas/config/tc-sh.c Sat Feb 08 12:06:13 2003 +0000
+++ b/gnu/dist/toolchain/gas/config/tc-sh.c Sat Feb 08 17:09:35 2003 +0000
@@ -3136,9 +3136,23 @@
}
long
-md_pcrel_from (fixP)
+md_pcrel_from_section (fixP, sec)
fixS *fixP;
+ segT sec;
{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_IS_EXTERN (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != sec))
+ {
+ /* The symbol is undefined (or is defined but not in this section,
+ or we're not sure about it being the final definition). Let the
+ linker figure it out. We need to adjust the subtraction of a
+ symbol to the position of the relocated data, though. */
+ return fixP->fx_subsy ? fixP->fx_where + fixP->fx_frag->fr_address : 0;
+ }
+
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address + 2;
}
diff -r 09088cfa9d54 -r 8928d2847a3b gnu/dist/toolchain/gas/config/tc-sh.h
--- a/gnu/dist/toolchain/gas/config/tc-sh.h Sat Feb 08 12:06:13 2003 +0000
+++ b/gnu/dist/toolchain/gas/config/tc-sh.h Sat Feb 08 17:09:35 2003 +0000
@@ -70,6 +70,9 @@
#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP)
#endif
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
#define IGNORE_NONSTANDARD_ESCAPES
#define LISTING_HEADER (!target_big_endian ? "Hitachi Super-H GAS Little Endian" : "Hitachi Super-H GAS Big Endian")
Home |
Main Index |
Thread Index |
Old Index