From e074d05eac56e4281f5954b7f9d9cc94a81a4cf4 Mon Sep 17 00:00:00 2001
From: Fred Fish <fnf@specifix.com>
Date: Sat, 24 May 1997 15:30:55 +0000
Subject: [PATCH] 	* libcoff-in.h (struct coff_final_link_info): Add
 boolean 	global_to_static member for support of task linking. 
 (_bfd_coff_write_task_globals): Add prototype. 	* libcoff.h:
 Regenerate. 	* coffcode.h (coff_write_object_contents): Use #ifdef to 
 check RS6000COFF_C, to be consistent with all other uses 	in this file. 
 * cofflink.c (_bfd_coff_final_link): If doing task linking, 	call
 _bfd_coff_write_task_globals. 	(_bfd_coff_link_input_bfd): If doing task
 linking, convert 	global functions to static. 
 (_bfd_coff_write_global_sym): If doing task linking, convert 	global
 variables to static. 	(_bfd_coff_write_task_globals): New function. 	*
 coff-tic80.c (TIC80COFF): Define this instead of just TIC80. 	(C_AUTOARG):
 #undef since it clashes with C_UEXT. 	(C_LASTENT): #undef since it clashes
 with C_STATLAB. 	* coffcode.h (coff_write_object_contents): Use
 TIC80COFF 	rather than TIC80. 	(coff_slurp_symbol_table): Use
 C_SYSTEM.  Hide C_AUTOARG use 	when TIC80COFF defined (clashes with C_UEXT). 
 Explicitly 	recognize C_UEXT, C_STATLAB, and C_EXTLAB as unsupported. PR
 12236

---
 bfd/ChangeLog  | 27 ++++++++++++++++++++++++
 bfd/cofflink.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7c2081deb75..3cdf64f6b81 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,30 @@
+Fri May 23 15:14:58 1997  Fred Fish  <fnf@cygnus.com>
+
+	* libcoff-in.h (struct coff_final_link_info): Add boolean
+	global_to_static member for support of task linking.
+	(_bfd_coff_write_task_globals): Add prototype.
+	* libcoff.h: Regenerate.
+	* coffcode.h (coff_write_object_contents): Use #ifdef to
+	check RS6000COFF_C, to be consistent with all other uses
+	in this file.
+	* cofflink.c (_bfd_coff_final_link): If doing task linking,
+	call _bfd_coff_write_task_globals.
+	(_bfd_coff_link_input_bfd): If doing task linking, convert
+	global functions to static.
+	(_bfd_coff_write_global_sym): If doing task linking, convert
+	global variables to static.
+	(_bfd_coff_write_task_globals): New function.
+start-sanitize-tic80
+	* coff-tic80.c (TIC80COFF): Define this instead of just TIC80.
+	(C_AUTOARG): #undef since it clashes with C_UEXT.
+	(C_LASTENT): #undef since it clashes with C_STATLAB.
+	* coffcode.h (coff_write_object_contents): Use TIC80COFF
+	rather than TIC80.
+	(coff_slurp_symbol_table): Use C_SYSTEM.  Hide C_AUTOARG use
+	when TIC80COFF defined (clashes with C_UEXT).  Explicitly
+	recognize C_UEXT, C_STATLAB, and C_EXTLAB as unsupported.
+end-sanitize-tic80
+
 start-sanitize-tic80
 Fri May 23 12:38:24 1997  Ian Lance Taylor  <ian@cygnus.com>
 
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index c721bdf9de1..38a181f2075 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -838,6 +838,18 @@ _bfd_coff_final_link (abfd, info)
 	return false;
     }
 
+  /* If doing task linking (ld --task-link) then make a pass through the
+     global symbols, writing out any that are defined, and making them
+     static. */
+  if (info->task_link)
+    {
+      finfo.failed = false;
+      coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_task_globals,
+			       (PTR) &finfo);
+      if (finfo.failed)
+	goto error_return;
+    }
+
   /* Write out the global symbols.  */
   finfo.failed = false;
   coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
@@ -1604,6 +1616,12 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
 	      finfo->last_file = isym;
 	    }
 
+	  /* If doing task linking, convert normal global function symbols to
+	     static functions. */
+
+	  if (finfo->info->task_link && isym.n_sclass == C_EXT)
+	    isym.n_sclass = C_STAT;
+
 	  /* Output the symbol.  */
 
 	  bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
@@ -2290,6 +2308,18 @@ _bfd_coff_write_global_sym (h, data)
   if (isym.n_sclass == C_NULL)
     isym.n_sclass = C_EXT;
 
+  /* If doing task linking and this is the pass where we convert defined globals to
+     statics, then do that conversion now.  If the symbol is not being converted,
+     just ignore it and it will be output during a later pass. */
+  if (finfo->global_to_static)
+    {
+      if (isym.n_sclass != C_EXT)
+	{
+	  return true;
+	}
+      isym.n_sclass = C_STAT;
+    }
+
   isym.n_numaux = h->numaux;
   
   bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms);
@@ -2328,6 +2358,33 @@ _bfd_coff_write_global_sym (h, data)
   return true;
 }
 
+/* Write out task global symbols, converting them to statics.  Called
+   via coff_link_hash_traverse.  Calls bfd_coff_write_global_sym to do
+   the dirty work, if the symbol we are processing needs conversion. */
+
+boolean
+_bfd_coff_write_task_globals (h, data)
+     struct coff_link_hash_entry *h;
+     PTR data;
+{
+  struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
+  boolean rtnval = true;
+
+  if (h->indx < 0)
+    {
+      switch (h->root.type)
+	{
+	case bfd_link_hash_defined:
+	case bfd_link_hash_defweak:
+	  finfo->global_to_static = true;
+	  rtnval = _bfd_coff_write_global_sym (h, data);
+	  finfo->global_to_static = false;
+	  break;
+	}
+    }
+  return (rtnval);
+}
+
 /* Handle a link order which is supposed to generate a reloc.  */
 
 boolean