/* Stabs in sections linking support.
- Copyright 1996, 1997 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
/* This is a linked list of N_BINCL symbols which should be
converted into N_EXCL symbols. */
struct stab_excl_list *excls;
+
+ /* This is used to map input stab offsets within their sections
+ to output stab offsets, to take into account stabs that have
+ been deleted. If it is NULL, the output offsets are the same
+ as the input offsets, because no stabs have been deleted from
+ this section. Otherwise the i'th entry is the number of
+ bytes of stabs that have been deleted prior to the i'th
+ stab. */
+ bfd_size_type *cumulative_skips;
+
/* This is an array of string indices. For each stab symbol, we
store the string index here. If a stab symbol should not be
included in the final output, the string index is -1. */
sinfo->strings = _bfd_stringtab_init ();
if (sinfo->strings == NULL)
goto error_return;
+ /* Make sure the first byte is zero. */
+ (void) _bfd_stringtab_add (sinfo->strings, "", true, true);
if (! bfd_hash_table_init_n (&sinfo->includes.root,
stab_link_includes_newfunc,
251))
secinfo = (struct stab_section_info *) *psecinfo;
secinfo->excls = NULL;
+ secinfo->cumulative_skips = NULL;
memset (secinfo->stridxs, 0, count * sizeof (bfd_size_type));
/* Read the stabs information from abfd. */
/* Record this symbol, so that we can set the value
correctly. */
ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne);
+ if (ne == NULL)
+ goto error_return;
ne->offset = sym - stabbuf;
ne->val = val;
ne->type = N_BINCL;
}
free (stabbuf);
+ stabbuf = NULL;
free (stabstrbuf);
+ stabstrbuf = NULL;
/* We need to set the section sizes such that the linker will
compute the output section sizes correctly. We set the .stab
stabstrsec->flags |= SEC_EXCLUDE;
sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
+ /* Calculate 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;
+
+ secinfo->cumulative_skips =
+ (bfd_size_type *) bfd_alloc (abfd, count * sizeof (bfd_size_type));
+ 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 true;
error_return:
}
}
- BFD_ASSERT (tosym - contents == stabsec->_cooked_size);
+ BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);
return bfd_set_section_contents (output_bfd, stabsec->output_section,
contents, stabsec->output_offset,
if (sinfo == NULL)
return true;
+ if (bfd_is_abs_section (sinfo->stabstr->output_section))
+ {
+ /* The section was discarded from the link. */
+ return true;
+ }
+
BFD_ASSERT ((sinfo->stabstr->output_offset
+ _bfd_stringtab_size (sinfo->strings))
<= sinfo->stabstr->output_section->_raw_size);
return true;
}
+
+/* Adjust an address in the .stab section. Given OFFSET within
+ STABSEC, this returns the new offset in the adjusted stab section,
+ or -1 if the address refers to a stab which has been removed. */
+
+bfd_vma
+_bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)
+ bfd *output_bfd ATTRIBUTE_UNUSED;
+ PTR *psinfo ATTRIBUTE_UNUSED;
+ asection *stabsec;
+ PTR *psecinfo;
+ bfd_vma offset;
+{
+ struct stab_section_info *secinfo;
+
+ secinfo = (struct stab_section_info *) *psecinfo;
+
+ if (secinfo == NULL)
+ return offset;
+
+ if (offset >= stabsec->_raw_size)
+ return offset - (stabsec->_cooked_size - stabsec->_raw_size);
+
+ if (secinfo->cumulative_skips)
+ {
+ bfd_vma i;
+
+ i = offset / STABSIZE;
+
+ if (secinfo->stridxs [i] == (bfd_size_type) -1)
+ return (bfd_vma) -1;
+
+ return offset - secinfo->cumulative_skips [i];
+ }
+
+ return offset;
+}