📄 001-debian.patch
字号:
- h->got.offset = sgot->_raw_size;-- /* Make sure this symbol is output as a dynamic symbol. */- if (h->dynindx == -1)- if (! bfd_elf32_link_record_dynamic_symbol (info, h))- return FALSE;-- srelgot->_raw_size += sizeof (Elf32_External_Rel);+ h->got.refcount++; } else {- /* This is a global offset table entry for a local- symbol. */- if (local_got_offsets == NULL)+ bfd_signed_vma *local_got_refcounts;++ /* This is a global offset table entry for a local symbol. */+ local_got_refcounts = elf_local_got_refcounts (abfd);+ if (local_got_refcounts == NULL) { bfd_size_type size;- unsigned int i; size = symtab_hdr->sh_info;- size *= sizeof (bfd_vma);- local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);- if (local_got_offsets == NULL)+ size *= (sizeof (bfd_signed_vma) + sizeof(char));+ local_got_refcounts = ((bfd_signed_vma *)+ bfd_zalloc (abfd, size));+ if (local_got_refcounts == NULL) return FALSE;- elf_local_got_offsets (abfd) = local_got_offsets;- for (i = 0; i < symtab_hdr->sh_info; i++)- local_got_offsets[i] = (bfd_vma) -1;+ elf_local_got_refcounts (abfd) = local_got_refcounts; }-- if (local_got_offsets[r_symndx] != (bfd_vma) -1)- /* We have already allocated space in the .got. */- break;-- local_got_offsets[r_symndx] = sgot->_raw_size;-- if (info->shared)- /* If we are generating a shared object, we need to- output a R_ARM_RELATIVE reloc so that the dynamic- linker can adjust this GOT entry. */- srelgot->_raw_size += sizeof (Elf32_External_Rel);+ local_got_refcounts[r_symndx] += 1; }-- sgot->_raw_size += 4; break; - 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. */-- /* If this is a local symbol, we resolve it directly without- creating a procedure linkage table entry. */- if (h == NULL)- continue;-- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;+ case R_ARM_GOTOFF:+ case R_ARM_GOTPC:+ if (htab->sgot == NULL)+ {+ if (htab->root.dynobj == NULL)+ htab->root.dynobj = abfd;+ if (!create_got_section (htab->root.dynobj, info))+ return FALSE;+ } break; case R_ARM_ABS32: case R_ARM_REL32: case R_ARM_PC24:+ if (h != NULL && !info->shared)+ {+ /* If this reloc is in a read-only section, we might+ need a copy reloc. We can't check reliably at this+ stage whether the section is read-only, as input+ sections have not yet been mapped to output sections.+ Tentatively set the flag for now, and correct in+ adjust_dynamic_symbol. */+ h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;+ + /* We may need a .plt entry if the function this reloc+ refers to is in a shared lib. */+ h->plt.refcount += 1;+ }+ /* If we are creating a shared library, and this is a reloc against a global symbol, or a non PC relative reloc against a local symbol, then we need to copy the reloc@@ -2784,14 +2987,17 @@ possible that DEF_REGULAR is not set now but will be set later (it is never cleared). We account for that possibility below by storing information in the- pcrel_relocs_copied field of the hash table entry. */+ relocs_copied field of the hash table entry. */ if (info->shared- && (ELF32_R_TYPE (rel->r_info) != R_ARM_PC24- || (h != NULL- && (! info->symbolic- || (h->elf_link_hash_flags- & ELF_LINK_HASH_DEF_REGULAR) == 0))))+ && (sec->flags & SEC_ALLOC) != 0+ && (ELF32_R_TYPE (rel->r_info) != R_ARM_PC24+ || (h != NULL+ && (! info->symbolic+ || (h->elf_link_hash_flags+ & ELF_LINK_HASH_DEF_REGULAR) == 0)))) {+ struct elf32_arm_relocs_copied *p, **head;+ /* When creating a shared object, we must copy these reloc types into the output file. We create a reloc section in dynobj and make room for this reloc. */@@ -2825,45 +3031,49 @@ || ! bfd_set_section_alignment (dynobj, sreloc, 2)) return FALSE; }- if (sec->flags & SEC_READONLY)- info->flags |= DF_TEXTREL;++ elf_section_data (sec)->sreloc = sreloc; } - sreloc->_raw_size += sizeof (Elf32_External_Rel);- /* If we are linking with -Bsymbolic, and this is a- global symbol, we count the number of PC relative- relocations we have entered for this symbol, so that- we can discard them again if the symbol is later- defined by a regular object. Note that this function- is only called if we are using an elf_i386 linker- hash table, which means that h is really a pointer to- an elf_i386_link_hash_entry. */- if (h != NULL && info->symbolic- && ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)+ /* If this is a global symbol, we count the number of+ relocations we need for this symbol. */+ if (h != NULL) {- struct elf32_arm_link_hash_entry * eh;- struct elf32_arm_pcrel_relocs_copied * p;-- eh = (struct elf32_arm_link_hash_entry *) h;-- for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)- if (p->section == sreloc)- break;-+ head = &((struct elf32_arm_link_hash_entry *) h)->relocs_copied;+ }+ else+ {+ /* Track dynamic relocs needed for local syms too.+ We really need local syms available to do this+ easily. Oh well. */+ + asection *s;+ s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,+ sec, r_symndx);+ if (s == NULL)+ return FALSE;+ + head = ((struct elf32_arm_relocs_copied **)+ &elf_section_data (s)->local_dynrel);+ }+ + p = *head;+ if (p == NULL || p->section != sec)+ {+ bfd_size_type amt = sizeof *p;+ p = bfd_alloc (htab->root.dynobj, amt); if (p == NULL)- {- p = ((struct elf32_arm_pcrel_relocs_copied *)- bfd_alloc (dynobj, (bfd_size_type) sizeof * p));- if (p == NULL)- return FALSE;- p->next = eh->pcrel_relocs_copied;- eh->pcrel_relocs_copied = p;- p->section = sreloc;- p->count = 0;- }-- ++p->count;+ return FALSE;+ p->next = *head;+ *head = p;+ p->section = sec;+ p->count = 0;+ p->pc_count = 0; }+ + p->count += 1;+ if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)+ p->pc_count += 1; } break; @@ -3003,71 +3213,29 @@ if (h->type == STT_FUNC || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) {- /* If we link a program (not a DSO), we'll get rid of unnecessary- PLT entries; we point to the actual symbols -- even for pic- relocs, because a program built with -fpic should have the same- result as one built without -fpic, specifically considering weak- symbols.- FIXME: m68k and i386 differ here, for unclear reasons. */- if (! info->shared- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0)+ if (h->plt.refcount <= 0+ || SYMBOL_CALLS_LOCAL (info, h)+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT+ && h->root.type == bfd_link_hash_undefweak)) { /* This case can occur if we saw a PLT32 reloc in an input- file, but the symbol was not defined by a dynamic object.- In such a case, we don't actually need to build a- procedure linkage table, and we can just do a PC32 reloc- instead. */- BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);+ file, but the symbol was never referred to by a dynamic+ object, or if all references were garbage collected. In+ such a case, we don't actually need to build a procedure+ linkage table, and we can just do a PC24 reloc instead. */+ h->plt.offset = (bfd_vma) -1; h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;- return TRUE;- }-- /* Make sure this symbol is output as a dynamic symbol. */- if (h->dynindx == -1)- {- if (! bfd_elf32_link_record_dynamic_symbol (info, h))- return FALSE; } - s = bfd_get_section_by_name (dynobj, ".plt");- BFD_ASSERT (s != NULL);-- /* If this is the first .plt entry, make room for the special- first entry. */- if (s->_raw_size == 0)- s->_raw_size += PLT_ENTRY_SIZE;-- /* If this symbol is not defined in a regular file, and we are- not generating a shared library, then set the symbol to this- location in the .plt. This is required to make function- pointers compare as equal between the normal executable and- the shared library. */- if (! info->shared- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)- {- h->root.u.def.section = s;- h->root.u.def.value = s->_raw_size;- }-- h->plt.offset = s->_raw_size;-- /* Make room for this entry. */- s->_raw_size += PLT_ENTRY_SIZE;-- /* We also need to make an entry in the .got.plt section, which- will be placed in the .got section by the linker script. */- s = bfd_get_section_by_name (dynobj, ".got.plt");- BFD_ASSERT (s != NULL);- s->_raw_size += 4;-- /* We also need to make an entry in the .rel.plt section. */-- s = bfd_get_section_by_name (dynobj, ".rel.plt");- BFD_ASSERT (s != NULL);- s->_raw_size += sizeof (Elf32_External_Rel);- return TRUE; }+ else+ /* It's possible that we incorrectly decided a .plt reloc was+ needed for an R_ARM_PC24 reloc to a non-function sym in+ check_relocs. We can't decide accurately between function and+ non-function syms in check-relocs; Objects loaded later in+ the link may change h->type. So fix it now. */+ h->plt.offset = (bfd_vma) -1; /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the@@ -3142,6 +3310,198 @@ return TRUE; } +/* Allocate space in .plt, .got and associated reloc sections for+ dynamic relocs. */++static bfd_boolean+allocate_dynrelocs (h, inf)+ struct elf_link_hash_entry *h;+ PTR inf;+{+ struct bfd_link_info *info;+ struct elf32_arm_link_hash_table *htab;+ struct elf32_arm_link_hash_entry *eh;+ struct elf32_arm_relocs_copied *p;++ if (h->root.type == bfd_link_hash_indirect)+ return TRUE;++ if (h->root.type == bfd_link_hash_warning)+ /* When warning symbols are created, they **replace** the "real"+ entry in the hash table, thus we never get to see the real+ symbol in a hash traversal. So look at it now. */+ h = (struct elf_link_hash_entry *) h->root.u.i.link;++ info = (struct bfd_link_info *) inf;+ htab = elf32_arm_hash_table (info);++ if (htab->root.dynamic_sections_created+ && h->plt.refcount > 0)+ {+ /* Make sure this symbol is output as a dynamic symbol.+ Undefined weak syms won't yet be marked as dynamic. */+ if (h->dynindx == -1+ && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)+ {+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))+ return FALSE;+ }++ if (info->shared+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))+ {+ asection *s = htab->splt;++ /* If this is the first .plt entry, make room for the special+ first entry. */+ if (s->_raw_size == 0)+ s->_raw_size += PLT_HEADER_SIZE;++ h->plt.offset = s->_raw_size;++ /* If this symbol is not defined in a regular file, and we are+ not generating a shared library, then set the symbol to this+ location in the .plt. This is required to make function+ pointers compare as equal between the normal executable and+ the shared library. */+ if (! info->shared+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)+ {+ h->root.u.def.section = s;+ h->root.u.def.value = h->plt.offset;+ }++ /* Make room for this entry. */+ s->_raw_size += PLT_ENTRY_SIZE;++ /* We also need to make an entry in the .got.plt section, which+ will be placed in the .got section by the linker script. */+ htab->sgotplt->_raw_size += 4;++ /* We also need to make an entry in the .rel.plt section. */+ htab->srelplt->_raw_size += sizeof (Elf32_External_Rel);+ }+ else+ {+ h->plt.offset = (bfd_vma) -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -