mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-01 22:34:22 +08:00
bfd/
* elf32-arm.c (elf32_arm_final_link_relocate): Always fill in the GOT entry here, rather than leaving it to finish_dynamic_symbol. Only create a dynamic relocation for local references if info->shared. (allocate_dynrelocs_for_symbol): Update dynamic relocation allocation accordingly. (elf32_arm_finish_dynamic_symbol): Don't initialise the GOT entry here. ld/testsuite/ * ld-arm/exec-got-1a.s, ld-arm/exec-got-1b.s, ld-arm/exec-got-1.d, ld-arm/unresolved-1.s, ld-arm/unresolved-1.d, ld-arm/unresolved-1-dyn.d: New tests. * ld-arm/arm-elf.exp: Run them.
This commit is contained in:
parent
47beaa6a21
commit
b436d85411
@ -1,3 +1,13 @@
|
||||
2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* elf32-arm.c (elf32_arm_final_link_relocate): Always fill in the
|
||||
GOT entry here, rather than leaving it to finish_dynamic_symbol.
|
||||
Only create a dynamic relocation for local references if
|
||||
info->shared.
|
||||
(allocate_dynrelocs_for_symbol): Update dynamic relocation
|
||||
allocation accordingly.
|
||||
(elf32_arm_finish_dynamic_symbol): Don't initialise the GOT entry here.
|
||||
|
||||
2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* elf32-arm.c (elf32_arm_allocate_dynrelocs): New function.
|
||||
|
145
bfd/elf32-arm.c
145
bfd/elf32-arm.c
@ -8278,45 +8278,67 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
if (h != NULL)
|
||||
{
|
||||
bfd_vma off;
|
||||
bfd_boolean dyn;
|
||||
|
||||
off = h->got.offset;
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
dyn = globals->root.dynamic_sections_created;
|
||||
|
||||
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
|
||||
|| (info->shared
|
||||
&& SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
|| (ELF_ST_VISIBILITY (h->other)
|
||||
&& h->root.type == bfd_link_hash_undefweak))
|
||||
if ((off & 1) != 0)
|
||||
{
|
||||
/* This is actually a static link, or it is a -Bsymbolic link
|
||||
and the symbol is defined locally. We must initialize this
|
||||
entry in the global offset table. Since the offset must
|
||||
always be a multiple of 4, we use the least significant bit
|
||||
to record whether we have initialized it already.
|
||||
|
||||
When doing a dynamic link, we create a .rel(a).got relocation
|
||||
entry to initialize the value. This is done in the
|
||||
finish_dynamic_symbol routine. */
|
||||
if ((off & 1) != 0)
|
||||
off &= ~1;
|
||||
else
|
||||
{
|
||||
/* If we are addressing a Thumb function, we need to
|
||||
adjust the address by one, so that attempts to
|
||||
call the function pointer will correctly
|
||||
interpret it as Thumb code. */
|
||||
if (sym_flags == STT_ARM_TFUNC)
|
||||
value |= 1;
|
||||
|
||||
bfd_put_32 (output_bfd, value, sgot->contents + off);
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
/* We have already processsed one GOT relocation against
|
||||
this symbol. */
|
||||
off &= ~1;
|
||||
if (globals->root.dynamic_sections_created
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
*unresolved_reloc_p = FALSE;
|
||||
}
|
||||
else
|
||||
*unresolved_reloc_p = FALSE;
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
|
||||
if (!SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
{
|
||||
/* If the symbol doesn't resolve locally in a static
|
||||
object, we have an undefined reference. If the
|
||||
symbol doesn't resolve locally in a dynamic object,
|
||||
it should be resolved by the dynamic linker. */
|
||||
if (globals->root.dynamic_sections_created)
|
||||
{
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
|
||||
*unresolved_reloc_p = FALSE;
|
||||
}
|
||||
else
|
||||
outrel.r_info = 0;
|
||||
outrel.r_addend = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->shared)
|
||||
outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
|
||||
else
|
||||
outrel.r_info = 0;
|
||||
outrel.r_addend = value;
|
||||
if (sym_flags == STT_ARM_TFUNC)
|
||||
outrel.r_addend |= 1;
|
||||
}
|
||||
|
||||
/* The GOT entry is initialized to zero by default.
|
||||
See if we should install a different value. */
|
||||
if (outrel.r_addend != 0
|
||||
&& (outrel.r_info == 0 || globals->use_rel))
|
||||
{
|
||||
bfd_put_32 (output_bfd, outrel.r_addend,
|
||||
sgot->contents + off);
|
||||
outrel.r_addend = 0;
|
||||
}
|
||||
|
||||
if (outrel.r_info != 0)
|
||||
{
|
||||
outrel.r_offset = (sgot->output_section->vma
|
||||
+ sgot->output_offset
|
||||
+ off);
|
||||
elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
|
||||
}
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
value = sgot->output_offset + off;
|
||||
}
|
||||
else
|
||||
@ -12222,10 +12244,14 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
|
||||
if ((tls_type & GOT_TLS_GD) && indx != 0)
|
||||
elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
|
||||
}
|
||||
else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
&& (info->shared
|
||||
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
|
||||
else if (!SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
{
|
||||
if (htab->root.dynamic_sections_created)
|
||||
/* Reserve room for the GOT entry's R_ARM_GLOB_DAT relocation. */
|
||||
elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
|
||||
}
|
||||
else if (info->shared)
|
||||
/* Reserve room for the GOT entry's R_ARM_RELATIVE relocation. */
|
||||
elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
|
||||
}
|
||||
}
|
||||
@ -13016,53 +13042,6 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
if (h->got.offset != (bfd_vma) -1
|
||||
&& (! GOT_TLS_GD_ANY_P (elf32_arm_hash_entry (h)->tls_type))
|
||||
&& (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_IE) == 0)
|
||||
{
|
||||
asection * sgot;
|
||||
asection * srel;
|
||||
Elf_Internal_Rela rel;
|
||||
bfd_vma offset;
|
||||
|
||||
/* This symbol has an entry in the global offset table. Set it
|
||||
up. */
|
||||
sgot = htab->root.sgot;
|
||||
srel = htab->root.srelgot;
|
||||
BFD_ASSERT (sgot != NULL && srel != NULL);
|
||||
|
||||
offset = (h->got.offset & ~(bfd_vma) 1);
|
||||
rel.r_addend = 0;
|
||||
rel.r_offset = (sgot->output_section->vma
|
||||
+ sgot->output_offset
|
||||
+ offset);
|
||||
|
||||
/* If this is a static link, or it is a -Bsymbolic link and the
|
||||
symbol is defined locally or was forced to be local because
|
||||
of a version file, we just want to emit a RELATIVE reloc.
|
||||
The entry in the global offset table will already have been
|
||||
initialized in the relocate_section function. */
|
||||
if (info->shared
|
||||
&& SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
{
|
||||
BFD_ASSERT ((h->got.offset & 1) != 0);
|
||||
rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
|
||||
if (!htab->use_rel)
|
||||
{
|
||||
rel.r_addend = bfd_get_32 (output_bfd, sgot->contents + offset);
|
||||
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT ((h->got.offset & 1) == 0);
|
||||
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + offset);
|
||||
rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
|
||||
}
|
||||
|
||||
elf32_arm_add_dynreloc (output_bfd, info, srel, &rel);
|
||||
}
|
||||
|
||||
if (h->needs_copy)
|
||||
{
|
||||
asection * s;
|
||||
|
@ -1,3 +1,10 @@
|
||||
2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* ld-arm/exec-got-1a.s, ld-arm/exec-got-1b.s, ld-arm/exec-got-1.d,
|
||||
ld-arm/unresolved-1.s, ld-arm/unresolved-1.d,
|
||||
ld-arm/unresolved-1-dyn.d: New tests.
|
||||
* ld-arm/arm-elf.exp: Run them.
|
||||
|
||||
2011-03-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* ld-x86-64/tlsgd4.dd: New.
|
||||
|
@ -295,6 +295,14 @@ set armelftests {
|
||||
{"Data only mapping symbols" "-T data-only-map.ld -Map map" "" {data-only-map.s}
|
||||
{{objdump -dr data-only-map.d}}
|
||||
"data-only-map"}
|
||||
{"GOT relocations in executables (setup)" "-shared"
|
||||
"" {exec-got-1a.s}
|
||||
{}
|
||||
"exec-got-1.so"}
|
||||
{"GOT relocations in executables" "tmpdir/exec-got-1.so"
|
||||
"" {exec-got-1b.s}
|
||||
{{readelf --relocs exec-got-1.d}}
|
||||
"exec-got-1"}
|
||||
}
|
||||
|
||||
run_ld_link_tests $armelftests
|
||||
@ -582,3 +590,5 @@ run_dump_test "attr-merge-vfp-5r"
|
||||
run_dump_test "attr-merge-vfp-6"
|
||||
run_dump_test "attr-merge-vfp-6r"
|
||||
run_dump_test "attr-merge-incompatible"
|
||||
run_dump_test "unresolved-1"
|
||||
run_dump_test "unresolved-1-dyn"
|
||||
|
4
ld/testsuite/ld-arm/exec-got-1.d
Normal file
4
ld/testsuite/ld-arm/exec-got-1.d
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
Relocation section '\.rel\.dyn' .*
|
||||
Offset .*
|
||||
.* R_ARM_GLOB_DAT * 00000000 * foo
|
5
ld/testsuite/ld-arm/exec-got-1a.s
Normal file
5
ld/testsuite/ld-arm/exec-got-1a.s
Normal file
@ -0,0 +1,5 @@
|
||||
.globl foo
|
||||
.type foo,%object
|
||||
.size foo,4
|
||||
.data
|
||||
foo: .word 1
|
10
ld/testsuite/ld-arm/exec-got-1b.s
Normal file
10
ld/testsuite/ld-arm/exec-got-1b.s
Normal file
@ -0,0 +1,10 @@
|
||||
.globl _start
|
||||
.type _start,%function
|
||||
_start:
|
||||
ldr r1,1f
|
||||
ldr r1,2f
|
||||
1:
|
||||
.word foo(GOT)
|
||||
2:
|
||||
.word _start(GOT)
|
||||
.size _start,.-_start
|
8
ld/testsuite/ld-arm/unresolved-1-dyn.d
Normal file
8
ld/testsuite/ld-arm/unresolved-1-dyn.d
Normal file
@ -0,0 +1,8 @@
|
||||
#source: unresolved-1.s
|
||||
#ld: --warn-unresolved tmpdir/mixed-lib.so
|
||||
#warning: \(\.text\+0x8\): warning: undefined reference to `foo'
|
||||
#readelf: -r
|
||||
|
||||
Relocation section '\.rel\.dyn' .*
|
||||
Offset .*
|
||||
.* R_ARM_GLOB_DAT +00000000 +foo
|
8
ld/testsuite/ld-arm/unresolved-1.d
Normal file
8
ld/testsuite/ld-arm/unresolved-1.d
Normal file
@ -0,0 +1,8 @@
|
||||
#ld: --warn-unresolved
|
||||
#warning: \(\.text\+0x8\): warning: undefined reference to `foo'
|
||||
#objdump: -sj.rel.dyn -sj.got
|
||||
|
||||
.*
|
||||
|
||||
Contents of section \.got:
|
||||
*[^ ]* 00000000 00000000 00000000 00000000 .*
|
6
ld/testsuite/ld-arm/unresolved-1.s
Normal file
6
ld/testsuite/ld-arm/unresolved-1.s
Normal file
@ -0,0 +1,6 @@
|
||||
.globl _start
|
||||
_start:
|
||||
ldr r4,1f
|
||||
mov pc,lr
|
||||
1:
|
||||
.word foo(GOT)
|
Loading…
Reference in New Issue
Block a user