aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/mmo.em
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2004-10-14 12:54:47 +0000
committerAlan Modra <amodra@gmail.com>2004-10-14 12:54:47 +0000
commitafd7a018c9e949ee9f1126ae4517567bd9d2dcb1 (patch)
tree5d15c82c78d6d590e11d9b519e7ac7c8a8bd127f /ld/emultempl/mmo.em
parentad4c72d28343c31f9d4036beb90d18e2efa390ea (diff)
downloadgdb-afd7a018c9e949ee9f1126ae4517567bd9d2dcb1.zip
gdb-afd7a018c9e949ee9f1126ae4517567bd9d2dcb1.tar.gz
gdb-afd7a018c9e949ee9f1126ae4517567bd9d2dcb1.tar.bz2
ld/
PR 63 * ldlang.h (lang_output_section_statement_type): Make "next" a struct lang_output_section_statement_struct *. (struct orphan_save): Move from elf32.em. Add "name" and "flags". (lang_output_section_find_by_flags, lang_insert_orphan): Declare. * ldlang.c (lang_output_section_find_1): Adjust for changed output_section_statement "next". (strip_excluded_output_sections): Likewise. (lang_record_phdrs): Likewise. (lang_output_section_find_by_flags): New function. (output_prev_sec_find): Move from pe.em. Adjust iterator. (lang_insert_orphan): New function. Tail end of elf32.em's place_orphan merged with that from pe.em. Allow bfd_section to be placed first. New heuristic for placing new output section statement in existing script, and accompanying split of __start symbol alignment into a separate assignment to dot. (lang_add_section): Consistently use output->bfd_section rather than an alias, section->output_section. (map_input_to_output_sections): Rename overly long arg. Move initialization of data_statement output section to here.. (lang_check_section_addresses): ..from here. (print_assignment): Correct printing of etree_assert. (print_all_symbols): Don't bomb if userdata is NULL. (IGNORE_SECTION): Rearrange. * emultempl/elf32.em (output_rel_find): Adjust interator. (output_prev_sec_find): Delete. (struct orphan_save): Delete. (gld${EMULATION_NAME}_place_orphan): Cater for zero bfd_section flags without creating a duplicate output section statement. Revise code holding history of various orphan section placements. Allow orphan sections to place before script specified output sections. Call lang_output_section_find_by_flags when placement by name fails. Use lang_insert_orphan. * emultempl/mmo.em (output_prev_sec_find): Delete. (struct orphan_save): Delete. (mmo_place_orphan): Revise code holding history of orphan placement. Allow orphans to place before existing output sections. Use lang_insert_orphan. * emultempl/pe.em (output_prev_sec_find): Delete. (struct orphan_save): Delete. (gld_${EMULATION_NAME}_place_orphan): Revise to suit use of lang_insert_orphan. ld/testsuite/ * ld-scripts/overlay-size.d: Update for changed orphan section placement. * ld-mmix/bpo-18.d: Likewise.
Diffstat (limited to 'ld/emultempl/mmo.em')
-rw-r--r--ld/emultempl/mmo.em155
1 files changed, 19 insertions, 136 deletions
diff --git a/ld/emultempl/mmo.em b/ld/emultempl/mmo.em
index d6d30e6..cbe5108 100644
--- a/ld/emultempl/mmo.em
+++ b/ld/emultempl/mmo.em
@@ -32,47 +32,6 @@ EOF
cat >>e${EMULATION_NAME}.c <<EOF
-/* Find the last output section before given output statement.
- Used by place_orphan. */
-
-static asection *
-output_prev_sec_find (lang_output_section_statement_type *os)
-{
- asection *s = NULL;
- lang_statement_union_type *u;
- lang_output_section_statement_type *lookup;
-
- for (u = lang_output_section_statement.head;
- u != (lang_statement_union_type *) NULL;
- u = lookup->next)
- {
- lookup = &u->output_section_statement;
- if (lookup->constraint == -1)
- continue;
- if (lookup == os)
- break;
- if (lookup->bfd_section != NULL
- && lookup->bfd_section != bfd_abs_section_ptr
- && lookup->bfd_section != bfd_com_section_ptr
- && lookup->bfd_section != bfd_und_section_ptr)
- s = lookup->bfd_section;
- }
-
- if (u == NULL)
- return NULL;
-
- return s;
-}
-
-struct orphan_save {
- lang_output_section_statement_type *os;
- asection **section;
- lang_statement_union_type **stmt;
-};
-
-#define HAVE_SECTION(hold, name) \
-(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
-
/* Place an orphan section. We use this to put random SEC_CODE or
SEC_READONLY sections right after MMO_TEXT_SECTION_NAME. Much borrowed
from elf32.em. */
@@ -80,21 +39,25 @@ struct orphan_save {
static bfd_boolean
mmo_place_orphan (lang_input_statement_type *file, asection *s)
{
- static struct orphan_save hold_text;
+ static struct orphan_save hold_text =
+ {
+ MMO_TEXT_SECTION_NAME,
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
+ 0, 0, 0, 0
+ };
struct orphan_save *place;
+ const char *secname;
+ lang_output_section_statement_type *after;
lang_output_section_statement_type *os;
- lang_statement_list_type *old;
- lang_statement_list_type add;
- asection *snew, **pps, *bfd_section;
/* We have nothing to say for anything other than a final link. */
if (link_info.relocatable
- || (bfd_get_section_flags (s->owner, s)
- & (SEC_EXCLUDE | SEC_LOAD)) != SEC_LOAD)
+ || (s->flags & (SEC_EXCLUDE | SEC_LOAD)) != SEC_LOAD)
return FALSE;
/* Only care for sections we're going to load. */
- os = lang_output_section_find (bfd_get_section_name (s->owner, s));
+ secname = s->name;
+ os = lang_output_section_find (secname);
/* We have an output section by this name. Place the section inside it
(regardless of whether the linker script lists it as input). */
@@ -106,108 +69,28 @@ mmo_place_orphan (lang_input_statement_type *file, asection *s)
/* If this section does not have .text-type section flags or there's no
MMO_TEXT_SECTION_NAME, we don't have anything to say. */
- if ((bfd_get_section_flags (s->owner, s) & (SEC_CODE | SEC_READONLY)) == 0)
+ if ((s->flags & (SEC_CODE | SEC_READONLY)) == 0)
return FALSE;
if (hold_text.os == NULL)
- hold_text.os = lang_output_section_find (MMO_TEXT_SECTION_NAME);
+ hold_text.os = lang_output_section_find (hold_text.name);
place = &hold_text;
+ if (hold_text.os != NULL)
+ after = hold_text.os;
+ else
+ after = &lang_output_section_statement.head->output_section_statement;
/* If there's an output section by this name, we'll use it, regardless
of section flags, in contrast to what's done in elf32.em. */
-
- /* Start building a list of statements for this section.
- First save the current statement pointer. */
- old = stat_ptr;
-
- /* Add the output section statements for this orphan to our own private
- list, inserting them later into the global statement list. */
- stat_ptr = &add;
- lang_list_init (stat_ptr);
-
- os = lang_enter_output_section_statement (bfd_get_section_name (s->owner,
- s),
- NULL, 0,
- (etree_type *) NULL,
- (etree_type *) NULL,
- (etree_type *) NULL, 0);
-
- lang_add_section (&os->children, s, os, file);
-
- lang_leave_output_section_statement
- ((bfd_vma) 0, "*default*",
- (struct lang_output_section_phdr_list *) NULL, NULL);
-
- /* Restore the global list pointer. */
- stat_ptr = old;
-
- snew = os->bfd_section;
- if (snew == NULL)
- /* /DISCARD/ section. */
- return TRUE;
+ os = lang_insert_orphan (file, s, secname, after, place, NULL, NULL);
/* We need an output section for .text as a root, so if there was none
(might happen with a peculiar linker script such as in "map
addresses", map-address.exp), we grab the output section created
above. */
if (hold_text.os == NULL)
- {
- if (os == NULL)
- return FALSE;
- hold_text.os = os;
- }
-
- bfd_section = place->os->bfd_section;
- if (place->section == NULL && bfd_section == NULL)
- bfd_section = output_prev_sec_find (place->os);
-
- if (place->section != NULL
- || (bfd_section != NULL
- && bfd_section != snew))
- {
- /* Shuffle the section to make the output file look neater. This is
- really only cosmetic. */
- if (place->section == NULL)
- /* Put orphans after the first section on the list. */
- place->section = &bfd_section->next;
-
- /* Unlink the section. */
- for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
- ;
- bfd_section_list_remove (output_bfd, pps);
-
- /* Now tack it on to the "place->os" section list. */
- bfd_section_list_insert (output_bfd, place->section, snew);
- }
- place->section = &snew->next; /* Save the end of this list. */
-
- if (add.head != NULL)
- {
- /* We try to put the output statements in some sort of reasonable
- order here, because they determine the final load addresses of
- the orphan sections. */
- if (place->stmt == NULL)
- {
- /* Put the new statement list right at the head. */
- *add.tail = place->os->header.next;
- place->os->header.next = add.head;
- }
- else
- {
- /* Put it after the last orphan statement we added. */
- *add.tail = *place->stmt;
- *place->stmt = add.head;
- }
-
- /* Fix the global list pointer if we happened to tack our new list
- at the tail. */
- if (*old->tail == add.head)
- old->tail = add.tail;
-
- /* Save the end of this list. */
- place->stmt = add.tail;
- }
+ hold_text.os = os;
return TRUE;
}