summaryrefslogtreecommitdiffstats
path: root/ld/emultempl
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2008-10-03 09:40:49 +0000
committerAlan Modra <amodra@gmail.com>2008-10-03 09:40:49 +0000
commitbcacc0f587e22ba46333d9377e7e9e4576c90f74 (patch)
tree0035a6958c007460d3837b1e245b5f89edeb3661 /ld/emultempl
parent81ab4297b7f533d6750f073cad0fe6169f567e85 (diff)
downloadppe42-binutils-bcacc0f587e22ba46333d9377e7e9e4576c90f74.tar.gz
ppe42-binutils-bcacc0f587e22ba46333d9377e7e9e4576c90f74.zip
bfd/
* elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when the signature symbol is global. * elflink.c (elf_link_input_bfd): Ensure group signature symbol is output when ld -r. Set group sh_info when local. * linker.c (default_indirect_link_order): Handle group sections specially. ld/ * ldemul.c (ldemul_place_orphan): Add "name" param. * ldemul.h (ldemul_place_orphan): Update prototype. (struct ld_emulation_xfer_struct <place_orphan>): Likewise. * ldlang.c (lang_place_orphans): Generate unique section names here.. * emultempl/elf32.em (place_orphan): ..rather than here. Don't directly use an existing output section statement that has no bfd section. * emultempl/pe.em (place_orphan): Likewise. * emultempl/pep.em (place_orphan): Likewise. * emultempl/beos.em (place_orphan): Adjust. * emultempl/spuelf.em (spu_place_special_section): Adjust place_orphan call. * emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function. (LDEMUL_AFTER_OPEN): Define.
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/beos.em5
-rw-r--r--ld/emultempl/elf32.em59
-rw-r--r--ld/emultempl/genelf.em20
-rw-r--r--ld/emultempl/pe.em30
-rw-r--r--ld/emultempl/pep.em30
-rw-r--r--ld/emultempl/spuelf.em7
6 files changed, 56 insertions, 95 deletions
diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em
index fac0c893c6..997f3a63ce 100644
--- a/ld/emultempl/beos.em
+++ b/ld/emultempl/beos.em
@@ -665,9 +665,8 @@ gld_${EMULATION_NAME}_before_allocation (void)
which are not mentioned in the linker script. */
static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s)
+gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
{
- const char *secname;
char *output_secname, *ps;
lang_output_section_statement_type *os;
lang_statement_union_type *l;
@@ -682,8 +681,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
if (link_info.relocatable)
return FALSE;
- secname = bfd_get_section_name (s->owner, s);
-
/* Everything from the '\$' on gets deleted so don't allow '\$' as the
first character. */
if (*secname == '\$')
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index be9d78d2ef..65ad4f1346 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -62,7 +62,7 @@ fragment <<EOF
static void gld${EMULATION_NAME}_before_parse (void);
static void gld${EMULATION_NAME}_after_open (void);
static void gld${EMULATION_NAME}_before_allocation (void);
-static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *s);
+static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *, const char *);
static void gld${EMULATION_NAME}_finish (void);
EOF
@@ -1635,7 +1635,7 @@ output_rel_find (asection *sec, int isdyn)
sections in the right segment. */
static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s)
+gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
{
static struct orphan_save hold[] =
{
@@ -1673,15 +1673,12 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
};
static int orphan_init_done = 0;
struct orphan_save *place;
- const char *secname;
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))
@@ -1707,28 +1704,24 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
}
}
- if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
+ /* Look through the script to see where to place this section. */
+ os = lang_output_section_find (secname);
+
+ if (os != NULL
+ && os->bfd_section != NULL
+ && (os->bfd_section->flags == 0
+ || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
+ os->bfd_section, s->owner, s)
+ && ((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0)))
{
- /* Look through the script to see where to place this section. */
- os = lang_output_section_find (secname);
-
- if (os != NULL
- && (os->bfd_section == NULL
- || os->bfd_section->flags == 0
- || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
- os->bfd_section,
- s->owner, s)
- && ((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.
- If the section already exists but does not have any flags
- set, then it has been created by the linker, probably as a
- result of a --section-start command line switch. */
- lang_add_section (&os->children, s, os);
- return TRUE;
- }
+ /* We already have an output section statement with this
+ name, and its bfd section has compatible flags.
+ If the section already exists but does not have any flags
+ set, then it has been created by the linker, probably as a
+ result of a --section-start command line switch. */
+ lang_add_section (&os->children, s, os);
+ return TRUE;
}
if (!orphan_init_done)
@@ -1748,7 +1741,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
sections into the .text section to get them out of the way. */
if (link_info.executable
&& ! link_info.relocatable
- && CONST_STRNEQ (secname, ".gnu.warning.")
+ && CONST_STRNEQ (s->name, ".gnu.warning.")
&& hold[orphan_text].os != NULL)
{
lang_add_section (&hold[orphan_text].os->children, s,
@@ -1803,18 +1796,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s)
after = &lang_output_section_statement.head->output_section_statement;
}
- /* Choose a unique name for the section. This will be needed if the
- same section name appears in the input file with different
- loadable or allocatable characteristics. */
- if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
- {
- static int count = 1;
- secname = bfd_get_unique_section_name (link_info.output_bfd,
- secname, &count);
- if (secname == NULL)
- einfo ("%F%P: place_orphan failed: %E\n");
- }
-
lang_insert_orphan (s, secname, after, place, NULL, NULL);
return TRUE;
diff --git a/ld/emultempl/genelf.em b/ld/emultempl/genelf.em
index e44bb9b9e1..e6e8841f0d 100644
--- a/ld/emultempl/genelf.em
+++ b/ld/emultempl/genelf.em
@@ -34,7 +34,27 @@ gld${EMULATION_NAME}_finish (void)
gld${EMULATION_NAME}_map_segments (FALSE);
finish_default ();
}
+
+static void
+gld${EMULATION_NAME}_after_open (void)
+{
+ bfd *ibfd;
+ asection *sec;
+ asymbol **syms;
+
+ if (link_info.relocatable)
+ for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ if ((syms = bfd_get_outsymbols (ibfd)) != NULL
+ && bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP)
+ {
+ struct bfd_elf_section_data *sec_data = elf_section_data (sec);
+ elf_group_id (sec) = syms[sec_data->this_hdr.sh_info - 1];
+ }
+}
EOF
# Put these extra routines in ld_${EMULATION_NAME}_emulation
#
LDEMUL_FINISH=gld${EMULATION_NAME}_finish
+LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index cec399a052..89c521d9e9 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -1613,24 +1613,20 @@ gld_${EMULATION_NAME}_finish (void)
sort_sections. */
static bfd_boolean
-gld_${EMULATION_NAME}_place_orphan (asection *s)
+gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
{
- const char *secname;
- const char *orig_secname;
+ const char *orig_secname = secname;
char *dollar = NULL;
lang_output_section_statement_type *os;
lang_statement_list_type add_child;
- secname = bfd_get_section_name (s->owner, s);
-
/* Look through the script to see where to place this section. */
- orig_secname = secname;
if (!link_info.relocatable
&& (dollar = strchr (secname, '$')) != NULL)
{
- size_t len = dollar - orig_secname;
+ size_t len = dollar - secname;
char *newname = xmalloc (len + 1);
- memcpy (newname, orig_secname, len);
+ memcpy (newname, secname, len);
newname[len] = '\0';
secname = newname;
}
@@ -1640,13 +1636,13 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
lang_list_init (&add_child);
if (os != NULL
- && (os->bfd_section == NULL
- || os->bfd_section->flags == 0
+ && os->bfd_section != NULL
+ && (os->bfd_section->flags == 0
|| ((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.
+ name, and its bfd section has compatible flags.
If the section already exists but does not have any flags set,
then it has been created by the linker, probably as a result of
a --section-start command line switch. */
@@ -1723,18 +1719,6 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
->output_section_statement);
}
- /* Choose a unique name for the section. This will be needed if the
- same section name appears in the input file with different
- loadable or allocatable characteristics. */
- if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
- {
- static int count = 1;
- secname = bfd_get_unique_section_name (link_info.output_bfd,
- secname, &count);
- if (secname == NULL)
- einfo ("%F%P: place_orphan failed: %E\n");
- }
-
/* All sections in an executable must be aligned to a page boundary. */
address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
os = lang_insert_orphan (s, secname, after, place, address, &add_child);
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 0b9bf402b5..4afac022b6 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -1372,24 +1372,20 @@ gld_${EMULATION_NAME}_finish (void)
sort_sections. */
static bfd_boolean
-gld_${EMULATION_NAME}_place_orphan (asection *s)
+gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
{
- const char *secname;
- const char *orig_secname;
+ const char *orig_secname = secname;
char *dollar = NULL;
lang_output_section_statement_type *os;
lang_statement_list_type add_child;
- secname = bfd_get_section_name (s->owner, s);
-
/* Look through the script to see where to place this section. */
- orig_secname = secname;
if (!link_info.relocatable
&& (dollar = strchr (secname, '$')) != NULL)
{
- size_t len = dollar - orig_secname;
+ size_t len = dollar - secname;
char *newname = xmalloc (len + 1);
- memcpy (newname, orig_secname, len);
+ memcpy (newname, secname, len);
newname[len] = '\0';
secname = newname;
}
@@ -1399,13 +1395,13 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
lang_list_init (&add_child);
if (os != NULL
- && (os->bfd_section == NULL
- || os->bfd_section->flags == 0
+ && os->bfd_section != NULL
+ && (os->bfd_section->flags == 0
|| ((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.
+ name, and its bfd section has compatible flags.
If the section already exists but does not have any flags set,
then it has been created by the linker, probably as a result of
a --section-start command line switch. */
@@ -1482,18 +1478,6 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
->output_section_statement);
}
- /* Choose a unique name for the section. This will be needed if the
- same section name appears in the input file with different
- loadable or allocatable characteristics. */
- if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
- {
- static int count = 1;
- secname = bfd_get_unique_section_name (link_info.output_bfd,
- secname, &count);
- if (secname == NULL)
- einfo ("%F%P: place_orphan failed: %E\n");
- }
-
/* All sections in an executable must be aligned to a page boundary. */
address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
os = lang_insert_orphan (s, secname, after, place, address, &add_child);
diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em
index 116a0cc985..bc2f6b548f 100644
--- a/ld/emultempl/spuelf.em
+++ b/ld/emultempl/spuelf.em
@@ -114,12 +114,7 @@ spu_place_special_section (asection *s, asection *o, const char *output_name)
os = lang_output_section_find (o != NULL ? o->name : output_name);
if (os == NULL)
- {
- const char *save = s->name;
- s->name = output_name;
- gld${EMULATION_NAME}_place_orphan (s);
- s->name = save;
- }
+ gld${EMULATION_NAME}_place_orphan (s, output_name);
else if (o != NULL && os->children.head != NULL)
{
lang_statement_list_type add;
OpenPOWER on IntegriCloud