2013-07-02 Marcus Shawcroft * elf64-aarch64.c (aarch64_elf_create_got_section): New. (elf64_aarch64_check_relocs): Use aarch64_elf_create_got_section. (elf64_aarch64_create_dynamic_sections): Do not define _GLOBAL_OFFSET_TABLE_; call aarch64_elf_create_got_section. ld/testsuite/ * 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. 2013-07-02 Marcus Shawcroft * ld-aarch64/emit-relocs-309-low.d: Adjust .text address. * ld-aarch64/emit-relocs-309-up.d: Adjust .got address. * ld-aarch64/emit-relocs-312.d: Adjust offsets into .got. * ld-aarch64/tls-relax-all.d: Likewise. * ld-aarch64/gc-got-relocs.d: Adjust expected .got content. * ld-aarch64/gc-tls-relocs.d: Likewise. * ld-aarch64/tls-relax-gd-ie.d: Likewise. * ld-aarch64/tls-relax-gdesc-ie-2.d: Likewise. * ld-aarch64/tls-relax-gdesc-ie.d: Likewise. 2013-06-27 Marcus Shawcroft * elf64-aarch64.c (elf64_aarch64_check_relocs): Reserve one slot in sgot. (elf64_aarch64_finish_dynamic_sections): Place the &_DYNAMIC reference in sgot[0] rather than sgotplt[0]. Index: binutils-2.23.2/bfd/elf64-aarch64.c =================================================================== --- binutils-2.23.2.orig/bfd/elf64-aarch64.c +++ binutils-2.23.2/bfd/elf64-aarch64.c @@ -5077,6 +5077,70 @@ elf64_aarch64_allocate_local_symbols (bf 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 @@ -5315,13 +5379,10 @@ elf64_aarch64_check_relocs (bfd *abfd, s } } - 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; - } + if (htab->root.dynobj == NULL) + htab->root.dynobj = abfd; + if (! aarch64_elf_create_got_section (htab->root.dynobj, info)) + return FALSE; break; } @@ -5908,7 +5969,10 @@ elf64_aarch64_create_dynamic_sections (b struct bfd_link_info *info) { struct elf64_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; @@ -5921,16 +5985,6 @@ elf64_aarch64_create_dynamic_sections (b 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; } @@ -6939,15 +6993,8 @@ elf64_aarch64_finish_dynamic_sections (b /* Fill in the first three entries in the global offset table. */ if (htab->root.sgotplt->size > 0) { - /* Set the first entry in the global offset table to the address of - the dynamic section. */ - if (sdyn == NULL) - bfd_put_64 (output_bfd, (bfd_vma) 0, - htab->root.sgotplt->contents); - else - bfd_put_64 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - htab->root.sgotplt->contents); + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents); + /* Write GOT[1] and GOT[2], needed for the dynamic linker. */ bfd_put_64 (output_bfd, (bfd_vma) 0, @@ -6957,6 +7004,16 @@ elf64_aarch64_finish_dynamic_sections (b htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2); } + if (htab->root.sgot) + { + if (htab->root.sgot->size > 0) + { + bfd_vma addr = + sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0; + bfd_put_64 (output_bfd, addr, htab->root.sgot->contents); + } + } + elf_section_data (htab->root.sgotplt->output_section)-> this_hdr.sh_entsize = GOT_ENTRY_SIZE; } Index: binutils-2.23.2/ld/testsuite/ld-aarch64/emit-relocs-311.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/emit-relocs-311.d +++ binutils-2.23.2/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 +10010: R_AARCH64_ADR_PREL_PG_HI21 tempy3 - +10014: 90000083 adrp x3, 20000 + +10014: 90000083 adrp x3, 20000 <_GLOBAL_OFFSET_TABLE_> +10014: R_AARCH64_ADR_GOT_PAGE gempy Index: binutils-2.23.2/ld/testsuite/ld-aarch64/emit-relocs-312.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/emit-relocs-312.d +++ binutils-2.23.2/ld/testsuite/ld-aarch64/emit-relocs-312.d @@ -10,10 +10,10 @@ +1000c: R_AARCH64_LD_PREL_LO19 tempy2 +10010: 58f89131 ldr x17, 1234 +10010: R_AARCH64_LD_PREL_LO19 tempy3 - +10014: f9400843 ldr x3, \[x2.* + +10014: f9400c43 ldr x3, \[x2.* +10014: R_AARCH64_LD64_GOT_LO12_NC jempy - +10018: f9400444 ldr x4, \[x2.* + +10018: f9400844 ldr x4, \[x2.* +10018: R_AARCH64_LD64_GOT_LO12_NC gempy - +1001c: f9400045 ldr x5, \[x2.* + +1001c: f9400445 ldr x5, \[x2.* +1001c: R_AARCH64_LD64_GOT_LO12_NC lempy Index: binutils-2.23.2/ld/testsuite/ld-aarch64/tls-desc-ie.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/tls-desc-ie.d +++ binutils-2.23.2/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 +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 Index: binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-all.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/tls-relax-all.d +++ binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-all.d @@ -4,8 +4,8 @@ #... +10000: a9bf7bfd stp x29, x30, \[sp,#-16\]! +10004: 910003fd mov x29, sp - +10008: 90000080 adrp x0, 20000 - +1000c: f9400000 ldr x0, \[x0\] + +10008: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_> + +1000c: f9400400 ldr x0, \[x0,#8\] +10010: d503201f nop +10014: d503201f nop +10018: d53bd041 mrs x1, tpidr_el0 @@ -19,8 +19,8 @@ +10038: 8b000040 add x0, x2, x0 +1003c: b9400000 ldr w0, \[x0\] +10040: 0b000021 add w1, w1, w0 - +10044: 90000080 adrp x0, 20000 - +10048: f9400400 ldr x0, \[x0,#8\] + +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 +10054: b9400000 ldr w0, \[x0\] Index: binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d +++ binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-gd-ie.d @@ -2,8 +2,8 @@ #ld: -T relocs.ld -e0 #objdump: -dr #... - +10000: 90000080 adrp x0, 20000 - +10004: f9400000 ldr x0, \[x0\] + +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 +10010: b9400000 ldr w0, \[x0\] Index: binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d +++ binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie-2.d @@ -2,9 +2,9 @@ #ld: -T relocs.ld -e0 #objdump: -dr #... - +10000: 90000080 adrp x0, 20000 + +10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_> +10004: d503201f nop - +10008: f9400000 ldr x0, \[x0\] + +10008: f9400400 ldr x0, \[x0,#8\] +1000c: d503201f nop +10010: d503201f nop +10014: d503201f nop Index: binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d =================================================================== --- binutils-2.23.2.orig/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d +++ binutils-2.23.2/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.d @@ -2,8 +2,8 @@ #ld: -T relocs.ld -e0 #objdump: -dr #... - +10000: 90000080 adrp x0, 20000 - +10004: f9400000 ldr x0, \[x0\] + +10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_> + +10004: f9400400 ldr x0, \[x0,#8\] +10008: d503201f nop +1000c: d503201f nop +10010: d53bd041 mrs x1, tpidr_el0