diff options
author | Alan Modra <amodra@gmail.com> | 2004-10-14 12:54:47 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2004-10-14 12:54:47 +0000 |
commit | afd7a018c9e949ee9f1126ae4517567bd9d2dcb1 (patch) | |
tree | 5d15c82c78d6d590e11d9b519e7ac7c8a8bd127f /ld/emultempl/mmo.em | |
parent | ad4c72d28343c31f9d4036beb90d18e2efa390ea (diff) | |
download | gdb-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.em | 155 |
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; } |