• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

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

修訂6f20ed8a6ba1a01fb356eea8ea45310ed8478a27 (tree)
時間2015-08-31 22:24:06
作者Alan Modra <amodra@gmai...>
CommiterAlan Modra

Log Message

ppc64 section group handling

Two organizational changes to the array of additional info kept for
sections.
1) Move group info into a per-group allocated struct, in preparation
for future changes that need per-group accounting.
2) Expand the array to include output sections, which simplifies
sizing and removes the need for a separate output section array.

* section.c (section_id): Make file scope.
(bfd_get_next_section_id): New function.
* elf64-ppc.c (struct map_stub): Remove toc_off field. Move decl.
(struct ppc_stub_hash_entry): Delete stub_sec and id_sec. Add
group. Update all uses.
(struct ppc_link_hash_table): Delete top_id, top_index, and
input_list. Add sec_info_arr_size. Rename stub_group to
sec_info, and make group info indirect. Update stub_group refs
throughout file.
(ppc_add_stub): Don't look for stub_sec on link_sec stub_group
entry.
(ppc_build_one_stub): Delete FIXME.
(ppc64_elf_setup_section_lists): Size htab->sec_info for all
sections, not just input sections. Don't create htab->input_list.
(ppc64_elf_next_input_section): Update to use sec_info union as
list pointer.
(PREV_SEC): Delete.
(group_sections): Pass "info" param rather than "htab". Iterate
over output sections rather than input_list. Use sec_info union
as list pointers. Alloc atruct map_stub, and return fail status.
* bfd-in2.h: Regenerate.

Change Summary

差異

--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,29 @@
11 2015-08-31 Alan Modra <amodra@gmail.com>
22
3+ * section.c (section_id): Make file scope.
4+ (bfd_get_next_section_id): New function.
5+ * elf64-ppc.c (struct map_stub): Remove toc_off field. Move decl.
6+ (struct ppc_stub_hash_entry): Delete stub_sec and id_sec. Add
7+ group. Update all uses.
8+ (struct ppc_link_hash_table): Delete top_id, top_index, and
9+ input_list. Add sec_info_arr_size. Rename stub_group to
10+ sec_info, and make group info indirect. Update stub_group refs
11+ throughout file.
12+ (ppc_add_stub): Don't look for stub_sec on link_sec stub_group
13+ entry.
14+ (ppc_build_one_stub): Delete FIXME.
15+ (ppc64_elf_setup_section_lists): Size htab->sec_info for all
16+ sections, not just input sections. Don't create htab->input_list.
17+ (ppc64_elf_next_input_section): Update to use sec_info union as
18+ list pointer.
19+ (PREV_SEC): Delete.
20+ (group_sections): Pass "info" param rather than "htab". Iterate
21+ over output sections rather than input_list. Use sec_info union
22+ as list pointers. Alloc atruct map_stub, and return fail status.
23+ * bfd-in2.h: Regenerate.
24+
25+2015-08-31 Alan Modra <amodra@gmail.com>
26+
327 * elflink.c (elf_sort_symbol): Use correctly sized type for
428 calculating signed section->id difference.
529 (elf_link_add_object_symbols): Likewise.
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1818,6 +1818,8 @@ asection *bfd_make_section_with_flags
18181818
18191819 asection *bfd_make_section (bfd *, const char *name);
18201820
1821+int bfd_get_next_section_id (void);
1822+
18211823 bfd_boolean bfd_set_section_flags
18221824 (bfd *abfd, asection *sec, flagword flags);
18231825
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -3799,6 +3799,15 @@ enum ppc_stub_type {
37993799 ppc_stub_global_entry
38003800 };
38013801
3802+/* Information on stub grouping. */
3803+struct map_stub
3804+{
3805+ /* The stub section. */
3806+ asection *stub_sec;
3807+ /* This is the section to which stubs in the group will be attached. */
3808+ asection *link_sec;
3809+};
3810+
38023811 struct ppc_stub_hash_entry {
38033812
38043813 /* Base hash table entry structure. */
@@ -3806,8 +3815,8 @@ struct ppc_stub_hash_entry {
38063815
38073816 enum ppc_stub_type stub_type;
38083817
3809- /* The stub section. */
3810- asection *stub_sec;
3818+ /* Group information. */
3819+ struct map_stub *group;
38113820
38123821 /* Offset within stub_sec of the beginning of this stub. */
38133822 bfd_vma stub_offset;
@@ -3821,10 +3830,6 @@ struct ppc_stub_hash_entry {
38213830 struct ppc_link_hash_entry *h;
38223831 struct plt_entry *plt_ent;
38233832
3824- /* Where this stub is being called from, or, in the case of combined
3825- stub sections, the first input section in the group. */
3826- asection *id_sec;
3827-
38283833 /* Symbol st_other. */
38293834 unsigned char other;
38303835 };
@@ -3925,34 +3930,34 @@ struct ppc_link_hash_table
39253930 /* Various options and other info passed from the linker. */
39263931 struct ppc64_elf_params *params;
39273932
3928- /* Array to keep track of which stub sections have been created, and
3929- information on stub grouping. */
3930- struct map_stub {
3931- /* This is the section to which stubs in the group will be attached. */
3932- asection *link_sec;
3933- /* The stub section. */
3934- asection *stub_sec;
3935- /* Along with elf_gp, specifies the TOC pointer used in this group. */
3933+ /* The size of sec_info below. */
3934+ unsigned int sec_info_arr_size;
3935+
3936+ /* Per-section array of extra section info. Done this way rather
3937+ than as part of ppc64_elf_section_data so we have the info for
3938+ non-ppc64 sections. */
3939+ struct
3940+ {
3941+ /* Along with elf_gp, specifies the TOC pointer used by this section. */
39363942 bfd_vma toc_off;
3937- } *stub_group;
3943+
3944+ union
3945+ {
3946+ /* The section group that this section belongs to. */
3947+ struct map_stub *group;
3948+ /* A temp section list pointer. */
3949+ asection *list;
3950+ } u;
3951+ } *sec_info;
39383952
39393953 /* Temp used when calculating TOC pointers. */
39403954 bfd_vma toc_curr;
39413955 bfd *toc_bfd;
39423956 asection *toc_first_sec;
39433957
3944- /* Highest input section id. */
3945- unsigned int top_id;
3946-
3947- /* Highest output section index. */
3948- unsigned int top_index;
3949-
39503958 /* Used when adding symbols. */
39513959 struct ppc_link_hash_entry *dot_syms;
39523960
3953- /* List of input sections for each output section. */
3954- asection **input_list;
3955-
39563961 /* Shortcuts to get to dynamic linker sections. */
39573962 asection *dynbss;
39583963 asection *relbss;
@@ -4056,13 +4061,12 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
40564061 /* Initialize the local fields. */
40574062 eh = (struct ppc_stub_hash_entry *) entry;
40584063 eh->stub_type = ppc_stub_none;
4059- eh->stub_sec = NULL;
4064+ eh->group = NULL;
40604065 eh->stub_offset = 0;
40614066 eh->target_value = 0;
40624067 eh->target_section = NULL;
40634068 eh->h = NULL;
40644069 eh->plt_ent = NULL;
4065- eh->id_sec = NULL;
40664070 eh->other = 0;
40674071 }
40684072
@@ -4412,18 +4416,18 @@ ppc_get_stub_entry (const asection *input_section,
44124416 struct ppc_link_hash_table *htab)
44134417 {
44144418 struct ppc_stub_hash_entry *stub_entry;
4415- const asection *id_sec;
4419+ struct map_stub *group;
44164420
44174421 /* If this input section is part of a group of sections sharing one
44184422 stub section, then use the id of the first section in the group.
44194423 Stub names need to include a section id, as there may well be
44204424 more than one stub used to reach say, printf, and we need to
44214425 distinguish between them. */
4422- id_sec = htab->stub_group[input_section->id].link_sec;
4426+ group = htab->sec_info[input_section->id].u.group;
44234427
44244428 if (h != NULL && h->u.stub_cache != NULL
44254429 && h->u.stub_cache->h == h
4426- && h->u.stub_cache->id_sec == id_sec)
4430+ && h->u.stub_cache->group == group)
44274431 {
44284432 stub_entry = h->u.stub_cache;
44294433 }
@@ -4431,7 +4435,7 @@ ppc_get_stub_entry (const asection *input_section,
44314435 {
44324436 char *stub_name;
44334437
4434- stub_name = ppc_stub_name (id_sec, sym_sec, h, rel);
4438+ stub_name = ppc_stub_name (group->link_sec, sym_sec, h, rel);
44354439 if (stub_name == NULL)
44364440 return NULL;
44374441
@@ -4455,35 +4459,32 @@ ppc_add_stub (const char *stub_name,
44554459 struct bfd_link_info *info)
44564460 {
44574461 struct ppc_link_hash_table *htab = ppc_hash_table (info);
4462+ struct map_stub *group;
44584463 asection *link_sec;
44594464 asection *stub_sec;
44604465 struct ppc_stub_hash_entry *stub_entry;
44614466
4462- link_sec = htab->stub_group[section->id].link_sec;
4463- stub_sec = htab->stub_group[section->id].stub_sec;
4467+ group = htab->sec_info[section->id].u.group;
4468+ link_sec = group->link_sec;
4469+ stub_sec = group->stub_sec;
44644470 if (stub_sec == NULL)
44654471 {
4466- stub_sec = htab->stub_group[link_sec->id].stub_sec;
4467- if (stub_sec == NULL)
4468- {
4469- size_t namelen;
4470- bfd_size_type len;
4471- char *s_name;
4472+ size_t namelen;
4473+ bfd_size_type len;
4474+ char *s_name;
44724475
4473- namelen = strlen (link_sec->name);
4474- len = namelen + sizeof (STUB_SUFFIX);
4475- s_name = bfd_alloc (htab->params->stub_bfd, len);
4476- if (s_name == NULL)
4477- return NULL;
4476+ namelen = strlen (link_sec->name);
4477+ len = namelen + sizeof (STUB_SUFFIX);
4478+ s_name = bfd_alloc (htab->params->stub_bfd, len);
4479+ if (s_name == NULL)
4480+ return NULL;
44784481
4479- memcpy (s_name, link_sec->name, namelen);
4480- memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
4481- stub_sec = (*htab->params->add_stub_section) (s_name, link_sec);
4482- if (stub_sec == NULL)
4483- return NULL;
4484- htab->stub_group[link_sec->id].stub_sec = stub_sec;
4485- }
4486- htab->stub_group[section->id].stub_sec = stub_sec;
4482+ memcpy (s_name, link_sec->name, namelen);
4483+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
4484+ stub_sec = (*htab->params->add_stub_section) (s_name, link_sec);
4485+ if (stub_sec == NULL)
4486+ return NULL;
4487+ group->stub_sec = stub_sec;
44874488 }
44884489
44894490 /* Enter this entry into the linker stub hash table. */
@@ -4496,9 +4497,8 @@ ppc_add_stub (const char *stub_name,
44964497 return NULL;
44974498 }
44984499
4499- stub_entry->stub_sec = stub_sec;
4500+ stub_entry->group = group;
45004501 stub_entry->stub_offset = 0;
4501- stub_entry->id_sec = link_sec;
45024502 return stub_entry;
45034503 }
45044504
@@ -10257,7 +10257,7 @@ plt_stub_pad (struct ppc_link_hash_table *htab,
1025710257 {
1025810258 int stub_align = 1 << htab->params->plt_stub_align;
1025910259 unsigned stub_size = plt_stub_size (htab, stub_entry, plt_off);
10260- bfd_vma stub_off = stub_entry->stub_sec->size;
10260+ bfd_vma stub_off = stub_entry->group->stub_sec->size;
1026110261
1026210262 if (((stub_off + stub_size - 1) & -stub_align) - (stub_off & -stub_align)
1026310263 > ((stub_size - 1) & -stub_align))
@@ -10300,7 +10300,7 @@ build_plt_stub (struct ppc_link_hash_table *htab,
1030010300 to = (glinkoff
1030110301 + htab->glink->output_offset
1030210302 + htab->glink->output_section->vma);
10303- from = (p - stub_entry->stub_sec->contents
10303+ from = (p - stub_entry->group->stub_sec->contents
1030410304 + 4 * (ALWAYS_EMIT_R2SAVE
1030510305 || stub_entry->stub_type == ppc_stub_plt_call_r2save)
1030610306 + 4 * (PPC_HA (offset) != 0)
@@ -10308,8 +10308,8 @@ build_plt_stub (struct ppc_link_hash_table *htab,
1030810308 != PPC_HA (offset))
1030910309 + 4 * (plt_static_chain != 0)
1031010310 + 20
10311- + stub_entry->stub_sec->output_offset
10312- + stub_entry->stub_sec->output_section->vma);
10311+ + stub_entry->group->stub_sec->output_offset
10312+ + stub_entry->group->stub_sec->output_section->vma);
1031310313 cmp_branch_off = to - from;
1031410314 use_fake_dep = cmp_branch_off + (1 << 25) >= (1 << 26);
1031510315 }
@@ -10522,7 +10522,7 @@ get_r2off (struct bfd_link_info *info,
1052210522 struct ppc_stub_hash_entry *stub_entry)
1052310523 {
1052410524 struct ppc_link_hash_table *htab = ppc_hash_table (info);
10525- bfd_vma r2off = htab->stub_group[stub_entry->target_section->id].toc_off;
10525+ bfd_vma r2off = htab->sec_info[stub_entry->target_section->id].toc_off;
1052610526
1052710527 if (r2off == 0)
1052810528 {
@@ -10547,7 +10547,7 @@ get_r2off (struct bfd_link_info *info,
1054710547 r2off = bfd_get_64 (opd->owner, buf);
1054810548 r2off -= elf_gp (info->output_bfd);
1054910549 }
10550- r2off -= htab->stub_group[stub_entry->id_sec->id].toc_off;
10550+ r2off -= htab->sec_info[stub_entry->group->link_sec->id].toc_off;
1055110551 return r2off;
1055210552 }
1055310553
@@ -10574,8 +10574,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1057410574 return FALSE;
1057510575
1057610576 /* Make a note of the offset within the stubs for this entry. */
10577- stub_entry->stub_offset = stub_entry->stub_sec->size;
10578- loc = stub_entry->stub_sec->contents + stub_entry->stub_offset;
10577+ stub_entry->stub_offset = stub_entry->group->stub_sec->size;
10578+ loc = stub_entry->group->stub_sec->contents + stub_entry->stub_offset;
1057910579
1058010580 htab->stub_count[stub_entry->stub_type - 1] += 1;
1058110581 switch (stub_entry->stub_type)
@@ -10591,8 +10591,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1059110591
1059210592 /* And this is where we are coming from. */
1059310593 off -= (stub_entry->stub_offset
10594- + stub_entry->stub_sec->output_offset
10595- + stub_entry->stub_sec->output_section->vma);
10594+ + stub_entry->group->stub_sec->output_offset
10595+ + stub_entry->group->stub_sec->output_section->vma);
1059610596
1059710597 size = 4;
1059810598 if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
@@ -10631,10 +10631,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1063110631
1063210632 if (info->emitrelocations)
1063310633 {
10634- r = get_relocs (stub_entry->stub_sec, 1);
10634+ r = get_relocs (stub_entry->group->stub_sec, 1);
1063510635 if (r == NULL)
1063610636 return FALSE;
10637- r->r_offset = loc - stub_entry->stub_sec->contents;
10637+ r->r_offset = loc - stub_entry->group->stub_sec->contents;
1063810638 r->r_info = ELF64_R_INFO (0, R_PPC64_REL24);
1063910639 r->r_addend = dest;
1064010640 if (stub_entry->h != NULL)
@@ -10741,7 +10741,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1074110741
1074210742 off = (dest
1074310743 - elf_gp (htab->brlt->output_section->owner)
10744- - htab->stub_group[stub_entry->id_sec->id].toc_off);
10744+ - htab->sec_info[stub_entry->group->link_sec->id].toc_off);
1074510745
1074610746 if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
1074710747 {
@@ -10755,10 +10755,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1075510755
1075610756 if (info->emitrelocations)
1075710757 {
10758- r = get_relocs (stub_entry->stub_sec, 1 + (PPC_HA (off) != 0));
10758+ r = get_relocs (stub_entry->group->stub_sec, 1 + (PPC_HA (off) != 0));
1075910759 if (r == NULL)
1076010760 return FALSE;
10761- r[0].r_offset = loc - stub_entry->stub_sec->contents;
10761+ r[0].r_offset = loc - stub_entry->group->stub_sec->contents;
1076210762 if (bfd_big_endian (info->output_bfd))
1076310763 r[0].r_offset += 2;
1076410764 if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
@@ -10847,11 +10847,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1084710847 struct ppc_link_hash_entry *fh = ppc_follow_link (stub_entry->h->oh);
1084810848
1084910849 /* If the old-ABI "dot-symbol" is undefined make it weak so
10850- we don't get a link error from RELOC_FOR_GLOBAL_SYMBOL.
10851- FIXME: We used to define the symbol on one of the call
10852- stubs instead, which is why we test symbol section id
10853- against htab->top_id in various places. Likely all
10854- these checks could now disappear. */
10850+ we don't get a link error from RELOC_FOR_GLOBAL_SYMBOL. */
1085510851 if (fh->elf.root.type == bfd_link_hash_undefined)
1085610852 fh->elf.root.type = bfd_link_hash_undefweak;
1085710853 /* Stop undo_symbol_twiddle changing it back to undefined. */
@@ -10895,7 +10891,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1089510891
1089610892 off = (dest
1089710893 - elf_gp (plt->output_section->owner)
10898- - htab->stub_group[stub_entry->id_sec->id].toc_off);
10894+ - htab->sec_info[stub_entry->group->link_sec->id].toc_off);
1089910895
1090010896 if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
1090110897 {
@@ -10913,15 +10909,15 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1091310909 {
1091410910 unsigned pad = plt_stub_pad (htab, stub_entry, off);
1091510911
10916- stub_entry->stub_sec->size += pad;
10917- stub_entry->stub_offset = stub_entry->stub_sec->size;
10912+ stub_entry->group->stub_sec->size += pad;
10913+ stub_entry->stub_offset = stub_entry->group->stub_sec->size;
1091810914 loc += pad;
1091910915 }
1092010916
1092110917 r = NULL;
1092210918 if (info->emitrelocations)
1092310919 {
10924- r = get_relocs (stub_entry->stub_sec,
10920+ r = get_relocs (stub_entry->group->stub_sec,
1092510921 ((PPC_HA (off) != 0)
1092610922 + (htab->opd_abi
1092710923 ? 2 + (htab->params->plt_static_chain
@@ -10929,7 +10925,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1092910925 : 1)));
1093010926 if (r == NULL)
1093110927 return FALSE;
10932- r[0].r_offset = loc - stub_entry->stub_sec->contents;
10928+ r[0].r_offset = loc - stub_entry->group->stub_sec->contents;
1093310929 if (bfd_big_endian (info->output_bfd))
1093410930 r[0].r_offset += 2;
1093510931 r[0].r_addend = dest;
@@ -10949,7 +10945,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1094910945 return FALSE;
1095010946 }
1095110947
10952- stub_entry->stub_sec->size += size;
10948+ stub_entry->group->stub_sec->size += size;
1095310949
1095410950 if (htab->params->emit_stub_syms)
1095510951 {
@@ -10977,7 +10973,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1097710973 if (h->root.type == bfd_link_hash_new)
1097810974 {
1097910975 h->root.type = bfd_link_hash_defined;
10980- h->root.u.def.section = stub_entry->stub_sec;
10976+ h->root.u.def.section = stub_entry->group->stub_sec;
1098110977 h->root.u.def.value = stub_entry->stub_offset;
1098210978 h->ref_regular = 1;
1098310979 h->def_regular = 1;
@@ -11027,20 +11023,20 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1102711023 off += (plt->output_offset
1102811024 + plt->output_section->vma
1102911025 - elf_gp (plt->output_section->owner)
11030- - htab->stub_group[stub_entry->id_sec->id].toc_off);
11026+ - htab->sec_info[stub_entry->group->link_sec->id].toc_off);
1103111027
1103211028 size = plt_stub_size (htab, stub_entry, off);
1103311029 if (htab->params->plt_stub_align)
1103411030 size += plt_stub_pad (htab, stub_entry, off);
1103511031 if (info->emitrelocations)
1103611032 {
11037- stub_entry->stub_sec->reloc_count
11033+ stub_entry->group->stub_sec->reloc_count
1103811034 += ((PPC_HA (off) != 0)
1103911035 + (htab->opd_abi
1104011036 ? 2 + (htab->params->plt_static_chain
1104111037 && PPC_HA (off + 16) == PPC_HA (off))
1104211038 : 1));
11043- stub_entry->stub_sec->flags |= SEC_RELOC;
11039+ stub_entry->group->stub_sec->flags |= SEC_RELOC;
1104411040 }
1104511041 }
1104611042 else
@@ -11053,9 +11049,9 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1105311049 off = (stub_entry->target_value
1105411050 + stub_entry->target_section->output_offset
1105511051 + stub_entry->target_section->output_section->vma);
11056- off -= (stub_entry->stub_sec->size
11057- + stub_entry->stub_sec->output_offset
11058- + stub_entry->stub_sec->output_section->vma);
11052+ off -= (stub_entry->group->stub_sec->size
11053+ + stub_entry->group->stub_sec->output_offset
11054+ + stub_entry->group->stub_sec->output_section->vma);
1105911055
1106011056 /* Reset the stub type from the plt variant in case we now
1106111057 can reach with a shorter stub. */
@@ -11118,12 +11114,13 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1111811114 + htab->brlt->output_offset
1111911115 + htab->brlt->output_section->vma
1112011116 - elf_gp (htab->brlt->output_section->owner)
11121- - htab->stub_group[stub_entry->id_sec->id].toc_off);
11117+ - htab->sec_info[stub_entry->group->link_sec->id].toc_off);
1112211118
1112311119 if (info->emitrelocations)
1112411120 {
11125- stub_entry->stub_sec->reloc_count += 1 + (PPC_HA (off) != 0);
11126- stub_entry->stub_sec->flags |= SEC_RELOC;
11121+ stub_entry->group->stub_sec->reloc_count
11122+ += 1 + (PPC_HA (off) != 0);
11123+ stub_entry->group->stub_sec->flags |= SEC_RELOC;
1112711124 }
1112811125
1112911126 if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
@@ -11146,12 +11143,12 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1114611143 }
1114711144 else if (info->emitrelocations)
1114811145 {
11149- stub_entry->stub_sec->reloc_count += 1;
11150- stub_entry->stub_sec->flags |= SEC_RELOC;
11146+ stub_entry->group->stub_sec->reloc_count += 1;
11147+ stub_entry->group->stub_sec->flags |= SEC_RELOC;
1115111148 }
1115211149 }
1115311150
11154- stub_entry->stub_sec->size += size;
11151+ stub_entry->group->stub_sec->size += size;
1115511152 return TRUE;
1115611153 }
1115711154
@@ -11162,57 +11159,22 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
1116211159 int
1116311160 ppc64_elf_setup_section_lists (struct bfd_link_info *info)
1116411161 {
11165- bfd *input_bfd;
11166- unsigned int top_id, top_index, id;
11167- asection *section;
11168- asection **input_list;
11162+ unsigned int id;
1116911163 bfd_size_type amt;
1117011164 struct ppc_link_hash_table *htab = ppc_hash_table (info);
1117111165
1117211166 if (htab == NULL)
1117311167 return -1;
1117411168
11175- /* Find the top input section id. */
11176- for (input_bfd = info->input_bfds, top_id = 3;
11177- input_bfd != NULL;
11178- input_bfd = input_bfd->link.next)
11179- {
11180- for (section = input_bfd->sections;
11181- section != NULL;
11182- section = section->next)
11183- {
11184- if (top_id < section->id)
11185- top_id = section->id;
11186- }
11187- }
11188-
11189- htab->top_id = top_id;
11190- amt = sizeof (struct map_stub) * (top_id + 1);
11191- htab->stub_group = bfd_zmalloc (amt);
11192- if (htab->stub_group == NULL)
11169+ htab->sec_info_arr_size = bfd_get_next_section_id ();
11170+ amt = sizeof (*htab->sec_info) * (htab->sec_info_arr_size);
11171+ htab->sec_info = bfd_zmalloc (amt);
11172+ if (htab->sec_info == NULL)
1119311173 return -1;
1119411174
1119511175 /* Set toc_off for com, und, abs and ind sections. */
1119611176 for (id = 0; id < 3; id++)
11197- htab->stub_group[id].toc_off = TOC_BASE_OFF;
11198-
11199- /* We can't use output_bfd->section_count here to find the top output
11200- section index as some sections may have been removed, and
11201- strip_excluded_output_sections doesn't renumber the indices. */
11202- for (section = info->output_bfd->sections, top_index = 0;
11203- section != NULL;
11204- section = section->next)
11205- {
11206- if (top_index < section->index)
11207- top_index = section->index;
11208- }
11209-
11210- htab->top_index = top_index;
11211- amt = sizeof (asection *) * (top_index + 1);
11212- input_list = bfd_zmalloc (amt);
11213- htab->input_list = input_list;
11214- if (input_list == NULL)
11215- return -1;
11177+ htab->sec_info[id].toc_off = TOC_BASE_OFF;
1121611178
1121711179 return 1;
1121811180 }
@@ -11761,15 +11723,13 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
1176111723 return FALSE;
1176211724
1176311725 if ((isec->output_section->flags & SEC_CODE) != 0
11764- && isec->output_section->index <= htab->top_index)
11726+ && isec->output_section->id < htab->sec_info_arr_size)
1176511727 {
11766- asection **list = htab->input_list + isec->output_section->index;
11767- /* Steal the link_sec pointer for our list. */
11768-#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
1176911728 /* This happens to make the list in reverse order,
1177011729 which is what we want. */
11771- PREV_SEC (isec) = *list;
11772- *list = isec;
11730+ htab->sec_info[isec->id].u.list
11731+ = htab->sec_info[isec->output_section->id].u.list;
11732+ htab->sec_info[isec->output_section->id].u.list = isec;
1177311733 }
1177411734
1177511735 if (htab->multi_toc_needed)
@@ -11793,7 +11753,7 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
1179311753 htab->toc_curr = elf_gp (isec->owner);
1179411754 }
1179511755
11796- htab->stub_group[isec->id].toc_off = htab->toc_curr;
11756+ htab->sec_info[isec->id].toc_off = htab->toc_curr;
1179711757 return TRUE;
1179811758 }
1179911759
@@ -11815,8 +11775,8 @@ check_pasted_section (struct bfd_link_info *info, const char *name)
1181511775 if (i->has_toc_reloc)
1181611776 {
1181711777 if (toc_off == 0)
11818- toc_off = htab->stub_group[i->id].toc_off;
11819- else if (toc_off != htab->stub_group[i->id].toc_off)
11778+ toc_off = htab->sec_info[i->id].toc_off;
11779+ else if (toc_off != htab->sec_info[i->id].toc_off)
1182011780 return FALSE;
1182111781 }
1182211782
@@ -11824,14 +11784,14 @@ check_pasted_section (struct bfd_link_info *info, const char *name)
1182411784 for (i = o->map_head.s; i != NULL; i = i->map_head.s)
1182511785 if (i->makes_toc_func_call)
1182611786 {
11827- toc_off = htab->stub_group[i->id].toc_off;
11787+ toc_off = htab->sec_info[i->id].toc_off;
1182811788 break;
1182911789 }
1183011790
1183111791 /* Make sure the whole pasted function uses the same toc offset. */
1183211792 if (toc_off != 0)
1183311793 for (i = o->map_head.s; i != NULL; i = i->map_head.s)
11834- htab->stub_group[i->id].toc_off = toc_off;
11794+ htab->sec_info[i->id].toc_off = toc_off;
1183511795 }
1183611796 return TRUE;
1183711797 }
@@ -11850,15 +11810,20 @@ ppc64_elf_check_init_fini (struct bfd_link_info *info)
1185011810 _init and _fini functions into multiple parts. Putting a stub in
1185111811 the middle of a function is not a good idea. */
1185211812
11853-static void
11854-group_sections (struct ppc_link_hash_table *htab,
11813+static bfd_boolean
11814+group_sections (struct bfd_link_info *info,
1185511815 bfd_size_type stub_group_size,
1185611816 bfd_boolean stubs_always_before_branch)
1185711817 {
11858- asection **list;
11818+ struct ppc_link_hash_table *htab;
11819+ asection *osec;
1185911820 bfd_size_type stub14_group_size;
1186011821 bfd_boolean suppress_size_errors;
1186111822
11823+ htab = ppc_hash_table (info);
11824+ if (htab == NULL)
11825+ return FALSE;
11826+
1186211827 suppress_size_errors = FALSE;
1186311828 stub14_group_size = stub_group_size >> 10;
1186411829 if (stub_group_size == 1)
@@ -11877,10 +11842,14 @@ group_sections (struct ppc_link_hash_table *htab,
1187711842 suppress_size_errors = TRUE;
1187811843 }
1187911844
11880- list = htab->input_list + htab->top_index;
11881- do
11845+ for (osec = info->output_bfd->sections; osec != NULL; osec = osec->next)
1188211846 {
11883- asection *tail = *list;
11847+ asection *tail;
11848+
11849+ if (osec->id >= htab->sec_info_arr_size)
11850+ continue;
11851+
11852+ tail = htab->sec_info[osec->id].u.list;
1188411853 while (tail != NULL)
1188511854 {
1188611855 asection *curr;
@@ -11888,6 +11857,7 @@ group_sections (struct ppc_link_hash_table *htab,
1188811857 bfd_size_type total;
1188911858 bfd_boolean big_sec;
1189011859 bfd_vma curr_toc;
11860+ struct map_stub *group;
1189111861
1189211862 curr = tail;
1189311863 total = tail->size;
@@ -11897,14 +11867,14 @@ group_sections (struct ppc_link_hash_table *htab,
1189711867 if (big_sec && !suppress_size_errors)
1189811868 (*_bfd_error_handler) (_("%B section %A exceeds stub group size"),
1189911869 tail->owner, tail);
11900- curr_toc = htab->stub_group[tail->id].toc_off;
11870+ curr_toc = htab->sec_info[tail->id].toc_off;
1190111871
11902- while ((prev = PREV_SEC (curr)) != NULL
11872+ while ((prev = htab->sec_info[curr->id].u.list) != NULL
1190311873 && ((total += curr->output_offset - prev->output_offset)
1190411874 < (ppc64_elf_section_data (prev) != NULL
1190511875 && ppc64_elf_section_data (prev)->has_14bit_branch
1190611876 ? stub14_group_size : stub_group_size))
11907- && htab->stub_group[prev->id].toc_off == curr_toc)
11877+ && htab->sec_info[prev->id].toc_off == curr_toc)
1190811878 curr = prev;
1190911879
1191011880 /* OK, the size from the start of CURR to the end is less
@@ -11917,11 +11887,16 @@ group_sections (struct ppc_link_hash_table *htab,
1191711887 only break if stubs added make the total size more than
1191811888 2^25, ie. for the default stub_group_size, if stubs total
1191911889 more than 2097152 bytes, or nearly 75000 plt call stubs. */
11890+ group = bfd_alloc (curr->owner, sizeof (*group));
11891+ if (group == NULL)
11892+ return FALSE;
11893+ group->link_sec = curr;
11894+ group->stub_sec = NULL;
1192011895 do
1192111896 {
11922- prev = PREV_SEC (tail);
11897+ prev = htab->sec_info[tail->id].u.list;
1192311898 /* Set up this stub group. */
11924- htab->stub_group[tail->id].link_sec = curr;
11899+ htab->sec_info[tail->id].u.group = group;
1192511900 }
1192611901 while (tail != curr && (tail = prev) != NULL);
1192711902
@@ -11938,19 +11913,17 @@ group_sections (struct ppc_link_hash_table *htab,
1193811913 < (ppc64_elf_section_data (prev) != NULL
1193911914 && ppc64_elf_section_data (prev)->has_14bit_branch
1194011915 ? stub14_group_size : stub_group_size))
11941- && htab->stub_group[prev->id].toc_off == curr_toc)
11916+ && htab->sec_info[prev->id].toc_off == curr_toc)
1194211917 {
1194311918 tail = prev;
11944- prev = PREV_SEC (tail);
11945- htab->stub_group[tail->id].link_sec = curr;
11919+ prev = htab->sec_info[tail->id].u.list;
11920+ htab->sec_info[tail->id].u.group = group;
1194611921 }
1194711922 }
1194811923 tail = prev;
1194911924 }
1195011925 }
11951- while (list-- != htab->input_list);
11952- free (htab->input_list);
11953-#undef PREV_SEC
11926+ return TRUE;
1195411927 }
1195511928
1195611929 static const unsigned char glink_eh_frame_cie[] =
@@ -12055,7 +12028,8 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
1205512028 else
1205612029 stub_group_size = htab->params->group_size;
1205712030
12058- group_sections (htab, stub_group_size, stubs_always_before_branch);
12031+ if (!group_sections (info, stub_group_size, stubs_always_before_branch))
12032+ return FALSE;
1205912033
1206012034 while (1)
1206112035 {
@@ -12258,8 +12232,8 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
1225812232 fact a call needing a TOC adjustment. */
1225912233 if (code_sec != NULL
1226012234 && code_sec->output_section != NULL
12261- && (htab->stub_group[code_sec->id].toc_off
12262- != htab->stub_group[section->id].toc_off)
12235+ && (htab->sec_info[code_sec->id].toc_off
12236+ != htab->sec_info[section->id].toc_off)
1226312237 && (code_sec->has_toc_reloc
1226412238 || code_sec->makes_toc_func_call))
1226512239 stub_type = ppc_stub_long_branch_r2off;
@@ -12299,7 +12273,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
1229912273 stub_type = ppc_stub_plt_call_r2save;
1230012274
1230112275 /* Support for grouping stub sections. */
12302- id_sec = htab->stub_group[section->id].link_sec;
12276+ id_sec = htab->sec_info[section->id].u.group->link_sec;
1230312277
1230412278 /* Get the name of this stub. */
1230512279 stub_name = ppc_stub_name (id_sec, sym_sec, hash, irela);
@@ -13234,8 +13208,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
1323413208
1323513209 if (h != NULL && &h->elf == htab->elf.hgot)
1323613210 {
13237- relocation = (TOCstart
13238- + htab->stub_group[input_section->id].toc_off);
13211+ relocation = TOCstart + htab->sec_info[input_section->id].toc_off;
1323913212 sec = bfd_abs_section_ptr;
1324013213 unresolved_reloc = FALSE;
1324113214 }
@@ -13943,8 +13916,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
1394313916 /* Munge up the value and addend so that we call the stub
1394413917 rather than the procedure directly. */
1394513918 relocation = (stub_entry->stub_offset
13946- + stub_entry->stub_sec->output_offset
13947- + stub_entry->stub_sec->output_section->vma);
13919+ + stub_entry->group->stub_sec->output_offset
13920+ + stub_entry->group->stub_sec->output_section->vma);
1394813921 addend = 0;
1394913922 reloc_dest = DEST_STUB;
1395013923
@@ -14241,7 +14214,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
1424114214 abort ();
1424214215
1424314216 relocation = got->output_section->vma + got->output_offset + off;
14244- addend = -(TOCstart + htab->stub_group[input_section->id].toc_off);
14217+ addend = -(TOCstart + htab->sec_info[input_section->id].toc_off);
1424514218 }
1424614219 break;
1424714220
@@ -14282,11 +14255,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
1428214255 /* Relocation value is TOC base. */
1428314256 relocation = TOCstart;
1428414257 if (r_symndx == STN_UNDEF)
14285- relocation += htab->stub_group[input_section->id].toc_off;
14258+ relocation += htab->sec_info[input_section->id].toc_off;
1428614259 else if (unresolved_reloc)
1428714260 ;
14288- else if (sec != NULL && sec->id <= htab->top_id)
14289- relocation += htab->stub_group[sec->id].toc_off;
14261+ else if (sec != NULL && sec->id < htab->sec_info_arr_size)
14262+ relocation += htab->sec_info[sec->id].toc_off;
1429014263 else
1429114264 unresolved_reloc = TRUE;
1429214265 goto dodyn;
@@ -14301,7 +14274,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
1430114274 case R_PPC64_TOC16_DS:
1430214275 case R_PPC64_TOC16_LO_DS:
1430314276 case R_PPC64_TOC16_HA:
14304- addend -= TOCstart + htab->stub_group[input_section->id].toc_off;
14277+ addend -= TOCstart + htab->sec_info[input_section->id].toc_off;
1430514278 break;
1430614279
1430714280 /* Relocate against the beginning of the section. */
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -821,13 +821,13 @@ _bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
821821 return TRUE;
822822 }
823823
824+static unsigned int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */
825+
824826 /* Initializes a new section. NEWSECT->NAME is already set. */
825827
826828 static asection *
827829 bfd_section_init (bfd *abfd, asection *newsect)
828830 {
829- static unsigned int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */
830-
831831 newsect->id = section_id;
832832 newsect->index = abfd->section_count;
833833 newsect->owner = abfd;
@@ -1275,6 +1275,23 @@ bfd_make_section (bfd *abfd, const char *name)
12751275
12761276 /*
12771277 FUNCTION
1278+ bfd_get_next_section_id
1279+
1280+SYNOPSIS
1281+ int bfd_get_next_section_id (void);
1282+
1283+DESCRIPTION
1284+ Returns the id that the next section created will have.
1285+*/
1286+
1287+int
1288+bfd_get_next_section_id (void)
1289+{
1290+ return section_id;
1291+}
1292+
1293+/*
1294+FUNCTION
12781295 bfd_set_section_flags
12791296
12801297 SYNOPSIS