aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl
diff options
context:
space:
mode:
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/armelf.em108
-rw-r--r--ld/emultempl/elf32.em108
-rw-r--r--ld/emultempl/pe.em90
3 files changed, 129 insertions, 177 deletions
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 8de6c9b..a1a3968 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -61,8 +61,7 @@ static void gld${EMULATION_NAME}_find_statement_assignment
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
static boolean gld${EMULATION_NAME}_place_orphan
PARAMS ((lang_input_statement_type *, asection *));
-static void gld${EMULATION_NAME}_place_section
- PARAMS ((lang_statement_union_type *));
+static lang_output_section_statement_type *output_rel_find PARAMS ((void));
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
@@ -783,21 +782,12 @@ gld${EMULATION_NAME}_vercheck (s)
/* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */
-static asection *hold_section;
-static lang_output_section_statement_type *hold_use;
-
struct orphan_save
{
lang_output_section_statement_type *os;
asection **section;
lang_statement_union_type **stmt;
};
-static struct orphan_save hold_text;
-static struct orphan_save hold_rodata;
-static struct orphan_save hold_data;
-static struct orphan_save hold_bss;
-static struct orphan_save hold_rel;
-static struct orphan_save hold_interp;
/*ARGSUSED*/
static boolean
@@ -805,6 +795,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
lang_input_statement_type *file;
asection *s;
{
+ static struct orphan_save hold_text;
+ static struct orphan_save hold_rodata;
+ static struct orphan_save hold_data;
+ static struct orphan_save hold_bss;
+ static struct orphan_save hold_rel;
+ static struct orphan_save hold_interp;
struct orphan_save *place;
lang_statement_list_type *old;
lang_statement_list_type add;
@@ -813,19 +809,22 @@ gld${EMULATION_NAME}_place_orphan (file, s)
const char *outsecname;
lang_output_section_statement_type *os;
+ secname = bfd_get_section_name (s->owner, s);
+
/* Look through the script to see where to place this section. */
- hold_section = s;
- hold_use = NULL;
- lang_for_each_statement (gld${EMULATION_NAME}_place_section);
+ os = lang_output_section_find (secname);
- if (hold_use != NULL)
+ if (os != NULL
+ && os->bfd_section != NULL
+ && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
{
/* We have already placed a section with this name. */
- wild_doit (&hold_use->children, s, hold_use, file);
+ wild_doit (&os->children, s, os, file);
return true;
}
- secname = bfd_get_section_name (s->owner, s);
+ if (hold_text.os == NULL)
+ hold_text.os = lang_output_section_find (".text");
/* If this is a final link, then always put .gnu.warning.SYMBOL
sections into the .text section to get them out of the way. */
@@ -843,26 +842,30 @@ gld${EMULATION_NAME}_place_orphan (file, s)
right after the .interp section, so that the PT_NOTE segment is
stored right after the program headers where the OS can read it
in the first page. */
+#define HAVE_SECTION(hold, name) \
+(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
+
if (s->flags & SEC_EXCLUDE)
return false;
else if ((s->flags & SEC_ALLOC) == 0)
place = NULL;
else if ((s->flags & SEC_LOAD) != 0
&& strncmp (secname, ".note", 4) == 0
- && hold_interp.os != NULL)
+ && HAVE_SECTION (hold_interp, ".interp"))
place = &hold_interp;
else if ((s->flags & SEC_HAS_CONTENTS) == 0
- && hold_bss.os != NULL)
+ && HAVE_SECTION (hold_bss, ".bss"))
place = &hold_bss;
else if ((s->flags & SEC_READONLY) == 0
- && hold_data.os != NULL)
+ && HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
else if (strncmp (secname, ".rel", 4) == 0
- && hold_rel.os != NULL)
+ && (hold_rel.os != NULL
+ || (hold_rel.os = output_rel_find ()) != NULL))
place = &hold_rel;
else if ((s->flags & SEC_CODE) == 0
&& (s->flags & SEC_READONLY) != 0
- && hold_rodata.os != NULL)
+ && HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
else if ((s->flags & SEC_READONLY) != 0
&& hold_text.os != NULL)
@@ -870,6 +873,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
else
place = NULL;
+#undef HAVE_SECTION
+
/* 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 allocateable characteristics. */
@@ -924,13 +929,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
else
address = NULL;
- lang_enter_output_section_statement (outsecname, address, 0,
- (bfd_vma) 0,
- (etree_type *) NULL,
- (etree_type *) NULL,
- (etree_type *) NULL);
+ os = lang_enter_output_section_statement (outsecname, address, 0,
+ (bfd_vma) 0,
+ (etree_type *) NULL,
+ (etree_type *) NULL,
+ (etree_type *) NULL);
- os = lang_output_section_statement_lookup (outsecname);
wild_doit (&os->children, s, os, file);
lang_leave_output_section_statement
@@ -1004,38 +1008,26 @@ gld${EMULATION_NAME}_place_orphan (file, s)
return true;
}
-static void
-gld${EMULATION_NAME}_place_section (s)
- lang_statement_union_type *s;
+/* A variant of lang_output_section_find. */
+static lang_output_section_statement_type *
+output_rel_find ()
{
- lang_output_section_statement_type *os;
-
- if (s->header.type != lang_output_section_statement_enum)
- return;
+ lang_statement_union_type *u;
+ lang_output_section_statement_type *lookup;
- os = &s->output_section_statement;
-
- if (strcmp (os->name, hold_section->name) == 0
- && os->bfd_section != NULL
- && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
- == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
- hold_use = os;
-
- if (strcmp (os->name, ".text") == 0)
- hold_text.os = os;
- else if (strcmp (os->name, ".rodata") == 0)
- hold_rodata.os = os;
- else if (strcmp (os->name, ".data") == 0)
- hold_data.os = os;
- else if (strcmp (os->name, ".bss") == 0)
- hold_bss.os = os;
- else if (hold_rel.os == NULL
- && os->bfd_section != NULL
- && (os->bfd_section->flags & SEC_ALLOC) != 0
- && strncmp (os->name, ".rel", 4) == 0)
- hold_rel.os = os;
- else if (strcmp (os->name, ".interp") == 0)
- hold_interp.os = os;
+ for (u = lang_output_section_statement.head;
+ u != (lang_statement_union_type *) NULL;
+ u = lookup->next)
+ {
+ lookup = &u->output_section_statement;
+ if (strncmp (".rel", lookup->name, 4) == 0
+ && lookup->bfd_section != NULL
+ && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+ {
+ return lookup;
+ }
+ }
+ return (lang_output_section_statement_type *) NULL;
}
/* Look through an expression for an assignment statement. */
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index d57aadb..9615285 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -65,8 +65,7 @@ static void gld${EMULATION_NAME}_find_statement_assignment
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
static boolean gld${EMULATION_NAME}_place_orphan
PARAMS ((lang_input_statement_type *, asection *));
-static void gld${EMULATION_NAME}_place_section
- PARAMS ((lang_statement_union_type *));
+static lang_output_section_statement_type *output_rel_find PARAMS ((void));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
static void
@@ -865,21 +864,12 @@ gld${EMULATION_NAME}_find_exp_assignment (exp)
/* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */
-static asection *hold_section;
-static lang_output_section_statement_type *hold_use;
-
struct orphan_save
{
lang_output_section_statement_type *os;
asection **section;
lang_statement_union_type **stmt;
};
-static struct orphan_save hold_text;
-static struct orphan_save hold_rodata;
-static struct orphan_save hold_data;
-static struct orphan_save hold_bss;
-static struct orphan_save hold_rel;
-static struct orphan_save hold_interp;
/*ARGSUSED*/
static boolean
@@ -887,6 +877,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
lang_input_statement_type *file;
asection *s;
{
+ static struct orphan_save hold_text;
+ static struct orphan_save hold_rodata;
+ static struct orphan_save hold_data;
+ static struct orphan_save hold_bss;
+ static struct orphan_save hold_rel;
+ static struct orphan_save hold_interp;
struct orphan_save *place;
lang_statement_list_type *old;
lang_statement_list_type add;
@@ -895,19 +891,22 @@ gld${EMULATION_NAME}_place_orphan (file, s)
const char *outsecname;
lang_output_section_statement_type *os;
+ secname = bfd_get_section_name (s->owner, s);
+
/* Look through the script to see where to place this section. */
- hold_section = s;
- hold_use = NULL;
- lang_for_each_statement (gld${EMULATION_NAME}_place_section);
+ os = lang_output_section_find (secname);
- if (hold_use != NULL)
+ if (os != NULL
+ && os->bfd_section != NULL
+ && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
{
/* We have already placed a section with this name. */
- wild_doit (&hold_use->children, s, hold_use, file);
+ wild_doit (&os->children, s, os, file);
return true;
}
- secname = bfd_get_section_name (s->owner, s);
+ if (hold_text.os == NULL)
+ hold_text.os = lang_output_section_find (".text");
/* If this is a final link, then always put .gnu.warning.SYMBOL
sections into the .text section to get them out of the way. */
@@ -925,26 +924,30 @@ gld${EMULATION_NAME}_place_orphan (file, s)
right after the .interp section, so that the PT_NOTE segment is
stored right after the program headers where the OS can read it
in the first page. */
+#define HAVE_SECTION(hold, name) \
+(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
+
if (s->flags & SEC_EXCLUDE)
return false;
else if ((s->flags & SEC_ALLOC) == 0)
place = NULL;
else if ((s->flags & SEC_LOAD) != 0
&& strncmp (secname, ".note", 4) == 0
- && hold_interp.os != NULL)
+ && HAVE_SECTION (hold_interp, ".interp"))
place = &hold_interp;
else if ((s->flags & SEC_HAS_CONTENTS) == 0
- && hold_bss.os != NULL)
+ && HAVE_SECTION (hold_bss, ".bss"))
place = &hold_bss;
else if ((s->flags & SEC_READONLY) == 0
- && hold_data.os != NULL)
+ && HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
else if (strncmp (secname, ".rel", 4) == 0
- && hold_rel.os != NULL)
+ && (hold_rel.os != NULL
+ || (hold_rel.os = output_rel_find ()) != NULL))
place = &hold_rel;
else if ((s->flags & SEC_CODE) == 0
&& (s->flags & SEC_READONLY) != 0
- && hold_rodata.os != NULL)
+ && HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
else if ((s->flags & SEC_READONLY) != 0
&& hold_text.os != NULL)
@@ -952,6 +955,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
else
place = NULL;
+#undef HAVE_SECTION
+
/* 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 allocateable characteristics. */
@@ -1006,13 +1011,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
else
address = NULL;
- lang_enter_output_section_statement (outsecname, address, 0,
- (bfd_vma) 0,
- (etree_type *) NULL,
- (etree_type *) NULL,
- (etree_type *) NULL);
+ os = lang_enter_output_section_statement (outsecname, address, 0,
+ (bfd_vma) 0,
+ (etree_type *) NULL,
+ (etree_type *) NULL,
+ (etree_type *) NULL);
- os = lang_output_section_statement_lookup (outsecname);
wild_doit (&os->children, s, os, file);
lang_leave_output_section_statement
@@ -1086,38 +1090,26 @@ gld${EMULATION_NAME}_place_orphan (file, s)
return true;
}
-static void
-gld${EMULATION_NAME}_place_section (s)
- lang_statement_union_type *s;
+/* A variant of lang_output_section_find. */
+static lang_output_section_statement_type *
+output_rel_find ()
{
- lang_output_section_statement_type *os;
-
- if (s->header.type != lang_output_section_statement_enum)
- return;
+ lang_statement_union_type *u;
+ lang_output_section_statement_type *lookup;
- os = &s->output_section_statement;
-
- if (strcmp (os->name, hold_section->name) == 0
- && os->bfd_section != NULL
- && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
- == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
- hold_use = os;
-
- if (strcmp (os->name, ".text") == 0)
- hold_text.os = os;
- else if (strcmp (os->name, ".rodata") == 0)
- hold_rodata.os = os;
- else if (strcmp (os->name, ".data") == 0)
- hold_data.os = os;
- else if (strcmp (os->name, ".bss") == 0)
- hold_bss.os = os;
- else if (hold_rel.os == NULL
- && os->bfd_section != NULL
- && (os->bfd_section->flags & SEC_ALLOC) != 0
- && strncmp (os->name, ".rel", 4) == 0)
- hold_rel.os = os;
- else if (strcmp (os->name, ".interp") == 0)
- hold_interp.os = os;
+ for (u = lang_output_section_statement.head;
+ u != (lang_statement_union_type *) NULL;
+ u = lookup->next)
+ {
+ lookup = &u->output_section_statement;
+ if (strncmp (".rel", lookup->name, 4) == 0
+ && lookup->bfd_section != NULL
+ && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+ {
+ return lookup;
+ }
+ }
+ return (lang_output_section_statement_type *) NULL;
}
static char *
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index aeecb61..06ae868 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -102,8 +102,6 @@ static void gld_${EMULATION_NAME}_after_parse PARAMS ((void));
static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
static boolean gld_${EMULATION_NAME}_place_orphan
PARAMS ((lang_input_statement_type *, asection *));
-static void gld${EMULATION_NAME}_place_section
- PARAMS ((lang_statement_union_type *));
static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
static void gld_${EMULATION_NAME}_finish PARAMS ((void));
@@ -1074,23 +1072,12 @@ gld_${EMULATION_NAME}_finish ()
default linker script using wildcards, and are sorted by
sort_sections. */
-static asection *hold_section;
-static char *hold_section_name;
-static lang_output_section_statement_type *hold_use;
-
struct orphan_save
{
lang_output_section_statement_type *os;
asection **section;
lang_statement_union_type **stmt;
};
-static struct orphan_save hold_text;
-static struct orphan_save hold_rdata;
-static struct orphan_save hold_data;
-static struct orphan_save hold_bss;
-
-/* Place an orphan section. We use this to put random SHF_ALLOC
- sections in the right segment. */
/*ARGSUSED*/
static boolean
@@ -1099,15 +1086,15 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
asection *s;
{
const char *secname;
+ char *hold_section_name;
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. */
- hold_section = s;
-
hold_section_name = xstrdup (secname);
if (!link_info.relocateable)
{
@@ -1116,18 +1103,23 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
*dollar = '\0';
}
- hold_use = NULL;
- lang_for_each_statement (gld${EMULATION_NAME}_place_section);
+ os = lang_output_section_find (hold_section_name);
lang_list_init (&add_child);
- if (hold_use != NULL)
+ if (os != NULL
+ && os->bfd_section != NULL
+ && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
{
- wild_doit (&add_child, s, hold_use, file);
+ wild_doit (&add_child, s, os, file);
}
else
{
struct orphan_save *place;
+ static struct orphan_save hold_text;
+ static struct orphan_save hold_rdata;
+ static struct orphan_save hold_data;
+ static struct orphan_save hold_bss;
char *outsecname;
lang_statement_list_type *old;
lang_statement_list_type add;
@@ -1135,23 +1127,28 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
/* Try to put the new output section in a reasonable place based
on the section name and section flags. */
+#define HAVE_SECTION(hold, name) \
+(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
+
place = NULL;
if ((s->flags & SEC_ALLOC) == 0)
;
else if ((s->flags & SEC_HAS_CONTENTS) == 0
- && hold_bss.os != NULL)
+ && HAVE_SECTION (hold_bss, ".bss"))
place = &hold_bss;
else if ((s->flags & SEC_READONLY) == 0
- && hold_data.os != NULL)
+ && HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
else if ((s->flags & SEC_CODE) == 0
&& (s->flags & SEC_READONLY) != 0
- && hold_rdata.os != NULL)
+ && HAVE_SECTION (hold_rdata, ".rdata"))
place = &hold_rdata;
else if ((s->flags & SEC_READONLY) != 0
- && hold_text.os != NULL)
+ && HAVE_SECTION (hold_text, ".text"))
place = &hold_text;
+#undef HAVE_SECTION
+
/* 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 allocateable characteristics. */
@@ -1192,19 +1189,17 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
exp_nameop (NAME, "__section_alignment__"));
}
- lang_enter_output_section_statement (outsecname, address, 0,
- (bfd_vma) 0,
- (etree_type *) NULL,
- (etree_type *) NULL,
- (etree_type *) NULL);
+ os = lang_enter_output_section_statement (outsecname, address, 0,
+ (bfd_vma) 0,
+ (etree_type *) NULL,
+ (etree_type *) NULL,
+ (etree_type *) NULL);
- hold_use = lang_output_section_statement_lookup (outsecname);
- wild_doit (&add_child, s, hold_use, file);
+ wild_doit (&add_child, s, os, file);
lang_leave_output_section_statement
((bfd_vma) 0, "*default*",
- (struct lang_output_section_phdr_list *) NULL,
- "*default*");
+ (struct lang_output_section_phdr_list *) NULL, "*default*");
stat_ptr = old;
@@ -1212,7 +1207,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
{
asection *snew, **pps;
- snew = hold_use->bfd_section;
+ snew = os->bfd_section;
if (place->os->bfd_section != NULL || place->section != NULL)
{
/* Shuffle the section to make the output file look neater. */
@@ -1261,7 +1256,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
}
{
- lang_statement_union_type **pl = &hold_use->children.head;
+ lang_statement_union_type **pl = &os->children.head;
if (dollar != NULL)
{
@@ -1308,33 +1303,6 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
return true;
}
-static void
-gld${EMULATION_NAME}_place_section (s)
- lang_statement_union_type *s;
-{
- lang_output_section_statement_type *os;
-
- if (s->header.type != lang_output_section_statement_enum)
- return;
-
- os = &s->output_section_statement;
-
- if (strcmp (os->name, hold_section_name) == 0
- && os->bfd_section != NULL
- && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
- == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
- hold_use = os;
-
- if (strcmp (os->name, ".text") == 0)
- hold_text.os = os;
- else if (strcmp (os->name, ".rdata") == 0)
- hold_rdata.os = os;
- else if (strcmp (os->name, ".data") == 0)
- hold_data.os = os;
- else if (strcmp (os->name, ".bss") == 0)
- hold_bss.os = os;
-}
-
static int
gld_${EMULATION_NAME}_find_potential_libraries (name, entry)
char * name;