* 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>
* Makefile.am: Add linux target for S/390.
@ -66,7 +88,7 @@
* libbfd-in.h (bfd_target_vector): Change extern array to pointer.
* libbfd.h (bfd_target_vector): Likewise.
* targets.c (bfd_target_vector): Rename to _bfd_target_vector and
make static; create pointer reference named bfd_target_vector.
make static; create pointer reference named bfd_target_vector.
(_bfd_target_vector_entries): Calculate this based on the array
typed _bfd_target_vector.

View file

@ -1,5 +1,5 @@
/* 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>
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
PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
boolean *again));
static boolean is_unwind_section_name
PARAMS ((const char *));
static boolean elfNN_ia64_section_from_shdr
PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
static boolean elfNN_ia64_fake_sections
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
PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
const char **namep, flagword *flagsp, asection **secp,
@ -900,6 +904,20 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
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
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)
{
case SHT_IA_64_UNWIND:
if (strcmp (name, ELF_STRING_ia64_unwind) != 0)
return false;
break;
case SHT_IA_64_EXT:
@ -968,8 +984,13 @@ elfNN_ia64_fake_sections (abfd, hdr, sec)
name = bfd_get_section_name (abfd, sec);
if (strcmp (name, ELF_STRING_ia64_unwind) == 0)
hdr->sh_type = SHT_IA_64_UNWIND;
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_flags |= SHF_LINK_ORDER;
}
else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
hdr->sh_type = SHT_IA_64_EXT;
else if (strcmp (name, ".reloc") == 0)
@ -999,6 +1020,58 @@ elfNN_ia64_fake_sections (abfd, hdr, sec)
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
file. We use it to put .comm items in .sbss, and not .bss. */
@ -1052,10 +1125,10 @@ elfNN_ia64_additional_program_headers (abfd)
if (s && (s->flags & SEC_LOAD))
++ret;
/* See if we need a PT_IA_64_UNWIND segment. */
s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
if (s && (s->flags & SEC_LOAD))
++ret;
/* Count how many PT_IA_64_UNWIND segments we need. */
for (s = abfd->sections; s; s = s->next)
if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
++ret;
return ret;
}
@ -1065,6 +1138,7 @@ elfNN_ia64_modify_segment_map (abfd)
bfd *abfd;
{
struct elf_segment_map *m, **pm;
Elf_Internal_Shdr *hdr;
asection *s;
/* If we need a PT_IA_64_ARCHEXT segment, it must come before
@ -1097,29 +1171,36 @@ elfNN_ia64_modify_segment_map (abfd)
}
}
/* Install the PT_IA_64_UNWIND segment, if needed. */
s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
if (s && (s->flags & SEC_LOAD))
/* Install PT_IA_64_UNWIND segments, if needed. */
for (s = abfd->sections; s; s = s->next)
{
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
if (m->p_type == PT_IA_64_UNWIND)
break;
if (m == NULL)
hdr = &elf_section_data (s)->this_hdr;
if (hdr->sh_type != SHT_IA_64_UNWIND)
continue;
if (s && (s->flags & SEC_LOAD))
{
m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
break;
if (m == NULL)
return false;
{
m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
if (m == NULL)
return false;
m->p_type = PT_IA_64_UNWIND;
m->count = 1;
m->sections[0] = s;
m->next = NULL;
m->p_type = PT_IA_64_UNWIND;
m->count = 1;
m->sections[0] = s;
m->next = NULL;
/* We want to put it last. */
pm = &elf_tdata (abfd)->segment_map;
while (*pm != NULL)
pm = &(*pm)->next;
*pm = m;
/* We want to put it last. */
pm = &elf_tdata (abfd)->segment_map;
while (*pm != NULL)
pm = &(*pm)->next;
*pm = m;
}
}
}
@ -4069,6 +4150,8 @@ elfNN_ia64_print_private_bfd_data (abfd, ptr)
elfNN_ia64_section_flags
#define elf_backend_fake_sections \
elfNN_ia64_fake_sections
#define elf_backend_final_write_processing \
elfNN_ia64_final_write_processing
#define elf_backend_add_symbol_hook \
elfNN_ia64_add_symbol_hook
#define elf_backend_additional_program_headers \