aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/coffgen.c34
-rw-r--r--bfd/cofflink.c88
-rw-r--r--bfd/libcoff-in.h3
-rw-r--r--bfd/libcoff.h3
5 files changed, 131 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f20d7cc..d4b33c5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+2011-11-02 Jan Beulich <jbeulich@suse.com>
+
+ * coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
+ internal_syment *' parameter. Extend 'dummy' to an array with two
+ elements. Set n_numaux early. Handle BSF_FILE.
+ (coff_write_symbols): Pass NULL as new third argument to
+ coff_write_alien_symbol().
+ * cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
+ obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
+ from non-COFF input BFDs.
+ * libcoff-in.h (coff_write_alien_symbol): Declare.
+ * libcoff.h (coff_write_alien_symbol): Re-generate.
+
2011-11-01 DJ Delorie <dj@redhat.com>
* Makefile.am (ALL_MACHINES): Add cpu-rl78.lo.
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 87a3bfa..c0505c6 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -983,31 +983,36 @@ coff_write_symbol (bfd *abfd,
file originally. This symbol may have been created by the linker,
or we may be linking a non COFF file to a COFF file. */
-static bfd_boolean
+bfd_boolean
coff_write_alien_symbol (bfd *abfd,
asymbol *symbol,
+ struct internal_syment *isym,
bfd_vma *written,
bfd_size_type *string_size_p,
asection **debug_string_section_p,
bfd_size_type *debug_string_size_p)
{
combined_entry_type *native;
- combined_entry_type dummy;
+ combined_entry_type dummy[2];
asection *output_section = symbol->section->output_section
? symbol->section->output_section
: symbol->section;
struct bfd_link_info *link_info = coff_data (abfd)->link_info;
+ bfd_boolean ret;
if ((!link_info || link_info->strip_discarded)
&& !bfd_is_abs_section (symbol->section)
&& symbol->section->output_section == bfd_abs_section_ptr)
{
symbol->name = "";
+ if (isym != NULL)
+ memset (isym, 0, sizeof(*isym));
return TRUE;
}
- native = &dummy;
+ native = dummy;
native->u.syment.n_type = T_NULL;
native->u.syment.n_flags = 0;
+ native->u.syment.n_numaux = 0;
if (bfd_is_und_section (symbol->section))
{
native->u.syment.n_scnum = N_UNDEF;
@@ -1018,6 +1023,11 @@ coff_write_alien_symbol (bfd *abfd,
native->u.syment.n_scnum = N_UNDEF;
native->u.syment.n_value = symbol->value;
}
+ else if (symbol->flags & BSF_FILE)
+ {
+ native->u.syment.n_scnum = N_DEBUG;
+ native->u.syment.n_numaux = 1;
+ }
else if (symbol->flags & BSF_DEBUGGING)
{
/* There isn't much point to writing out a debugging symbol
@@ -1025,6 +1035,8 @@ coff_write_alien_symbol (bfd *abfd,
format. So, we just ignore them. We must clobber the symbol
name to keep it from being put in the string table. */
symbol->name = "";
+ if (isym != NULL)
+ memset (isym, 0, sizeof(*isym));
return TRUE;
}
else
@@ -1045,16 +1057,20 @@ coff_write_alien_symbol (bfd *abfd,
}
native->u.syment.n_type = 0;
- if (symbol->flags & BSF_LOCAL)
+ if (symbol->flags & BSF_FILE)
+ native->u.syment.n_sclass = C_FILE;
+ else if (symbol->flags & BSF_LOCAL)
native->u.syment.n_sclass = C_STAT;
else if (symbol->flags & BSF_WEAK)
native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
else
native->u.syment.n_sclass = C_EXT;
- native->u.syment.n_numaux = 0;
- return coff_write_symbol (abfd, symbol, native, written, string_size_p,
- debug_string_section_p, debug_string_size_p);
+ ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
+ debug_string_section_p, debug_string_size_p);
+ if (isym != NULL)
+ *isym = native->u.syment;
+ return ret;
}
/* Write a native symbol to a COFF file. */
@@ -1170,8 +1186,8 @@ coff_write_symbols (bfd *abfd)
if (c_symbol == (coff_symbol_type *) NULL
|| c_symbol->native == (combined_entry_type *) NULL)
{
- if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size,
- &debug_string_section,
+ if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
+ &string_size, &debug_string_section,
&debug_string_size))
return FALSE;
}
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index bca1364..1ebdfdd 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -866,7 +866,7 @@ _bfd_coff_final_link (bfd *abfd,
size_t sz;
sub->output_has_begun = FALSE;
- sz = obj_raw_syment_count (sub);
+ sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
if (sz > max_sym_count)
max_sym_count = sz;
}
@@ -943,6 +943,92 @@ _bfd_coff_final_link (bfd *abfd,
}
}
+ if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
+ {
+ /* Add local symbols from foreign inputs. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ unsigned int i;
+
+ if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
+ continue;
+ for (i = 0; i < bfd_get_symcount (sub); ++i)
+ {
+ asymbol *sym = bfd_get_outsymbols (sub) [i];
+ file_ptr pos;
+ struct internal_syment isym;
+ bfd_size_type string_size = 0;
+ bfd_vma written = 0;
+ bfd_boolean rewrite = FALSE;
+
+ if (! (sym->flags & BSF_LOCAL)
+ || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+ | BSF_SYNTHETIC))
+ || ((sym->flags & BSF_DEBUGGING)
+ && ! (sym->flags & BSF_FILE)))
+ continue;
+
+ /* See if we are discarding symbols with this name. */
+ if ((finfo.info->strip == strip_some
+ && (bfd_hash_lookup (finfo.info->keep_hash,
+ bfd_asymbol_name(sym), FALSE, FALSE)
+ == NULL))
+ || (((finfo.info->discard == discard_sec_merge
+ && (bfd_get_section (sym)->flags & SEC_MERGE)
+ && ! finfo.info->relocatable)
+ || finfo.info->discard == discard_l)
+ && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
+ continue;
+
+ pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
+ * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ goto error_return;
+ if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+ &string_size, NULL, NULL))
+ goto error_return;
+
+ if (string_size)
+ {
+ bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (finfo.strtab,
+ bfd_asymbol_name (sym), hash,
+ FALSE);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ bfd_coff_swap_sym_out (abfd, &isym, finfo.outsyms);
+ rewrite = TRUE;
+ }
+
+ if (isym.n_sclass == C_FILE)
+ {
+ if (finfo.last_file_index != -1)
+ {
+ finfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+ finfo.outsyms);
+ pos = obj_sym_filepos (abfd) + finfo.last_file_index
+ * symesz;
+ rewrite = TRUE;
+ }
+ finfo.last_file_index = obj_raw_syment_count (abfd);
+ finfo.last_file = isym;
+ }
+
+ if (rewrite
+ && (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
+ goto error_return;
+
+ obj_raw_syment_count (abfd) += written;
+ }
+ }
+ }
+
if (! bfd_coff_final_link_postscript (abfd, & finfo))
goto error_return;
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index 8bfda72..0cd8de5 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -318,6 +318,9 @@ extern void coff_mangle_symbols
(bfd *);
extern bfd_boolean coff_write_symbols
(bfd *);
+extern bfd_boolean coff_write_alien_symbol
+ (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+ bfd_size_type *, asection **, bfd_size_type *);
extern bfd_boolean coff_write_linenumbers
(bfd *);
extern alent *coff_get_lineno
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index 958650c..8aef552 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -322,6 +322,9 @@ extern void coff_mangle_symbols
(bfd *);
extern bfd_boolean coff_write_symbols
(bfd *);
+extern bfd_boolean coff_write_alien_symbol
+ (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+ bfd_size_type *, asection **, bfd_size_type *);
extern bfd_boolean coff_write_linenumbers
(bfd *);
extern alent *coff_get_lineno