From 5ba474214c1c89d7d3efe4b6d8bc465b9c8c5042 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 18 Apr 2000 05:53:41 +0000 Subject: [PATCH] Yet another set of fixes for orphan sections. --- ld/ChangeLog | 17 +++++- ld/emultempl/armelf.em | 132 +++++++++++++++++++++++------------------ ld/emultempl/elf32.em | 132 +++++++++++++++++++++++------------------ ld/emultempl/pe.em | 156 +++++++++++++++++++++++++++---------------------- 4 files changed, 253 insertions(+), 184 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index d24b36e..fc0c50e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2000-04-18 Alan Modra + + * 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 * scripttempl/elfppc.sc: Remove. @@ -13,10 +24,10 @@ 2000-04-14 Alan Modra - * 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 diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index e5f1514..8632bd3 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -789,6 +789,7 @@ static lang_output_section_statement_type *hold_use; struct orphan_save { lang_output_section_statement_type *os; + asection **section; lang_statement_union_type **stmt; }; static struct orphan_save hold_text; @@ -805,7 +806,6 @@ gld${EMULATION_NAME}_place_orphan (file, s) asection *s; { struct orphan_save *place; - asection *snew, **pps; lang_statement_list_type *old; lang_statement_list_type add; etree_type *address; @@ -845,6 +845,8 @@ gld${EMULATION_NAME}_place_orphan (file, s) 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) @@ -892,45 +894,29 @@ 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 != 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) @@ -947,24 +933,59 @@ gld${EMULATION_NAME}_place_orphan (file, s) 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; @@ -976,9 +997,8 @@ gld${EMULATION_NAME}_place_orphan (file, s) *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; } diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 2489779..d5ee9af 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -871,6 +871,7 @@ static lang_output_section_statement_type *hold_use; struct orphan_save { lang_output_section_statement_type *os; + asection **section; lang_statement_union_type **stmt; }; static struct orphan_save hold_text; @@ -887,7 +888,6 @@ gld${EMULATION_NAME}_place_orphan (file, s) asection *s; { struct orphan_save *place; - asection *snew, **pps; lang_statement_list_type *old; lang_statement_list_type add; etree_type *address; @@ -927,6 +927,8 @@ gld${EMULATION_NAME}_place_orphan (file, s) 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) @@ -974,45 +976,29 @@ 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 != 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) @@ -1029,24 +1015,59 @@ gld${EMULATION_NAME}_place_orphan (file, s) 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; @@ -1058,9 +1079,8 @@ gld${EMULATION_NAME}_place_orphan (file, s) *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; } diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 0a94f58..aeecb61 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -1081,6 +1081,7 @@ static lang_output_section_statement_type *hold_use; struct orphan_save { lang_output_section_statement_type *os; + asection **section; lang_statement_union_type **stmt; }; static struct orphan_save hold_text; @@ -1099,6 +1100,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s) { const char *secname; char *dollar = NULL; + lang_statement_list_type add_child; secname = bfd_get_section_name (s->owner, s); @@ -1117,11 +1119,16 @@ gld_${EMULATION_NAME}_place_orphan (file, 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; @@ -1129,8 +1136,10 @@ gld_${EMULATION_NAME}_place_orphan (file, s) /* 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) @@ -1168,29 +1177,6 @@ gld_${EMULATION_NAME}_place_orphan (file, s) 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; @@ -1213,15 +1199,52 @@ gld_${EMULATION_NAME}_place_orphan (file, s) (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; @@ -1235,55 +1258,50 @@ gld_${EMULATION_NAME}_place_orphan (file, s) } 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); -- 2.7.4