📄 001-debian.patch
字号:
+/* Copy the extra info we tack onto an elf_link_hash_entry. */++static void+elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,+ struct elf_link_hash_entry *dir,+ struct elf_link_hash_entry *ind)+{+ struct elf32_arm_link_hash_entry *edir, *eind;++ edir = (struct elf32_arm_link_hash_entry *) dir;+ eind = (struct elf32_arm_link_hash_entry *) ind;++ if (eind->relocs_copied != NULL)+ {+ if (edir->relocs_copied != NULL)+ {+ struct elf32_arm_relocs_copied **pp;+ struct elf32_arm_relocs_copied *p;++ if (ind->root.type == bfd_link_hash_indirect)+ abort ();++ /* Add reloc counts against the weak sym to the strong sym+ list. Merge any entries against the same section. */+ for (pp = &eind->relocs_copied; (p = *pp) != NULL; )+ {+ struct elf32_arm_relocs_copied *q;++ for (q = edir->relocs_copied; q != NULL; q = q->next)+ if (q->section == p->section)+ {+ q->pc_count += p->pc_count;+ q->count += p->count;+ *pp = p->next;+ break;+ }+ if (q == NULL)+ pp = &p->next;+ }+ *pp = edir->relocs_copied;+ }++ edir->relocs_copied = eind->relocs_copied;+ eind->relocs_copied = NULL;+ }++ _bfd_elf_link_hash_copy_indirect (bed, dir, ind);+}+ /* Create an ARM elf linker hash table. */ static struct bfd_link_hash_table *@@ -256,10 +421,18 @@ return NULL; } + ret->sgot = NULL;+ ret->sgotplt = NULL;+ ret->srelgot = NULL;+ ret->splt = NULL;+ ret->srelplt = NULL;+ ret->sdynbss = NULL;+ ret->srelbss = NULL; ret->thumb_glue_size = 0; ret->arm_glue_size = 0; ret->bfd_of_glue_owner = NULL; ret->no_pipeline_knowledge = 0;+ ret->sym_sec.abfd = NULL; return &ret->root.root; }@@ -1134,16 +1307,21 @@ #ifndef OLD_ARM_ABI case R_ARM_XPC25: #endif+ /* r_symndx will be zero only for relocs against symbols+ from removed linkonce sections, or sections discarded by+ a linker script. */+ if (r_symndx == 0)+ return bfd_reloc_ok;+ /* When generating a shared object, these relocations are copied into the output file to be resolved at run time. */- if (info->shared- && r_symndx != 0- && (r_type != R_ARM_PC24- || (h != NULL- && h->dynindx != -1- && (! info->symbolic- || (h->elf_link_hash_flags- & ELF_LINK_HASH_DEF_REGULAR) == 0))))+ if ((info->shared+ && (input_section->flags & SEC_ALLOC)+ && (h == NULL+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT+ || h->root.type != bfd_link_hash_undefweak)+ && (r_type != R_ARM_PC24+ || !SYMBOL_CALLS_LOCAL (info, h)))) { Elf_Internal_Rela outrel; bfd_byte *loc;@@ -1184,30 +1362,19 @@ if (skip) memset (&outrel, 0, sizeof outrel);- else if (r_type == R_ARM_PC24)- {- BFD_ASSERT (h != NULL && h->dynindx != -1);- if ((input_section->flags & SEC_ALLOC) == 0)- relocate = TRUE;- outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_PC24);- }+ else if (h != NULL+ && h->dynindx != -1+ && (r_type == R_ARM_PC24+ || !info->shared+ || !info->symbolic+ || (h->elf_link_hash_flags+ & ELF_LINK_HASH_DEF_REGULAR) == 0))+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); else {- if (h == NULL- || ((info->symbolic || h->dynindx == -1)- && (h->elf_link_hash_flags- & ELF_LINK_HASH_DEF_REGULAR) != 0))- {- relocate = TRUE;- outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);- }- else- {- BFD_ASSERT (h->dynindx != -1);- if ((input_section->flags & SEC_ALLOC) == 0)- relocate = TRUE;- outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_ABS32);- }+ /* This symbol is local, or marked to become local. */+ relocate = TRUE;+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE); } loc = sreloc->contents;@@ -1617,16 +1784,17 @@ if (h != NULL) { bfd_vma off;- bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;+ 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)+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared- && (info->symbolic || h->dynindx == -1- || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))+ && SYMBOL_REFERENCES_LOCAL (info, h))+ || (ELF_ST_VISIBILITY (h->other)+ && h->root.type == bfd_link_hash_undefweak)) { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally. We must initialize this@@ -1712,7 +1880,8 @@ contents, rel->r_offset, value, (bfd_vma) 0); - if (h->plt.offset == (bfd_vma) -1)+ if (h->plt.offset == (bfd_vma) -1+ || globals->splt == NULL) /* We didn't make a PLT entry for this symbol. This happens when statically linking PIC code, or when using -Bsymbolic. */@@ -1958,7 +2127,7 @@ bfd_put_32 (input_bfd, value, contents + rel->r_offset); } #else- relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); #endif } else@@ -1983,9 +2152,10 @@ case R_ARM_THM_PC22: if (info->shared && (- (!info->symbolic && h->dynindx != -1)+ (!info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 )+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_ARM_ABS32 relocations in its sections against symbols defined externally@@ -2603,7 +2773,82 @@ asection *sec ATTRIBUTE_UNUSED; const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; {- /* We don't support garbage collection of GOT and PLT relocs yet. */+ Elf_Internal_Shdr *symtab_hdr;+ struct elf_link_hash_entry **sym_hashes;+ bfd_signed_vma *local_got_refcounts;+ const Elf_Internal_Rela *rel, *relend;+ unsigned long r_symndx;+ struct elf_link_hash_entry *h;++ elf_section_data (sec)->local_dynrel = NULL;++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;+ sym_hashes = elf_sym_hashes (abfd);+ local_got_refcounts = elf_local_got_refcounts (abfd);++ relend = relocs + sec->reloc_count;+ for (rel = relocs; rel < relend; rel++)+ switch (ELF32_R_TYPE (rel->r_info))+ {+ case R_ARM_GOT32:+ r_symndx = ELF32_R_SYM (rel->r_info);+ if (r_symndx >= symtab_hdr->sh_info)+ {+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];+ if (h->got.refcount > 0)+ h->got.refcount -= 1;+ }+ else if (local_got_refcounts != NULL)+ {+ if (local_got_refcounts[r_symndx] > 0)+ local_got_refcounts[r_symndx] -= 1;+ }+ break;++ case R_ARM_ABS32:+ case R_ARM_REL32:+ case R_ARM_PC24:+ r_symndx = ELF32_R_SYM (rel->r_info);+ if (r_symndx >= symtab_hdr->sh_info)+ {+ struct elf32_arm_link_hash_entry *eh;+ struct elf32_arm_relocs_copied **pp;+ struct elf32_arm_relocs_copied *p;++ h = sym_hashes[r_symndx - symtab_hdr->sh_info];++ if (!info->shared && h->plt.refcount > 0)+ h->plt.refcount -= 1;++ eh = (struct elf32_arm_link_hash_entry *) h;++ for (pp = &eh->relocs_copied; (p = *pp) != NULL; pp = &p->next)+ if (p->section == sec)+ {+ if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)+ p->pc_count -= 1;+ p->count -= 1;+ if (p->count == 0)+ *pp = p->next;+ break;+ }+ }+ break;++ case R_ARM_PLT32:+ r_symndx = ELF32_R_SYM (rel->r_info);+ if (r_symndx >= symtab_hdr->sh_info)+ {+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];+ if (h->plt.refcount > 0)+ h->plt.refcount -= 1;+ }+ break;++ default:+ break;+ }+ return TRUE; } @@ -2622,13 +2867,15 @@ const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; bfd *dynobj;- asection *sgot, *srelgot, *sreloc;+ asection *sreloc; bfd_vma *local_got_offsets;+ struct elf32_arm_link_hash_table *htab; if (info->relocatable) return TRUE; - sgot = srelgot = sreloc = NULL;+ htab = elf32_arm_hash_table (info);+ sreloc = NULL; dynobj = elf_hash_table (info)->dynobj; local_got_offsets = elf_local_got_offsets (abfd);@@ -2653,126 +2900,82 @@ else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - /* Some relocs require a global offset table. */- if (dynobj == NULL)- {- switch (ELF32_R_TYPE (rel->r_info))- {- case R_ARM_GOT32:- case R_ARM_GOTOFF:- case R_ARM_GOTPC:- elf_hash_table (info)->dynobj = dynobj = abfd;- if (! _bfd_elf_create_got_section (dynobj, info))- return FALSE;- break;-- default:- break;- }- }- switch (ELF32_R_TYPE (rel->r_info)) {- case R_ARM_GOT32:- /* This symbol requires a global offset table entry. */- if (sgot == NULL)- {- sgot = bfd_get_section_by_name (dynobj, ".got");- BFD_ASSERT (sgot != NULL);- }+ case R_ARM_PLT32:+ /* This symbol requires a procedure linkage table entry. We+ actually build the entry in adjust_dynamic_symbol,+ because this might be a case of linking PIC code which is+ never referenced by a dynamic object, in which case we+ don't need to generate a procedure linkage table entry+ after all. */ - /* Get the got relocation section if necessary. */- if (srelgot == NULL- && (h != NULL || info->shared))- {- srelgot = bfd_get_section_by_name (dynobj, ".rel.got");+ /* If this is a local symbol, we resolve it directly without+ creating a procedure linkage table entry. */+ if (h == NULL)+ continue; - /* If no got relocation section, make one and initialize. */- if (srelgot == NULL)- {- srelgot = bfd_make_section (dynobj, ".rel.got");- if (srelgot == NULL- || ! bfd_set_section_flags (dynobj, srelgot,- (SEC_ALLOC- | SEC_LOAD- | SEC_HAS_CONTENTS- | SEC_IN_MEMORY- | SEC_LINKER_CREATED- | SEC_READONLY))- || ! bfd_set_section_alignment (dynobj, srelgot, 2))- return FALSE;- }- }+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;+ h->plt.refcount++;+ break; + case R_ARM_GOT32:+ /* This symbol requires a global offset table entry. */ if (h != NULL) {- if (h->got.offset != (bfd_vma) -1)- /* We have already allocated space in the .got. */- break;-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -