Common Symbols and Archives [Patch]

Ian Dall ian@beware.dropbear.id.au
Sun Jul 28 07:45:00 GMT 2002


Ian Lance Taylor writes:
 > > I can see three ways forward. The first would be to make the behaviour
 > > optional with a platform dependent default. The second would be to
 > > abandon a.out. The third is more radical.
 > 
 > I would definitely advise abandoning a.out.  I can't think of any
 > reason to stick with it.
 > 
 > > Is there any reason why there could not be an extra symbol flag, say
 > > N_RODATA. Arrange gcc and as to cause symbols referring to const data
 > > to have N_RODATA and N_TEXT set (this allows backward compatibility).
 > > Then common symbols should only match with N_DATA or N_RODATA symbols.
 > > The existing behaviour could be optional, and on by default for
 > > appropriate targets. These symbols would still refer to data in the
 > > text segment.
 > > 
 > > It should be possible to duplicate the type 2 correctness above and
 > > select between type 1 and type 3 correctness for targets where they
 > > conflict.
 > 
 > The only problem with a new symbol flag is that you only have 5 bits,
 > and most of the values are taken with standard a.out stuff or with GNU
 > extensions.  But if you can squeeze in another bit, it's worth a try.
 > Backward compatibility won't be possible, as the flags are values, not
 > bits, excepts for N_EXT, so there is no meaningful way to set both
 > N_TEXT and N_RODATA.

Since this can't be done backward compatibly, and since it would also need
compiler changes, it seems too much effort compared with the alternative
of transitioning to ELF.

In the meantime I would like to at least have backward compatability
for a.out.  However, the current binutils linker is *not* compatable
with the NetBSD a.out linker and I would like to propose the following
patch.  It requires patches to both bfd and ld.

Here is the bfd/ChangeLog entry:

2002-07-26  Ian Dall  <ian@sibyl.beware.dropbear.id.au>

	* aoutx.h (aout_link_check_ar_symbols): Whether to include an
	archive object is target dependant.

Here is the ld/ChangeLog entry:

2002-07-27  Ian Dall  <ian@sibyl.beware.dropbear.id.au>

	* emultempl/netbsd.em (LDEMUL_BEFORE_PARSE): New file to custom set
	link_info.common_skip_ar_aymbols.
	* emulparams/ns32knbsd.sh (EXTRA_EM_FILE): Refer to extra file.

	* ldmain.c (main): Initialize new field
	link_info.common_skip_ar_aymbols.


Index: bfd/aoutx.h
===================================================================
RCS file: /cvs/src/src/bfd/aoutx.h,v
retrieving revision 1.30
diff -c -r1.30 aoutx.h
*** bfd/aoutx.h	25 Jun 2002 06:21:47 -0000	1.30
--- bfd/aoutx.h	28 Jul 2002 13:07:33 -0000
***************
*** 3222,3242 ****
  	  || type == (N_ABS | N_EXT)
  	  || type == (N_INDR | N_EXT))
  	{
  	  /* This object file defines this symbol.  We must link it
  	     in.  This is true regardless of whether the current
! 	     definition of the symbol is undefined or common.  If the
! 	     current definition is common, we have a case in which we
! 	     have already seen an object file including
  	         int a;
  	     and this object file from the archive includes
  	         int a = 5;
! 	     In such a case we must include this object file.
! 
! 	     FIXME: The SunOS 4.1.3 linker will pull in the archive
! 	     element if the symbol is defined in the .data section,
! 	     but not if it is defined in the .text section.  That
! 	     seems a bit crazy to me, and I haven't implemented it.
! 	     However, it might be correct.  */
  	  if (! (*info->callbacks->add_archive_element) (info, abfd, name))
  	    return false;
  	  *pneeded = true;
--- 3222,3255 ----
  	  || type == (N_ABS | N_EXT)
  	  || type == (N_INDR | N_EXT))
  	{
+ 	  int skip = 0;
  	  /* This object file defines this symbol.  We must link it
  	     in.  This is true regardless of whether the current
! 	     definition of the symbol is undefined or common.
! 
!              If the current definition is common, we have a case in
! 	     which we have already seen an object file including
  	         int a;
  	     and this object file from the archive includes
  	         int a = 5;
! 	     In such a case, whether to include this object is target
!              dependant for backward compatability */
! 	  if (h->type == bfd_link_hash_common)
! 	    /*  */
! 	    switch (info->common_skip_ar_aymbols)
! 	      {
! 	      case bfd_link_common_skip_text:
! 		skip = (type == (N_TEXT | N_EXT));
! 		break;
! 	      case bfd_link_common_skip_data:
! 		skip = (type == (N_DATA | N_EXT));
! 		break;
! 	      case bfd_link_common_skip_all:
! 		skip = 1;
! 		break;
! 	      }
! 	  if (skip)
! 	    continue;
  	  if (! (*info->callbacks->add_archive_element) (info, abfd, name))
  	    return false;
  	  *pneeded = true;
Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.20
diff -c -r1.20 bfdlink.h
*** include/bfdlink.h	1 Jul 2002 08:04:47 -0000	1.20
--- include/bfdlink.h	28 Jul 2002 13:08:24 -0000
***************
*** 66,71 ****
--- 66,79 ----
    bfd_link_hash_warning		/* Like indirect, but warn if referenced.  */
  };
  
+ enum bfd_link_common_skip_ar_aymbols
+ {
+   bfd_link_common_skip_none,
+   bfd_link_common_skip_text,
+   bfd_link_common_skip_data,
+   bfd_link_common_skip_all
+ };
+ 
  /* The linking routines use a hash table which uses this structure for
     its elements.  */
  
***************
*** 343,348 ****
--- 351,360 ----
  
    /* How many spare .dynamic DT_NULL entries should be added?  */
    unsigned int spare_dynamic_tags;
+ 
+   /* Criteria for skipping symbols when detemining whether to include
+      an object from an archive. */
+   enum bfd_link_common_skip_ar_aymbols common_skip_ar_aymbols;
  };
  
  /* This structures holds a set of callback functions.  These are
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.49
diff -c -r1.49 ldmain.c
*** ld/ldmain.c	1 Jul 2002 08:07:29 -0000	1.49
--- ld/ldmain.c	28 Jul 2002 13:08:34 -0000
***************
*** 264,269 ****
--- 264,270 ----
    link_info.pei386_auto_import = -1;
    link_info.combreloc = true;
    link_info.spare_dynamic_tags = 5;
+   link_info.common_skip_ar_aymbols = bfd_link_common_skip_none;
  
    ldfile_add_arch ("");
  
Index: ld/emulparams/ns32knbsd.sh
===================================================================
RCS file: /cvs/src/src/ld/emulparams/ns32knbsd.sh,v
retrieving revision 1.2
diff -c -r1.2 ns32knbsd.sh
*** ld/emulparams/ns32knbsd.sh	5 Jun 2002 16:59:12 -0000	1.2
--- ld/emulparams/ns32knbsd.sh	28 Jul 2002 13:08:34 -0000
***************
*** 5,7 ****
--- 5,8 ----
  ARCH=ns32k
  EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'
  NONPAGED_TEXT_START_ADDR=0x1000
+ EXTRA_EM_FILE=netbsd
diff -c --unidirectional-new-file --exclude=CVS /tmp/emultempl/netbsd.em ld/emultempl/netbsd.em
*** /tmp/emultempl/netbsd.em	Thu Jan  1 09:30:00 1970
--- ld/emultempl/netbsd.em	Fri Jul 26 22:28:42 2002
***************
*** 0 ****
--- 1,9 ----
+ LDEMUL_BEFORE_PARSE=gldnetbsd_before_parse
+ cat >>e${EMULATION_NAME}.c <<EOF
+ static void
+ gldnetbsd_before_parse()
+ {
+   gld${EMULATION_NAME}_before_parse();
+   link_info.common_skip_ar_aymbols = bfd_link_common_skip_text;
+ }
+ EOF



More information about the Binutils mailing list