diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2001-06-09 22:29:42 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2001-06-09 22:29:42 +0000 |
commit | b087ddea52407e4a9b8fe07d0ad234d36379fb67 (patch) | |
tree | eb75e416899d445ace73b11fb08d1328b3a1f368 /gnu/usr.bin/binutils/ld/emultempl | |
parent | fcab77976ead6644881c2eb7bb3499cdfabed685 (diff) |
Automatic cvs merge. Dread what I will have to fix after this excuse
of a program is done...
Diffstat (limited to 'gnu/usr.bin/binutils/ld/emultempl')
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/elf32.em | 309 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em | 7 |
2 files changed, 190 insertions, 126 deletions
diff --git a/gnu/usr.bin/binutils/ld/emultempl/elf32.em b/gnu/usr.bin/binutils/ld/emultempl/elf32.em index d629d9a245b..2df71c1ee3e 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/elf32.em +++ b/gnu/usr.bin/binutils/ld/emultempl/elf32.em @@ -7,7 +7,7 @@ cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} - Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 + Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. Written by Steve Chamberlain <sac@cygnus.com> ELF support by Ian Lance Taylor <ian@cygnus.com> @@ -63,10 +63,9 @@ static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); static void gld${EMULATION_NAME}_find_statement_assignment PARAMS ((lang_statement_union_type *)); static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); +static lang_output_section_statement_type *output_rel_find 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 *isfile)); EOF @@ -538,7 +537,7 @@ cat >>e${EMULATION_NAME}.c <<EOF if (force < 2) continue; - einfo ("%P: warning: %s, needed by %B, not found (try using --rpath)\n", + einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n", l->name, l->by); } } @@ -1024,58 +1023,83 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) } } +/* A variant of lang_output_section_find. Used by place_orphan. */ + +static lang_output_section_statement_type * +output_rel_find () +{ + 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 (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; +} + /* 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; -static lang_output_section_statement_type *hold_text; -static lang_output_section_statement_type *hold_rodata; -static lang_output_section_statement_type *hold_data; -static lang_output_section_statement_type *hold_bss; -static lang_output_section_statement_type *hold_rel; -static lang_output_section_statement_type *hold_interp; +struct orphan_save { + lang_output_section_statement_type *os; + asection **section; + lang_statement_union_type **stmt; +}; -/*ARGSUSED*/ static boolean gld${EMULATION_NAME}_place_orphan (file, s) lang_input_statement_type *file; asection *s; { - lang_output_section_statement_type *place; - asection *snew, **pps; + 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; etree_type *address; - const char *secname, *ps; + const char *secname; const char *outsecname; + const char *ps = NULL; lang_output_section_statement_type *os; - if ((s->flags & SEC_ALLOC) == 0) - return false; + 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); + /* Look through the script to see where to place this 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. */ if (! link_info.shared && ! link_info.relocateable && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 - && hold_text != NULL) + && hold_text.os != NULL) { - wild_doit (&hold_text->children, s, hold_text, file); + wild_doit (&hold_text.os->children, s, hold_text.os, file); return true; } @@ -1084,31 +1108,37 @@ 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. */ - place = NULL; +#define HAVE_SECTION(hold, name) \ +(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL) + if (s->flags & SEC_EXCLUDE) return false; + + place = NULL; + if ((s->flags & SEC_ALLOC) == 0) + ; else if ((s->flags & SEC_LOAD) != 0 - && strncmp (secname, ".note", 4) == 0 - && hold_interp != NULL) - place = hold_interp; + && strncmp (secname, ".note", 4) == 0 + && HAVE_SECTION (hold_interp, ".interp")) + place = &hold_interp; else if ((s->flags & SEC_HAS_CONTENTS) == 0 - && hold_bss != NULL) - place = hold_bss; + && HAVE_SECTION (hold_bss, ".bss")) + place = &hold_bss; else if ((s->flags & SEC_READONLY) == 0 - && hold_data != NULL) - place = hold_data; + && HAVE_SECTION (hold_data, ".data")) + place = &hold_data; else if (strncmp (secname, ".rel", 4) == 0 - && hold_rel != NULL) - place = hold_rel; - else if ((s->flags & SEC_CODE) == 0 - && (s->flags & SEC_READONLY) != 0 - && hold_rodata != NULL) - place = hold_rodata; - else if ((s->flags & SEC_READONLY) != 0 - && hold_text != NULL) - place = hold_text; - if (place == NULL) - return false; + && (hold_rel.os != NULL + || (hold_rel.os = output_rel_find ()) != NULL)) + place = &hold_rel; + else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY + && HAVE_SECTION (hold_rodata, ".rodata")) + place = &hold_rodata; + else if ((s->flags & (SEC_CODE | SEC_READONLY)) == (SEC_CODE | SEC_READONLY) + && hold_text.os != NULL) + 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 @@ -1134,113 +1164,142 @@ gld${EMULATION_NAME}_place_orphan (file, s) 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->bfd_section != NULL) - { - for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) - ; - *pps = snew->next; - snew->next = place->bfd_section->next; - place->bfd_section->next = snew; - } - - /* Start building a list of statements for this section. */ + /* Start building a list of statements for this section. + First save the current statement pointer. */ 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 we have found an appropriate place for the output section + statements for this orphan, add them to our own private list, + inserting them later into the global statement list. */ + if (place != NULL) { - char *symname; + stat_ptr = &add; + lang_list_init (stat_ptr); + } - 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)))); + if (config.build_constructors) + { + /* 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') + { + 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) - address = NULL; - else + if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) address = exp_intop ((bfd_vma) 0); + 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 - ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL, - "*default*"); - stat_ptr = &add; + ((bfd_vma) 0, "*default*", + (struct lang_output_section_phdr_list *) NULL, "*default*"); - if (*ps == '\0' && config.build_constructors) + if (config.build_constructors && *ps == '\0') { char *symname; + /* lang_leave_ouput_section_statement resets stat_ptr. Put + stat_ptr back where we want it. */ + if (place != NULL) + stat_ptr = &add; + symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_"); sprintf (symname, "__stop_%s", outsecname); lang_add_assignment (exp_assop ('=', symname, exp_nameop (NAME, "."))); } - /* Now stick the new statement list right after PLACE. */ - *add.tail = place->header.next; - place->header.next = add.head; - + /* Restore the global list pointer. */ stat_ptr = old; - return true; -} + if (place != NULL) + { + asection *snew, **pps; -static void -gld${EMULATION_NAME}_place_section (s) - lang_statement_union_type *s; -{ - lang_output_section_statement_type *os; + snew = os->bfd_section; + if (place->section != NULL + || (place->os->bfd_section != NULL + && place->os->bfd_section != snew)) + { + /* Shuffle the section to make the output file look neater. + This is really only cosmetic. */ + 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 + } - if (s->header.type != lang_output_section_statement_enum) - return; + /* Unlink the section. */ + for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) + ; + *pps = snew->next; - os = &s->output_section_statement; + /* 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 (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; - else if (strcmp (os->name, ".rodata") == 0) - hold_rodata = os; - else if (strcmp (os->name, ".data") == 0) - hold_data = os; - else if (strcmp (os->name, ".bss") == 0) - hold_bss = os; - else if (hold_rel == NULL - && os->bfd_section != NULL - && (os->bfd_section->flags & SEC_ALLOC) != 0 - && strncmp (os->name, ".rel", 4) == 0) - hold_rel = os; - else if (strcmp (os->name, ".interp") == 0) - hold_interp = os; + 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; + } + } + + return true; } static char * diff --git a/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em b/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em index 4c932a14fad..61ab7d4e91b 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em +++ b/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em @@ -69,6 +69,11 @@ gld${EMULATION_NAME}_after_open () { asection *datasec; + /* As first-order business, make sure that each input BFD is ECOFF. It + better be, as we are directly calling an ECOFF backend function. */ + if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour) + einfo ("%F%B: all input objects must be ECOFF for --embedded-relocs\n"); + datasec = bfd_get_section_by_name (abfd, ".sdata"); /* Note that we assume that the reloc_count field has already @@ -113,7 +118,7 @@ check_sections (abfd, sec, sdatasec) if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0 && sec != (asection *) sdatasec && sec->reloc_count != 0) - einfo ("%P%X: section %s has relocs; can not use --embedded-relocs\n", + einfo ("%B%X: section %s has relocs; can not use --embedded-relocs\n", abfd, bfd_get_section_name (abfd, sec)); } |