This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[AArch64] Fix the creation of .got and _GLOBAL_OFFSET_TABLE_ placement.
- From: Marcus Shawcroft <marcus dot shawcroft at arm dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Mon, 01 Jul 2013 17:43:53 +0100
- Subject: [AArch64] Fix the creation of .got and _GLOBAL_OFFSET_TABLE_ placement.
Hi,
My recent patch: http://sourceware.org/ml/binutils/2013-06/msg00248.html
to place &_DYNAMIC in .got[0] instead of .gotplt[0] exposes an issue in
the placement of the _GLOBAL_OFFSET_TABLE_ symbol.
The AArch64 back end has code in elfNN_aarch64_create_dynamic_sections
to place _GLOBAL_OFFSET_TABLE_ at got[0]. However, the .got section is
initially created by a call to the generic _bfd_elf_create_got_section
which contains code to place the symbol at gotplt[0]. The overall
effect is that the symbol placement changes dependent on whether
elfNN_aarch64_create_dynamic_sections is called for an object.
This patch follows the MIPs approach and defines a target specific
alternative to _bfd_elf_create_got_section and drops the bogus code from
elfNN_aarch64_create_dynamic_sections.
Regressed on aarch64-none-linux-gnu.
/Marcus
2013-07-01 Marcus Shawcroft <marcus.shawcroft@arm.com>
* elfnn-aarch64.c (aarch64_elf_create_got_section): New.
(elfNN_aarch64_check_relocs): Use aarch64_elf_create_got_section.
(elfNN_aarch64_create_dynamic_sections): Do not define
_GLOBAL_OFFSET_TABLE_; call aarch64_elf_create_got_section.
/ld/testsuite/ChangeLog
2013-07-01 Marcus Shawcroft <marcus.shawcroft@arm.com>
* ld-aarch64/gc-plt-relocs.d: Adjust expected .got offsets.
* ld-aarch64/tls-desc-ie.d: Likewise.
* ld-aarch64/emit-relocs-311.d: Adjust expected symbol.
* ld-aarch64/tls-relax-all.d: Likewise.
* ld-aarch64/tls-relax-gd-ie.d: Likewise.
* ld-aarch64/tls-relax-gdesc-ie.d: Likewise.
* ld-aarch64/tls-relax-gdesc-ie-2.d: Likewise.
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 1eda859..dcc6f27 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4647,6 +4647,70 @@ elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
return TRUE;
}
+/* Create the .got section to hold the global offset table. */
+
+static bfd_boolean
+aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ flagword flags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.got" : ".rel.got"),
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->srelgot = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->sgot = s;
+ htab->sgot->size += GOT_ENTRY_SIZE;
+
+ if (bed->want_got_sym)
+ {
+ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
+ (or .got.plt) section. We don't do this in the linker script
+ because we don't want to define the symbol if we are not creating
+ a global offset table. */
+ h = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->sgotplt = s;
+ }
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ return TRUE;
+}
+
/* Look through the relocs for a section during the first phase. */
static bfd_boolean
@@ -4880,14 +4944,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
}
}
- if (htab->root.sgot == NULL)
- {
- if (htab->root.dynobj == NULL)
- htab->root.dynobj = abfd;
- if (!_bfd_elf_create_got_section (htab->root.dynobj, info))
- return FALSE;
- htab->root.sgot->size += GOT_ENTRY_SIZE;
- }
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
+ return FALSE;
break;
}
@@ -5481,7 +5541,10 @@ elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
struct bfd_link_info *info)
{
struct elf_aarch64_link_hash_table *htab;
- struct elf_link_hash_entry *h;
+
+ /* We need to create .got section. */
+ if (!aarch64_elf_create_got_section (dynobj, info))
+ return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
@@ -5494,16 +5557,6 @@ elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
if (!htab->sdynbss || (!info->shared && !htab->srelbss))
abort ();
- /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
- dynobj's .got section. We don't do this in the linker script
- because we don't want to define the symbol if we are not creating
- a global offset table. */
- h = _bfd_elf_define_linkage_sym (dynobj, info,
- htab->root.sgot, "_GLOBAL_OFFSET_TABLE_");
- elf_hash_table (info)->hgot = h;
- if (h == NULL)
- return FALSE;
-
return TRUE;
}
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-311.d b/ld/testsuite/ld-aarch64/emit-relocs-311.d
index 5f1b47f..578d6d3 100644
--- a/ld/testsuite/ld-aarch64/emit-relocs-311.d
+++ b/ld/testsuite/ld-aarch64/emit-relocs-311.d
@@ -10,5 +10,5 @@
+1000c: R_AARCH64_ADR_PREL_PG_HI21 tempy2
+10010: b0ffff91 adrp x17, 1000 <tempy3-0x234>
+10010: R_AARCH64_ADR_PREL_PG_HI21 tempy3
- +10014: 90000083 adrp x3, 20000 <tempy[+]0xf000>
+ +10014: 90000083 adrp x3, 20000 <_GLOBAL_OFFSET_TABLE_>
+10014: R_AARCH64_ADR_GOT_PAGE gempy
diff --git a/ld/testsuite/ld-aarch64/gc-plt-relocs.d b/ld/testsuite/ld-aarch64/gc-plt-relocs.d
index 6c4d3ca..cb38c8d 100644
--- a/ld/testsuite/ld-aarch64/gc-plt-relocs.d
+++ b/ld/testsuite/ld-aarch64/gc-plt-relocs.d
@@ -36,13 +36,13 @@ Disassembly of section .plt:
0+8010 \<\.plt\>:
8010: a9bf7bf0 stp x16, x30, \[sp,#-16\]!
8014: b0000010 adrp x16, 9000 .*
- 8018: f9400a11 ldr x17, \[x16,#16\]
- 801c: 91004210 add x16, x16, #0x10
+ 8018: f9400e11 ldr x17, \[x16,#24\]
+ 801c: 91006210 add x16, x16, #0x18
8020: d61f0220 br x17
8024: d503201f nop
8028: d503201f nop
802c: d503201f nop
8030: b0000010 adrp x16, 9000 .*
- 8034: f9400e11 ldr x17, \[x16,#24\]
- 8038: 91006210 add x16, x16, #0x18
+ 8034: f9401211 ldr x17, \[x16,#32\]
+ 8038: 91008210 add x16, x16, #0x20
803c: d61f0220 br x17
diff --git a/ld/testsuite/ld-aarch64/tls-desc-ie.d b/ld/testsuite/ld-aarch64/tls-desc-ie.d
index 712e39c..037da07 100644
--- a/ld/testsuite/ld-aarch64/tls-desc-ie.d
+++ b/ld/testsuite/ld-aarch64/tls-desc-ie.d
@@ -3,18 +3,18 @@
#objdump: -dr
#...
+10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10004: 91002000 add x0, x0, #0x8
+ +10004: 91004000 add x0, x0, #0x10
+10008: 94000016 bl 10060 <v1\+0x10060>
+1000c: d503201f nop
+10010: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10014: f9400000 ldr x0, \[x0\]
+ +10014: f9400400 ldr x0, \[x0,#8\]
+10018: d503201f nop
+1001c: d503201f nop
+10020: d53bd041 mrs x1, tpidr_el0
+10024: 8b000020 add x0, x1, x0
+10028: d53bd042 mrs x2, tpidr_el0
+1002c: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10030: f9400000 ldr x0, \[x0\]
+ +10030: f9400400 ldr x0, \[x0,#8\]
+10034: 8b000040 add x0, x2, x0
+10038: b9400000 ldr w0, \[x0\]
+1003c: 0b000020 add w0, w1, w0
@@ -24,13 +24,13 @@ Disassembly of section .plt:
0000000000010040 <.plt>:
+10040: a9bf7bf0 stp x16, x30, \[sp,#-16\]!
+10044: 90000090 adrp x16, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10048: f9401611 ldr x17, \[x16,#40\]
- +1004c: 9100a210 add x16, x16, #0x28
+ +10048: f9401a11 ldr x17, \[x16,#48\]
+ +1004c: 9100c210 add x16, x16, #0x30
+10050: d61f0220 br x17
+10054: d503201f nop
+10058: d503201f nop
+1005c: d503201f nop
+10060: 90000090 adrp x16, 20000 <_GLOBAL_OFFSET_TABLE_>
- +10064: f9401a11 ldr x17, \[x16,#48\]
- +10068: 9100c210 add x16, x16, #0x30
+ +10064: f9401e11 ldr x17, \[x16,#56\]
+ +10068: 9100e210 add x16, x16, #0x38
+1006c: d61f0220 br x17
diff --git a/ld/testsuite/ld-aarch64/tls-relax-all.d b/ld/testsuite/ld-aarch64/tls-relax-all.d
index f8485f1..b36b634 100644
--- a/ld/testsuite/ld-aarch64/tls-relax-all.d
+++ b/ld/testsuite/ld-aarch64/tls-relax-all.d
@@ -4,7 +4,7 @@
#...
+10000: a9bf7bfd stp x29, x30, \[sp,#-16\]!
+10004: 910003fd mov x29, sp
- +10008: 90000080 adrp x0, 20000 <ie_var\+0x1fff0>
+ +10008: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+1000c: f9400400 ldr x0, \[x0,#8\]
+10010: d503201f nop
+10014: d503201f nop
@@ -19,7 +19,7 @@
+10038: 8b000040 add x0, x2, x0
+1003c: b9400000 ldr w0, \[x0\]
+10040: 0b000021 add w1, w1, w0
- +10044: 90000080 adrp x0, 20000 <ie_var\+0x1fff0>
+ +10044: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+10048: f9400800 ldr x0, \[x0,#16\]
+1004c: d53bd041 mrs x1, tpidr_el0
+10050: 8b000020 add x0, x1, x0
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d b/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d
index 2dc00ca..d3783ac 100644
--- a/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d
+++ b/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d
@@ -2,7 +2,7 @@
#ld: -T relocs.ld -e0
#objdump: -dr
#...
- +10000: 90000080 adrp x0, 20000 <var\+0x20000>
+ +10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+10004: f9400400 ldr x0, \[x0,#8\]
+10008: d53bd041 mrs x1, tpidr_el0
+1000c: 8b000020 add x0, x1, x0
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d
index 23d9d1d..92002de 100644
--- a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d
+++ b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d
@@ -2,7 +2,7 @@
#ld: -T relocs.ld -e0
#objdump: -dr
#...
- +10000: 90000080 adrp x0, 20000 <var\+0x20000>
+ +10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+10004: d503201f nop
+10008: f9400400 ldr x0, \[x0,#8\]
+1000c: d503201f nop
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d
index 3aec3ad..634a55a 100644
--- a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d
+++ b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d
@@ -2,7 +2,7 @@
#ld: -T relocs.ld -e0
#objdump: -dr
#...
- +10000: 90000080 adrp x0, 20000 <var\+0x20000>
+ +10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+10004: f9400400 ldr x0, \[x0,#8\]
+10008: d503201f nop
+1000c: d503201f nop