X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Farc-got.h;h=762d84dab09672f33893bed692eda8cb1ee6ff60;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=b8a6d15a2273cb498e02eb67708bef3c60769157;hpb=535b785fb0c97220dea23a18f07baad6b5d77ae5;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/arc-got.h b/bfd/arc-got.h index b8a6d15a22..762d84dab0 100644 --- a/bfd/arc-got.h +++ b/bfd/arc-got.h @@ -1,5 +1,5 @@ /* ARC-specific support for 32-bit ELF - Copyright (C) 1994-2017 Free Software Foundation, Inc. + Copyright (C) 1994-2020 Free Software Foundation, Inc. Contributed by Cupertino Miranda (cmiranda@synopsys.com). This file is part of BFD, the Binary File Descriptor library. @@ -22,6 +22,11 @@ #ifndef ARC_GOT_H #define ARC_GOT_H +#define TCB_SIZE (8) + +#define align_power(addr, align) \ + (((addr) + ((bfd_vma) 1 << (align)) - 1) & (-((bfd_vma) 1 << (align)))) + enum tls_type_e { GOT_UNKNOWN = 0, @@ -49,27 +54,26 @@ struct got_entry enum tls_got_entries existing_entries; }; +/* Return the local got list, if not defined, create an empty one. */ + static struct got_entry ** arc_get_local_got_ents (bfd * abfd) { - static struct got_entry **local_got_ents = NULL; - - if (local_got_ents == NULL) + if (elf_local_got_ents (abfd) == NULL) { - size_t size; - Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr); - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_ents = (struct got_entry **) - bfd_alloc (abfd, sizeof (struct got_entry *) * size); - if (local_got_ents == NULL) - return FALSE; - - memset (local_got_ents, 0, sizeof (struct got_entry *) * size); - elf_local_got_ents (abfd) = local_got_ents; + bfd_size_type amt = (elf_tdata (abfd)->symtab_hdr.sh_info + * sizeof (*elf_local_got_ents (abfd))); + elf_local_got_ents (abfd) = bfd_zmalloc (amt); + if (elf_local_got_ents (abfd) == NULL) + { + _bfd_error_handler (_("%pB: cannot allocate memory for local " + "GOT entries"), abfd); + bfd_set_error (bfd_error_bad_value); + return NULL; + } } - return local_got_ents; + return elf_local_got_ents (abfd); } static struct got_entry * @@ -154,15 +158,15 @@ get_got_entry_list_for_symbol (bfd *abfd, unsigned long r_symndx, struct elf_link_hash_entry *h) { - if (h != NULL) + struct elf_arc_link_hash_entry *h1 = + ((struct elf_arc_link_hash_entry *) h); + if (h1 != NULL) { - return &h->got.glist; + return &h1->got_ents; } else { - struct got_entry **local_got_ents - = arc_get_local_got_ents (abfd); - return &local_got_ents[r_symndx]; + return arc_get_local_got_ents (abfd) + r_symndx; } } @@ -204,7 +208,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto) __LINE__, name_for_global_symbol (H)); \ } \ if (H) \ - if (h->dynindx == -1 && !h->forced_local) \ + if (H->dynindx == -1 && !H->forced_local) \ if (! bfd_elf_link_record_dynamic_symbol (info, H)) \ return FALSE; \ htab->s##SECNAME->size += 4; \ @@ -225,10 +229,10 @@ arc_fill_got_info_for_reloc (enum tls_type_e type, { case GOT_NORMAL: { - bfd_vma offset + bfd_vma offset = ADD_SYMBOL_REF_SEC_AND_RELOC (got, bfd_link_pic (info) || h != NULL, h); - new_got_entry_to_list (list, type, offset, TLS_GOT_NONE); + new_got_entry_to_list (list, type, offset, TLS_GOT_NONE); } break; @@ -260,14 +264,14 @@ arc_fill_got_info_for_reloc (enum tls_type_e type, static bfd_vma -relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, - enum tls_type_e type, - struct bfd_link_info * info, - bfd * output_bfd, - unsigned long r_symndx, - Elf_Internal_Sym * local_syms, - asection ** local_sections, - struct elf_link_hash_entry * h, +relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, + enum tls_type_e type, + struct bfd_link_info * info, + bfd * output_bfd, + unsigned long r_symndx, + Elf_Internal_Sym * local_syms, + asection ** local_sections, + struct elf_link_hash_entry * h, struct arc_relocation_data * reloc_data) { struct elf_link_hash_table *htab = elf_hash_table (info); @@ -280,6 +284,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, BFD_ASSERT (entry); if (h == NULL + || h->forced_local == TRUE || (! elf_hash_table (info)->dynamic_sections_created || (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)))) @@ -327,23 +332,31 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, BFD_ASSERT (tls_sec && tls_sec->output_section); bfd_vma sec_vma = tls_sec->output_section->vma; - bfd_put_32 (output_bfd, - sym_value - sec_vma, + if (h == NULL || h->forced_local + || !elf_hash_table (info)->dynamic_sections_created) + { + bfd_put_32 (output_bfd, + sym_value - sec_vma + + (elf_hash_table (info)->dynamic_sections_created + ? 0 + : (align_power (0, + tls_sec->alignment_power))), htab->sgot->contents + entry->offset + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0)); - ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx " - "@ %lx, for symbol %s\n", - (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" : - "GOT_TLS_IE"), - (long) (sym_value - sec_vma), - (long) (htab->sgot->output_section->vma - + htab->sgot->output_offset->vma - + entry->offset - + (entry->existing_entries == TLS_GOT_MOD_AND_OFF - ? 4 : 0)), - symbol_name); + ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx " + "@ %lx, for symbol %s\n", + (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" : + "GOT_TLS_IE"), + (long) (sym_value - sec_vma), + (long) (htab->sgot->output_section->vma + + htab->sgot->output_offset + + entry->offset + + (entry->existing_entries == TLS_GOT_MOD_AND_OFF + ? 4 : 0)), + symbol_name); + } } break; @@ -354,7 +367,11 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, = tls_sec->output_section->vma; bfd_put_32 (output_bfd, - sym_value - sec_vma, + sym_value - sec_vma + + (elf_hash_table (info)->dynamic_sections_created + ? 0 + : (align_power (TCB_SIZE, + tls_sec->alignment_power))), htab->sgot->contents + entry->offset + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0)); @@ -365,7 +382,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, "GOT_TLS_IE"), (long) (sym_value - sec_vma), (long) (htab->sgot->output_section->vma - + htab->sgot->output_offset->vma + + htab->sgot->output_offset + entry->offset + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0)), @@ -457,14 +474,14 @@ create_got_dynrelocs_for_single_entry (struct got_entry *list, enum tls_got_entries e = list->existing_entries; BFD_ASSERT (list->type != GOT_TLS_GD - || list->existing_entries == TLS_GOT_MOD_AND_OFF); + || list->existing_entries == TLS_GOT_MOD_AND_OFF); bfd_vma dynindx = (h == NULL || h->dynindx == -1) ? 0 : h->dynindx; if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD) { ADD_RELA (output_bfd, got, got_offset, dynindx, - R_ARC_TLS_DTPMOD, 0); + R_ARC_TLS_DTPMOD, 0); ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \ GOT_OFFSET = %#lx, GOT_VMA = %#lx, INDEX = %ld, ADDEND = 0x0\n", list->type, @@ -478,8 +495,10 @@ GOT_OFFSET = %#lx, GOT_VMA = %#lx, INDEX = %ld, ADDEND = 0x0\n", { bfd_vma addend = 0; if (list->type == GOT_TLS_IE) + { addend = bfd_get_32 (output_bfd, htab->sgot->contents + got_offset); + } ADD_RELA (output_bfd, got, got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0), @@ -504,7 +523,7 @@ static void create_got_dynrelocs_for_got_info (struct got_entry **list_p, bfd *output_bfd, struct bfd_link_info * info, - struct elf_link_hash_entry *h) + struct elf_link_hash_entry *h) { if (list_p == NULL) return;