* elf32-mips.c (mips_elf_adjust_addend): New function, mostly split
	out from...
	(_bfd_mips_elf_relocate_section): ...here.  Use it to adjust r_addend
	for final links too.

ld/testsuite/
	* ld-mips/emit-relocs-1a.s, ld-mips/emit-relocs-1b.s,
	* ld-mips/emit-relocs-1.ld, ld-mips/emit-relocs-1.d: New test.
	* ld-mips/mips-elf.exp: Run it.
This commit is contained in:
Richard Sandiford 2006-03-14 07:47:49 +00:00
parent 2f83030ff5
commit 81d43bffb5
8 changed files with 159 additions and 32 deletions

View File

@ -1,3 +1,10 @@
2006-03-14 Richard Sandiford <richard@codesourcery.com>
* elf32-mips.c (mips_elf_adjust_addend): New function, mostly split
out from...
(_bfd_mips_elf_relocate_section): ...here. Use it to adjust r_addend
for final links too.
2006-03-13 Richard Sandiford <richard@codesourcery.com>
* elfxx-mips.c (mips_elf_create_got_section): Initialize hgot.

View File

@ -6934,6 +6934,48 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
return TRUE;
}
/* REL is a relocation in INPUT_BFD that is being copied to OUTPUT_BFD.
Adjust its R_ADDEND field so that it is correct for the output file.
LOCAL_SYMS and LOCAL_SECTIONS are arrays of INPUT_BFD's local symbols
and sections respectively; both use symbol indexes. */
static void
mips_elf_adjust_addend (bfd *output_bfd, struct bfd_link_info *info,
bfd *input_bfd, Elf_Internal_Sym *local_syms,
asection **local_sections, Elf_Internal_Rela *rel)
{
unsigned int r_type, r_symndx;
Elf_Internal_Sym *sym;
asection *sec;
if (mips_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE))
{
r_type = ELF_R_TYPE (output_bfd, rel->r_info);
if (r_type == R_MIPS16_GPREL
|| r_type == R_MIPS_GPREL16
|| r_type == R_MIPS_GPREL32
|| r_type == R_MIPS_LITERAL)
{
rel->r_addend += _bfd_get_gp_value (input_bfd);
rel->r_addend -= _bfd_get_gp_value (output_bfd);
}
r_symndx = ELF_R_SYM (output_bfd, rel->r_info);
sym = local_syms + r_symndx;
/* Adjust REL's addend to account for section merging. */
if (!info->relocatable)
{
sec = local_sections[r_symndx];
_bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
}
/* This would normally be done by the rela_normal code in elflink.c. */
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
rel->r_addend += local_sections[r_symndx]->output_offset;
}
}
/* Relocate a MIPS ELF section. */
bfd_boolean
@ -7084,47 +7126,19 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
else
addend = rel->r_addend;
mips_elf_adjust_addend (output_bfd, info, input_bfd,
local_syms, local_sections, rel);
}
if (info->relocatable)
{
Elf_Internal_Sym *sym;
unsigned long r_symndx;
if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)
&& bfd_big_endian (input_bfd))
rel->r_offset -= 4;
/* Since we're just relocating, all we need to do is copy
the relocations back out to the object file, unless
they're against a section symbol, in which case we need
to adjust by the section offset, or unless they're GP
relative in which case we need to adjust by the amount
that we're adjusting GP in this relocatable object. */
if (! mips_elf_local_relocation_p (input_bfd, rel, local_sections,
FALSE))
/* There's nothing to do for non-local relocations. */
continue;
if (r_type == R_MIPS16_GPREL
|| r_type == R_MIPS_GPREL16
|| r_type == R_MIPS_GPREL32
|| r_type == R_MIPS_LITERAL)
addend -= (_bfd_get_gp_value (output_bfd)
- _bfd_get_gp_value (input_bfd));
r_symndx = ELF_R_SYM (output_bfd, rel->r_info);
sym = local_syms + r_symndx;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
/* Adjust the addend appropriately. */
addend += local_sections[r_symndx]->output_offset;
if (rela_relocation_p)
/* If this is a RELA relocation, just update the addend. */
rel->r_addend = addend;
else
if (!rela_relocation_p && rel->r_addend)
{
addend += rel->r_addend;
if (r_type == R_MIPS_HI16
|| r_type == R_MIPS_GOT16)
addend = mips_elf_high (addend);

View File

@ -1,3 +1,9 @@
2006-03-14 Richard Sandiford <richard@codesourcery.com>
* ld-mips/emit-relocs-1a.s, ld-mips/emit-relocs-1b.s,
* ld-mips/emit-relocs-1.ld, ld-mips/emit-relocs-1.d: New test.
* ld-mips/mips-elf.exp: Run it.
2006-03-07 Richard Sandiford <richard@codesourcery.com>
* ld-arm/vxworks1.dd, ld-arm/vxworks1.ld, ld-arm/vxworks1-lib.dd,

View File

@ -0,0 +1,37 @@
#name: Emit relocs 1
#source: emit-relocs-1a.s -mabi=n32 -EB
#source: emit-relocs-1b.s -mabi=n32 -EB
#ld: -q -T emit-relocs-1.ld -melf32btsmipn32
#objdump: -sr
.*: file format .*
RELOCATION RECORDS FOR \[\.data\]:
OFFSET TYPE VALUE *
00000000 R_MIPS_32 \.data
00000004 R_MIPS_32 \.data\+0x00001000
00000008 R_MIPS_32 \.merge1\+0x00000002
0000000c R_MIPS_32 \.merge2
00000010 R_MIPS_32 \.merge3
00000014 R_MIPS_32 \.merge3\+0x00000004
00000020 R_MIPS_32 \.data\+0x00000020
00000024 R_MIPS_32 \.data\+0x00001020
00000028 R_MIPS_32 \.merge1
0000002c R_MIPS_32 \.merge2\+0x00000002
00000030 R_MIPS_32 \.merge3\+0x00000008
00000034 R_MIPS_32 \.merge3\+0x00000004
Contents of section \.text:
80000 03e00008 00000000 00000000 00000000 .*
Contents of section \.merge1:
80400 666c7574 74657200 flutter.*
Contents of section \.merge2:
80800 74617374 696e6700 tasting.*
Contents of section \.merge3:
80c00 00000100 00000200 00000300 .*
Contents of section \.data:
81000 00081000 00082000 00080402 00080800 .*
81010 00080c00 00080c04 00000000 00000000 .*
81020 00081020 00082020 00080400 00080802 .*
81030 00080c08 00080c04 .*

View File

@ -0,0 +1,20 @@
ENTRY(_start)
SECTIONS
{
. = 0x80000;
.text : { *(.text) }
. = ALIGN (0x400);
.merge1 : { *(.merge1) }
. = ALIGN (0x400);
.merge2 : { *(.merge2) }
. = ALIGN (0x400);
.merge3 : { *(.merge3) }
. = ALIGN (0x400);
.data : { *(.data) }
/DISCARD/ : { *(*) }
}

View File

@ -0,0 +1,22 @@
.text
.globl _start
_start:
jr $31
.section .merge1,"aMS",@progbits,1
A: .string "utter"
.section .merge2,"aMS",@progbits,1
B: .string "tasting"
.section .merge3,"aM",@progbits,4
C: .4byte 0x100
D: .4byte 0x200
.data
E: .4byte E
.4byte E + 0x1000
.4byte A
.4byte B
.4byte C
.4byte D

View File

@ -0,0 +1,17 @@
.section .merge1,"aMS",@progbits,1
A: .string "flutter"
.section .merge2,"aMS",@progbits,1
B: .string "sting"
.section .merge3,"aM",@progbits,4
C: .4byte 0x300
D: .4byte 0x200
.data
E: .4byte E
.4byte E + 0x1000
.4byte A
.4byte B
.4byte C
.4byte D

View File

@ -105,6 +105,10 @@ if { $linux_gnu } {
run_dump_test "textrel-1"
}
if $has_newabi {
run_dump_test "emit-relocs-1"
}
# For tests which may involve multiple files, use run_ld_link_tests.
# List contains test-items with 3 items followed by 2 lists: