| commit cc0efaa8024bd8b8774cb9f1bea0241f81e20a67 |
| Author: Marcus Shawcroft <mshawcroft@sourceware.org> |
| Date: Tue Jul 2 06:39:26 2013 +0000 |
| |
| [AArch64] Fix creation of .got and placement of _GLOBAL_OFFSET_TABLE_ |
| |
| |
| |
| @@ -5128,6 +5128,70 @@ |
| 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 |
| @@ -5370,14 +5434,10 @@ |
| } |
| } |
| |
| - 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; |
| } |
| |
| @@ -5965,7 +6025,10 @@ |
| 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; |
| @@ -5978,16 +6041,6 @@ |
| 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; |
| } |
| |