This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Linker is broken
On Wed, May 26, 2004 at 07:21:10AM -0700, H. J. Lu wrote:
> On Wed, May 26, 2004 at 07:43:35PM +0930, Alan Modra wrote:
> > OK, I've audited places that set SEC_EXCLUDE and think I have it all
> > sorted out. SEC_EXCLUDE, as the comment says in sections.c, is really
> > only meant for final linking, but it may be set by various ELF backend
> > section_from_shdr functions, where the type of linker operation, if any,
> > isn't available. We do want to ignore SEC_EXCLUDE in these cases if
> > doing a relocatable link. However, the linker should act on SEC_EXCLUDE
> > set by bfd/stabs.c during relocatable linking. That's the reason for
> > the SEC_DEBUGGING test.
> >
> > The cleanest solution that I can see to the current problem is to
> > twiddle SEC_EXCLUDE in ldlang.c:lang_add_section. Then all later linker
> > code can simply test SEC_EXCLUDE without worrying about SEC_DEBUGGING
> > and link_info.relocatable.
> >
> > * elf.c (_bfd_elf_make_section_from_shdr): Don't set SEC_EXCLUDE
> > for SHT_GROUP sections.
>
> objdump -n won't show SEC_EXCLUDE on SHT_GROUP sections now.
>
> > * ldlang.c (lang_add_section): Set SEC_EXCLUDE for SEC_GROUP
> > sections when doing a final link. Clear SEC_EXCLUDE when doing
> > a relocable link, except for SEC_DEBUGGING sections.
>
> It seems broken to me if we rely on linker to set/clear SEC_EXCLUDE
> since there are many other SEC_EXCLUDE sections, which aren't set and
> cleared by linker. I am not sure it will work on SHF_EXCLUDE sections.
> I think we should test ld -r, SEC_DEBUGGING and SEC_EXCLUDE together
> when deciding if a section can be ignored.
>
> > * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Use the
> > same condition here to drop SEC_EXCLUDE orphan sections.
Here is a patch.
H.J.
-----
bfd/
2004-05-26 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (_bfd_elf_make_section_from_shdr): Undo the last
change.
ld/
2004-05-26 H.J. Lu <hongjiu.lu@intel.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Undo
the last change.
* ldlang.c (lang_add_section): Clear SEC_EXCLUDE on non-
SEC_DEBUGGING sections for relocatable link.
--- binutils/bfd/elf.c.exclude 2004-05-26 08:23:16.815215189 -0700
+++ binutils/bfd/elf.c 2004-05-26 08:29:32.228664936 -0700
@@ -697,7 +697,7 @@ _bfd_elf_make_section_from_shdr (bfd *ab
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
if (hdr->sh_type == SHT_GROUP)
- flags |= SEC_GROUP;
+ flags |= SEC_GROUP | SEC_EXCLUDE;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
flags |= SEC_ALLOC;
--- binutils/ld/emultempl/elf32.em.exclude 2004-05-26 08:21:22.128046699 -0700
+++ binutils/ld/emultempl/elf32.em 2004-05-26 08:36:06.515678123 -0700
@@ -1182,9 +1182,7 @@ gld${EMULATION_NAME}_place_orphan (lang_
#define HAVE_SECTION(hold, name) \
(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
- if (((s->flags & (SEC_EXCLUDE | SEC_GROUP)) != 0 && !link_info.relocatable)
- || ((s->flags & (SEC_EXCLUDE | SEC_DEBUGGING))
- == (SEC_EXCLUDE | SEC_DEBUGGING)))
+ if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocatable)
{
if (s->output_section == NULL)
s->output_section = bfd_abs_section_ptr;
--- binutils/ld/ldlang.c.exclude 2004-05-26 08:23:17.352145752 -0700
+++ binutils/ld/ldlang.c 2004-05-26 08:39:34.531796825 -0700
@@ -1169,29 +1169,20 @@ lang_add_section (lang_statement_list_ty
flags = bfd_get_section_flags (section->owner, section);
- discard = FALSE;
-
- if (link_info.relocatable)
- {
- /* SEC_EXCLUDE is ignored when doing a relocatable link,
- except in the special case of debug info. (See bfd/stabs.c) */
- if ((flags & SEC_DEBUGGING) == 0)
- flags &= ~SEC_EXCLUDE;
- }
- else
- {
- /* SEC_GROUP sections should be dropped on a final link. */
- if ((flags & SEC_GROUP) != 0)
- flags |= SEC_EXCLUDE;
+ /* SEC_EXCLUDE is ignored when doing a relocatable link, except in
+ the special case of debug info. (See bfd/stabs.c) */
+ if (link_info.relocatable && (flags & SEC_DEBUGGING) == 0)
+ {
+ flags &= ~SEC_EXCLUDE;
+
+ /* Write the modified flag back, to simplify later linker
+ code. */
+ if (section->owner != NULL)
+ bfd_set_section_flags (section->owner, section, flags);
}
- /* Write SEC_EXCLUDE flag back, to simplify later linker code. */
- if (section->owner != NULL)
- bfd_set_section_flags (section->owner, section, flags);
-
/* Discard sections marked with SEC_EXCLUDE. */
- if ((flags & SEC_EXCLUDE) != 0)
- discard = TRUE;
+ discard = (flags & SEC_EXCLUDE) != 0;
/* Discard input sections which are assigned to a section named
DISCARD_SECTION_NAME. */