This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Multiple sections with the same name again
On Mon, May 24, 2004 at 09:06:19AM +0200, Jakub Jelinek wrote:
> On Mon, May 24, 2004 at 01:10:52PM +0930, Alan Modra wrote:
> > I think what should be done is
> > - Remove the _bfd_merge_section call in elf_link_add_object_symbols.
> > This is primarily collecting information on what sections should be
> > merged.
> > - Move the bfd_merge_sections call in lang_process after
> > lang_place_orphans and before ldemul_before_allocation.
> > - Traverse the linker script in bfd_merge_sections to determine which
> > sections should be merged.
> >
> > Jakub, do you see any problem in doing things this way?
>
> It has been a few years since I wrote that, so I don't remember the details
> and things probably changed in that area too.
> But I remember I have been fighting badly with section removal at that time,
> at some point setting SEC_EXCLUDE no longer worked and clearing _cooked_size
> never actually worked (the size would be reset from _raw_size).
> If it works now, I have certainly no problems with moving the call.
Applying mainline.
bfd/ChangeLog
* elflink.c (elf_link_add_object_symbols): Don't set up merge
section data here..
* elf.c (_bfd_elf_merge_sections): .. Do it here instead.
* merge.c (_bfd_merge_section): Update comment. Don't test
section name to determine sinfo group, instead test output
section.
ld/ChangeLog
* ldlang.c (lang_process): Call bfd_merge_sections later, and
only when not a relocatable link.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.227
diff -u -p -r1.227 elf.c
--- bfd/elf.c 22 May 2004 01:56:30 -0000 1.227
+++ bfd/elf.c 24 May 2004 06:25:00 -0000
@@ -901,9 +901,29 @@ merge_sections_remove_hook (bfd *abfd AT
bfd_boolean
_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
{
+ bfd *ibfd;
+ asection *sec;
+
if (!is_elf_hash_table (info->hash))
return FALSE;
- if (elf_hash_table (info)->merge_info)
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ if ((ibfd->flags & DYNAMIC) == 0)
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_MERGE) != 0
+ && !bfd_is_abs_section (sec->output_section))
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (sec);
+ if (! _bfd_merge_section (abfd, &elf_hash_table (info)->merge_info,
+ sec, &secdata->sec_info))
+ return FALSE;
+ else if (secdata->sec_info)
+ sec->sec_info_type = ELF_INFO_TYPE_MERGE;
+ }
+
+ if (elf_hash_table (info)->merge_info != NULL)
_bfd_merge_sections (abfd, elf_hash_table (info)->merge_info,
merge_sections_remove_hook);
return TRUE;
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.70
diff -u -p -r1.70 elflink.c
--- bfd/elflink.c 22 May 2004 01:56:30 -0000 1.70
+++ bfd/elflink.c 24 May 2004 06:14:25 -0000
@@ -4127,28 +4127,6 @@ elf_link_add_object_symbols (bfd *abfd,
}
}
- if (! info->relocatable
- && ! dynamic
- && is_elf_hash_table (hash_table))
- {
- asection *s;
-
- for (s = abfd->sections; s != NULL; s = s->next)
- if ((s->flags & SEC_MERGE) != 0
- && !bfd_is_abs_section (s->output_section))
- {
- struct bfd_elf_section_data *secdata;
-
- secdata = elf_section_data (s);
- if (! _bfd_merge_section (abfd,
- & hash_table->merge_info,
- s, &secdata->sec_info))
- goto error_return;
- else if (secdata->sec_info)
- s->sec_info_type = ELF_INFO_TYPE_MERGE;
- }
- }
-
if (is_elf_hash_table (hash_table))
{
/* Add this bfd to the loaded list. */
Index: bfd/merge.c
===================================================================
RCS file: /cvs/src/src/bfd/merge.c,v
retrieving revision 1.19
diff -u -p -r1.19 merge.c
--- bfd/merge.c 22 May 2004 01:56:30 -0000 1.19
+++ bfd/merge.c 24 May 2004 06:14:27 -0000
@@ -328,8 +328,7 @@ sec_merge_emit (bfd *abfd, struct sec_me
return entry == NULL || entry->secinfo != secinfo;
}
-/* This function is called for each input file from the add_symbols
- pass of the linker. */
+/* This function is called for non-dynamic SEC_MERGE input sections. */
bfd_boolean
_bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo)
@@ -340,7 +339,7 @@ _bfd_merge_section (bfd *abfd, void **ps
bfd_size_type amt;
if (sec->_raw_size == 0
- || (sec->flags & SEC_EXCLUDE)
+ || (sec->flags & SEC_EXCLUDE) != 0
|| (sec->flags & SEC_MERGE) == 0
|| sec->entsize == 0)
return TRUE;
@@ -371,7 +370,7 @@ _bfd_merge_section (bfd *abfd, void **ps
if ((secinfo = sinfo->chain)
&& ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
&& secinfo->sec->entsize == sec->entsize
- && ! strcmp (secinfo->sec->name, sec->name))
+ && secinfo->sec->output_section == sec->output_section)
break;
if (sinfo == NULL)
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.147
diff -u -p -r1.147 ldlang.c
--- ld/ldlang.c 19 May 2004 14:15:55 -0000 1.147
+++ ld/ldlang.c 24 May 2004 06:14:57 -0000
@@ -4384,12 +4384,6 @@ lang_process (void)
if (command_line.gc_sections)
lang_gc_sections ();
- /* If there were any SEC_MERGE sections, finish their merging, so that
- section sizes can be computed. This has to be done after GC of sections,
- so that GCed sections are not merged, but before assigning output
- sections, since removing whole input sections is hard then. */
- bfd_merge_sections (output_bfd, &link_info);
-
/* Size up the common data. */
lang_common ();
@@ -4402,8 +4396,16 @@ lang_process (void)
if (! link_info.relocatable)
{
+ asection *found;
+
+ /* Merge SEC_MERGE sections. This has to be done after GC of
+ sections, so that GCed sections are not merged, but before
+ assigning dynamic symbols, since removing whole input sections
+ is hard then. */
+ bfd_merge_sections (output_bfd, &link_info);
+
/* Look for a text section and set the readonly attribute in it. */
- asection *found = bfd_get_section_by_name (output_bfd, ".text");
+ found = bfd_get_section_by_name (output_bfd, ".text");
if (found != NULL)
{
--
Alan Modra
IBM OzLabs - Linux Technology Centre