* elfxx-ia64.c (is_unwind_section_name): New function. Returns

true if section name is an unwind table section name.
        (elfNN_ia64_additional_program_headers): Count each unwind section
        separately.
        (elfNN_ia64_modify_segment_map): Install one unwind program header
        for each unwind separate section.  Note: normally the linker
        script merges the unwind sections that go into a single segment,
        so this still generates at most one unwind program header per
        segment.

        * elfxx-ia64.c (elfNN_ia64_section_from_shdr): Accept any section
        name for SHT_IA_64_UNWIND, not just .IA_64.unwind.
        (elfNN_ia64_fake_sections): Mark sections with names that start
        with .IA_64.unwind but not with .IA_64.unwind_info as an IA-64
        unwind section.

        * elfxx-ia64.c (elfNN_ia64_final_write_processing): New function.
        Use it to make sh_info in unwind section point to the text section
        it applies to.
This commit is contained in:
Richard Henderson
2001-02-10 01:41:06 +00:00
parent a85d7ed0f0
commit 81545d45ad
2 changed files with 133 additions and 28 deletions

View File

@ -1,3 +1,25 @@
2001-02-09 David Mosberger <davidm@hpl.hp.com>
* elfxx-ia64.c (is_unwind_section_name): New function. Returns
true if section name is an unwind table section name.
(elfNN_ia64_additional_program_headers): Count each unwind section
separately.
(elfNN_ia64_modify_segment_map): Install one unwind program header
for each unwind separate section. Note: normally the linker
script merges the unwind sections that go into a single segment,
so this still generates at most one unwind program header per
segment.
* elfxx-ia64.c (elfNN_ia64_section_from_shdr): Accept any section
name for SHT_IA_64_UNWIND, not just .IA_64.unwind.
(elfNN_ia64_fake_sections): Mark sections with names that start
with .IA_64.unwind but not with .IA_64.unwind_info as an IA-64
unwind section.
* elfxx-ia64.c (elfNN_ia64_final_write_processing): New function.
Use it to make sh_info in unwind section point to the text section
it applies to.
2001-02-09 Martin Schwidefsky <schwidefsky@de.ibm.com> 2001-02-09 Martin Schwidefsky <schwidefsky@de.ibm.com>
* Makefile.am: Add linux target for S/390. * Makefile.am: Add linux target for S/390.

View File

@ -1,5 +1,5 @@
/* IA-64 support for 64-bit ELF /* IA-64 support for 64-bit ELF
Copyright 1998, 1999, 2000 Free Software Foundation, Inc. Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of BFD, the Binary File Descriptor library. This file is part of BFD, the Binary File Descriptor library.
@ -157,10 +157,14 @@ static void elfNN_ia64_info_to_howto
static boolean elfNN_ia64_relax_section static boolean elfNN_ia64_relax_section
PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info, PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
boolean *again)); boolean *again));
static boolean is_unwind_section_name
PARAMS ((const char *));
static boolean elfNN_ia64_section_from_shdr static boolean elfNN_ia64_section_from_shdr
PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *)); PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
static boolean elfNN_ia64_fake_sections static boolean elfNN_ia64_fake_sections
PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec)); PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
static void elfNN_ia64_final_write_processing
PARAMS ((bfd *abfd, boolean linker));
static boolean elfNN_ia64_add_symbol_hook static boolean elfNN_ia64_add_symbol_hook
PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym, PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
const char **namep, flagword *flagsp, asection **secp, const char **namep, flagword *flagsp, asection **secp,
@ -900,6 +904,20 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
return false; return false;
} }
/* Return true if NAME is an unwind table section name. */
static inline boolean
is_unwind_section_name (name)
const char *name;
{
size_t len1, len2;
len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
return (strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
&& strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0);
}
/* Handle an IA-64 specific section when reading an object file. This /* Handle an IA-64 specific section when reading an object file. This
is called when elfcode.h finds a section with an unknown type. */ is called when elfcode.h finds a section with an unknown type. */
@ -919,8 +937,6 @@ elfNN_ia64_section_from_shdr (abfd, hdr, name)
switch (hdr->sh_type) switch (hdr->sh_type)
{ {
case SHT_IA_64_UNWIND: case SHT_IA_64_UNWIND:
if (strcmp (name, ELF_STRING_ia64_unwind) != 0)
return false;
break; break;
case SHT_IA_64_EXT: case SHT_IA_64_EXT:
@ -968,8 +984,13 @@ elfNN_ia64_fake_sections (abfd, hdr, sec)
name = bfd_get_section_name (abfd, sec); name = bfd_get_section_name (abfd, sec);
if (strcmp (name, ELF_STRING_ia64_unwind) == 0) if (is_unwind_section_name (name))
{
/* We don't have the sections numbered at this point, so sh_info
is set later, in elfNN_ia64_final_write_processing. */
hdr->sh_type = SHT_IA_64_UNWIND; hdr->sh_type = SHT_IA_64_UNWIND;
hdr->sh_flags |= SHF_LINK_ORDER;
}
else if (strcmp (name, ELF_STRING_ia64_archext) == 0) else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
hdr->sh_type = SHT_IA_64_EXT; hdr->sh_type = SHT_IA_64_EXT;
else if (strcmp (name, ".reloc") == 0) else if (strcmp (name, ".reloc") == 0)
@ -999,6 +1020,58 @@ elfNN_ia64_fake_sections (abfd, hdr, sec)
return true; return true;
} }
/* The final processing done just before writing out an IA-64 ELF
object file. */
static void
elfNN_ia64_final_write_processing (abfd, linker)
bfd *abfd;
boolean linker ATTRIBUTE_UNUSED;
{
Elf_Internal_Shdr *hdr;
const char *sname;
asection *text_sect, *s;
size_t len;
for (s = abfd->sections; s; s = s->next)
{
hdr = &elf_section_data (s)->this_hdr;
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
/* 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;
}
break;
}
}
}
/* Hook called by the linker routine which adds symbols from an object /* Hook called by the linker routine which adds symbols from an object
file. We use it to put .comm items in .sbss, and not .bss. */ file. We use it to put .comm items in .sbss, and not .bss. */
@ -1052,9 +1125,9 @@ elfNN_ia64_additional_program_headers (abfd)
if (s && (s->flags & SEC_LOAD)) if (s && (s->flags & SEC_LOAD))
++ret; ++ret;
/* See if we need a PT_IA_64_UNWIND segment. */ /* Count how many PT_IA_64_UNWIND segments we need. */
s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind); for (s = abfd->sections; s; s = s->next)
if (s && (s->flags & SEC_LOAD)) if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
++ret; ++ret;
return ret; return ret;
@ -1065,6 +1138,7 @@ elfNN_ia64_modify_segment_map (abfd)
bfd *abfd; bfd *abfd;
{ {
struct elf_segment_map *m, **pm; struct elf_segment_map *m, **pm;
Elf_Internal_Shdr *hdr;
asection *s; asection *s;
/* If we need a PT_IA_64_ARCHEXT segment, it must come before /* If we need a PT_IA_64_ARCHEXT segment, it must come before
@ -1097,13 +1171,19 @@ elfNN_ia64_modify_segment_map (abfd)
} }
} }
/* Install the PT_IA_64_UNWIND segment, if needed. */ /* Install PT_IA_64_UNWIND segments, if needed. */
s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind); for (s = abfd->sections; s; s = s->next)
{
hdr = &elf_section_data (s)->this_hdr;
if (hdr->sh_type != SHT_IA_64_UNWIND)
continue;
if (s && (s->flags & SEC_LOAD)) if (s && (s->flags & SEC_LOAD))
{ {
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
if (m->p_type == PT_IA_64_UNWIND) if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
break; break;
if (m == NULL) if (m == NULL)
{ {
m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
@ -1122,6 +1202,7 @@ elfNN_ia64_modify_segment_map (abfd)
*pm = m; *pm = m;
} }
} }
}
/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
the input sections for each output section in the segment and testing the input sections for each output section in the segment and testing
@ -4069,6 +4150,8 @@ elfNN_ia64_print_private_bfd_data (abfd, ptr)
elfNN_ia64_section_flags elfNN_ia64_section_flags
#define elf_backend_fake_sections \ #define elf_backend_fake_sections \
elfNN_ia64_fake_sections elfNN_ia64_fake_sections
#define elf_backend_final_write_processing \
elfNN_ia64_final_write_processing
#define elf_backend_add_symbol_hook \ #define elf_backend_add_symbol_hook \
elfNN_ia64_add_symbol_hook elfNN_ia64_add_symbol_hook
#define elf_backend_additional_program_headers \ #define elf_backend_additional_program_headers \