aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elf.c35
-rw-r--r--bfd/elfxx-ia64.c67
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-ia64.c5
6 files changed, 69 insertions, 61 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e2c49e8..ff86f84 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2004-07-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * 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 <hongjiu.lu@intel.com>
* elflink.c (elf_fixup_link_order): Add _() to error message.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 5e50683..c260fa2 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 4371f15..300ed27 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 e0c70c1..614d1d8 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 cd6a533..70bf40c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2004-07-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * 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 <diwil@spec.ru>
* config/tc-msp430.c: Add new subtargets: msp430x1610,
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index 13cf19d..b48557d 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);
}