[gnu.utils.bug] "ld" port to ISI 68k

crl@GIBBS.PHYSICS.PURDUE.EDU ("Charles R. LaBrec") (10/23/88)

Here are the mods required to get "ld" running on an Integrated
Solutions 68k machine running 4.3 BSD Rel 4.0D.  The biggest changes
are due to a hack ISI put into their "ld" and libc.  It treats
symbols that begin with a "_$" specially.  You don't want to know any
more.

Charles LaBrec
crl @ maxwell.physics.purdue.edu

*** ld.c-dist	Wed Sep 14 18:19:50 1988
--- ld.c	Sun Oct 23 01:11:18 1988
***************
*** 190,196 ****
--- 197,206 ----
  #ifdef vax
  #define N_TXTADDR(X) 0
  #endif
+ #ifdef is68k
+ #define N_TXTADDR(x) (sizeof (HEADER_TYPE))
  #endif
+ #endif
  
  #ifndef N_DATADDR
  #ifdef vax
***************
*** 198,204 ****
--- 208,220 ----
  	(((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
  	: (page_size+((N_TXTADDR(x)+(x).a_text-1) & ~(page_size-1))))
  #endif
+ #ifdef is68k
+ #define SEGMENT_SIZE 0x20000
+ #define N_DATADDR(x) \
+ 	(((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
+ 	: (SEGMENT_SIZE+((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1))))
  #endif
+ #endif
  
  #ifdef hpux
  #define getpagesize() EXEC_PAGESIZE
***************
*** 208,213 ****
--- 224,239 ----
  #ifdef sun
  #define INITIALIZE_HEADER outheader.a_machtype = M_68020
  #endif
+ 
+ #ifdef is68k
+ #ifdef M_68020
+ /* ISI rel 4.0D doesn't use it, and rel 3.05 doesn't have an a_machtype field
+    and so won't recognize the magic number.  To keep binary compatibility for
+    now, just ignore it */
+ #define INITIALIZE_HEADER outheader.a_machtype = 0;
+ #endif
+ #endif /* is68k */
+ 
  #ifdef hpux
  #define INITIALIZE_HEADER outheader.a_machtype = HP9000S200_ID
  #endif
***************
*** 584,594 ****
--- 610,624 ----
  
  /* Standard directories to search for files specified by -l.  */
  char *standard_search_dirs[] =
+ #ifdef STANDARD_SEARCH_DIRS
+   STANDARD_SEARCH_DIRS;
+ #else
  #ifdef NON_NATIVE
    {"/usr/local/lib/gnu"};
  #else
    {"/lib", "/usr/lib", "/usr/local/lib"};
  #endif
+ #endif
  
  /* Actual vector of directories to search;
     this contains those specified with -L plus the standard ones.  */
***************
*** 1496,1502 ****
--- 1526,1552 ----
  	}
      }
    else
+ #ifdef is68k
+     if (!oldref)
+       {
+ 	if (entry->superfile && type == (N_UNDF | N_EXT) && name[1] == '$')
+ 	  {
+ 	    /* this is an ISI $-conditional, skip it */
+ 	    sp->referenced = 0;
+ 	    if (sp->trace)
+ 	      {
+ 		fprintf (stderr, "symbol %s is a $-conditional ignored in ", sp->name);
+ 		print_file_name (entry, stderr);
+ 		fprintf (stderr, "\n");
+ 	      }
+ 	    return;
+ 	  }
+ 	else
+ 	  undefined_global_sym_count++;
+       }
+ #else
      if (!oldref) undefined_global_sym_count++;
+ #endif
  
    if (sp == end_symbol && entry->just_syms_flag && !T_flag_specified)
      text_start = nlist_p->n_value;
***************
*** 1872,1887 ****
    register struct nlist *p;
    register struct nlist *end
      = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
  
    for (p = entry->symbols; p < end; p++)
      {
        register int type = p->n_type;
  
!       if (type & N_EXT && (type != (N_UNDF | N_EXT) || p->n_value))
  	{
- 	  register char *name = p->n_un.n_strx + entry->strings;
  	  register symbol *sp = getsym_soft (name);
  
  	  /* If this symbol has not been hashed, we can't be looking for it. */
  
  	  if (!sp) continue;
--- 1922,1966 ----
    register struct nlist *p;
    register struct nlist *end
      = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
+ #ifdef is68k
+   register int dolcond = 0;
+ #endif
  
    for (p = entry->symbols; p < end; p++)
      {
        register int type = p->n_type;
+       register char *name = p->n_un.n_strx + entry->strings;
  
!       if (type & N_EXT && (type != (N_UNDF | N_EXT) || p->n_value
! #ifdef is68k
! 			   || name[1] == '$'
! #endif
! ))
  	{
  	  register symbol *sp = getsym_soft (name);
  
+ #ifdef is68k
+ 	  /* ISI has a really kludgey way of trying to cut down memory usage.
+ 	     If a symbol begins with _$, then the object file is included only
+ 	     if the rest of the symbol name has been referenced. */
+ 	  if (name[1] == '$')
+ 	    {
+ 	      sp = getsym_soft (&name[2]);
+ 	      dolcond = 1;
+ 	      if (!sp) continue;
+ 	      if (sp->referenced)
+ 		{
+ 		  if (write_map)
+ 		    {
+ 		      print_file_name (entry, stdout);
+ 		      fprintf (stdout, " needed due to $-conditional %s\n", name);
+ 		    }
+ 		  return 1;
+ 		}
+ 	      continue;
+ 	    }
+ #endif
+ 
  	  /* If this symbol has not been hashed, we can't be looking for it. */
  
  	  if (!sp) continue;
***************
*** 1889,1894 ****
--- 1968,1976 ----
  	  if (sp->referenced && !sp->defined)
  	    {
  	      /* This is a symbol we are looking for.  */
+ #ifdef is68k
+ 	      if (dolcond) continue;
+ #endif
  	      if (type == (N_UNDF | N_EXT))
  		{
  		  /* Symbol being defined as common.