From ccd2ec6a8718548c570e4dead571af5c6ba0e2e3 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 24 Oct 2005 01:40:58 +0000 Subject: [PATCH] bfd/ 2005-10-23 H.J. Lu PR ld/1487 * elf-bfd.h (_bfd_generic_init_private_section_data): New. (_bfd_elf_init_private_section_data): New. * elf.c (elf_fake_sections): Don't set SHF_GROUP for relocatable link. (bfd_elf_set_group_contents): Don't handle relocatable link specially. (assign_section_numbers): If it isn't called by assembler, use the output section of elf_linked_to_section for SHF_LINK_ORDER. (_bfd_elf_init_private_section_data): New. (_bfd_elf_copy_private_section_data): Call it. * libbfd-in.h (_bfd_generic_init_private_section_data): New. * libbfd.c (_bfd_generic_init_private_section_data): New. * targets.c (BFD_JUMP_TABLE_COPY): Add _bfd_generic_init_private_section_data. (bfd_init_private_section_data): Likewise. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. ld/ 2005-10-23 H.J. Lu PR ld/1487 * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Call bfd_match_sections_by_type to match section types. * ldlang.c (init_os): Take the input section. Call bfd_init_private_section_data if the input section isn't NULL. (exp_init_os): Pass NULL to init_os. (map_input_to_output_sections): Likewise. (lang_add_section): Pass the input section to init_os. ld/testsuite/ 2005-10-23 H.J. Lu PR ld/1487 * ld-ia64/tlspic.rd: Updated. --- bfd/ChangeLog | 27 +++++ bfd/bfd-in2.h | 7 ++ bfd/elf-bfd.h | 4 + bfd/elf.c | 207 +++++++++++++++------------------ bfd/libbfd-in.h | 3 + bfd/libbfd.c | 10 ++ bfd/libbfd.h | 3 + bfd/targets.c | 7 ++ ld/ChangeLog | 12 ++ ld/emultempl/elf32.em | 5 +- ld/ldlang.c | 19 +-- ld/testsuite/ChangeLog | 5 + ld/testsuite/ld-ia64/tlspic.rd | 1 - 13 files changed, 185 insertions(+), 125 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 118c82d91a0..d69e998402b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,30 @@ +2005-10-23 H.J. Lu + + PR ld/1487 + * elf-bfd.h (_bfd_generic_init_private_section_data): New. + (_bfd_elf_init_private_section_data): New. + + * elf.c (elf_fake_sections): Don't set SHF_GROUP for + relocatable link. + (bfd_elf_set_group_contents): Don't handle relocatable link + specially. + (assign_section_numbers): If it isn't called by assembler, + use the output section of elf_linked_to_section for + SHF_LINK_ORDER. + (_bfd_elf_init_private_section_data): New. + (_bfd_elf_copy_private_section_data): Call it. + + * libbfd-in.h (_bfd_generic_init_private_section_data): New. + + * libbfd.c (_bfd_generic_init_private_section_data): New. + + * targets.c (BFD_JUMP_TABLE_COPY): Add + _bfd_generic_init_private_section_data. + (bfd_init_private_section_data): Likewise. + + * bfd-in2.h: Regenerated. + * libbfd.h: Likewise. + 2005-10-23 Alan Modra * elf64-ppc.c (dec_dynrel_count): Don't report errors for local diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 1d93b0f3050..6cf7e3c955c 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -4770,6 +4770,7 @@ typedef struct bfd_target #define BFD_JUMP_TABLE_COPY(NAME) \ NAME##_bfd_copy_private_bfd_data, \ NAME##_bfd_merge_private_bfd_data, \ + _bfd_generic_init_private_section_data, \ NAME##_bfd_copy_private_section_data, \ NAME##_bfd_copy_private_symbol_data, \ NAME##_bfd_copy_private_header_data, \ @@ -4782,6 +4783,12 @@ typedef struct bfd_target /* Called to merge BFD general private data from one object file to a common output file when linking. */ bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); + /* Called to initialize BFD private section data from one object file + to another. */ +#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \ + BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info)) + bfd_boolean (*_bfd_init_private_section_data) + (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *); /* Called to copy BFD private section data from one object file to another. */ bfd_boolean (*_bfd_copy_private_section_data) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index d011a454ee7..90cd4cae501 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1492,6 +1492,10 @@ extern bfd_boolean _bfd_elf_copy_private_header_data (bfd *, bfd *); extern bfd_boolean _bfd_elf_copy_private_symbol_data (bfd *, asymbol *, bfd *, asymbol *); +#define _bfd_generic_init_private_section_data \ + _bfd_elf_init_private_section_data +extern bfd_boolean _bfd_elf_init_private_section_data + (bfd *, asection *, bfd *, asection *, struct bfd_link_info *); extern bfd_boolean _bfd_elf_copy_private_section_data (bfd *, asection *, bfd *, asection *); extern bfd_boolean _bfd_elf_write_object_contents diff --git a/bfd/elf.c b/bfd/elf.c index 3a139a0bcf0..b7f38be1fbb 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -2670,29 +2670,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg) if (this_hdr->sh_type == SHT_NULL) { if ((asect->flags & SEC_GROUP) != 0) - { - /* We also need to mark SHF_GROUP here for relocatable - link. */ - struct bfd_link_order *l; - asection *elt; - - for (l = asect->map_head.link_order; l != NULL; l = l->next) - if (l->type == bfd_indirect_link_order - && (elt = elf_next_in_group (l->u.indirect.section)) != NULL) - do - { - /* The name is not important. Anything will do. */ - elf_group_name (elt->output_section) = "G"; - elf_section_flags (elt->output_section) |= SHF_GROUP; - - elt = elf_next_in_group (elt); - /* During a relocatable link, the lists are - circular. */ - } - while (elt != elf_next_in_group (l->u.indirect.section)); - - this_hdr->sh_type = SHT_GROUP; - } + this_hdr->sh_type = SHT_GROUP; else if ((asect->flags & SEC_ALLOC) != 0 && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) || (asect->flags & SEC_NEVER_LOAD) != 0)) @@ -2827,7 +2805,6 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) unsigned long symindx; asection *elt, *first; unsigned char *loc; - struct bfd_link_order *l; bfd_boolean gas; /* Ignore linker created group section. See elfNN_ia64_object_p in @@ -2896,22 +2873,6 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) break; } - /* If this is a relocatable link, then the above did nothing because - SEC is the output section. Look through the input sections - instead. */ - for (l = sec->map_head.link_order; l != NULL; l = l->next) - if (l->type == bfd_indirect_link_order - && (elt = elf_next_in_group (l->u.indirect.section)) != NULL) - do - { - loc -= 4; - H_PUT_32 (abfd, - elf_section_data (elt->output_section)->this_idx, loc); - elt = elf_next_in_group (elt); - /* During a relocatable link, the lists are circular. */ - } - while (elt != elf_next_in_group (l->u.indirect.section)); - if ((loc -= 4) != sec->contents) abort (); @@ -3091,67 +3052,46 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) { s = elf_linked_to_section (sec); if (s) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - else { - struct bfd_link_order *p; - - /* Find out what the corresponding section in output - is. */ - for (p = sec->map_head.link_order; p != NULL; p = p->next) + if (link_info != NULL) { - s = p->u.indirect.section; - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (s->owner) - == bfd_target_elf_flavour)) + /* For linker, elf_linked_to_section points to the + input section. */ + if (elf_discarded_section (s)) { - Elf_Internal_Shdr ** const elf_shdrp - = elf_elfsections (s->owner); - int elfsec - = _bfd_elf_section_from_bfd_section (s->owner, s); - elfsec = elf_shdrp[elfsec]->sh_link; - /* PR 290: - The Intel C compiler generates SHT_IA_64_UNWIND with - SHF_LINK_ORDER. But it doesn't set the sh_link or - sh_info fields. Hence we could get the situation - where elfsec is 0. */ - if (elfsec == 0) - { - const struct elf_backend_data *bed - = get_elf_backend_data (abfd); - if (bed->link_order_error_handler) - bed->link_order_error_handler - (_("%B: warning: sh_link not set for section `%A'"), - abfd, s); - } - else + asection *kept; + (*_bfd_error_handler) + (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"), + abfd, d->this_hdr.bfd_section, + s, s->owner); + /* Point to the kept section if it has the same + size as the discarded one. */ + kept = _bfd_elf_check_kept_section (s); + if (kept == NULL) { - s = elf_shdrp[elfsec]->bfd_section; - if (elf_discarded_section (s)) - { - asection *kept; - (*_bfd_error_handler) - (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"), - abfd, d->this_hdr.bfd_section, - s, s->owner); - /* Point to the kept section if it has - the same size as the discarded - one. */ - kept = _bfd_elf_check_kept_section (s); - if (kept == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - s = kept; - } - s = s->output_section; - BFD_ASSERT (s != NULL); - d->this_hdr.sh_link = elf_section_data (s)->this_idx; + bfd_set_error (bfd_error_bad_value); + return FALSE; } - break; + s = kept; } + s = s->output_section; + BFD_ASSERT (s != NULL); } + d->this_hdr.sh_link = elf_section_data (s)->this_idx; + } + else + { + /* PR 290: + The Intel C compiler generates SHT_IA_64_UNWIND with + SHF_LINK_ORDER. But it doesn't set the sh_link or + sh_info fields. Hence we could get the situation + where s is NULL. */ + const struct elf_backend_data *bed + = get_elf_backend_data (abfd); + if (bed->link_order_error_handler) + bed->link_order_error_handler + (_("%B: warning: sh_link not set for section `%A'"), + abfd, sec); } } @@ -5665,6 +5605,62 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd) return TRUE; } +/* Initialize private output section information from input section. */ + +bfd_boolean +_bfd_elf_init_private_section_data (bfd *ibfd, + asection *isec, + bfd *obfd, + asection *osec, + struct bfd_link_info *link_info) + +{ + Elf_Internal_Shdr *ihdr, *ohdr; + bfd_boolean need_group = link_info == NULL || link_info->relocatable; + + if (ibfd->xvec->flavour != bfd_target_elf_flavour + || obfd->xvec->flavour != bfd_target_elf_flavour) + return TRUE; + + /* FIXME: What if the output ELF section type has been set to + something different? */ + if (elf_section_type (osec) == SHT_NULL) + elf_section_type (osec) = elf_section_type (isec); + + /* Set things up for objcopy and relocatable link. The output + SHT_GROUP section will have its elf_next_in_group pointing back + to the input group members. Ignore linker created group section. + See elfNN_ia64_object_p in elfxx-ia64.c. */ + + if (need_group) + { + if (elf_sec_group (isec) == NULL + || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0) + { + if (elf_section_flags (isec) & SHF_GROUP) + elf_section_flags (osec) |= SHF_GROUP; + elf_next_in_group (osec) = elf_next_in_group (isec); + elf_group_name (osec) = elf_group_name (isec); + } + } + + ihdr = &elf_section_data (isec)->this_hdr; + + /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We + don't use the output section of the linked-to section since it + may be NULL at this point. */ + if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0) + { + ohdr = &elf_section_data (osec)->this_hdr; + ohdr->sh_flags |= SHF_LINK_ORDER; + elf_linked_to_section (osec) = elf_linked_to_section (isec); + } + + osec->use_rela_p = isec->use_rela_p; + + return TRUE; +} + /* Copy private section information. This copies over the entsize field, and sometimes the info field. */ @@ -5691,27 +5687,8 @@ _bfd_elf_copy_private_section_data (bfd *ibfd, || ihdr->sh_type == SHT_GNU_verdef) ohdr->sh_info = ihdr->sh_info; - /* Set things up for objcopy. The output SHT_GROUP section will - have its elf_next_in_group pointing back to the input group - members. Ignore linker created group section. See - elfNN_ia64_object_p in elfxx-ia64.c. We also need to handle - elf_linked_to_section for SHF_LINK_ORDER. */ - - if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0 - && elf_linked_to_section (isec) != 0) - elf_linked_to_section (osec) - = elf_linked_to_section (isec)->output_section; - - if (elf_sec_group (isec) == NULL - || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0) - { - elf_next_in_group (osec) = elf_next_in_group (isec); - elf_group_name (osec) = elf_group_name (isec); - } - - osec->use_rela_p = isec->use_rela_p; - - return TRUE; + return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec, + NULL); } /* Copy private header information. */ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 0290c84eda3..1b1789aab05 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -234,6 +234,9 @@ extern bfd_boolean _bfd_generic_get_section_contents_in_window #define _bfd_generic_bfd_print_private_bfd_data \ ((bfd_boolean (*) (bfd *, void *)) bfd_true) +extern bfd_boolean _bfd_generic_init_private_section_data + (bfd *, asection *, bfd *, asection *, struct bfd_link_info *); + /* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ diff --git a/bfd/libbfd.c b/bfd/libbfd.c index 3b27e08a8f3..34e32ac1112 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -1042,3 +1042,13 @@ _bfd_generic_match_sections_by_type (bfd *abfd ATTRIBUTE_UNUSED, { return TRUE; } + +bfd_boolean +_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, + asection *isec ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED, + asection *osec ATTRIBUTE_UNUSED, + struct bfd_link_info *link_info ATTRIBUTE_UNUSED) +{ + return TRUE; +} diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 56ad092983f..9125663515b 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -239,6 +239,9 @@ extern bfd_boolean _bfd_generic_get_section_contents_in_window #define _bfd_generic_bfd_print_private_bfd_data \ ((bfd_boolean (*) (bfd *, void *)) bfd_true) +extern bfd_boolean _bfd_generic_init_private_section_data + (bfd *, asection *, bfd *, asection *, struct bfd_link_info *); + /* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ diff --git a/bfd/targets.c b/bfd/targets.c index 271954fd9c0..78449711c02 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -271,6 +271,7 @@ BFD_JUMP_TABLE macros. .#define BFD_JUMP_TABLE_COPY(NAME) \ . NAME##_bfd_copy_private_bfd_data, \ . NAME##_bfd_merge_private_bfd_data, \ +. _bfd_generic_init_private_section_data, \ . NAME##_bfd_copy_private_section_data, \ . NAME##_bfd_copy_private_symbol_data, \ . NAME##_bfd_copy_private_header_data, \ @@ -283,6 +284,12 @@ BFD_JUMP_TABLE macros. . {* Called to merge BFD general private data from one object file . to a common output file when linking. *} . bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); +. {* Called to initialize BFD private section data from one object file +. to another. *} +.#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \ +. BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info)) +. bfd_boolean (*_bfd_init_private_section_data) +. (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *); . {* Called to copy BFD private section data from one object file . to another. *} . bfd_boolean (*_bfd_copy_private_section_data) diff --git a/ld/ChangeLog b/ld/ChangeLog index e40b47d75a5..4d74ef9804f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2005-10-23 H.J. Lu + + PR ld/1487 + * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Call + bfd_match_sections_by_type to match section types. + + * ldlang.c (init_os): Take the input section. Call + bfd_init_private_section_data if the input section isn't NULL. + (exp_init_os): Pass NULL to init_os. + (map_input_to_output_sections): Likewise. + (lang_add_section): Pass the input section to init_os. + 2005-10-19 Paul Brook * emulparams/armelf.sh: Add .ARM.attributes to OTHER_SECTIONS. diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index e1e37f16cc9..0425d15b78b 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1363,8 +1363,9 @@ gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s) if (os != NULL && (os->bfd_section == NULL || os->bfd_section->flags == 0 - || ((!iself - || sh_type == elf_section_type (os->bfd_section)) + || (bfd_match_sections_by_type (output_bfd, + os->bfd_section, + s->owner, s) && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0))) { diff --git a/ld/ldlang.c b/ld/ldlang.c index b82a7e55cf6..7824d2430c9 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1674,7 +1674,7 @@ sort_def_symbol (hash_entry, info) /* Initialize an output section. */ static void -init_os (lang_output_section_statement_type *s) +init_os (lang_output_section_statement_type *s, asection *isec) { if (s->bfd_section != NULL) return; @@ -1711,6 +1711,11 @@ init_os (lang_output_section_statement_type *s) if (s->load_base != NULL) exp_init_os (s->load_base); + + if (isec) + bfd_init_private_section_data (isec->owner, isec, + output_bfd, s->bfd_section, + &link_info); } /* Make sure that all output sections mentioned in an expression are @@ -1756,7 +1761,7 @@ exp_init_os (etree_type *exp) os = lang_output_section_find (exp->name.name); if (os != NULL && os->bfd_section == NULL) - init_os (os); + init_os (os, NULL); } } break; @@ -1833,7 +1838,7 @@ lang_add_section (lang_statement_list_type *ptr, flagword flags; if (output->bfd_section == NULL) - init_os (output); + init_os (output, section); first = ! output->bfd_section->linker_has_input; output->bfd_section->linker_has_input = 1; @@ -3099,7 +3104,7 @@ map_input_to_output_sections are initialized. */ exp_init_os (s->data_statement.exp); if (os != NULL && os->bfd_section == NULL) - init_os (os); + init_os (os, NULL); /* The output section gets contents, and then we inspect for any flags set in the input script which override any ALLOC. */ os->bfd_section->flags |= SEC_HAS_CONTENTS; @@ -3113,11 +3118,11 @@ map_input_to_output_sections case lang_padding_statement_enum: case lang_input_statement_enum: if (os != NULL && os->bfd_section == NULL) - init_os (os); + init_os (os, NULL); break; case lang_assignment_statement_enum: if (os != NULL && os->bfd_section == NULL) - init_os (os); + init_os (os, NULL); /* Make sure that any sections mentioned in the assignment are initialized. */ @@ -3145,7 +3150,7 @@ map_input_to_output_sections (s->address_statement.section_name)); if (aos->bfd_section == NULL) - init_os (aos); + init_os (aos, NULL); aos->addr_tree = s->address_statement.address; } break; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 8c228b18354..82f9b1b4ef6 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-10-23 H.J. Lu + + PR ld/1487 + * ld-ia64/tlspic.rd: Updated. + 2005-10-21 H.J. Lu PR ld/1467 diff --git a/ld/testsuite/ld-ia64/tlspic.rd b/ld/testsuite/ld-ia64/tlspic.rd index 2e9b2c82d6f..c1efeb54697 100644 --- a/ld/testsuite/ld-ia64/tlspic.rd +++ b/ld/testsuite/ld-ia64/tlspic.rd @@ -61,7 +61,6 @@ Symbol table '.dynsym' contains [0-9]+ entries: .* NOTYPE +LOCAL +DEFAULT +UND * .* SECTION LOCAL +DEFAULT +7 * .* SECTION LOCAL +DEFAULT +8 * -.* SECTION LOCAL +DEFAULT +9 * .* SECTION LOCAL +DEFAULT +10 * .* SECTION LOCAL +DEFAULT +11 * .* SECTION LOCAL +DEFAULT +14 * -- 2.30.2