+2000-04-18 Alan Modra <alan@linuxcare.com.au>
+
+ * emultempl/elf32.em (struct orphan_save): Add section field.
+ (gld${EMULATION_NAME}_place_orphan): Use above to keep sections in
+ better order, and place first orphan section as we did before the
+ 2000-04-12 patch. Ignore ~SEC_ALLOC sections when choosing place.
+ Don't call make_bfd_section here, let wild_doit do the job for us.
+ Don't build a statement list when we'll only throw it away.
+ * emultempl/armelf.em: Ditto.
+ * emultempl/pe.em: Similarly.
+
2000-04-14 Geoff Keating <geoffk@cygnus.com>
* scripttempl/elfppc.sc: Remove.
2000-04-14 Alan Modra <alan@linuxcare.com.au>
- * emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Process
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Process
~SEC_ALLOC sections too. Init start address of debug sections.
- * emultempl/armelf.em (gld${EMULATION_NAME}_place_section): Ditto.
- * emultempl/pe.em (gld${EMULATION_NAME}_place_section): Ditto.
+ * emultempl/armelf.em (gld${EMULATION_NAME}_place_orphan): Ditto.
+ * emultempl/pe.em (gld${EMULATION_NAME}_place_orphan): Ditto.
Also set all relocateable section start addresses.
2000-04-13 Geoff Keating <geoffk@cygnus.com>
struct orphan_save
{
lang_output_section_statement_type *os;
+ asection **section;
lang_statement_union_type **stmt;
};
static struct orphan_save hold_text;
asection *s;
{
struct orphan_save *place;
- asection *snew, **pps;
lang_statement_list_type *old;
lang_statement_list_type add;
etree_type *address;
in the first page. */
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)
outsecname = newname;
}
- /* Create the section in the output file, and put it in the right
- place. This shuffling is to make the output file look neater. */
- snew = bfd_make_section (output_bfd, outsecname);
- if (snew == NULL)
- einfo ("%P%F: output format %s cannot represent section called %s\n",
- output_bfd->xvec->name, outsecname);
- if (place != NULL && place->os->bfd_section != NULL)
- {
- /* Unlink it first. */
- for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
- ;
- *pps = snew->next;
- snew->next = NULL;
- /* Now tack it on to the end of the "place->os" section list. */
- for (pps = &place->os->bfd_section; *pps; pps = &(*pps)->next)
- ;
- *pps = snew;
- }
-
- /* Start building a list of statements for this section. */
- old = stat_ptr;
- stat_ptr = &add;
- lang_list_init (stat_ptr);
-
- /* If the name of the section is representable in C, then create
- symbols to mark the start and the end of the section. */
- for (ps = outsecname; *ps != '\0'; ps++)
- if (! isalnum ((unsigned char) *ps) && *ps != '_')
- break;
- if (*ps == '\0' && config.build_constructors)
+ if (place != NULL)
{
- char *symname;
-
- symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
- sprintf (symname, "__start_%s", outsecname);
- lang_add_assignment (exp_assop ('=', symname,
- exp_unop (ALIGN_K,
- exp_intop ((bfd_vma) 1
- << s->alignment_power))));
+ /* Start building a list of statements for this section. */
+ old = stat_ptr;
+ stat_ptr = &add;
+ lang_list_init (stat_ptr);
+
+ /* If the name of the section is representable in C, then create
+ symbols to mark the start and the end of the section. */
+ for (ps = outsecname; *ps != '\0'; ps++)
+ if (! isalnum ((unsigned char) *ps) && *ps != '_')
+ break;
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+ etree_type *e_align;
+
+ symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
+ sprintf (symname, "__start_%s", outsecname);
+ e_align = exp_unop (ALIGN_K,
+ exp_intop ((bfd_vma) 1 << s->alignment_power));
+ lang_add_assignment (exp_assop ('=', symname, e_align));
+ }
}
if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
os = lang_output_section_statement_lookup (outsecname);
wild_doit (&os->children, s, os, file);
- lang_leave_output_section_statement
- ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL,
- "*default*");
- stat_ptr = &add;
-
- if (*ps == '\0' && config.build_constructors)
+ if (place != NULL)
{
- char *symname;
+ asection *snew, **pps;
- symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
- sprintf (symname, "__stop_%s", outsecname);
- lang_add_assignment (exp_assop ('=', symname,
- exp_nameop (NAME, ".")));
- }
+ lang_leave_output_section_statement
+ ((bfd_vma) 0, "*default*",
+ (struct lang_output_section_phdr_list *) NULL, "*default*");
+ stat_ptr = &add;
- if (place != NULL)
- {
- if (! place->stmt)
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+
+ symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
+ sprintf (symname, "__stop_%s", outsecname);
+ lang_add_assignment (exp_assop ('=', symname,
+ exp_nameop (NAME, ".")));
+ }
+ stat_ptr = old;
+
+ snew = os->bfd_section;
+ if (place->os->bfd_section != NULL || place->section != NULL)
+ {
+ /* Shuffle the section to make the output file look neater. */
+ if (place->section == NULL)
+ {
+#if 0
+ /* Finding the end of the list is a little tricky. We
+ make a wild stab at it by comparing section flags. */
+ flagword first_flags = place->os->bfd_section->flags;
+ for (pps = &place->os->bfd_section->next;
+ *pps != NULL && (*pps)->flags == first_flags;
+ pps = &(*pps)->next)
+ ;
+ place->section = pps;
+#else
+ /* Put orphans after the first section on the list. */
+ place->section = &place->os->bfd_section->next;
+#endif
+ }
+
+ /* Unlink the section. */
+ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+ ;
+ *pps = snew->next;
+
+ /* Now tack it on to the "place->os" section list. */
+ snew->next = *place->section;
+ *place->section = snew;
+ }
+ place->section = &snew->next; /* Save the end of this list. */
+
+ if (place->stmt == NULL)
{
/* Put the new statement list right at the head. */
*add.tail = place->os->header.next;
*add.tail = *place->stmt;
*place->stmt = add.head;
}
- place->stmt = add.tail; /* Save the end of this list. */
+ place->stmt = add.tail; /* Save the end of this list. */
}
- stat_ptr = old;
return true;
}
struct orphan_save
{
lang_output_section_statement_type *os;
+ asection **section;
lang_statement_union_type **stmt;
};
static struct orphan_save hold_text;
asection *s;
{
struct orphan_save *place;
- asection *snew, **pps;
lang_statement_list_type *old;
lang_statement_list_type add;
etree_type *address;
in the first page. */
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)
outsecname = newname;
}
- /* Create the section in the output file, and put it in the right
- place. This shuffling is to make the output file look neater. */
- snew = bfd_make_section (output_bfd, outsecname);
- if (snew == NULL)
- einfo ("%P%F: output format %s cannot represent section called %s\n",
- output_bfd->xvec->name, outsecname);
- if (place != NULL && place->os->bfd_section != NULL)
- {
- /* Unlink it first. */
- for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
- ;
- *pps = snew->next;
- snew->next = NULL;
- /* Now tack it on to the end of the "place->os" section list. */
- for (pps = &place->os->bfd_section; *pps; pps = &(*pps)->next)
- ;
- *pps = snew;
- }
-
- /* Start building a list of statements for this section. */
- old = stat_ptr;
- stat_ptr = &add;
- lang_list_init (stat_ptr);
-
- /* If the name of the section is representable in C, then create
- symbols to mark the start and the end of the section. */
- for (ps = outsecname; *ps != '\0'; ps++)
- if (! isalnum ((unsigned char) *ps) && *ps != '_')
- break;
- if (*ps == '\0' && config.build_constructors)
+ if (place != NULL)
{
- char *symname;
-
- symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
- sprintf (symname, "__start_%s", outsecname);
- lang_add_assignment (exp_assop ('=', symname,
- exp_unop (ALIGN_K,
- exp_intop ((bfd_vma) 1
- << s->alignment_power))));
+ /* Start building a list of statements for this section. */
+ old = stat_ptr;
+ stat_ptr = &add;
+ lang_list_init (stat_ptr);
+
+ /* If the name of the section is representable in C, then create
+ symbols to mark the start and the end of the section. */
+ for (ps = outsecname; *ps != '\0'; ps++)
+ if (! isalnum ((unsigned char) *ps) && *ps != '_')
+ break;
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+ etree_type *e_align;
+
+ symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
+ sprintf (symname, "__start_%s", outsecname);
+ e_align = exp_unop (ALIGN_K,
+ exp_intop ((bfd_vma) 1 << s->alignment_power));
+ lang_add_assignment (exp_assop ('=', symname, e_align));
+ }
}
if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
os = lang_output_section_statement_lookup (outsecname);
wild_doit (&os->children, s, os, file);
- lang_leave_output_section_statement
- ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL,
- "*default*");
- stat_ptr = &add;
-
- if (*ps == '\0' && config.build_constructors)
+ if (place != NULL)
{
- char *symname;
+ asection *snew, **pps;
- symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
- sprintf (symname, "__stop_%s", outsecname);
- lang_add_assignment (exp_assop ('=', symname,
- exp_nameop (NAME, ".")));
- }
+ lang_leave_output_section_statement
+ ((bfd_vma) 0, "*default*",
+ (struct lang_output_section_phdr_list *) NULL, "*default*");
+ stat_ptr = &add;
- if (place != NULL)
- {
- if (! place->stmt)
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+
+ symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
+ sprintf (symname, "__stop_%s", outsecname);
+ lang_add_assignment (exp_assop ('=', symname,
+ exp_nameop (NAME, ".")));
+ }
+ stat_ptr = old;
+
+ snew = os->bfd_section;
+ if (place->os->bfd_section != NULL || place->section != NULL)
+ {
+ /* Shuffle the section to make the output file look neater. */
+ if (place->section == NULL)
+ {
+#if 0
+ /* Finding the end of the list is a little tricky. We
+ make a wild stab at it by comparing section flags. */
+ flagword first_flags = place->os->bfd_section->flags;
+ for (pps = &place->os->bfd_section->next;
+ *pps != NULL && (*pps)->flags == first_flags;
+ pps = &(*pps)->next)
+ ;
+ place->section = pps;
+#else
+ /* Put orphans after the first section on the list. */
+ place->section = &place->os->bfd_section->next;
+#endif
+ }
+
+ /* Unlink the section. */
+ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+ ;
+ *pps = snew->next;
+
+ /* Now tack it on to the "place->os" section list. */
+ snew->next = *place->section;
+ *place->section = snew;
+ }
+ place->section = &snew->next; /* Save the end of this list. */
+
+ if (place->stmt == NULL)
{
/* Put the new statement list right at the head. */
*add.tail = place->os->header.next;
*add.tail = *place->stmt;
*place->stmt = add.head;
}
- place->stmt = add.tail; /* Save the end of this list. */
+ place->stmt = add.tail; /* Save the end of this list. */
}
- stat_ptr = old;
return true;
}
struct orphan_save
{
lang_output_section_statement_type *os;
+ asection **section;
lang_statement_union_type **stmt;
};
static struct orphan_save hold_text;
{
const char *secname;
char *dollar = NULL;
+ lang_statement_list_type add_child;
secname = bfd_get_section_name (s->owner, s);
hold_use = NULL;
lang_for_each_statement (gld${EMULATION_NAME}_place_section);
- if (hold_use == NULL)
+ lang_list_init (&add_child);
+
+ if (hold_use != NULL)
+ {
+ wild_doit (&add_child, s, hold_use, file);
+ }
+ else
{
struct orphan_save *place;
char *outsecname;
- asection *snew, **pps;
lang_statement_list_type *old;
lang_statement_list_type add;
etree_type *address;
/* Try to put the new output section in a reasonable place based
on the section name and section flags. */
place = NULL;
- if ((s->flags & SEC_HAS_CONTENTS) == 0
- && hold_bss.os != NULL)
+ if ((s->flags & SEC_ALLOC) == 0)
+ ;
+ else if ((s->flags & SEC_HAS_CONTENTS) == 0
+ && hold_bss.os != NULL)
place = &hold_bss;
else if ((s->flags & SEC_READONLY) == 0
&& hold_data.os != NULL)
outsecname = newname;
}
- /* We don't want to free OUTSECNAME, as it may get attached to
- the output section statement. */
-
- /* Create the section in the output file, and put it in the
- right place. This shuffling is to make the output file look
- neater. */
- snew = bfd_make_section (output_bfd, outsecname);
- if (snew == NULL)
- einfo ("%P%F: output format %s cannot represent section called %s\n",
- output_bfd->xvec->name, outsecname);
- if (place != NULL && place->os->bfd_section != NULL)
- {
- /* Unlink it first. */
- for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
- ;
- *pps = snew->next;
- snew->next = NULL;
- /* Now tack it on to the end of the "place->os" section list. */
- for (pps = &place->os->bfd_section; *pps; pps = &(*pps)->next)
- ;
- *pps = snew;
- }
-
/* Start building a list of statements for this section. */
old = stat_ptr;
stat_ptr = &add;
(etree_type *) NULL);
hold_use = lang_output_section_statement_lookup (outsecname);
+ wild_doit (&add_child, s, hold_use, file);
lang_leave_output_section_statement
((bfd_vma) 0, "*default*",
(struct lang_output_section_phdr_list *) NULL,
"*default*");
+ stat_ptr = old;
+
if (place != NULL)
{
- if (! place->stmt)
+ asection *snew, **pps;
+
+ snew = hold_use->bfd_section;
+ if (place->os->bfd_section != NULL || place->section != NULL)
+ {
+ /* Shuffle the section to make the output file look neater. */
+ if (place->section == NULL)
+ {
+#if 0
+ /* Finding the end of the list is a little tricky. We
+ make a wild stab at it by comparing section flags. */
+ flagword first_flags = place->os->bfd_section->flags;
+ for (pps = &place->os->bfd_section->next;
+ *pps != NULL && (*pps)->flags == first_flags;
+ pps = &(*pps)->next)
+ ;
+ place->section = pps;
+#else
+ /* Put orphans after the first section on the list. */
+ place->section = &place->os->bfd_section->next;
+#endif
+ }
+
+ /* Unlink the section. */
+ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+ ;
+ *pps = snew->next;
+
+ /* Now tack it on to the "place->os" section list. */
+ snew->next = *place->section;
+ *place->section = snew;
+ }
+ place->section = &snew->next; /* Save the end of this list. */
+
+ if (place->stmt == NULL)
{
/* Put the new statement list right at the head. */
*add.tail = place->os->header.next;
}
place->stmt = add.tail; /* Save the end of this list. */
}
-
- stat_ptr = old;
}
- if (dollar == NULL)
- wild_doit (&hold_use->children, s, hold_use, file);
- else
- {
- lang_statement_union_type **pl;
- boolean found_dollar;
- lang_statement_list_type list;
+ {
+ lang_statement_union_type **pl = &hold_use->children.head;
- /* The section name has a '$'. Sort it with the other '$'
- sections. */
+ if (dollar != NULL)
+ {
+ boolean found_dollar;
- found_dollar = false;
- for (pl = &hold_use->children.head; *pl != NULL; pl = &(*pl)->next)
- {
- lang_input_section_type *ls;
- const char *lname;
+ /* The section name has a '$'. Sort it with the other '$'
+ sections. */
- if ((*pl)->header.type != lang_input_section_enum)
- continue;
+ found_dollar = false;
+ for ( ; *pl != NULL; pl = &(*pl)->next)
+ {
+ lang_input_section_type *ls;
+ const char *lname;
- ls = &(*pl)->input_section;
+ if ((*pl)->header.type != lang_input_section_enum)
+ continue;
- lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
- if (strchr (lname, '$') == NULL)
- {
- if (found_dollar)
- break;
- }
- else
- {
- found_dollar = true;
- if (strcmp (secname, lname) < 0)
- break;
- }
- }
+ ls = &(*pl)->input_section;
- lang_list_init (&list);
- wild_doit (&list, s, hold_use, file);
- if (list.head != NULL)
- {
- ASSERT (list.head->next == NULL);
- list.head->next = *pl;
- *pl = list.head;
- }
- }
+ lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
+ if (strchr (lname, '$') == NULL)
+ {
+ if (found_dollar)
+ break;
+ }
+ else
+ {
+ found_dollar = true;
+ if (strcmp (secname, lname) < 0)
+ break;
+ }
+ }
+ }
+
+ if (add_child.head != NULL)
+ {
+ add_child.head->next = *pl;
+ *pl = add_child.head;
+ }
+ }
free (hold_section_name);