This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: ld/1467: Orphaned section is put in the odd place
On Wed, Oct 12, 2005 at 09:19:33AM -0400, Daniel Jacobowitz wrote:
> On Tue, Oct 11, 2005 at 10:49:33PM -0700, H. J. Lu wrote:
> > The ELF linker doesn't check section type and checks section name when
> > placing orphan. Both may lead to odd orphaned section placement. This
> > patch adds section type check and removes the section name check.
>
> Hi HJ,
>
> My biggest complaint about almost every patch you post is that you
> don't explain what you're doing. What does "odd" mean here? What does
> it look like before and after? Is anything actually wrong? Some bits
> of this patch are pretty obvious, but some I couldn't figure out by
> looking at them.
>
Here is an updated patch to handle non-ELF input and reduce the code
duplication. The old section order is
[ 1] .text PROGBITS 0000000000000000 00100000
0000000000000004 0000000000000000 AX 0 0 4
[ 2] .data PROGBITS 0000000000000004 00100004
0000000000000004 0000000000000000 WA 0 0 4
[ 3] .note NOTE 0000000000000008 00100008
0000000000000004 0000000000000000 A 0 0 1
[ 4] .notbad PROGBITS 000000000000000c 0010000c
0000000000000004 0000000000000000 A 0 0 1
[ 5] .note.bar NOTE 0000000000000010 00100010
0000000000000004 0000000000000000 A 0 0 1
where an orphaned PROGBITS section is placed between 2 NOTE sections.
The new one is
[ 1] .text PROGBITS 0000000000000000 00100000
0000000000000004 0000000000000000 AX 0 0 4
[ 2] .notbad PROGBITS 0000000000000004 00100004
0000000000000004 0000000000000000 A 0 0 1
[ 3] .data PROGBITS 0000000000000008 00100008
0000000000000004 0000000000000000 WA 0 0 4
[ 4] .note NOTE 000000000000000c 0010000c
0000000000000004 0000000000000000 A 0 0 1
[ 5] .note.bar NOTE 0000000000000010 00100010
0000000000000004 0000000000000000 A 0 0 1
H.J.
----
bfd/
2005-10-12 H.J. Lu <hongjiu.lu@intel.com>
PR ld/1467
* elf-bfd.h (_bfd_elf_match_sections_by_type): New.
(_bfd_generic_match_sections_by_type): New. Defined.
* elf.c (_bfd_elf_match_sections_by_type): New.
* libbfd-in.h (_bfd_generic_match_sections_by_type): New.
* bfd-in2.h: Regenerated.
* libbfd.h: Likewise.
* libbfd.c (_bfd_generic_match_sections_by_type): New.
* targets.c (BFD_JUMP_TABLE_LINK): Initialize
_bfd_match_sections_by_type with
_bfd_generic_match_sections_by_type.
(bfd_target): Add _bfd_match_sections_by_type.
ld/
2005-10-12 H.J. Lu <hongjiu.lu@intel.com>
PR ld/1467
* emultempl/elf32.em: Include "elf-bfd.h".
(gld${EMULATION_NAME}_place_orphan): Check section type and
don't use section name for ELF input sections.
* ldlang.c (lang_output_section_find_by_flags): Match section
types by calling bfd_match_sections_by_type.
--- binutils/bfd/elf-bfd.h.orphan 2005-09-28 10:40:36.000000000 -0700
+++ binutils/bfd/elf-bfd.h 2005-10-12 10:39:22.000000000 -0700
@@ -1474,6 +1474,10 @@ extern bfd_boolean _bfd_elf_slurp_versio
(bfd *, bfd_boolean);
extern bfd_boolean _bfd_elf_merge_sections
(bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_match_sections_by_type
+ (bfd *, const asection *, bfd *, const asection *);
+#define _bfd_generic_match_sections_by_type \
+ _bfd_elf_match_sections_by_type
extern bfd_boolean bfd_elf_is_group_section
(bfd *, const struct bfd_section *);
extern void _bfd_elf_section_already_linked
--- binutils/bfd/elf.c.orphan 2005-10-07 13:47:31.000000000 -0700
+++ binutils/bfd/elf.c 2005-10-12 10:37:40.000000000 -0700
@@ -8502,3 +8502,18 @@ asection _bfd_elf_large_com_section
= BFD_FAKE_SECTION (_bfd_elf_large_com_section,
SEC_IS_COMMON, NULL, NULL, "LARGE_COMMON",
0);
+
+/* Return TRUE if 2 section types are compatible. */
+
+bfd_boolean
+_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec,
+ bfd *bbfd, const asection *bsec)
+{
+ if (asec == NULL
+ || bsec == NULL
+ || abfd->xvec->flavour != bfd_target_elf_flavour
+ || bbfd->xvec->flavour != bfd_target_elf_flavour)
+ return TRUE;
+
+ return elf_section_type (asec) == elf_section_type (bsec);
+}
--- binutils/bfd/libbfd-in.h.orphan 2005-07-06 08:45:40.000000000 -0700
+++ binutils/bfd/libbfd-in.h 2005-10-12 10:37:54.000000000 -0700
@@ -399,6 +399,8 @@ extern bfd_boolean _bfd_generic_set_sect
((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
#define _bfd_nolink_section_already_linked \
((void (*) (bfd *, struct bfd_section *)) bfd_void)
+extern bfd_boolean _bfd_generic_match_sections_by_type
+ (bfd *, const asection *, bfd *, const asection *);
/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC
--- binutils/bfd/libbfd.c.orphan 2005-10-07 13:47:31.000000000 -0700
+++ binutils/bfd/libbfd.c 2005-10-12 10:38:09.000000000 -0700
@@ -1033,3 +1033,12 @@ _bfd_generic_find_line (bfd *abfd ATTRIB
{
return FALSE;
}
+
+bfd_boolean
+_bfd_generic_match_sections_by_type (bfd *abfd ATTRIBUTE_UNUSED,
+ const asection *asec ATTRIBUTE_UNUSED,
+ bfd *bbfd ATTRIBUTE_UNUSED,
+ const asection *bsec ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
--- binutils/bfd/targets.c.orphan 2005-09-30 08:45:11.000000000 -0700
+++ binutils/bfd/targets.c 2005-10-12 10:39:49.000000000 -0700
@@ -427,6 +427,7 @@ BFD_JUMP_TABLE macros.
. NAME##_bfd_link_split_section, \
. NAME##_bfd_gc_sections, \
. NAME##_bfd_merge_sections, \
+. _bfd_generic_match_sections_by_type, \
. NAME##_bfd_is_group_section, \
. NAME##_bfd_discard_group, \
. NAME##_section_already_linked \
@@ -466,6 +467,12 @@ BFD_JUMP_TABLE macros.
. {* Attempt to merge SEC_MERGE sections. *}
. bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
.
+.#define bfd_match_sections_by_type(abfd, asec, bbfd, bsec) \
+. BFD_SEND (abfd, _bfd_match_sections_by_type, (abfd, asec, bbfd, bsec))
+. {* Return TRUE if 2 section types are compatible. *}
+. bfd_boolean (*_bfd_match_sections_by_type)
+. (bfd *, const asection *, bfd *, const asection *);
+.
. {* Is this section a member of a group? *}
. bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
.
--- binutils/ld/emultempl/elf32.em.orphan 2005-09-07 11:42:00.000000000 -0700
+++ binutils/ld/emultempl/elf32.em 2005-10-12 10:54:36.000000000 -0700
@@ -53,6 +53,7 @@ Foundation, Inc., 51 Franklin Street - F
#include "ldemul.h"
#include <ldgram.h>
#include "elf/common.h"
+#include "elf-bfd.h"
/* Declare functions used by various EXTRA_EM_FILEs. */
static void gld${EMULATION_NAME}_before_parse (void);
@@ -1324,19 +1325,34 @@ gld${EMULATION_NAME}_place_orphan (lang_
lang_output_section_statement_type *after;
lang_output_section_statement_type *os;
int isdyn = 0;
+ int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
+ unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
secname = bfd_get_section_name (s->owner, s);
if (! link_info.relocatable
&& link_info.combreloc
- && (s->flags & SEC_ALLOC)
- && strncmp (secname, ".rel", 4) == 0)
+ && (s->flags & SEC_ALLOC))
{
- if (secname[4] == 'a')
- secname = ".rela.dyn";
- else
- secname = ".rel.dyn";
- isdyn = 1;
+ if (iself)
+ switch (sh_type)
+ {
+ case SHT_RELA:
+ secname = ".rela.dyn";
+ isdyn = 1;
+ break;
+ case SHT_REL:
+ secname = ".rel.dyn";
+ isdyn = 1;
+ break;
+ default:
+ break;
+ }
+ else if (strncmp (secname, ".rel", 4) == 0)
+ {
+ secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn";
+ isdyn = 1;
+ }
}
if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
@@ -1347,8 +1363,10 @@ gld${EMULATION_NAME}_place_orphan (lang_
if (os != NULL
&& (os->bfd_section == NULL
|| os->bfd_section->flags == 0
- || ((s->flags ^ os->bfd_section->flags)
- & (SEC_LOAD | SEC_ALLOC)) == 0))
+ || ((!iself
+ || sh_type == elf_section_type (os->bfd_section))
+ && ((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0)))
{
/* We already have an output section statement with this
name, and its bfd section, if any, has compatible flags.
@@ -1395,7 +1413,8 @@ gld${EMULATION_NAME}_place_orphan (lang_
if ((s->flags & SEC_ALLOC) == 0)
;
else if ((s->flags & SEC_LOAD) != 0
- && strncmp (secname, ".note", 5) == 0)
+ && ((iself && sh_type == SHT_NOTE)
+ || (!iself && strncmp (secname, ".note", 5) == 0)))
place = &hold[orphan_interp];
else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
place = &hold[orphan_bss];
@@ -1403,7 +1422,8 @@ gld${EMULATION_NAME}_place_orphan (lang_
place = &hold[orphan_sdata];
else if ((s->flags & SEC_READONLY) == 0)
place = &hold[orphan_data];
- else if (strncmp (secname, ".rel", 4) == 0
+ else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
+ || (!iself && strncmp (secname, ".rel", 4) == 0))
&& (s->flags & SEC_LOAD) != 0)
place = &hold[orphan_rel];
else if ((s->flags & SEC_CODE) == 0)
--- binutils/ld/ldlang.c.orphan 2005-10-04 09:28:29.000000000 -0700
+++ binutils/ld/ldlang.c 2005-10-12 10:41:17.000000000 -0700
@@ -1149,7 +1149,13 @@ lang_output_section_find_by_flags (const
{
flags = look->flags;
if (look->bfd_section != NULL)
- flags = look->bfd_section->flags;
+ {
+ flags = look->bfd_section->flags;
+ if (!bfd_match_sections_by_type (output_bfd,
+ look->bfd_section,
+ sec->owner, sec))
+ continue;
+ }
flags ^= sec->flags;
if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
@@ -1168,7 +1174,13 @@ lang_output_section_find_by_flags (const
{
flags = look->flags;
if (look->bfd_section != NULL)
- flags = look->bfd_section->flags;
+ {
+ flags = look->bfd_section->flags;
+ if (!bfd_match_sections_by_type (output_bfd,
+ look->bfd_section,
+ sec->owner, sec))
+ continue;
+ }
flags ^= sec->flags;
if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
| SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
@@ -1184,7 +1196,13 @@ lang_output_section_find_by_flags (const
{
flags = look->flags;
if (look->bfd_section != NULL)
- flags = look->bfd_section->flags;
+ {
+ flags = look->bfd_section->flags;
+ if (!bfd_match_sections_by_type (output_bfd,
+ look->bfd_section,
+ sec->owner, sec))
+ continue;
+ }
flags ^= sec->flags;
if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
| SEC_READONLY))
@@ -1201,7 +1219,13 @@ lang_output_section_find_by_flags (const
{
flags = look->flags;
if (look->bfd_section != NULL)
- flags = look->bfd_section->flags;
+ {
+ flags = look->bfd_section->flags;
+ if (!bfd_match_sections_by_type (output_bfd,
+ look->bfd_section,
+ sec->owner, sec))
+ continue;
+ }
flags ^= sec->flags;
if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
| SEC_THREAD_LOCAL))
@@ -1219,7 +1243,13 @@ lang_output_section_find_by_flags (const
{
flags = look->flags;
if (look->bfd_section != NULL)
- flags = look->bfd_section->flags;
+ {
+ flags = look->bfd_section->flags;
+ if (!bfd_match_sections_by_type (output_bfd,
+ look->bfd_section,
+ sec->owner, sec))
+ continue;
+ }
flags ^= sec->flags;
if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
| SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
@@ -1233,7 +1263,13 @@ lang_output_section_find_by_flags (const
{
flags = look->flags;
if (look->bfd_section != NULL)
- flags = look->bfd_section->flags;
+ {
+ flags = look->bfd_section->flags;
+ if (!bfd_match_sections_by_type (output_bfd,
+ look->bfd_section,
+ sec->owner, sec))
+ continue;
+ }
flags ^= sec->flags;
if (!(flags & SEC_ALLOC))
found = look;