📄 001-debian.patch
字号:
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;+ }+ }+ else+ {+ h->plt.offset = (bfd_vma) -1;+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;+ }++ if (h->got.refcount > 0)+ {+ asection *s;+ bfd_boolean dyn;++ /* 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;+ }++ s = htab->sgot;+ h->got.offset = s->_raw_size;+ s->_raw_size += 4;+ dyn = htab->root.dynamic_sections_created;+ if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT+ || h->root.type != bfd_link_hash_undefweak)+ && (info->shared+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))+ htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);+ }+ else+ h->got.offset = (bfd_vma) -1;++ eh = (struct elf32_arm_link_hash_entry *) h;+ if (eh->relocs_copied == NULL)+ return TRUE;++ /* In the shared -Bsymbolic case, discard space allocated for+ dynamic pc-relative relocs against symbols which turn out to be+ defined in regular objects. For the normal shared case, discard+ space for pc-relative relocs that have become local due to symbol+ visibility changes. */++ if (info->shared)+ {+ /* The only reloc that uses pc_count is R_ARM_PC24, which will+ appear on a call or on something like ".long foo - .". We+ want calls to protected symbols to resolve directly to the+ function rather than going via the plt. If people want+ function pointer comparisons to work as expected then they+ should avoid writing assembly like ".long foo - .". */+ if (SYMBOL_CALLS_LOCAL (info, h))+ {+ struct elf32_arm_relocs_copied **pp;++ for (pp = &eh->relocs_copied; (p = *pp) != NULL; )+ {+ p->count -= p->pc_count;+ p->pc_count = 0;+ if (p->count == 0)+ *pp = p->next;+ else+ pp = &p->next;+ }+ }++ /* Also discard relocs on undefined weak syms with non-default+ visibility. */+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT+ && h->root.type == bfd_link_hash_undefweak)+ eh->relocs_copied = NULL;+ }+ else+ {+ /* For the non-shared case, discard space for relocs against+ symbols which turn out to need copy relocs or are not+ dynamic. */++ if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0+ && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)+ || (htab->root.dynamic_sections_created+ && (h->root.type == bfd_link_hash_undefweak+ || h->root.type == bfd_link_hash_undefined))))+ {+ /* 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 that succeeded, we know we'll be keeping all the+ relocs. */+ if (h->dynindx != -1)+ goto keep;+ }++ eh->relocs_copied = NULL;++ keep: ;+ }++ /* Finally, allocate space. */+ for (p = eh->relocs_copied; p != NULL; p = p->next)+ {+ asection *sreloc = elf_section_data (p->section)->sreloc;+ sreloc->_raw_size += p->count * sizeof (Elf32_External_Rel);+ }++ return TRUE;+}+ /* Set the sizes of the dynamic sections. */ static bfd_boolean@@ -3153,7 +3513,10 @@ asection * s; bfd_boolean plt; bfd_boolean relocs;+ bfd *ibfd;+ struct elf32_arm_link_hash_table *htab; + htab = elf32_arm_hash_table (info); dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -3168,26 +3531,74 @@ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; } }- else- {- /* We may have created entries in the .rel.got section.- However, if we are not creating the dynamic sections, we will- not actually use these entries. Reset the size of .rel.got,- which will cause it to get stripped from the output file- below. */- s = bfd_get_section_by_name (dynobj, ".rel.got");- if (s != NULL)- s->_raw_size = 0;- }-- /* If this is a -Bsymbolic shared link, then we need to discard all- PC relative relocs against symbols defined in a regular object.- We allocated space for them in the check_relocs routine, but we- will not fill them in in the relocate_section routine. */- if (info->shared && info->symbolic)- elf32_arm_link_hash_traverse (elf32_arm_hash_table (info),- elf32_arm_discard_copies,- (PTR) NULL);++ /* Set up .got offsets for local syms, and space for local dynamic+ relocs. */+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)+ {+ bfd_signed_vma *local_got;+ bfd_signed_vma *end_local_got;+ char *local_tls_type;+ bfd_size_type locsymcount;+ Elf_Internal_Shdr *symtab_hdr;+ asection *srel;++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)+ continue;++ for (s = ibfd->sections; s != NULL; s = s->next)+ {+ struct elf32_arm_relocs_copied *p;++ for (p = *((struct elf32_arm_relocs_copied **)+ &elf_section_data (s)->local_dynrel);+ p != NULL;+ p = p->next)+ {+ if (!bfd_is_abs_section (p->section)+ && bfd_is_abs_section (p->section->output_section))+ {+ /* Input section has been discarded, either because+ it is a copy of a linkonce section or due to+ linker script /DISCARD/, so we'll be discarding+ the relocs too. */+ }+ else if (p->count != 0)+ {+ srel = elf_section_data (p->section)->sreloc;+ srel->_raw_size += p->count * sizeof (Elf32_External_Rel);+ if ((p->section->output_section->flags & SEC_READONLY) != 0)+ info->flags |= DF_TEXTREL;+ }+ }+ }++ local_got = elf_local_got_refcounts (ibfd);+ if (!local_got)+ continue;++ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;+ locsymcount = symtab_hdr->sh_info;+ end_local_got = local_got + locsymcount;+ s = htab->sgot;+ srel = htab->srelgot;+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)+ {+ if (*local_got > 0)+ {+ *local_got = s->_raw_size;+ s->_raw_size += 4;+ if (info->shared)+ srel->_raw_size += sizeof (Elf32_External_Rel);+ }+ else+ *local_got = (bfd_vma) -1;+ }+ }++ /* Allocate global sym .plt and .got entries, and space for global+ sym dynamic relocs. */+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info); /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate@@ -3312,33 +3723,6 @@ return TRUE; } -/* This function is called via elf32_arm_link_hash_traverse if we are- creating a shared object with -Bsymbolic. It discards the space- allocated to copy PC relative relocs against symbols which are- defined in regular objects. We allocated space for them in the- check_relocs routine, but we won't fill them in in the- relocate_section routine. */--static bfd_boolean-elf32_arm_discard_copies (h, ignore)- struct elf32_arm_link_hash_entry * h;- PTR ignore ATTRIBUTE_UNUSED;-{- struct elf32_arm_pcrel_relocs_copied * s;-- if (h->root.root.type == bfd_link_hash_warning)- h = (struct elf32_arm_link_hash_entry *) h->root.root.u.i.link;-- /* We only discard relocs for symbols defined in a regular object. */- if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)- return TRUE;-- for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)- s->section->_raw_size -= s->count * sizeof (Elf32_External_Rel);-- return TRUE;-}- /* Finish up dynamic symbol handling. We set the contents of various dynamic sections here. */ @@ -3362,6 +3746,7 @@ bfd_vma got_offset; Elf_Internal_Rela rel; bfd_byte *loc;+ bfd_vma got_displacement; /* This symbol has an entry in the procedure linkage table. Set it up. */@@ -3377,35 +3762,43 @@ corresponds to this symbol. This is the index of this symbol in all the symbols for which we are making plt entries. The first entry in the procedure linkage table is reserved. */- plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;+ plt_index = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; /* Get the offset into the .got table of the entry that corresponds to this function. Each .got entry is 4 bytes. The first three are reserved. */ got_offset = (plt_index + 3) * 4; + /* Calculate the displacement between the PLT slot and the+ entry in the GOT. */+ got_displacement = (sgot->output_section->vma+ + sgot->output_offset+ + got_offset+ - splt->output_section->vma+ - splt->output_offset+ - h->plt.offset+ - 8);++ BFD_ASSERT ((got_displacement & 0xf0000000) == 0);+ /* Fill in the entry in the procedure linkage table. */- bfd_put_32 (output_bfd, elf32_arm_plt_entry[0],+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20), splt->contents + h->plt.offset + 0);- bfd_put_32 (output_bfd, elf32_arm_plt_entry[1],+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12), splt->contents + h->plt.offset + 4);- bfd_put_32 (output_bfd, elf32_arm_plt_entry[2],+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[2] | (got_displacement & 0x00000fff), splt->contents + h->plt.offset + 8);- bfd_put_32 (output_bfd,- (sgot->output_section->vma- + sgot->output_offset- + got_offset- - splt->output_section->vma- - splt->output_offset- - h->plt.offset - 12),- splt->contents + h->plt.offset + 12);+#ifdef FOUR_WORD_PLT+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[3],+ splt->contents + h->plt.offset + 12);+#endif /* Fill in the entry in the global offset table. */ bfd_put_32 (output_bfd, (splt->output_section->vma + splt->output_offset), sgot->contents + got_offset);-+ /* Fill in the entry in the .rel.plt section. */ rel.r_offset = (sgot->output_section->vma + sgot->output_offset@@ -3446,16 +3839,20 @@ + sgot->output_offset + (h->got.offset &~ (bfd_vma) 1)); - /* If this is a -Bsymbolic link, and the symbol is defined- locally, we just want to emit a RELATIVE reloc. The entry in- the global offset table will already have been initialized in- the relocate_section function. */+ /* If this is a static link, or it is a -Bsymbolic link and the+ symbol is defined locally or was forced to be local because+ of a version file, we just want to emit a RELATIVE reloc.+ The entry in the global offset table will already have been+ initialized in the relocate_section function. */ if (info->shared- && (info->symbolic || h->dynindx == -1)- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))- rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);+ && SYMBOL_REFERENCES_LOCAL (info, h))+ {+ BFD_ASSERT((h->got.offset & 1) != 0);+ rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);+ } else {+ BFD_ASSERT((h->got.offset & 1) == 0); bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT); }@@ -3609,10 +4006,26 @@ /* Fill in the first entry in the procedure linkage table. */ if (splt->_raw_size > 0) {+ bfd_vma got_displacement;++ /* Calculate the displacement between the PLT slot and &GOT[0]. */+ got_displacement = (sgot->output_section->vma+ + sgot->output_offset+ - splt->output_section->vma+ - splt->output_offset+ - 16);+ bfd_put_32 (output_bfd, elf32_arm_plt0_entry[0], splt->contents + 0); bfd_put_32 (output_bfd, elf32_arm_plt0_entry[1], splt->contents + 4); bfd_put_32 (output_bfd, elf32_arm_plt0_entry[2], splt->contents + 8); bfd_put_32 (output_bfd, elf32_arm_plt0_entry[3], splt->contents + 12);+#ifdef FOUR_WORD_PLT+ /* The displacement value goes in the otherwise-unused last word of+ the second entry. */+ bfd_put_32 (output_bfd, got_displacement, splt->contents + 28);+#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -