place_orphan optimisations
This commit is contained in:
parent
8d82e76a9d
commit
aea4bd9d34
6 changed files with 159 additions and 182 deletions
23
ld/ChangeLog
23
ld/ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
2000-04-25 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Delete.
|
||||||
|
(output_rel_find): New function.
|
||||||
|
(hold_section, hold_use): Delete.
|
||||||
|
(hold_text, hold_rodata, hold_data, hold_bss, hold_rel,
|
||||||
|
hold_interp): Make local to place_orphan.
|
||||||
|
(gld${EMULATION_NAME}_place_orphan): Use lang_output_section_find
|
||||||
|
rather than place_section to find possible previous use of orphan.
|
||||||
|
Similarly find the place-holder output sections. Use returned
|
||||||
|
value from lang_enter_output_section_statement rather than calling
|
||||||
|
lang_output_section_statement_lookup.
|
||||||
|
* emultempl/armelf.em: Same here.
|
||||||
|
* emultempl/pe.em: Similar to above, but no need for output_rel_find.
|
||||||
|
|
||||||
|
* ldlang.c (lang_enter_output_section_statement): Return output
|
||||||
|
section statement.
|
||||||
|
* ldlang.h (lang_enter_output_section_statement): Change
|
||||||
|
declaration too.
|
||||||
|
|
||||||
|
* ldlang.h (lang_output_section_statement): Export it.
|
||||||
|
* ldlang.c (lang_output_section_statement): Ditto.
|
||||||
|
|
||||||
2000-04-24 Nick Clifton <nickc@cygnus.com>
|
2000-04-24 Nick Clifton <nickc@cygnus.com>
|
||||||
|
|
||||||
* ld.texinfo (Output Section Data): Add note that section data
|
* ld.texinfo (Output Section Data): Add note that section data
|
||||||
|
|
|
@ -61,8 +61,7 @@ static void gld${EMULATION_NAME}_find_statement_assignment
|
||||||
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
|
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
|
||||||
static boolean gld${EMULATION_NAME}_place_orphan
|
static boolean gld${EMULATION_NAME}_place_orphan
|
||||||
PARAMS ((lang_input_statement_type *, asection *));
|
PARAMS ((lang_input_statement_type *, asection *));
|
||||||
static void gld${EMULATION_NAME}_place_section
|
static lang_output_section_statement_type *output_rel_find PARAMS ((void));
|
||||||
PARAMS ((lang_statement_union_type *));
|
|
||||||
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
|
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
|
||||||
static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
|
static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
|
||||||
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
|
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
|
/* Place an orphan section. We use this to put random SHF_ALLOC
|
||||||
sections in the right segment. */
|
sections in the right segment. */
|
||||||
|
|
||||||
static asection *hold_section;
|
|
||||||
static lang_output_section_statement_type *hold_use;
|
|
||||||
|
|
||||||
struct orphan_save
|
struct orphan_save
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
asection **section;
|
asection **section;
|
||||||
lang_statement_union_type **stmt;
|
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*/
|
/*ARGSUSED*/
|
||||||
static boolean
|
static boolean
|
||||||
|
@ -805,6 +795,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
lang_input_statement_type *file;
|
lang_input_statement_type *file;
|
||||||
asection *s;
|
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;
|
struct orphan_save *place;
|
||||||
lang_statement_list_type *old;
|
lang_statement_list_type *old;
|
||||||
lang_statement_list_type add;
|
lang_statement_list_type add;
|
||||||
|
@ -813,19 +809,22 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
const char *outsecname;
|
const char *outsecname;
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
|
|
||||||
/* Look through the script to see where to place this section. */
|
secname = bfd_get_section_name (s->owner, s);
|
||||||
hold_section = s;
|
|
||||||
hold_use = NULL;
|
|
||||||
lang_for_each_statement (gld${EMULATION_NAME}_place_section);
|
|
||||||
|
|
||||||
if (hold_use != NULL)
|
/* Look through the script to see where to place this section. */
|
||||||
|
os = lang_output_section_find (secname);
|
||||||
|
|
||||||
|
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. */
|
/* 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;
|
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
|
/* If this is a final link, then always put .gnu.warning.SYMBOL
|
||||||
sections into the .text section to get them out of the way. */
|
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
|
right after the .interp section, so that the PT_NOTE segment is
|
||||||
stored right after the program headers where the OS can read it
|
stored right after the program headers where the OS can read it
|
||||||
in the first page. */
|
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)
|
if (s->flags & SEC_EXCLUDE)
|
||||||
return false;
|
return false;
|
||||||
else if ((s->flags & SEC_ALLOC) == 0)
|
else if ((s->flags & SEC_ALLOC) == 0)
|
||||||
place = NULL;
|
place = NULL;
|
||||||
else if ((s->flags & SEC_LOAD) != 0
|
else if ((s->flags & SEC_LOAD) != 0
|
||||||
&& strncmp (secname, ".note", 4) == 0
|
&& strncmp (secname, ".note", 4) == 0
|
||||||
&& hold_interp.os != NULL)
|
&& HAVE_SECTION (hold_interp, ".interp"))
|
||||||
place = &hold_interp;
|
place = &hold_interp;
|
||||||
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
||||||
&& hold_bss.os != NULL)
|
&& HAVE_SECTION (hold_bss, ".bss"))
|
||||||
place = &hold_bss;
|
place = &hold_bss;
|
||||||
else if ((s->flags & SEC_READONLY) == 0
|
else if ((s->flags & SEC_READONLY) == 0
|
||||||
&& hold_data.os != NULL)
|
&& HAVE_SECTION (hold_data, ".data"))
|
||||||
place = &hold_data;
|
place = &hold_data;
|
||||||
else if (strncmp (secname, ".rel", 4) == 0
|
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;
|
place = &hold_rel;
|
||||||
else if ((s->flags & SEC_CODE) == 0
|
else if ((s->flags & SEC_CODE) == 0
|
||||||
&& (s->flags & SEC_READONLY) != 0
|
&& (s->flags & SEC_READONLY) != 0
|
||||||
&& hold_rodata.os != NULL)
|
&& HAVE_SECTION (hold_rodata, ".rodata"))
|
||||||
place = &hold_rodata;
|
place = &hold_rodata;
|
||||||
else if ((s->flags & SEC_READONLY) != 0
|
else if ((s->flags & SEC_READONLY) != 0
|
||||||
&& hold_text.os != NULL)
|
&& hold_text.os != NULL)
|
||||||
|
@ -870,6 +873,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
else
|
else
|
||||||
place = NULL;
|
place = NULL;
|
||||||
|
|
||||||
|
#undef HAVE_SECTION
|
||||||
|
|
||||||
/* Choose a unique name for the section. This will be needed if the
|
/* Choose a unique name for the section. This will be needed if the
|
||||||
same section name appears in the input file with different
|
same section name appears in the input file with different
|
||||||
loadable or allocateable characteristics. */
|
loadable or allocateable characteristics. */
|
||||||
|
@ -924,13 +929,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
else
|
else
|
||||||
address = NULL;
|
address = NULL;
|
||||||
|
|
||||||
lang_enter_output_section_statement (outsecname, address, 0,
|
os = lang_enter_output_section_statement (outsecname, address, 0,
|
||||||
(bfd_vma) 0,
|
(bfd_vma) 0,
|
||||||
(etree_type *) NULL,
|
(etree_type *) NULL,
|
||||||
(etree_type *) NULL,
|
(etree_type *) NULL,
|
||||||
(etree_type *) NULL);
|
(etree_type *) NULL);
|
||||||
|
|
||||||
os = lang_output_section_statement_lookup (outsecname);
|
|
||||||
wild_doit (&os->children, s, os, file);
|
wild_doit (&os->children, s, os, file);
|
||||||
|
|
||||||
lang_leave_output_section_statement
|
lang_leave_output_section_statement
|
||||||
|
@ -1004,38 +1008,26 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* A variant of lang_output_section_find. */
|
||||||
gld${EMULATION_NAME}_place_section (s)
|
static lang_output_section_statement_type *
|
||||||
lang_statement_union_type *s;
|
output_rel_find ()
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_statement_union_type *u;
|
||||||
|
lang_output_section_statement_type *lookup;
|
||||||
|
|
||||||
if (s->header.type != lang_output_section_statement_enum)
|
for (u = lang_output_section_statement.head;
|
||||||
return;
|
u != (lang_statement_union_type *) NULL;
|
||||||
|
u = lookup->next)
|
||||||
os = &s->output_section_statement;
|
{
|
||||||
|
lookup = &u->output_section_statement;
|
||||||
if (strcmp (os->name, hold_section->name) == 0
|
if (strncmp (".rel", lookup->name, 4) == 0
|
||||||
&& os->bfd_section != NULL
|
&& lookup->bfd_section != NULL
|
||||||
&& ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
|
&& (lookup->bfd_section->flags & SEC_ALLOC) != 0)
|
||||||
== (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
|
{
|
||||||
hold_use = os;
|
return lookup;
|
||||||
|
}
|
||||||
if (strcmp (os->name, ".text") == 0)
|
}
|
||||||
hold_text.os = os;
|
return (lang_output_section_statement_type *) NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look through an expression for an assignment statement. */
|
/* Look through an expression for an assignment statement. */
|
||||||
|
|
|
@ -65,8 +65,7 @@ static void gld${EMULATION_NAME}_find_statement_assignment
|
||||||
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
|
static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
|
||||||
static boolean gld${EMULATION_NAME}_place_orphan
|
static boolean gld${EMULATION_NAME}_place_orphan
|
||||||
PARAMS ((lang_input_statement_type *, asection *));
|
PARAMS ((lang_input_statement_type *, asection *));
|
||||||
static void gld${EMULATION_NAME}_place_section
|
static lang_output_section_statement_type *output_rel_find PARAMS ((void));
|
||||||
PARAMS ((lang_statement_union_type *));
|
|
||||||
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
|
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
|
||||||
|
|
||||||
static void
|
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
|
/* Place an orphan section. We use this to put random SHF_ALLOC
|
||||||
sections in the right segment. */
|
sections in the right segment. */
|
||||||
|
|
||||||
static asection *hold_section;
|
|
||||||
static lang_output_section_statement_type *hold_use;
|
|
||||||
|
|
||||||
struct orphan_save
|
struct orphan_save
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
asection **section;
|
asection **section;
|
||||||
lang_statement_union_type **stmt;
|
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*/
|
/*ARGSUSED*/
|
||||||
static boolean
|
static boolean
|
||||||
|
@ -887,6 +877,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
lang_input_statement_type *file;
|
lang_input_statement_type *file;
|
||||||
asection *s;
|
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;
|
struct orphan_save *place;
|
||||||
lang_statement_list_type *old;
|
lang_statement_list_type *old;
|
||||||
lang_statement_list_type add;
|
lang_statement_list_type add;
|
||||||
|
@ -895,19 +891,22 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
const char *outsecname;
|
const char *outsecname;
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
|
|
||||||
/* Look through the script to see where to place this section. */
|
secname = bfd_get_section_name (s->owner, s);
|
||||||
hold_section = s;
|
|
||||||
hold_use = NULL;
|
|
||||||
lang_for_each_statement (gld${EMULATION_NAME}_place_section);
|
|
||||||
|
|
||||||
if (hold_use != NULL)
|
/* Look through the script to see where to place this section. */
|
||||||
|
os = lang_output_section_find (secname);
|
||||||
|
|
||||||
|
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. */
|
/* 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;
|
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
|
/* If this is a final link, then always put .gnu.warning.SYMBOL
|
||||||
sections into the .text section to get them out of the way. */
|
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
|
right after the .interp section, so that the PT_NOTE segment is
|
||||||
stored right after the program headers where the OS can read it
|
stored right after the program headers where the OS can read it
|
||||||
in the first page. */
|
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)
|
if (s->flags & SEC_EXCLUDE)
|
||||||
return false;
|
return false;
|
||||||
else if ((s->flags & SEC_ALLOC) == 0)
|
else if ((s->flags & SEC_ALLOC) == 0)
|
||||||
place = NULL;
|
place = NULL;
|
||||||
else if ((s->flags & SEC_LOAD) != 0
|
else if ((s->flags & SEC_LOAD) != 0
|
||||||
&& strncmp (secname, ".note", 4) == 0
|
&& strncmp (secname, ".note", 4) == 0
|
||||||
&& hold_interp.os != NULL)
|
&& HAVE_SECTION (hold_interp, ".interp"))
|
||||||
place = &hold_interp;
|
place = &hold_interp;
|
||||||
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
||||||
&& hold_bss.os != NULL)
|
&& HAVE_SECTION (hold_bss, ".bss"))
|
||||||
place = &hold_bss;
|
place = &hold_bss;
|
||||||
else if ((s->flags & SEC_READONLY) == 0
|
else if ((s->flags & SEC_READONLY) == 0
|
||||||
&& hold_data.os != NULL)
|
&& HAVE_SECTION (hold_data, ".data"))
|
||||||
place = &hold_data;
|
place = &hold_data;
|
||||||
else if (strncmp (secname, ".rel", 4) == 0
|
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;
|
place = &hold_rel;
|
||||||
else if ((s->flags & SEC_CODE) == 0
|
else if ((s->flags & SEC_CODE) == 0
|
||||||
&& (s->flags & SEC_READONLY) != 0
|
&& (s->flags & SEC_READONLY) != 0
|
||||||
&& hold_rodata.os != NULL)
|
&& HAVE_SECTION (hold_rodata, ".rodata"))
|
||||||
place = &hold_rodata;
|
place = &hold_rodata;
|
||||||
else if ((s->flags & SEC_READONLY) != 0
|
else if ((s->flags & SEC_READONLY) != 0
|
||||||
&& hold_text.os != NULL)
|
&& hold_text.os != NULL)
|
||||||
|
@ -952,6 +955,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
else
|
else
|
||||||
place = NULL;
|
place = NULL;
|
||||||
|
|
||||||
|
#undef HAVE_SECTION
|
||||||
|
|
||||||
/* Choose a unique name for the section. This will be needed if the
|
/* Choose a unique name for the section. This will be needed if the
|
||||||
same section name appears in the input file with different
|
same section name appears in the input file with different
|
||||||
loadable or allocateable characteristics. */
|
loadable or allocateable characteristics. */
|
||||||
|
@ -1006,13 +1011,12 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
else
|
else
|
||||||
address = NULL;
|
address = NULL;
|
||||||
|
|
||||||
lang_enter_output_section_statement (outsecname, address, 0,
|
os = lang_enter_output_section_statement (outsecname, address, 0,
|
||||||
(bfd_vma) 0,
|
(bfd_vma) 0,
|
||||||
(etree_type *) NULL,
|
(etree_type *) NULL,
|
||||||
(etree_type *) NULL,
|
(etree_type *) NULL,
|
||||||
(etree_type *) NULL);
|
(etree_type *) NULL);
|
||||||
|
|
||||||
os = lang_output_section_statement_lookup (outsecname);
|
|
||||||
wild_doit (&os->children, s, os, file);
|
wild_doit (&os->children, s, os, file);
|
||||||
|
|
||||||
lang_leave_output_section_statement
|
lang_leave_output_section_statement
|
||||||
|
@ -1086,38 +1090,26 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* A variant of lang_output_section_find. */
|
||||||
gld${EMULATION_NAME}_place_section (s)
|
static lang_output_section_statement_type *
|
||||||
lang_statement_union_type *s;
|
output_rel_find ()
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_statement_union_type *u;
|
||||||
|
lang_output_section_statement_type *lookup;
|
||||||
|
|
||||||
if (s->header.type != lang_output_section_statement_enum)
|
for (u = lang_output_section_statement.head;
|
||||||
return;
|
u != (lang_statement_union_type *) NULL;
|
||||||
|
u = lookup->next)
|
||||||
os = &s->output_section_statement;
|
{
|
||||||
|
lookup = &u->output_section_statement;
|
||||||
if (strcmp (os->name, hold_section->name) == 0
|
if (strncmp (".rel", lookup->name, 4) == 0
|
||||||
&& os->bfd_section != NULL
|
&& lookup->bfd_section != NULL
|
||||||
&& ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
|
&& (lookup->bfd_section->flags & SEC_ALLOC) != 0)
|
||||||
== (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
|
{
|
||||||
hold_use = os;
|
return lookup;
|
||||||
|
}
|
||||||
if (strcmp (os->name, ".text") == 0)
|
}
|
||||||
hold_text.os = os;
|
return (lang_output_section_statement_type *) NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
|
|
@ -102,8 +102,6 @@ static void gld_${EMULATION_NAME}_after_parse PARAMS ((void));
|
||||||
static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
|
static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
|
||||||
static boolean gld_${EMULATION_NAME}_place_orphan
|
static boolean gld_${EMULATION_NAME}_place_orphan
|
||||||
PARAMS ((lang_input_statement_type *, asection *));
|
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 char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
|
||||||
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
|
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
|
||||||
static void gld_${EMULATION_NAME}_finish PARAMS ((void));
|
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
|
default linker script using wildcards, and are sorted by
|
||||||
sort_sections. */
|
sort_sections. */
|
||||||
|
|
||||||
static asection *hold_section;
|
|
||||||
static char *hold_section_name;
|
|
||||||
static lang_output_section_statement_type *hold_use;
|
|
||||||
|
|
||||||
struct orphan_save
|
struct orphan_save
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
asection **section;
|
asection **section;
|
||||||
lang_statement_union_type **stmt;
|
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*/
|
/*ARGSUSED*/
|
||||||
static boolean
|
static boolean
|
||||||
|
@ -1099,15 +1086,15 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
|
||||||
asection *s;
|
asection *s;
|
||||||
{
|
{
|
||||||
const char *secname;
|
const char *secname;
|
||||||
|
char *hold_section_name;
|
||||||
char *dollar = NULL;
|
char *dollar = NULL;
|
||||||
|
lang_output_section_statement_type *os;
|
||||||
lang_statement_list_type add_child;
|
lang_statement_list_type add_child;
|
||||||
|
|
||||||
secname = bfd_get_section_name (s->owner, s);
|
secname = bfd_get_section_name (s->owner, s);
|
||||||
|
|
||||||
/* Look through the script to see where to place this section. */
|
/* Look through the script to see where to place this section. */
|
||||||
|
|
||||||
hold_section = s;
|
|
||||||
|
|
||||||
hold_section_name = xstrdup (secname);
|
hold_section_name = xstrdup (secname);
|
||||||
if (!link_info.relocateable)
|
if (!link_info.relocateable)
|
||||||
{
|
{
|
||||||
|
@ -1116,18 +1103,23 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
|
||||||
*dollar = '\0';
|
*dollar = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
hold_use = NULL;
|
os = lang_output_section_find (hold_section_name);
|
||||||
lang_for_each_statement (gld${EMULATION_NAME}_place_section);
|
|
||||||
|
|
||||||
lang_list_init (&add_child);
|
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
|
else
|
||||||
{
|
{
|
||||||
struct orphan_save *place;
|
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;
|
char *outsecname;
|
||||||
lang_statement_list_type *old;
|
lang_statement_list_type *old;
|
||||||
lang_statement_list_type add;
|
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
|
/* Try to put the new output section in a reasonable place based
|
||||||
on the section name and section flags. */
|
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;
|
place = NULL;
|
||||||
if ((s->flags & SEC_ALLOC) == 0)
|
if ((s->flags & SEC_ALLOC) == 0)
|
||||||
;
|
;
|
||||||
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
||||||
&& hold_bss.os != NULL)
|
&& HAVE_SECTION (hold_bss, ".bss"))
|
||||||
place = &hold_bss;
|
place = &hold_bss;
|
||||||
else if ((s->flags & SEC_READONLY) == 0
|
else if ((s->flags & SEC_READONLY) == 0
|
||||||
&& hold_data.os != NULL)
|
&& HAVE_SECTION (hold_data, ".data"))
|
||||||
place = &hold_data;
|
place = &hold_data;
|
||||||
else if ((s->flags & SEC_CODE) == 0
|
else if ((s->flags & SEC_CODE) == 0
|
||||||
&& (s->flags & SEC_READONLY) != 0
|
&& (s->flags & SEC_READONLY) != 0
|
||||||
&& hold_rdata.os != NULL)
|
&& HAVE_SECTION (hold_rdata, ".rdata"))
|
||||||
place = &hold_rdata;
|
place = &hold_rdata;
|
||||||
else if ((s->flags & SEC_READONLY) != 0
|
else if ((s->flags & SEC_READONLY) != 0
|
||||||
&& hold_text.os != NULL)
|
&& HAVE_SECTION (hold_text, ".text"))
|
||||||
place = &hold_text;
|
place = &hold_text;
|
||||||
|
|
||||||
|
#undef HAVE_SECTION
|
||||||
|
|
||||||
/* Choose a unique name for the section. This will be needed if
|
/* Choose a unique name for the section. This will be needed if
|
||||||
the same section name appears in the input file with
|
the same section name appears in the input file with
|
||||||
different loadable or allocateable characteristics. */
|
different loadable or allocateable characteristics. */
|
||||||
|
@ -1192,19 +1189,17 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
|
||||||
exp_nameop (NAME, "__section_alignment__"));
|
exp_nameop (NAME, "__section_alignment__"));
|
||||||
}
|
}
|
||||||
|
|
||||||
lang_enter_output_section_statement (outsecname, address, 0,
|
os = lang_enter_output_section_statement (outsecname, address, 0,
|
||||||
(bfd_vma) 0,
|
(bfd_vma) 0,
|
||||||
(etree_type *) NULL,
|
(etree_type *) NULL,
|
||||||
(etree_type *) NULL,
|
(etree_type *) NULL,
|
||||||
(etree_type *) NULL);
|
(etree_type *) NULL);
|
||||||
|
|
||||||
hold_use = lang_output_section_statement_lookup (outsecname);
|
wild_doit (&add_child, s, os, file);
|
||||||
wild_doit (&add_child, s, hold_use, file);
|
|
||||||
|
|
||||||
lang_leave_output_section_statement
|
lang_leave_output_section_statement
|
||||||
((bfd_vma) 0, "*default*",
|
((bfd_vma) 0, "*default*",
|
||||||
(struct lang_output_section_phdr_list *) NULL,
|
(struct lang_output_section_phdr_list *) NULL, "*default*");
|
||||||
"*default*");
|
|
||||||
|
|
||||||
stat_ptr = old;
|
stat_ptr = old;
|
||||||
|
|
||||||
|
@ -1212,7 +1207,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
|
||||||
{
|
{
|
||||||
asection *snew, **pps;
|
asection *snew, **pps;
|
||||||
|
|
||||||
snew = hold_use->bfd_section;
|
snew = os->bfd_section;
|
||||||
if (place->os->bfd_section != NULL || place->section != NULL)
|
if (place->os->bfd_section != NULL || place->section != NULL)
|
||||||
{
|
{
|
||||||
/* Shuffle the section to make the output file look neater. */
|
/* 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)
|
if (dollar != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1308,33 +1303,6 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
|
||||||
return true;
|
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
|
static int
|
||||||
gld_${EMULATION_NAME}_find_potential_libraries (name, entry)
|
gld_${EMULATION_NAME}_find_potential_libraries (name, entry)
|
||||||
char * name;
|
char * name;
|
||||||
|
|
|
@ -58,7 +58,6 @@ static lang_output_section_statement_type *default_common_section;
|
||||||
static boolean map_option_f;
|
static boolean map_option_f;
|
||||||
static bfd_vma print_dot;
|
static bfd_vma print_dot;
|
||||||
static lang_input_statement_type *first_file;
|
static lang_input_statement_type *first_file;
|
||||||
static lang_statement_list_type lang_output_section_statement;
|
|
||||||
static CONST char *current_target;
|
static CONST char *current_target;
|
||||||
static CONST char *output_target;
|
static CONST char *output_target;
|
||||||
static lang_statement_list_type statement_list;
|
static lang_statement_list_type statement_list;
|
||||||
|
@ -166,6 +165,7 @@ static char * get_first_input_target PARAMS ((void));
|
||||||
|
|
||||||
/* EXPORTS */
|
/* EXPORTS */
|
||||||
lang_output_section_statement_type *abs_output_section;
|
lang_output_section_statement_type *abs_output_section;
|
||||||
|
lang_statement_list_type lang_output_section_statement;
|
||||||
lang_statement_list_type *stat_ptr = &statement_list;
|
lang_statement_list_type *stat_ptr = &statement_list;
|
||||||
lang_statement_list_type file_chain = { NULL, NULL };
|
lang_statement_list_type file_chain = { NULL, NULL };
|
||||||
const char *entry_symbol = NULL;
|
const char *entry_symbol = NULL;
|
||||||
|
@ -3813,7 +3813,7 @@ topower (x)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
lang_output_section_statement_type *
|
||||||
lang_enter_output_section_statement (output_section_statement_name,
|
lang_enter_output_section_statement (output_section_statement_name,
|
||||||
address_exp, sectype, block_value,
|
address_exp, sectype, block_value,
|
||||||
align, subalign, ebase)
|
align, subalign, ebase)
|
||||||
|
@ -3861,6 +3861,7 @@ lang_enter_output_section_statement (output_section_statement_name,
|
||||||
"section alignment", 0));
|
"section alignment", 0));
|
||||||
|
|
||||||
os->load_base = ebase;
|
os->load_base = ebase;
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -371,6 +371,7 @@ struct lang_nocrossrefs
|
||||||
extern struct lang_nocrossrefs *nocrossref_list;
|
extern struct lang_nocrossrefs *nocrossref_list;
|
||||||
|
|
||||||
extern lang_output_section_statement_type *abs_output_section;
|
extern lang_output_section_statement_type *abs_output_section;
|
||||||
|
extern lang_statement_list_type lang_output_section_statement;
|
||||||
extern boolean lang_has_input_file;
|
extern boolean lang_has_input_file;
|
||||||
extern etree_type *base;
|
extern etree_type *base;
|
||||||
extern lang_statement_list_type *stat_ptr;
|
extern lang_statement_list_type *stat_ptr;
|
||||||
|
@ -388,7 +389,7 @@ extern void lang_map PARAMS ((void));
|
||||||
extern void lang_set_flags PARAMS ((lang_memory_region_type *, const char *,
|
extern void lang_set_flags PARAMS ((lang_memory_region_type *, const char *,
|
||||||
int));
|
int));
|
||||||
extern void lang_add_output PARAMS ((const char *, int from_script));
|
extern void lang_add_output PARAMS ((const char *, int from_script));
|
||||||
extern void lang_enter_output_section_statement
|
extern lang_output_section_statement_type *lang_enter_output_section_statement
|
||||||
PARAMS ((const char *output_section_statement_name,
|
PARAMS ((const char *output_section_statement_name,
|
||||||
etree_type * address_exp,
|
etree_type * address_exp,
|
||||||
enum section_type sectype,
|
enum section_type sectype,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue