• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisãob9399fcf4ec90d898a610e39bd9141e85c008fbb (tree)
Hora2017-10-10 13:16:07
AutorAlan Modra <amodra@gmai...>
CommiterAlan Modra

Mensagem de Log

Prepare powerpc64 for late check_relocs

check_relocs was setting up some data used by the --gc-sections
gc_mark_hook. If we change ld to run check_relocs after gc_sections
that data needs to be set up elsewhere. Done by this patch in the
backend check_directives function (ppc64_elf_before_check_relocs).

* elf64-ppc.c (ppc64_elf_before_check_relocs): Set sec_type for
.opd whenever .opd is present and non-zero size. Move code
setting abiversion to/from output file earlier. Only set
u.opd.func_sec when --gc-sections. Read relocs and set up
u.opd.func_sec values here..
(ppc64_elf_check_relocs): ..rather than here. Simplify opd
section tests.
(ppc64_elf_edit_opd): Don't set sec_type for .opd here.

Mudança Sumário

Diff

--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
1+2017-10-10 Alan Modra <amodra@gmail.com>
2+
3+ * elf64-ppc.c (ppc64_elf_before_check_relocs): Set sec_type for
4+ .opd whenever .opd is present and non-zero size. Move code
5+ setting abiversion to/from output file earlier. Only set
6+ u.opd.func_sec when --gc-sections. Read relocs and set up
7+ u.opd.func_sec values here..
8+ (ppc64_elf_check_relocs): ..rather than here. Simplify opd
9+ section tests.
10+ (ppc64_elf_edit_opd): Don't set sec_type for .opd here.
11+
112 2017-10-09 H.J. Lu <hongjiu.lu@intel.com>
213
314 * elf-m10300.c (mn10300_elf_check_relocs): Don't free cached
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5182,6 +5182,9 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
51825182
51835183 if (opd != NULL && opd->size != 0)
51845184 {
5185+ BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
5186+ ppc64_elf_section_data (opd)->sec_type = sec_opd;
5187+
51855188 if (abiversion (ibfd) == 0)
51865189 set_abiversion (ibfd, 1);
51875190 else if (abiversion (ibfd) >= 2)
@@ -5193,48 +5196,84 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
51935196 bfd_set_error (bfd_error_bad_value);
51945197 return FALSE;
51955198 }
5199+ }
51965200
5197- if ((ibfd->flags & DYNAMIC) == 0
5198- && (opd->flags & SEC_RELOC) != 0
5199- && opd->reloc_count != 0
5200- && !bfd_is_abs_section (opd->output_section))
5201- {
5202- /* Garbage collection needs some extra help with .opd sections.
5203- We don't want to necessarily keep everything referenced by
5204- relocs in .opd, as that would keep all functions. Instead,
5205- if we reference an .opd symbol (a function descriptor), we
5206- want to keep the function code symbol's section. This is
5207- easy for global symbols, but for local syms we need to keep
5208- information about the associated function section. */
5209- bfd_size_type amt;
5210- asection **opd_sym_map;
5211-
5212- amt = OPD_NDX (opd->size) * sizeof (*opd_sym_map);
5213- opd_sym_map = bfd_zalloc (ibfd, amt);
5214- if (opd_sym_map == NULL)
5215- return FALSE;
5216- ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
5217- BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
5218- ppc64_elf_section_data (opd)->sec_type = sec_opd;
5219- }
5201+ if (is_ppc64_elf (info->output_bfd))
5202+ {
5203+ /* For input files without an explicit abiversion in e_flags
5204+ we should have flagged any with symbol st_other bits set
5205+ as ELFv1 and above flagged those with .opd as ELFv2.
5206+ Set the output abiversion if not yet set, and for any input
5207+ still ambiguous, take its abiversion from the output.
5208+ Differences in ABI are reported later. */
5209+ if (abiversion (info->output_bfd) == 0)
5210+ set_abiversion (info->output_bfd, abiversion (ibfd));
5211+ else if (abiversion (ibfd) == 0)
5212+ set_abiversion (ibfd, abiversion (info->output_bfd));
52205213 }
52215214
5222- if (!is_ppc64_elf (info->output_bfd))
5223- return TRUE;
52245215 htab = ppc_hash_table (info);
52255216 if (htab == NULL)
5226- return FALSE;
5217+ return TRUE;
5218+
5219+ if (opd != NULL && opd->size != 0
5220+ && (ibfd->flags & DYNAMIC) == 0
5221+ && (opd->flags & SEC_RELOC) != 0
5222+ && opd->reloc_count != 0
5223+ && !bfd_is_abs_section (opd->output_section)
5224+ && info->gc_sections)
5225+ {
5226+ /* Garbage collection needs some extra help with .opd sections.
5227+ We don't want to necessarily keep everything referenced by
5228+ relocs in .opd, as that would keep all functions. Instead,
5229+ if we reference an .opd symbol (a function descriptor), we
5230+ want to keep the function code symbol's section. This is
5231+ easy for global symbols, but for local syms we need to keep
5232+ information about the associated function section. */
5233+ bfd_size_type amt;
5234+ asection **opd_sym_map;
5235+ Elf_Internal_Shdr *symtab_hdr;
5236+ Elf_Internal_Rela *relocs, *rel_end, *rel;
5237+
5238+ amt = OPD_NDX (opd->size) * sizeof (*opd_sym_map);
5239+ opd_sym_map = bfd_zalloc (ibfd, amt);
5240+ if (opd_sym_map == NULL)
5241+ return FALSE;
5242+ ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
5243+ relocs = _bfd_elf_link_read_relocs (ibfd, opd, NULL, NULL,
5244+ info->keep_memory);
5245+ if (relocs == NULL)
5246+ return FALSE;
5247+ symtab_hdr = &elf_symtab_hdr (ibfd);
5248+ rel_end = relocs + opd->reloc_count - 1;
5249+ for (rel = relocs; rel < rel_end; rel++)
5250+ {
5251+ enum elf_ppc64_reloc_type r_type = ELF64_R_TYPE (rel->r_info);
5252+ unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
5253+
5254+ if (r_type == R_PPC64_ADDR64
5255+ && ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC
5256+ && r_symndx < symtab_hdr->sh_info)
5257+ {
5258+ Elf_Internal_Sym *isym;
5259+ asection *s;
52275260
5228- /* For input files without an explicit abiversion in e_flags
5229- we should have flagged any with symbol st_other bits set
5230- as ELFv1 and above flagged those with .opd as ELFv2.
5231- Set the output abiversion if not yet set, and for any input
5232- still ambiguous, take its abiversion from the output.
5233- Differences in ABI are reported later. */
5234- if (abiversion (info->output_bfd) == 0)
5235- set_abiversion (info->output_bfd, abiversion (ibfd));
5236- else if (abiversion (ibfd) == 0)
5237- set_abiversion (ibfd, abiversion (info->output_bfd));
5261+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, r_symndx);
5262+ if (isym == NULL)
5263+ {
5264+ if (elf_section_data (opd)->relocs != relocs)
5265+ free (relocs);
5266+ return FALSE;
5267+ }
5268+
5269+ s = bfd_section_from_elf_index (ibfd, isym->st_shndx);
5270+ if (s != NULL && s != opd)
5271+ opd_sym_map[OPD_NDX (rel->r_offset)] = s;
5272+ }
5273+ }
5274+ if (elf_section_data (opd)->relocs != relocs)
5275+ free (relocs);
5276+ }
52385277
52395278 p = &htab->dot_syms;
52405279 while ((eh = *p) != NULL)
@@ -5397,8 +5436,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
53975436 const Elf_Internal_Rela *rel;
53985437 const Elf_Internal_Rela *rel_end;
53995438 asection *sreloc;
5400- asection **opd_sym_map;
54015439 struct elf_link_hash_entry *tga, *dottga;
5440+ bfd_boolean is_opd;
54025441
54035442 if (bfd_link_relocatable (info))
54045443 return TRUE;
@@ -5425,11 +5464,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
54255464 symtab_hdr = &elf_symtab_hdr (abfd);
54265465 sym_hashes = elf_sym_hashes (abfd);
54275466 sreloc = NULL;
5428- opd_sym_map = NULL;
5429- if (ppc64_elf_section_data (sec) != NULL
5430- && ppc64_elf_section_data (sec)->sec_type == sec_opd)
5431- opd_sym_map = ppc64_elf_section_data (sec)->u.opd.func_sec;
5432-
5467+ is_opd = ppc64_elf_section_data (sec)->sec_type == sec_opd;
54335468 rel_end = relocs + sec->reloc_count;
54345469 for (rel = relocs; rel < rel_end; rel++)
54355470 {
@@ -5857,26 +5892,12 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
58575892 goto dodyn;
58585893
58595894 case R_PPC64_ADDR64:
5860- if (opd_sym_map != NULL
5895+ if (is_opd
58615896 && rel + 1 < rel_end
58625897 && ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
58635898 {
58645899 if (h != NULL)
58655900 ((struct ppc_link_hash_entry *) h)->is_func = 1;
5866- else
5867- {
5868- asection *s;
5869- Elf_Internal_Sym *isym;
5870-
5871- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
5872- abfd, r_symndx);
5873- if (isym == NULL)
5874- return FALSE;
5875-
5876- s = bfd_section_from_elf_index (abfd, isym->st_shndx);
5877- if (s != NULL && s != sec)
5878- opd_sym_map[OPD_NDX (rel->r_offset)] = s;
5879- }
58805901 }
58815902 /* Fall through. */
58825903
@@ -5916,7 +5937,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
59165937 h->non_got_ref = 1;
59175938
59185939 /* Don't propagate .opd relocs. */
5919- if (NO_OPD_RELOCS && opd_sym_map != NULL)
5940+ if (NO_OPD_RELOCS && is_opd)
59205941 break;
59215942
59225943 /* If we are creating a shared library, and this is a reloc
@@ -8116,7 +8137,6 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
81168137 opd->adjust = bfd_zalloc (sec->owner, amt);
81178138 if (opd->adjust == NULL)
81188139 return FALSE;
8119- ppc64_elf_section_data (sec)->sec_type = sec_opd;
81208140
81218141 /* This seems a waste of time as input .opd sections are all
81228142 zeros as generated by gcc, but I suppose there's no reason