bfd/Changelog:
* libbfd-in.h (_bfd_link_section_stabs): Add string offset parameter. * cofflink.c (coff_link_add_symbols): Deal with split stab sections. * elflink.h (elf_link_add_object_symbols): Deal with split stab sections. * stabs.c (_bfd_link_section_stabs): Add string offset parameter. * libbfd.h: Regenerated. ld/ChangeLog: * ldwrite.c (unsplittable_name): New. (clone_section): Strip existing numeric suffix. Only truncate names for coff targets. (split_sections): Use unsplittable_name. binutils/ChangeLog: * objdump.c (read_section_stabs): Just read one section, return pointer to it. Add size parameter. (print_section_stabs): Add string offset parameter. Adjust. (struct stab_section_names): Add string offset member. (find_stabs_sections): Correct check for split section suffix, adjust read_section_stabs and print_section_stabs calls. (dump_stabs_section): Clear string_offset, free string table.
This commit is contained in:
parent
cd339148de
commit
29ca8dc5bb
@ -1,5 +1,14 @@
|
||||
2003-10-07 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* libbfd-in.h (_bfd_link_section_stabs): Add string offset
|
||||
parameter.
|
||||
* cofflink.c (coff_link_add_symbols): Deal with split stab
|
||||
sections.
|
||||
* elflink.h (elf_link_add_object_symbols): Deal with split stab
|
||||
sections.
|
||||
* stabs.c (_bfd_link_section_stabs): Add string offset parameter.
|
||||
* libbfd.h: Regenerated.
|
||||
|
||||
* coffcode.h (coff_set_alignment_hook): With PE_COFF reloc
|
||||
overflow, set reloc start position to after the count
|
||||
reloc. Subtract one from num relocs. Give error on 0xffff relocs
|
||||
|
@ -570,19 +570,24 @@ coff_link_add_symbols (bfd *abfd,
|
||||
&& info->hash->creator->flavour == bfd_get_flavour (abfd)
|
||||
&& (info->strip != strip_all && info->strip != strip_debugger))
|
||||
{
|
||||
asection *stab, *stabstr;
|
||||
asection *stabstr;
|
||||
|
||||
stab = bfd_get_section_by_name (abfd, ".stab");
|
||||
if (stab != NULL)
|
||||
stabstr = bfd_get_section_by_name (abfd, ".stabstr");
|
||||
|
||||
if (stabstr != NULL)
|
||||
{
|
||||
stabstr = bfd_get_section_by_name (abfd, ".stabstr");
|
||||
|
||||
if (stabstr != NULL)
|
||||
bfd_size_type string_offset = 0;
|
||||
asection *stab;
|
||||
|
||||
for (stab = abfd->sections; stab; stab = stab->next)
|
||||
if (strncmp (".stab", stab->name, 5) == 0
|
||||
&& (!stab->name[5]
|
||||
|| (stab->name[5] == '.' && isdigit (stab->name[6]))))
|
||||
{
|
||||
struct coff_link_hash_table *table;
|
||||
struct coff_section_tdata *secdata;
|
||||
|
||||
secdata = coff_section_data (abfd, stab);
|
||||
struct coff_section_tdata *secdata
|
||||
= coff_section_data (abfd, stab);
|
||||
|
||||
if (secdata == NULL)
|
||||
{
|
||||
amt = sizeof (struct coff_section_tdata);
|
||||
@ -596,7 +601,8 @@ coff_link_add_symbols (bfd *abfd,
|
||||
|
||||
if (! _bfd_link_section_stabs (abfd, &table->stab_info,
|
||||
stab, stabstr,
|
||||
&secdata->stab_info))
|
||||
&secdata->stab_info,
|
||||
&string_offset))
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
/* ELF linker code. */
|
||||
|
||||
#include "safe-ctype.h"
|
||||
|
||||
static bfd_boolean elf_link_add_object_symbols (bfd *, struct bfd_link_info *);
|
||||
static bfd_boolean elf_link_add_archive_symbols (bfd *,
|
||||
struct bfd_link_info *);
|
||||
@ -1607,27 +1609,32 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
&& is_elf_hash_table (info)
|
||||
&& (info->strip != strip_all && info->strip != strip_debugger))
|
||||
{
|
||||
asection *stab, *stabstr;
|
||||
|
||||
stab = bfd_get_section_by_name (abfd, ".stab");
|
||||
if (stab != NULL
|
||||
&& (stab->flags & SEC_MERGE) == 0
|
||||
&& !bfd_is_abs_section (stab->output_section))
|
||||
asection *stabstr;
|
||||
|
||||
stabstr = bfd_get_section_by_name (abfd, ".stabstr");
|
||||
if (stabstr != NULL)
|
||||
{
|
||||
stabstr = bfd_get_section_by_name (abfd, ".stabstr");
|
||||
bfd_size_type string_offset = 0;
|
||||
asection *stab;
|
||||
|
||||
if (stabstr != NULL)
|
||||
{
|
||||
struct bfd_elf_section_data *secdata;
|
||||
|
||||
secdata = elf_section_data (stab);
|
||||
if (! _bfd_link_section_stabs (abfd,
|
||||
& hash_table->stab_info,
|
||||
stab, stabstr,
|
||||
&secdata->sec_info))
|
||||
goto error_return;
|
||||
if (secdata->sec_info)
|
||||
stab->sec_info_type = ELF_INFO_TYPE_STABS;
|
||||
for (stab = abfd->sections; stab; stab = stab->next)
|
||||
if (strncmp (".stab", stab->name, 5) == 0
|
||||
&& (!stab->name[5] ||
|
||||
(stab->name[5] == '.' && ISDIGIT (stab->name[6])))
|
||||
&& (stab->flags & SEC_MERGE) == 0
|
||||
&& !bfd_is_abs_section (stab->output_section))
|
||||
{
|
||||
struct bfd_elf_section_data *secdata;
|
||||
|
||||
secdata = elf_section_data (stab);
|
||||
if (! _bfd_link_section_stabs (abfd,
|
||||
& hash_table->stab_info,
|
||||
stab, stabstr,
|
||||
&secdata->sec_info,
|
||||
&string_offset))
|
||||
goto error_return;
|
||||
if (secdata->sec_info)
|
||||
stab->sec_info_type = ELF_INFO_TYPE_STABS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ extern bfd_reloc_status_type _bfd_relocate_contents
|
||||
/* Link stabs in sections in the first pass. */
|
||||
|
||||
extern bfd_boolean _bfd_link_section_stabs
|
||||
(bfd *, void **, asection *, asection *, void **);
|
||||
(bfd *, void **, asection *, asection *, void **, bfd_size_type *);
|
||||
|
||||
/* Eliminate stabs for discarded functions and symbols. */
|
||||
extern bfd_boolean _bfd_discard_section_stabs
|
||||
|
@ -495,7 +495,7 @@ extern bfd_reloc_status_type _bfd_relocate_contents
|
||||
/* Link stabs in sections in the first pass. */
|
||||
|
||||
extern bfd_boolean _bfd_link_section_stabs
|
||||
(bfd *, void **, asection *, asection *, void **);
|
||||
(bfd *, void **, asection *, asection *, void **, bfd_size_type *);
|
||||
|
||||
/* Eliminate stabs for discarded functions and symbols. */
|
||||
extern bfd_boolean _bfd_discard_section_stabs
|
||||
|
11
bfd/stabs.c
11
bfd/stabs.c
@ -169,12 +169,13 @@ stab_link_includes_newfunc (entry, table, string)
|
||||
pass of the linker. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
|
||||
_bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_offset)
|
||||
bfd *abfd;
|
||||
PTR *psinfo;
|
||||
asection *stabsec;
|
||||
asection *stabstrsec;
|
||||
PTR *psecinfo;
|
||||
bfd_size_type *pstring_offset;
|
||||
{
|
||||
bfd_boolean first;
|
||||
struct stab_info *sinfo;
|
||||
@ -276,7 +277,11 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
|
||||
and identify N_BINCL symbols which can be eliminated. */
|
||||
|
||||
stroff = 0;
|
||||
next_stroff = 0;
|
||||
/* The stabs sections can be split when
|
||||
-split-by-reloc/-split-by-file is used. We must keep track of
|
||||
each stab section's place in the single concatenated string
|
||||
table. */
|
||||
next_stroff = pstring_offset ? *pstring_offset : 0;
|
||||
skip = 0;
|
||||
|
||||
symend = stabbuf + stabsec->_raw_size;
|
||||
@ -302,6 +307,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
|
||||
string table. We only copy the very first one. */
|
||||
stroff = next_stroff;
|
||||
next_stroff += bfd_get_32 (abfd, sym + 8);
|
||||
if (pstring_offset)
|
||||
*pstring_offset = next_stroff;
|
||||
if (! first)
|
||||
{
|
||||
*pstridx = (bfd_size_type) -1;
|
||||
|
@ -1,3 +1,13 @@
|
||||
2003-10-07 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* objdump.c (read_section_stabs): Just read one section, return
|
||||
pointer to it. Add size parameter.
|
||||
(print_section_stabs): Add string offset parameter. Adjust.
|
||||
(struct stab_section_names): Add string offset member.
|
||||
(find_stabs_sections): Correct check for split section suffix,
|
||||
adjust read_section_stabs and print_section_stabs calls.
|
||||
(dump_stabs_section): Clear string_offset, free string table.
|
||||
|
||||
2003-10-01 Martin Fuchs <martin-fuchs@gmx.net>
|
||||
|
||||
* resrc.c (define_icon): Fix storage of color attributes 'planes' and
|
||||
|
@ -1873,63 +1873,39 @@ disassemble_data (bfd *abfd)
|
||||
free (sorted_syms);
|
||||
}
|
||||
|
||||
/* Read ABFD's stabs section STABSECT_NAME into `stabs'
|
||||
and string table section STRSECT_NAME into `strtab'.
|
||||
If the section exists and was read, allocate the space and return TRUE.
|
||||
Otherwise return FALSE. */
|
||||
/* Read ABFD's stabs section STABSECT_NAME, and return a pointer to
|
||||
it. Return NULL on failure. */
|
||||
|
||||
static bfd_boolean
|
||||
read_section_stabs (bfd *abfd, const char *stabsect_name,
|
||||
const char *strsect_name)
|
||||
static char *
|
||||
read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
|
||||
{
|
||||
asection *stabsect, *stabstrsect;
|
||||
asection *stabsect;
|
||||
bfd_size_type size;
|
||||
char *contents;
|
||||
|
||||
stabsect = bfd_get_section_by_name (abfd, stabsect_name);
|
||||
stabsect = bfd_get_section_by_name (abfd, sect_name);
|
||||
if (stabsect == NULL)
|
||||
{
|
||||
printf (_("No %s section present\n\n"), stabsect_name);
|
||||
printf (_("No %s section present\n\n"), sect_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
|
||||
if (stabstrsect == NULL)
|
||||
{
|
||||
non_fatal (_("%s has no %s section"),
|
||||
bfd_get_filename (abfd), strsect_name);
|
||||
exit_status = 1;
|
||||
return FALSE;
|
||||
}
|
||||
size = bfd_section_size (abfd, stabsect);
|
||||
contents = xmalloc (size);
|
||||
|
||||
stab_size = bfd_section_size (abfd, stabsect);
|
||||
stabstr_size = bfd_section_size (abfd, stabstrsect);
|
||||
|
||||
stabs = xmalloc (stab_size);
|
||||
strtab = xmalloc (stabstr_size);
|
||||
|
||||
if (! bfd_get_section_contents (abfd, stabsect, stabs, 0, stab_size))
|
||||
if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size))
|
||||
{
|
||||
non_fatal (_("Reading %s section of %s failed: %s"),
|
||||
stabsect_name, bfd_get_filename (abfd),
|
||||
sect_name, bfd_get_filename (abfd),
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
free (stabs);
|
||||
free (strtab);
|
||||
free (contents);
|
||||
exit_status = 1;
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (! bfd_get_section_contents (abfd, stabstrsect, (void *) strtab, 0,
|
||||
stabstr_size))
|
||||
{
|
||||
non_fatal (_("Reading %s section of %s failed: %s\n"),
|
||||
strsect_name, bfd_get_filename (abfd),
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
free (stabs);
|
||||
free (strtab);
|
||||
exit_status = 1;
|
||||
return FALSE;
|
||||
}
|
||||
*size_ptr = size;
|
||||
|
||||
return TRUE;
|
||||
return contents;
|
||||
}
|
||||
|
||||
/* Stabs entries use a 12 byte format:
|
||||
@ -1951,11 +1927,11 @@ read_section_stabs (bfd *abfd, const char *stabsect_name,
|
||||
using string table section STRSECT_NAME (in `strtab'). */
|
||||
|
||||
static void
|
||||
print_section_stabs (bfd *abfd, const char *stabsect_name)
|
||||
print_section_stabs (bfd *abfd, const char *stabsect_name, unsigned *string_offset_ptr)
|
||||
{
|
||||
int i;
|
||||
unsigned file_string_table_offset = 0;
|
||||
unsigned next_file_string_table_offset = 0;
|
||||
unsigned next_file_string_table_offset = *string_offset_ptr;
|
||||
bfd_byte *stabp, *stabs_end;
|
||||
|
||||
stabp = stabs;
|
||||
@ -2015,12 +1991,14 @@ print_section_stabs (bfd *abfd, const char *stabsect_name)
|
||||
}
|
||||
}
|
||||
printf ("\n\n");
|
||||
*string_offset_ptr = next_file_string_table_offset;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * section_name;
|
||||
const char * string_section_name;
|
||||
unsigned string_offset;
|
||||
}
|
||||
stab_section_names;
|
||||
|
||||
@ -2031,7 +2009,7 @@ find_stabs_section (bfd *abfd, asection *section, void *names)
|
||||
stab_section_names * sought = (stab_section_names *) names;
|
||||
|
||||
/* Check for section names for which stabsect_name is a prefix, to
|
||||
handle .stab0, etc. */
|
||||
handle .stab.N, etc. */
|
||||
len = strlen (sought->section_name);
|
||||
|
||||
/* If the prefix matches, and the files section name ends with a
|
||||
@ -2039,13 +2017,17 @@ find_stabs_section (bfd *abfd, asection *section, void *names)
|
||||
match or a section followed by a number. */
|
||||
if (strncmp (sought->section_name, section->name, len) == 0
|
||||
&& (section->name[len] == 0
|
||||
|| ISDIGIT (section->name[len])))
|
||||
|| (section->name[len] == '.' && ISDIGIT (section->name[len + 1]))))
|
||||
{
|
||||
if (read_section_stabs (abfd, section->name, sought->string_section_name))
|
||||
if (strtab == NULL)
|
||||
strtab = read_section_stabs (abfd, sought->string_section_name,
|
||||
&stabstr_size);
|
||||
|
||||
if (strtab)
|
||||
{
|
||||
print_section_stabs (abfd, section->name);
|
||||
free (stabs);
|
||||
free (strtab);
|
||||
stabs = read_section_stabs (abfd, section->name, &stab_size);
|
||||
if (stabs)
|
||||
print_section_stabs (abfd, section->name, &sought->string_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2057,8 +2039,12 @@ dump_stabs_section (bfd *abfd, char *stabsect_name, char *strsect_name)
|
||||
|
||||
s.section_name = stabsect_name;
|
||||
s.string_section_name = strsect_name;
|
||||
|
||||
s.string_offset = 0;
|
||||
|
||||
bfd_map_over_sections (abfd, find_stabs_section, & s);
|
||||
|
||||
free (strtab);
|
||||
strtab = NULL;
|
||||
}
|
||||
|
||||
/* Dump the any sections containing stabs debugging information. */
|
||||
|
@ -1,3 +1,10 @@
|
||||
2003-10-07 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* ldwrite.c (unsplittable_name): New.
|
||||
(clone_section): Strip existing numeric suffix. Only truncate names
|
||||
for coff targets.
|
||||
(split_sections): Use unsplittable_name.
|
||||
|
||||
2003-10-06 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* lexsup.c (parse_args): Report unresolved symbols in shared
|
||||
|
63
ld/ldwrite.c
63
ld/ldwrite.c
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "sysdep.h"
|
||||
#include "bfdlink.h"
|
||||
#include "libiberty.h"
|
||||
#include "safe-ctype.h"
|
||||
|
||||
#include "ld.h"
|
||||
#include "ldexp.h"
|
||||
@ -285,6 +286,25 @@ build_link_order (lang_statement_union_type *statement)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if NAME is the name of an unsplittable section. These
|
||||
are the stabs strings, dwarf strings. */
|
||||
|
||||
static bfd_boolean
|
||||
unsplittable_name (const char *name)
|
||||
{
|
||||
if (strncmp (name, ".stab", 5) == 0)
|
||||
{
|
||||
/* There are several stab like string sections. We pattern match on
|
||||
".stab...str" */
|
||||
unsigned len = strlen (name);
|
||||
if (strcmp (&name[len-3], "str") == 0)
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp (name, "$GDB_STRINGS$") == 0)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Wander around the input sections, make sure that
|
||||
we'll never try and create an output section with more relocs
|
||||
than will fit.. Do this by always assuming the worst case, and
|
||||
@ -293,16 +313,41 @@ build_link_order (lang_statement_union_type *statement)
|
||||
static asection *
|
||||
clone_section (bfd *abfd, asection *s, const char *name, int *count)
|
||||
{
|
||||
char templ[6];
|
||||
char *tname;
|
||||
char *sname;
|
||||
unsigned int len;
|
||||
asection *n;
|
||||
struct bfd_link_hash_entry *h;
|
||||
|
||||
/* Invent a section name from the first five chars of the base
|
||||
section name and a digit suffix. */
|
||||
strncpy (templ, name, sizeof (templ) - 1);
|
||||
templ[sizeof (templ) - 1] = '\0';
|
||||
if ((sname = bfd_get_unique_section_name (abfd, templ, count)) == NULL
|
||||
/* Invent a section name from the section name and a dotted numeric
|
||||
suffix. */
|
||||
len = strlen (name);
|
||||
tname = xmalloc (len + 1);
|
||||
memcpy (tname, name, len + 1);
|
||||
/* Remove a dotted number suffix, from a previous split link. */
|
||||
while (len && ISDIGIT (tname[len-1]))
|
||||
len--;
|
||||
if (len > 1 && tname[len-1] == '.')
|
||||
/* It was a dotted number. */
|
||||
tname[len-1] = 0;
|
||||
|
||||
/* We want to use the whole of the original section name for the
|
||||
split name, but coff can be restricted to 8 character names. */
|
||||
if (bfd_family_coff (abfd) && strlen (tname) > 5)
|
||||
{
|
||||
/* Some section names cannot be truncated, as the name is
|
||||
used to locate some other section. */
|
||||
if (strncmp (name, ".stab", 5) == 0
|
||||
|| strcmp (name, "$GDB_SYMBOLS$") == 0)
|
||||
{
|
||||
einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
|
||||
/* Silence gcc warnings. einfo exits, so we never reach here. */
|
||||
return NULL;
|
||||
}
|
||||
tname[5] = 0;
|
||||
}
|
||||
|
||||
if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
|
||||
|| (n = bfd_make_section_anyway (abfd, sname)) == NULL
|
||||
|| (h = bfd_link_hash_lookup (link_info.hash,
|
||||
sname, TRUE, TRUE, FALSE)) == NULL)
|
||||
@ -311,7 +356,8 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count)
|
||||
/* Silence gcc warnings. einfo exits, so we never reach here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free (tname);
|
||||
|
||||
/* Set up section symbol. */
|
||||
h->type = bfd_link_hash_defined;
|
||||
h->u.def.value = 0;
|
||||
@ -436,7 +482,8 @@ split_sections (bfd *abfd, struct bfd_link_info *info)
|
||||
if (l != NULL
|
||||
&& (thisrelocs + relocs >= config.split_by_reloc
|
||||
|| thislines + lines >= config.split_by_reloc
|
||||
|| thissize + sec_size >= config.split_by_file))
|
||||
|| (thissize + sec_size >= config.split_by_file))
|
||||
&& !unsplittable_name (cursor->name))
|
||||
{
|
||||
/* Create a new section and put this link order and the
|
||||
following link orders into it. */
|
||||
|
Loading…
Reference in New Issue
Block a user