mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 12:39:59 +00:00
2001-11-11 Daniel Jacobowitz <drow@mvista.com>
* bfd-in.h (bfd_elf32_discard_info): Add prototype. (bfd_elf64_discard_info): Likewise. * bfd-in2.h: Regenerate. * elf-bfd.h (struct elf_reloc_cookie): New. (struct elf_backend_data): Add elf_backend_discard_info, elf_backend_ignore_discarded_relocs, and elf_backend_write_section. (_bfd_elf32_reloc_symbol_deleted_p): Add prototype. (_bfd_elf64_reloc_symbol_deleted_p): Likewise. * elf32-mips.c (_bfd_elf32_mips_discard_info): New. (_bfd_elf32_mips_ignore_discarded_relocs): New. (_bfd_elf32_mips_write_section): New. (elf_backend_discard_info): Define. (elf_backend_ignore_discarded_relocs): Define. (elf_backend_write_section): Define. * elfcode.h (elf_bfd_discard_info): Define. (elf_reloc_symbol_deleted_p): Define. * elflink.h (elf_link_input_bfd): Check elf_section_ignore_discarded_relocs. Call bed->elf_backend_write_section if available. (elf_reloc_symbol_deleted_p): New. (elf_bfd_discard_info): New. (elf_section_ignore_discarded_relocs): New. * elfxx-target.h (elf_backend_discard_info): Define. (elf_backend_ignore_discarded_relocs): Define. (elf_backend_write_section): Define. (elfNN_bed): Add elf_backend_discard_info, elf_backend_ignore_discarded_relocs, and elf_backend_write_section. * libbfd-in.h (_bfd_discard_section_stabs): Add prototype. * libbfd.h: Regenerate. * stabs.c (_bfd_discard_section_stabs): New. 2001-11-11 Daniel Jacobowitz <drow@mvista.com> * emultempl/elf32.em (gld${EMULATION_NAME}_finish): New. (struct ld_emulation_xfer_struct): Use it.
This commit is contained in:
parent
86651999ac
commit
73d074b4e2
@ -1,3 +1,37 @@
|
||||
2001-11-14 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* bfd-in.h (bfd_elf32_discard_info): Add prototype.
|
||||
(bfd_elf64_discard_info): Likewise.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* elf-bfd.h (struct elf_reloc_cookie): New.
|
||||
(struct elf_backend_data): Add elf_backend_discard_info,
|
||||
elf_backend_ignore_discarded_relocs, and elf_backend_write_section.
|
||||
(_bfd_elf32_reloc_symbol_deleted_p): Add prototype.
|
||||
(_bfd_elf64_reloc_symbol_deleted_p): Likewise.
|
||||
* elf32-mips.c (_bfd_elf32_mips_discard_info): New.
|
||||
(_bfd_elf32_mips_ignore_discarded_relocs): New.
|
||||
(_bfd_elf32_mips_write_section): New.
|
||||
(elf_backend_discard_info): Define.
|
||||
(elf_backend_ignore_discarded_relocs): Define.
|
||||
(elf_backend_write_section): Define.
|
||||
* elfcode.h (elf_bfd_discard_info): Define.
|
||||
(elf_reloc_symbol_deleted_p): Define.
|
||||
* elflink.h (elf_link_input_bfd): Check
|
||||
elf_section_ignore_discarded_relocs. Call
|
||||
bed->elf_backend_write_section if available.
|
||||
(elf_reloc_symbol_deleted_p): New.
|
||||
(elf_bfd_discard_info): New.
|
||||
(elf_section_ignore_discarded_relocs): New.
|
||||
* elfxx-target.h (elf_backend_discard_info): Define.
|
||||
(elf_backend_ignore_discarded_relocs): Define.
|
||||
(elf_backend_write_section): Define.
|
||||
(elfNN_bed): Add elf_backend_discard_info,
|
||||
elf_backend_ignore_discarded_relocs, and
|
||||
elf_backend_write_section.
|
||||
* libbfd-in.h (_bfd_discard_section_stabs): Add prototype.
|
||||
* libbfd.h: Regenerate.
|
||||
* stabs.c (_bfd_discard_section_stabs): New.
|
||||
|
||||
2001-11-14 Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
|
||||
* elf32-s390.c (elf_s390_relocate_section): Use the "unresolved_reloc"
|
||||
|
@ -635,6 +635,10 @@ extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
|
||||
extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
|
||||
extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
extern boolean bfd_elf32_discard_info
|
||||
PARAMS ((struct bfd_link_info *));
|
||||
extern boolean bfd_elf64_discard_info
|
||||
PARAMS ((struct bfd_link_info *));
|
||||
|
||||
/* Return an upper bound on the number of bytes required to store a
|
||||
copy of ABFD's program header table entries. Return -1 if an error
|
||||
|
@ -641,6 +641,10 @@ extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
|
||||
extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
|
||||
extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
extern boolean bfd_elf32_discard_info
|
||||
PARAMS ((struct bfd_link_info *));
|
||||
extern boolean bfd_elf64_discard_info
|
||||
PARAMS ((struct bfd_link_info *));
|
||||
|
||||
/* Return an upper bound on the number of bytes required to store a
|
||||
copy of ABFD's program header table entries. Return -1 if an error
|
||||
|
@ -381,6 +381,17 @@ enum elf_reloc_type_class {
|
||||
reloc_class_copy
|
||||
};
|
||||
|
||||
struct elf_reloc_cookie
|
||||
{
|
||||
Elf_Internal_Rela *rels, *rel, *relend;
|
||||
void *locsyms;
|
||||
bfd *abfd;
|
||||
size_t locsymcount;
|
||||
size_t extsymoff;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
boolean bad_symtab;
|
||||
};
|
||||
|
||||
struct elf_backend_data
|
||||
{
|
||||
/* The architecture for this backend. */
|
||||
@ -703,6 +714,21 @@ struct elf_backend_data
|
||||
enum elf_reloc_type_class (*elf_backend_reloc_type_class)
|
||||
PARAMS ((const Elf_Internal_Rela *));
|
||||
|
||||
/* This function, if defined, removes information about discarded functions
|
||||
from other sections which mention them. */
|
||||
boolean (*elf_backend_discard_info)
|
||||
PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *));
|
||||
|
||||
/* This function, if defined, signals that the function above has removed
|
||||
the discarded relocations for this section. */
|
||||
boolean (*elf_backend_ignore_discarded_relocs)
|
||||
PARAMS ((asection *));
|
||||
|
||||
/* This function, if defined, may write out the given section.
|
||||
Returns true if it did so and false if the caller should. */
|
||||
boolean (*elf_backend_write_section)
|
||||
PARAMS ((bfd *, asection *, bfd_byte *));
|
||||
|
||||
/* The swapping table to use when dealing with ECOFF information.
|
||||
Used for the MIPS ELF .mdebug section. */
|
||||
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
|
||||
@ -1437,6 +1463,11 @@ extern boolean _bfd_elf64_gc_record_vtinherit
|
||||
extern boolean _bfd_elf64_gc_record_vtentry
|
||||
PARAMS ((bfd *, asection *, struct elf_link_hash_entry *, bfd_vma));
|
||||
|
||||
extern boolean _bfd_elf32_reloc_symbol_deleted_p
|
||||
PARAMS ((bfd_vma, PTR));
|
||||
extern boolean _bfd_elf64_reloc_symbol_deleted_p
|
||||
PARAMS ((bfd_vma, PTR));
|
||||
|
||||
/* MIPS ELF specific routines. */
|
||||
|
||||
extern boolean _bfd_mips_elf_object_p
|
||||
|
119
bfd/elf32-mips.c
119
bfd/elf32-mips.c
@ -219,6 +219,12 @@ static boolean _bfd_elf32_mips_grok_prstatus
|
||||
PARAMS ((bfd *, Elf_Internal_Note *));
|
||||
static boolean _bfd_elf32_mips_grok_psinfo
|
||||
PARAMS ((bfd *, Elf_Internal_Note *));
|
||||
static boolean _bfd_elf32_mips_discard_info
|
||||
PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *));
|
||||
static boolean _bfd_elf32_mips_ignore_discarded_relocs
|
||||
PARAMS ((asection *));
|
||||
static boolean _bfd_elf32_mips_write_section
|
||||
PARAMS ((bfd *, asection *, bfd_byte *));
|
||||
|
||||
extern const bfd_target bfd_elf32_tradbigmips_vec;
|
||||
extern const bfd_target bfd_elf32_tradlittlemips_vec;
|
||||
@ -9226,6 +9232,114 @@ _bfd_elf32_mips_grok_psinfo (abfd, note)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define PDR_SIZE 32
|
||||
|
||||
static boolean
|
||||
_bfd_elf32_mips_discard_info (abfd, cookie, info)
|
||||
bfd *abfd;
|
||||
struct elf_reloc_cookie *cookie;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
asection *o;
|
||||
struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
boolean ret = false;
|
||||
unsigned char *tdata;
|
||||
size_t i, skip;
|
||||
|
||||
o = bfd_get_section_by_name (abfd, ".pdr");
|
||||
if (! o)
|
||||
return false;
|
||||
if (o->_raw_size == 0)
|
||||
return false;
|
||||
if (o->_raw_size % PDR_SIZE != 0)
|
||||
return false;
|
||||
if (o->output_section != NULL
|
||||
&& bfd_is_abs_section (o->output_section))
|
||||
return false;
|
||||
|
||||
tdata = bfd_zmalloc (o->_raw_size / PDR_SIZE);
|
||||
if (! tdata)
|
||||
return false;
|
||||
|
||||
cookie->rels = _bfd_elf32_link_read_relocs (abfd, o, (PTR) NULL,
|
||||
(Elf_Internal_Rela *) NULL,
|
||||
info->keep_memory);
|
||||
if (!cookie->rels)
|
||||
{
|
||||
free (tdata);
|
||||
return false;
|
||||
}
|
||||
|
||||
cookie->rel = cookie->rels;
|
||||
cookie->relend =
|
||||
cookie->rels + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||
|
||||
for (i = 0, skip = 0; i < o->_raw_size; i ++)
|
||||
{
|
||||
if (_bfd_elf32_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
|
||||
{
|
||||
tdata[i] = 1;
|
||||
skip ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (skip != 0)
|
||||
{
|
||||
elf_section_data (o)->tdata = tdata;
|
||||
o->_cooked_size = o->_raw_size - skip * PDR_SIZE;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
free (tdata);
|
||||
|
||||
if (! info->keep_memory)
|
||||
free (cookie->rels);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static boolean
|
||||
_bfd_elf32_mips_ignore_discarded_relocs (sec)
|
||||
asection *sec;
|
||||
{
|
||||
if (strcmp (sec->name, ".pdr") == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean
|
||||
_bfd_elf32_mips_write_section (output_bfd, sec, contents)
|
||||
bfd *output_bfd;
|
||||
asection *sec;
|
||||
bfd_byte *contents;
|
||||
{
|
||||
bfd_byte *to, *from, *end;
|
||||
int i;
|
||||
|
||||
if (strcmp (sec->name, ".pdr") != 0)
|
||||
return false;
|
||||
|
||||
if (elf_section_data (sec)->tdata == NULL)
|
||||
return false;
|
||||
|
||||
to = contents;
|
||||
end = contents + sec->_raw_size;
|
||||
for (from = contents, i = 0;
|
||||
from < end;
|
||||
from += PDR_SIZE, i++)
|
||||
{
|
||||
if (((unsigned char *)elf_section_data (sec)->tdata)[i] == 1)
|
||||
continue;
|
||||
if (to != from)
|
||||
memcpy (to, from, PDR_SIZE);
|
||||
to += PDR_SIZE;
|
||||
}
|
||||
bfd_set_section_contents (output_bfd, sec->output_section, contents,
|
||||
(file_ptr) sec->output_offset,
|
||||
sec->_cooked_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is almost identical to bfd_generic_get_... except that some
|
||||
MIPS relocations need to be handled specially. Sigh. */
|
||||
|
||||
@ -9516,6 +9630,11 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
|
||||
#define elf_backend_grok_prstatus _bfd_elf32_mips_grok_prstatus
|
||||
#define elf_backend_grok_psinfo _bfd_elf32_mips_grok_psinfo
|
||||
|
||||
#define elf_backend_discard_info _bfd_elf32_mips_discard_info
|
||||
#define elf_backend_ignore_discarded_relocs \
|
||||
_bfd_elf32_mips_ignore_discarded_relocs
|
||||
#define elf_backend_write_section _bfd_elf32_mips_write_section
|
||||
|
||||
#define bfd_elf32_bfd_is_local_label_name \
|
||||
mips_elf_is_local_label_name
|
||||
#define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
|
||||
|
@ -123,6 +123,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table)
|
||||
#define elf_link_create_dynamic_sections \
|
||||
NAME(bfd_elf,link_create_dynamic_sections)
|
||||
#define elf_bfd_discard_info NAME(bfd_elf,discard_info)
|
||||
#define elf_reloc_symbol_deleted_p NAME(_bfd_elf,reloc_symbol_deleted_p)
|
||||
#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
|
||||
#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link)
|
||||
#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section)
|
||||
|
209
bfd/elflink.h
209
bfd/elflink.h
@ -75,6 +75,8 @@ static int elf_link_sort_cmp2
|
||||
PARAMS ((const void *, const void *));
|
||||
static size_t elf_link_sort_relocs
|
||||
PARAMS ((bfd *, struct bfd_link_info *, asection **));
|
||||
static boolean elf_section_ignore_discarded_relocs
|
||||
PARAMS ((asection *));
|
||||
|
||||
/* Given an ELF BFD, add symbols to the global hash table as
|
||||
appropriate. */
|
||||
@ -6287,7 +6289,8 @@ elf_link_input_bfd (finfo, input_bfd)
|
||||
.eh_frame to describe a routine in the linkonce section,
|
||||
and it turns out to be hard to remove the .eh_frame
|
||||
entry too. FIXME. */
|
||||
if (!finfo->info->relocateable)
|
||||
if (!finfo->info->relocateable
|
||||
&& !elf_section_ignore_discarded_relocs (o))
|
||||
{
|
||||
Elf_Internal_Rela *rel, *relend;
|
||||
|
||||
@ -6591,7 +6594,12 @@ elf_link_input_bfd (finfo, input_bfd)
|
||||
}
|
||||
|
||||
/* Write out the modified section contents. */
|
||||
if (elf_section_data (o)->stab_info)
|
||||
if (bed->elf_backend_write_section
|
||||
&& bed->elf_backend_write_section (output_bfd, o, contents))
|
||||
{
|
||||
/* Section written out. */
|
||||
}
|
||||
else if (elf_section_data (o)->stab_info)
|
||||
{
|
||||
if (! (_bfd_write_section_stabs
|
||||
(output_bfd, &elf_hash_table (finfo->info)->stab_info,
|
||||
@ -7756,3 +7764,200 @@ elf_collect_hash_codes (h, data)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean
|
||||
elf_reloc_symbol_deleted_p (offset, cookie)
|
||||
bfd_vma offset;
|
||||
PTR cookie;
|
||||
{
|
||||
struct elf_reloc_cookie *rcookie = (struct elf_reloc_cookie *)cookie;
|
||||
|
||||
if (rcookie->bad_symtab)
|
||||
rcookie->rel = rcookie->rels;
|
||||
|
||||
for (; rcookie->rel < rcookie->relend; rcookie->rel++)
|
||||
{
|
||||
unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info);
|
||||
Elf_Internal_Sym isym;
|
||||
|
||||
if (! rcookie->bad_symtab)
|
||||
if (rcookie->rel->r_offset > offset)
|
||||
return false;
|
||||
if (rcookie->rel->r_offset != offset)
|
||||
continue;
|
||||
|
||||
if (rcookie->locsyms)
|
||||
elf_swap_symbol_in (rcookie->abfd,
|
||||
((Elf_External_Sym *)rcookie->locsyms) + r_symndx,
|
||||
&isym);
|
||||
|
||||
if (r_symndx >= rcookie->locsymcount
|
||||
|| (rcookie->locsyms
|
||||
&& ELF_ST_BIND (isym.st_info) != STB_LOCAL))
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
|
||||
h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff];
|
||||
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
if ((h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
&& ! bfd_is_abs_section (h->root.u.def.section)
|
||||
&& bfd_is_abs_section (h->root.u.def.section
|
||||
->output_section))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (rcookie->locsyms)
|
||||
{
|
||||
/* It's not a relocation against a global symbol,
|
||||
but it could be a relocation against a section
|
||||
symbol for a discarded section. */
|
||||
asection *isec;
|
||||
|
||||
/* Need to: get the symbol; get the section. */
|
||||
if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
|
||||
{
|
||||
isec = section_from_elf_index (rcookie->abfd, isym.st_shndx);
|
||||
if (isec != NULL
|
||||
&& ELF_ST_TYPE (isym.st_info) == STT_SECTION
|
||||
&& ! bfd_is_abs_section (isec)
|
||||
&& bfd_is_abs_section (isec->output_section))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Discard unneeded references to discarded sections.
|
||||
Returns true if any section's size was changed. */
|
||||
/* This function assumes that the relocations are in sorted order,
|
||||
which is true for all known assemblers. */
|
||||
|
||||
boolean
|
||||
elf_bfd_discard_info (info)
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
struct elf_reloc_cookie cookie;
|
||||
asection *o;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
Elf_External_Sym *freesyms;
|
||||
struct elf_backend_data *bed;
|
||||
bfd *abfd;
|
||||
boolean ret = false;
|
||||
|
||||
if (info->relocateable
|
||||
|| info->traditional_format
|
||||
|| info->hash->creator->flavour != bfd_target_elf_flavour
|
||||
|| ! is_elf_hash_table (info)
|
||||
|| info->strip == strip_all
|
||||
|| info->strip == strip_debugger)
|
||||
return false;
|
||||
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
|
||||
{
|
||||
bed = get_elf_backend_data (abfd);
|
||||
|
||||
if ((abfd->flags & DYNAMIC) != 0)
|
||||
continue;
|
||||
|
||||
o = bfd_get_section_by_name (abfd, ".stab");
|
||||
if (! o && ! bed->elf_backend_discard_info)
|
||||
continue;
|
||||
|
||||
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
|
||||
cookie.abfd = abfd;
|
||||
cookie.sym_hashes = elf_sym_hashes (abfd);
|
||||
cookie.bad_symtab = elf_bad_symtab (abfd);
|
||||
if (cookie.bad_symtab)
|
||||
{
|
||||
cookie.locsymcount =
|
||||
symtab_hdr->sh_size / sizeof (Elf_External_Sym);
|
||||
cookie.extsymoff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cookie.locsymcount = symtab_hdr->sh_info;
|
||||
cookie.extsymoff = symtab_hdr->sh_info;
|
||||
}
|
||||
|
||||
freesyms = NULL;
|
||||
if (symtab_hdr->contents)
|
||||
cookie.locsyms = (void *) symtab_hdr->contents;
|
||||
else if (cookie.locsymcount == 0)
|
||||
cookie.locsyms = NULL;
|
||||
else
|
||||
{
|
||||
bfd_size_type amt = cookie.locsymcount * sizeof (Elf_External_Sym);
|
||||
cookie.locsyms = bfd_malloc (amt);
|
||||
if (cookie.locsyms == NULL
|
||||
|| bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|
||||
|| bfd_bread (cookie.locsyms, amt, abfd) != amt)
|
||||
{
|
||||
/* Something is very wrong - but we can still do our job for
|
||||
global symbols, so don't give up. */
|
||||
if (cookie.locsyms)
|
||||
free (cookie.locsyms);
|
||||
cookie.locsyms = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
freesyms = cookie.locsyms;
|
||||
}
|
||||
}
|
||||
|
||||
if (o)
|
||||
{
|
||||
cookie.rels = (NAME(_bfd_elf,link_read_relocs)
|
||||
(abfd, o, (PTR) NULL,
|
||||
(Elf_Internal_Rela *) NULL,
|
||||
info->keep_memory));
|
||||
if (cookie.rels)
|
||||
{
|
||||
cookie.rel = cookie.rels;
|
||||
cookie.relend =
|
||||
cookie.rels + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||
if (_bfd_discard_section_stabs (abfd, o,
|
||||
elf_section_data (o)->stab_info,
|
||||
elf_reloc_symbol_deleted_p,
|
||||
&cookie))
|
||||
ret = true;
|
||||
if (! info->keep_memory)
|
||||
free (cookie.rels);
|
||||
}
|
||||
}
|
||||
|
||||
if (bed->elf_backend_discard_info)
|
||||
{
|
||||
if (bed->elf_backend_discard_info (abfd, &cookie, info))
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (freesyms)
|
||||
free (freesyms);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static boolean
|
||||
elf_section_ignore_discarded_relocs (sec)
|
||||
asection *sec;
|
||||
{
|
||||
if (strcmp (sec->name, ".stab") == 0)
|
||||
return true;
|
||||
else if ((get_elf_backend_data (sec->owner)
|
||||
->elf_backend_ignore_discarded_relocs != NULL)
|
||||
&& (get_elf_backend_data (sec->owner)
|
||||
->elf_backend_ignore_discarded_relocs (sec)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -358,6 +358,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#ifndef elf_backend_reloc_type_class
|
||||
#define elf_backend_reloc_type_class _bfd_elf_reloc_type_class
|
||||
#endif
|
||||
#ifndef elf_backend_discard_info
|
||||
#define elf_backend_discard_info NULL
|
||||
#endif
|
||||
#ifndef elf_backend_ignore_discarded_relocs
|
||||
#define elf_backend_ignore_discarded_relocs NULL
|
||||
#endif
|
||||
#ifndef elf_backend_write_section
|
||||
#define elf_backend_write_section NULL
|
||||
#endif
|
||||
|
||||
/* Previously, backends could only use SHT_REL or SHT_RELA relocation
|
||||
sections, but not both. They defined USE_REL to indicate SHT_REL
|
||||
@ -446,6 +455,9 @@ static const struct elf_backend_data elfNN_bed =
|
||||
elf_backend_sprintf_vma,
|
||||
elf_backend_fprintf_vma,
|
||||
elf_backend_reloc_type_class,
|
||||
elf_backend_discard_info,
|
||||
elf_backend_ignore_discarded_relocs,
|
||||
elf_backend_write_section,
|
||||
elf_backend_ecoff_debug_swap,
|
||||
ELF_MACHINE_ALT1,
|
||||
ELF_MACHINE_ALT2,
|
||||
|
@ -446,6 +446,11 @@ extern bfd_reloc_status_type _bfd_relocate_contents
|
||||
extern boolean _bfd_link_section_stabs
|
||||
PARAMS ((bfd *, PTR *, asection *, asection *, PTR *));
|
||||
|
||||
/* Eliminate stabs for discarded functions and symbols. */
|
||||
extern boolean _bfd_discard_section_stabs
|
||||
PARAMS ((bfd *, asection *, PTR,
|
||||
boolean (*) (bfd_vma, PTR), PTR));
|
||||
|
||||
/* Write out the .stab section when linking stabs in sections. */
|
||||
|
||||
extern boolean _bfd_write_section_stabs
|
||||
|
@ -451,6 +451,11 @@ extern bfd_reloc_status_type _bfd_relocate_contents
|
||||
extern boolean _bfd_link_section_stabs
|
||||
PARAMS ((bfd *, PTR *, asection *, asection *, PTR *));
|
||||
|
||||
/* Eliminate stabs for discarded functions and symbols. */
|
||||
extern boolean _bfd_discard_section_stabs
|
||||
PARAMS ((bfd *, asection *, PTR,
|
||||
boolean (*) (bfd_vma, PTR), PTR));
|
||||
|
||||
/* Write out the .stab section when linking stabs in sections. */
|
||||
|
||||
extern boolean _bfd_write_section_stabs
|
||||
|
170
bfd/stabs.c
170
bfd/stabs.c
@ -502,6 +502,176 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* This function is called for each input file before the stab
|
||||
section is relocated. It discards stab entries for discarded
|
||||
functions and variables. The function returns true iff
|
||||
any entries have been deleted.
|
||||
*/
|
||||
|
||||
boolean
|
||||
_bfd_discard_section_stabs (abfd, stabsec, psecinfo,
|
||||
reloc_symbol_deleted_p, cookie)
|
||||
bfd *abfd;
|
||||
asection *stabsec;
|
||||
PTR psecinfo;
|
||||
boolean (*reloc_symbol_deleted_p) (bfd_vma, PTR);
|
||||
PTR cookie;
|
||||
{
|
||||
bfd_size_type count, amt;
|
||||
struct stab_section_info *secinfo;
|
||||
bfd_byte *stabbuf = NULL;
|
||||
bfd_byte *sym, *symend;
|
||||
bfd_size_type skip;
|
||||
bfd_size_type *pstridx;
|
||||
int deleting;
|
||||
|
||||
if (stabsec->_raw_size == 0)
|
||||
{
|
||||
/* This file does not contain stabs debugging information. */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stabsec->_raw_size % STABSIZE != 0)
|
||||
{
|
||||
/* Something is wrong with the format of these stab symbols.
|
||||
Don't try to optimize them. */
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((stabsec->output_section != NULL
|
||||
&& bfd_is_abs_section (stabsec->output_section)))
|
||||
{
|
||||
/* At least one of the sections is being discarded from the
|
||||
link, so we should just ignore them. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We should have initialized our data in _bfd_link_stab_sections.
|
||||
If there was some bizarre error reading the string sections, though,
|
||||
we might not have. Bail rather than asserting. */
|
||||
if (psecinfo == NULL)
|
||||
return false;
|
||||
|
||||
count = stabsec->_raw_size / STABSIZE;
|
||||
secinfo = (struct stab_section_info *) psecinfo;
|
||||
|
||||
/* Read the stabs information from abfd. */
|
||||
|
||||
stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
|
||||
if (stabbuf == NULL)
|
||||
goto error_return;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,
|
||||
stabsec->_raw_size))
|
||||
goto error_return;
|
||||
|
||||
/* Look through the stabs symbols and discard any information for
|
||||
discarded functions. */
|
||||
|
||||
skip = 0;
|
||||
deleting = -1;
|
||||
|
||||
symend = stabbuf + stabsec->_raw_size;
|
||||
for (sym = stabbuf, pstridx = secinfo->stridxs;
|
||||
sym < symend;
|
||||
sym += STABSIZE, ++pstridx)
|
||||
{
|
||||
int type;
|
||||
|
||||
if (*pstridx == (bfd_size_type) -1)
|
||||
{
|
||||
/* This stab was deleted in a previous pass. */
|
||||
continue;
|
||||
}
|
||||
|
||||
type = sym[TYPEOFF];
|
||||
|
||||
if (type == N_FUN)
|
||||
{
|
||||
int strx = bfd_get_32 (abfd, sym + STRDXOFF);
|
||||
|
||||
if (strx == 0)
|
||||
{
|
||||
if (deleting)
|
||||
{
|
||||
skip++;
|
||||
*pstridx = -1;
|
||||
}
|
||||
deleting = -1;
|
||||
continue;
|
||||
}
|
||||
deleting = 0;
|
||||
if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
|
||||
deleting = 1;
|
||||
}
|
||||
|
||||
if (deleting == 1)
|
||||
{
|
||||
*pstridx = -1;
|
||||
skip++;
|
||||
}
|
||||
else if (deleting == -1)
|
||||
{
|
||||
/* Outside of a function. Check for deleted variables. */
|
||||
if (type == N_STSYM || type == N_LCSYM)
|
||||
if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
|
||||
{
|
||||
*pstridx = -1;
|
||||
skip ++;
|
||||
}
|
||||
/* We should also check for N_GSYM entries which reference a
|
||||
deleted global, but those are less harmful to debuggers
|
||||
and would require parsing the stab strings. */
|
||||
}
|
||||
}
|
||||
|
||||
free (stabbuf);
|
||||
stabbuf = NULL;
|
||||
|
||||
/* Shrink the stabsec as needed. */
|
||||
stabsec->_cooked_size -= skip * STABSIZE;
|
||||
if (stabsec->_cooked_size == 0)
|
||||
stabsec->flags |= SEC_EXCLUDE;
|
||||
|
||||
/* Recalculate the `cumulative_skips' array now that stabs have been
|
||||
deleted for this section. */
|
||||
|
||||
if (skip != 0)
|
||||
{
|
||||
bfd_size_type i, offset;
|
||||
bfd_size_type *pskips;
|
||||
|
||||
if (secinfo->cumulative_skips == NULL)
|
||||
{
|
||||
amt = count * sizeof (bfd_size_type);
|
||||
secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
|
||||
if (secinfo->cumulative_skips == NULL)
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
pskips = secinfo->cumulative_skips;
|
||||
pstridx = secinfo->stridxs;
|
||||
offset = 0;
|
||||
|
||||
for (i = 0; i < count; i++, pskips++, pstridx++)
|
||||
{
|
||||
*pskips = offset;
|
||||
if (*pstridx == (bfd_size_type) -1)
|
||||
offset += STABSIZE;
|
||||
}
|
||||
|
||||
BFD_ASSERT (offset != 0);
|
||||
}
|
||||
|
||||
return (skip > 0);
|
||||
|
||||
error_return:
|
||||
if (stabbuf != NULL)
|
||||
free (stabbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Write out the stab section. This is called with the relocated
|
||||
contents. */
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2001-11-14 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* emultempl/elf32.em (gld${EMULATION_NAME}_finish): New.
|
||||
(struct ld_emulation_xfer_struct): Use it.
|
||||
|
||||
Tue Nov 13 11:27:14 2001 Ross Alexander <ross.alexander@uk.neceur.com>
|
||||
|
||||
* emulparams/elf64hppa.sh (OTHER_BSS_END_SECTIONS): Add
|
||||
|
@ -80,6 +80,8 @@ static asection *output_prev_sec_find
|
||||
PARAMS ((lang_output_section_statement_type *));
|
||||
static boolean gld${EMULATION_NAME}_place_orphan
|
||||
PARAMS ((lang_input_statement_type *, asection *));
|
||||
static void gld${EMULATION_NAME}_finish
|
||||
PARAMS ((void));
|
||||
static char *gld${EMULATION_NAME}_get_script
|
||||
PARAMS ((int *isfile));
|
||||
|
||||
@ -1319,6 +1321,25 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
gld${EMULATION_NAME}_finish ()
|
||||
{
|
||||
${LDEMUL_FINISH+${LDEMUL_FINISH} ();}
|
||||
|
||||
if (bfd_elf${ELFSIZE}_discard_info (&link_info))
|
||||
{
|
||||
/* Resize the sections. */
|
||||
lang_size_sections (stat_ptr->head, abs_output_section,
|
||||
&stat_ptr->head, 0, (bfd_vma) 0, false);
|
||||
|
||||
/* Redo special stuff. */
|
||||
ldemul_after_allocation ();
|
||||
|
||||
/* Do the assignments again. */
|
||||
lang_do_assignments (stat_ptr->head, abs_output_section,
|
||||
(fill_type) 0, (bfd_vma) 0);
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
@ -1618,7 +1639,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
||||
${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
|
||||
"${EMULATION_NAME}",
|
||||
"${OUTPUT_FORMAT}",
|
||||
${LDEMUL_FINISH-NULL},
|
||||
gld${EMULATION_NAME}_finish,
|
||||
${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
|
||||
${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
|
||||
${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
|
||||
|
Loading…
Reference in New Issue
Block a user