From 38ce5b119123653044ec30f4e7a770cd806fcd09 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 26 Jul 2004 21:01:15 +0000 Subject: [PATCH] bfd/ 2004-07-26 H.J. Lu * elf-bfd.h (bfd_elf_section_data): Add a pointer for the linked-to section. (elf_linked_to_section): New. * elf.c (assign_section_numbers): Set up sh_link for SHF_LINK_ORDER. * elfxx-ia64.c (elfNN_ia64_final_write_processing): Set sh_info to sh_link for SHT_IA_64_UNWIND sections. gas/ 2004-07-26 H.J. Lu * config/tc-ia64.c (start_unwind_section): Set the linked-to section. (ia64_elf_section_change_hook): Set the linked-to section for SHT_IA_64_UNWIND. --- bfd/ChangeLog | 12 ++++++++ bfd/elf-bfd.h | 4 +++ bfd/elf.c | 35 +++++++++++++++++++++++ bfd/elfxx-ia64.c | 67 ++++---------------------------------------- gas/ChangeLog | 7 +++++ gas/config/tc-ia64.c | 5 ++++ 6 files changed, 69 insertions(+), 61 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e2c49e834c..ff86f84376 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2004-07-26 H.J. Lu + + * elf-bfd.h (bfd_elf_section_data): Add a pointer for the + linked-to section. + (elf_linked_to_section): New. + + * elf.c (assign_section_numbers): Set up sh_link for + SHF_LINK_ORDER. + + * elfxx-ia64.c (elfNN_ia64_final_write_processing): Set sh_info + to sh_link for SHT_IA_64_UNWIND sections. + 2004-07-22 H.J. Lu * elflink.c (elf_fixup_link_order): Add _() to error message. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 5e5068379a..c260fa2b5f 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1038,6 +1038,9 @@ struct bfd_elf_section_data no dynamic symbol for this section. */ int dynindx; + /* A pointer to the linked-to section for SHF_LINK_ORDER. */ + asection *linked_to; + /* Used by the backend linker to store the symbol hash table entries associated with relocs against global symbols. */ struct elf_link_hash_entry **rel_hashes; @@ -1071,6 +1074,7 @@ struct bfd_elf_section_data }; #define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd) +#define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to) #define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type) #define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags) #define elf_group_name(sec) (elf_section_data(sec)->group.name) diff --git a/bfd/elf.c b/bfd/elf.c index 4371f15869..300ed276f5 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -2790,6 +2790,7 @@ assign_section_numbers (bfd *abfd) i_shdrp[t->strtab_section] = &t->strtab_hdr; t->symtab_hdr.sh_link = t->strtab_section; } + for (sec = abfd->sections; sec; sec = sec->next) { struct bfd_elf_section_data *d = elf_section_data (sec); @@ -2818,6 +2819,40 @@ assign_section_numbers (bfd *abfd) d->rel_hdr2->sh_info = d->this_idx; } + /* We need to set up sh_link for SHF_LINK_ORDER. */ + if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0) + { + 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->link_order_head; p != NULL; p = p->next) + { + s = p->u.indirect.section; + if (p->type == bfd_indirect_link_order + && (bfd_get_flavour (s->owner) + == bfd_target_elf_flavour)) + { + 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; + BFD_ASSERT (elfsec != 0); + s = elf_shdrp[elfsec]->bfd_section->output_section; + BFD_ASSERT (s != NULL); + d->this_hdr.sh_link = elf_section_data (s)->this_idx; + break; + } + } + } + } + switch (d->this_hdr.sh_type) { case SHT_REL: diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index e0c70c11ae..614d1d8a3d 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -1365,9 +1365,7 @@ elfNN_ia64_final_write_processing (abfd, linker) bfd_boolean linker ATTRIBUTE_UNUSED; { Elf_Internal_Shdr *hdr; - const char *sname; - asection *text_sect, *s; - size_t len; + asection *s; for (s = abfd->sections; s; s = s->next) { @@ -1375,64 +1373,11 @@ elfNN_ia64_final_write_processing (abfd, linker) switch (hdr->sh_type) { case SHT_IA_64_UNWIND: - /* See comments in gas/config/tc-ia64.c:dot_endp on why we - have to do this. */ - sname = bfd_get_section_name (abfd, s); - len = sizeof (ELF_STRING_ia64_unwind) - 1; - if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0) - { - sname += len; - - if (sname[0] == '\0') - /* .IA_64.unwind -> .text */ - text_sect = bfd_get_section_by_name (abfd, ".text"); - else - /* .IA_64.unwindFOO -> FOO */ - text_sect = bfd_get_section_by_name (abfd, sname); - } - else if (sname - && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1, - strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0) - { - /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */ - size_t len2 = sizeof (".gnu.linkonce.t.") - 1; - char *once_name = bfd_malloc (len2 + strlen (sname + len) + 1); - - if (once_name != NULL) - { - memcpy (once_name, ".gnu.linkonce.t.", len2); - strcpy (once_name + len2, sname + len); - text_sect = bfd_get_section_by_name (abfd, once_name); - free (once_name); - } - else - /* Should only happen if we run out of memory, in - which case we're probably toast anyway. Try to - cope by finding the section the slow way. */ - for (text_sect = abfd->sections; - text_sect != NULL; - text_sect = text_sect->next) - { - if (strncmp (bfd_section_name (abfd, text_sect), - ".gnu.linkonce.t.", len2) == 0 - && strcmp (bfd_section_name (abfd, text_sect) + len2, - sname + len) == 0) - break; - } - } - else - /* last resort: fall back on .text */ - text_sect = bfd_get_section_by_name (abfd, ".text"); - - if (text_sect) - { - /* The IA-64 processor-specific ABI requires setting - sh_link to the unwind section, whereas HP-UX requires - sh_info to do so. For maximum compatibility, we'll - set both for now... */ - hdr->sh_link = elf_section_data (text_sect)->this_idx; - hdr->sh_info = elf_section_data (text_sect)->this_idx; - } + /* The IA-64 processor-specific ABI requires setting sh_link + to the unwind section, whereas HP-UX requires sh_info to + do so. For maximum compatibility, we'll set both for + now... */ + hdr->sh_info = hdr->sh_link; break; } } diff --git a/gas/ChangeLog b/gas/ChangeLog index cd6a533838..70bf40cf7b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2004-07-26 H.J. Lu + + * config/tc-ia64.c (start_unwind_section): Set the linked-to + section. + (ia64_elf_section_change_hook): Set the linked-to section for + SHT_IA_64_UNWIND. + 2004-07-26 Dmitry Diky * config/tc-msp430.c: Add new subtargets: msp430x1610, diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 13cf19dbb6..b48557d6d5 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -3403,6 +3403,8 @@ start_unwind_section (const segT text_seg, int sec_index) bfd_set_section_flags (stdoutput, now_seg, SEC_LOAD | SEC_ALLOC | SEC_READONLY); } + + elf_linked_to_section (now_seg) = text_seg; } static void @@ -11022,6 +11024,9 @@ ia64_float_to_chars_littleendian (char *lit, LITTLENUM_TYPE *words, void ia64_elf_section_change_hook (void) { + if (elf_section_type (now_seg) == SHT_IA_64_UNWIND + && elf_linked_to_section (now_seg) == NULL) + elf_linked_to_section (now_seg) = text_section; dot_byteorder (-1); } -- 2.34.1