unsigned int numaux = native->u.syment.n_numaux;
int type = native->u.syment.n_type;
int n_sclass = (int) native->u.syment.n_sclass;
+ asection *output_section = symbol->section->output_section
+ ? symbol->section->output_section
+ : symbol->section;
void * buf;
bfd_size_type symesz;
else
native->u.syment.n_scnum =
- symbol->section->output_section->target_index;
+ output_section->target_index;
coff_fix_symbol_name (abfd, symbol, native, string_size_p,
debug_string_section_p, debug_string_size_p);
{
combined_entry_type *native;
combined_entry_type dummy;
-
+ asection *output_section = symbol->section->output_section
+ ? symbol->section->output_section
+ : symbol->section;
+ struct bfd_link_info *link_info = coff_data (abfd)->link_info;
+
+ if ((!link_info || link_info->strip_discarded)
+ && !bfd_is_abs_section (symbol->section)
+ && symbol->section->output_section == bfd_abs_section_ptr)
+ {
+ symbol->name = "";
+ return TRUE;
+ }
native = &dummy;
native->u.syment.n_type = T_NULL;
native->u.syment.n_flags = 0;
}
else
{
- native->u.syment.n_scnum =
- symbol->section->output_section->target_index;
+ native->u.syment.n_scnum = output_section->target_index;
native->u.syment.n_value = (symbol->value
+ symbol->section->output_offset);
if (! obj_pe (abfd))
- native->u.syment.n_value += symbol->section->output_section->vma;
+ native->u.syment.n_value += output_section->vma;
/* Copy the any flags from the file header into the symbol.
FIXME: Why? */
{
combined_entry_type *native = symbol->native;
alent *lineno = symbol->lineno;
+ struct bfd_link_info *link_info = coff_data (abfd)->link_info;
+
+ if ((!link_info || link_info->strip_discarded)
+ && !bfd_is_abs_section (symbol->symbol.section)
+ && symbol->symbol.section->output_section == bfd_abs_section_ptr)
+ {
+ symbol->symbol.name = "";
+ return TRUE;
+ }
/* If this symbol has an associated line number, we must store the
symbol index in the line number field. We also tag the auxent to
nearest to the wanted location. */
bfd_boolean
-coff_find_nearest_line (bfd *abfd,
- asection *section,
- asymbol **symbols,
- bfd_vma offset,
- const char **filename_ptr,
- const char **functionname_ptr,
- unsigned int *line_ptr)
+coff_find_nearest_line_with_names (bfd *abfd,
+ const struct dwarf_debug_section *debug_sections,
+ asection *section,
+ asymbol **symbols,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
{
bfd_boolean found;
unsigned int i;
return TRUE;
/* Also try examining DWARF2 debugging information. */
- if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ if (_bfd_dwarf2_find_nearest_line (abfd, debug_sections,
+ section, symbols, offset,
filename_ptr, functionname_ptr,
line_ptr, 0,
&coff_data(abfd)->dwarf2_find_line_info))
maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
while (1)
{
+ bfd_vma file_addr;
combined_entry_type *p2;
for (p2 = p + 1 + p->u.syment.n_numaux;
}
}
+ file_addr = (bfd_vma) p2->u.syment.n_value;
+ /* PR 11512: Include the section address of the function name symbol. */
+ if (p2->u.syment.n_scnum > 0)
+ file_addr += coff_section_from_bfd_index (abfd,
+ p2->u.syment.n_scnum)->vma;
/* We use <= MAXDIFF here so that if we get a zero length
file, we actually use the next file entry. */
if (p2 < pend
- && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value
- && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff)
+ && offset + sec_vma >= file_addr
+ && offset + sec_vma - file_addr <= maxdiff)
{
*filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
maxdiff = offset + sec_vma - p2->u.syment.n_value;
return TRUE;
}
+bfd_boolean
+coff_find_nearest_line (bfd *abfd,
+ asection *section,
+ asymbol **symbols,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
+{
+ return coff_find_nearest_line_with_names (abfd, dwarf_debug_sections,
+ section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr);
+}
+
bfd_boolean
coff_find_inliner_info (bfd *abfd,
const char **filename_ptr,
else
return NULL;
}
+
+bfd_boolean
+_bfd_coff_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info)
+{
+ flagword flags;
+ const char *name, *key;
+ struct bfd_section_already_linked *l;
+ struct bfd_section_already_linked_hash_entry *already_linked_list;
+ struct coff_comdat_info *s_comdat;
+
+ flags = sec->flags;
+ if ((flags & SEC_LINK_ONCE) == 0)
+ return FALSE;
+
+ /* The COFF backend linker doesn't support group sections. */
+ if ((flags & SEC_GROUP) != 0)
+ return FALSE;
+
+ name = bfd_get_section_name (abfd, sec);
+ s_comdat = bfd_coff_get_comdat_section (abfd, sec);
+
+ if (s_comdat != NULL)
+ key = s_comdat->name;
+ else
+ {
+ if (CONST_STRNEQ (name, ".gnu.linkonce.")
+ && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
+ key++;
+ else
+ /* FIXME: gcc as of 2011-09 emits sections like .text$<key>,
+ .xdata$<key> and .pdata$<key> only the first of which has a
+ comdat key. Should these all match the LTO IR key? */
+ key = name;
+ }
+
+ already_linked_list = bfd_section_already_linked_table_lookup (key);
+
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ {
+ struct coff_comdat_info *l_comdat;
+
+ l_comdat = bfd_coff_get_comdat_section (l->sec->owner, l->sec);
+
+ /* The section names must match, and both sections must be
+ comdat and have the same comdat name, or both sections must
+ be non-comdat. LTO IR plugin sections are an exception. They
+ are always named .gnu.linkonce.t.<key> (<key> is some string)
+ and match any comdat section with comdat name of <key>, and
+ any linkonce section with the same suffix, ie.
+ .gnu.linkonce.*.<key>. */
+ if (((s_comdat != NULL) == (l_comdat != NULL)
+ && strcmp (name, l->sec->name) == 0)
+ || (l->sec->owner->flags & BFD_PLUGIN) != 0)
+ {
+ /* The section has already been linked. See if we should
+ issue a warning. */
+ return _bfd_handle_already_linked (sec, l, info);
+ }
+ }
+
+ /* This is the first section with this name. Record it. */
+ if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
+ info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ return FALSE;
+}