[gnu.g++] g++ and shared libraries on SunOS 4.0

nieh@eng3.crd.ge.com (03/21/89)

I am working on a prototype system by using (practicing) g++ on sun-4/OS4.0. 
I got to the point that I need to use dynamic linking and 
shared libraries. Can g++ use the shared libries feature provided
by SunOS 4.0 ? I don't have the shared libraries manual on hand.
Can someone out on the net give me some direction about how to
use the dynamic linking, shared libraries with g++ on Sun4.

Thanks

--

Ko-Haw Nieh

General Electric Company               | nieh@crd.ge.com
Corporate Research and Development     | nieh@steinmetz.ge.com 
P.O BOX 8, K1-ES224 		       | uunet!steinmetz!nieh
Schenectady, NY 12301		       | 518-387-7431                      

grunwald@flute.cs.uiuc.edu (03/22/89)

You'd need to add ``CFLAGS=-DNO_GNU_LD'' to the Makefile. To get ``collect''
to work correctly, you might also need to apply the following patches,
which also implement COFF support for g++ via collect.

NOTE: I've only used this on an Encore Multimax. I make no claims as to BSD
derived systems. Also, collect has been munged & you'll have to change it
if you're porting this code to non-UMAX systems (it's because I couldn't
find a umax-specific symbol to indicate when to include <sgs.h>).

*** /tmp/,RCSt1a14526	Tue Mar 21 20:54:32 1989
--- gcc.c	Sun Mar 19 01:08:06 1989
***************
*** 286,300 ****
  /* C++: Here is the spec for collecting global ctor and dtor
     requirements.  */
  char *collect_spec =
!   "%{!c:%{!M*:%{!E:%{!S:collect -o %g.S %o\n\
! 		       as %g.S -o %g.O\n }}}}";
  
  /* Here is the spec for running the linker, after compiling all files.  */
! char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
   %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
   %{y*} %{!nostdlib:%S} \
!  %{L*} %o %g.O %{!nostdlib:-lg++ gnulib%s %{g:-lg} %L}\n\
!  rm -f %g.O\n }}}}";
  #else
  /* Here is the spec for running the linker, after compiling all files.
     Note that ld++ find constructors and destructors for us.  */
--- 286,302 ----
  /* C++: Here is the spec for collecting global ctor and dtor
     requirements.  */
  char *collect_spec =
!   "%{!c:%{!M*:%{!E:%{!S:collect -o %g.S %g.R\n\
! as %g.S -o %g.O\n\
! ld %{o*} %g.R %g.O\n\
! rm -f %g.R %g.O\n\
! }}}}";
  
  /* Here is the spec for running the linker, after compiling all files.  */
! char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld -r -o %g.R %l\
   %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
   %{y*} %{!nostdlib:%S} \
!  %{L*} %o %{!nostdlib:-lg++ gnulib%s %{g:-lg} %L\n}}}}}";
  #else
  /* Here is the spec for running the linker, after compiling all files.
     Note that ld++ find constructors and destructors for us.  */
***************
*** 1604,1609 ****
--- 1606,1621 ----
  	}
      }
  
+ 
+   /* Run ld to link all the compiler output files.  */
+ 
+   if (! nolink && error_count == 0)
+     {
+       value = do_spec (link_spec);
+       if (value < 0)
+ 	error_count = 1;
+     }
+ 
  #ifdef NO_GNU_LD
    /* C++: now collect all the requirements for
       calling global constructors and destructors,
***************
*** 1616,1630 ****
  	error_count = 1;
      }
  #endif
- 
-   /* Run ld to link all the compiler output files.  */
- 
-   if (! nolink && error_count == 0)
-     {
-       value = do_spec (link_spec);
-       if (value < 0)
- 	error_count = 1;
-     }
  
    /* Delete some or all of the temporary files we made.  */
  
--- 1628,1633 ----
*** /tmp/,RCSt1a14531	Tue Mar 21 20:54:43 1989
--- collect.c	Sun Mar 19 01:27:59 1989
***************
*** 39,57 ****
  
  #include "config.h"
  
  /* For this file, some special macros.  These should be merged
     into tm.h some time.  */
  #undef ASM_OUTPUT_INT
  #undef ASM_OUTPUT_LABELREF
  
! #ifndef hp9000s300
  #define ASM_OUTPUT_INT(FILE,VALUE)  \
!   fprintf (FILE, "\t.long %d\n", VALUE)
  #define ASM_OUTPUT_PTR_INT_SUM(FILE,PTRNAME,VALUE)	\
!   fprintf (FILE, "\t.long _%s+%d\n", PTRNAME, VALUE)
  #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
!   fprintf (FILE, "\t.long _%s\n", NAME);
  #else
  #define ASM_OUTPUT_INT(FILE,VALUE)  \
    fprintf (FILE, "\tlong %d\n", VALUE)
  #define ASM_OUTPUT_PTR_INT_SUM(FILE,PTRNAME,VALUE)	\
--- 39,74 ----
  
  #include "config.h"
  
+ /*
+  *	This may not always be true, but I can't find another flag
+  *	to use.
+  */
+ #ifdef SDB_DEBUGGING_INFO
+ #define COFF
+ #define UMAX	/* need to define this conditionally */
+ #endif
+ 
  /* For this file, some special macros.  These should be merged
     into tm.h some time.  */
+ 
  #undef ASM_OUTPUT_INT
  #undef ASM_OUTPUT_LABELREF
  
! #if defined(COFF)
! 
  #define ASM_OUTPUT_INT(FILE,VALUE)  \
!   fprintf (FILE, "\t.double %d\n", VALUE)
! 
  #define ASM_OUTPUT_PTR_INT_SUM(FILE,PTRNAME,VALUE)	\
!   fprintf (FILE, "\t.double _%s+%d\n", PTRNAME, VALUE)
! 
  #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
!   fprintf (FILE, "\t.double _%s\n", NAME);
! 
! 
  #else
+ 
+ #if	define(hp9000s300)
  #define ASM_OUTPUT_INT(FILE,VALUE)  \
    fprintf (FILE, "\tlong %d\n", VALUE)
  #define ASM_OUTPUT_PTR_INT_SUM(FILE,PTRNAME,VALUE)	\
***************
*** 58,64 ****
--- 75,93 ----
    fprintf (FILE, "\tlong _%s+%d\n", PTRNAME, VALUE)
  #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
    fprintf (FILE, "\tlong _%s\n", NAME);
+ 
+ 
+ #else
+ #define ASM_OUTPUT_INT(FILE,VALUE)  \
+   fprintf (FILE, "\t.long %d\n", VALUE)
+ 
+ #define ASM_OUTPUT_PTR_INT_SUM(FILE,PTRNAME,VALUE)	\
+   fprintf (FILE, "\t.long _%s+%d\n", PTRNAME, VALUE)
+ 
+ #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+   fprintf (FILE, "\t.long _%s\n", NAME);
  #endif /* hp9000s300 */
+ #endif /* COFF */
  
  #include <sys/types.h>
  #include <sys/stat.h>
***************
*** 67,72 ****
--- 96,105 ----
  #include <a.out.h>
  #include <ar.h>
  
+ #ifdef UMAX
+ #include <sgs.h>
+ #endif
+ 
  extern int xmalloc ();
  extern void free ();
  
***************
*** 113,118 ****
--- 146,152 ----
    int i, nerrs = 0;
    enum error_code code;
    FILE *fp;
+   char *main_input_filename;
  
    if (argc > 2 && !strcmp (argv[1], "-o"))
      {
***************
*** 127,132 ****
--- 161,170 ----
        perror ("collect");
        exit (-1);
      }
+ 
+   main_input_filename = outfile_name;
+   ASM_FILE_START(outfile);
+ 
    fprintf (outfile, "%s\n", TEXT_SECTION_ASM_OP);
    ASM_GLOBALIZE_LABEL (outfile, CTOR_TABLE_NAME);
    ASM_OUTPUT_LABEL (outfile, CTOR_TABLE_NAME);
***************
*** 146,152 ****
  	  exit (-1);
  	}
  
!       switch (code = process (fp))
  	{
  	case OK:
  	  break;
--- 184,190 ----
  	  exit (-1);
  	}
  
!       switch (code = process (fp, argv[i]))
  	{
  	case OK:
  	  break;
***************
*** 211,221 ****
    exit (-1);
  }
  
  /* Figure out the type of file we need to process.
     Currently, only .o and .a formats are acceptable.  */
  enum error_code
! process (fp)
       FILE *fp;
  {
    struct stat file_stat;
    union
--- 249,349 ----
    exit (-1);
  }
  
+ #ifdef COFF
+ 
+ #include <ldfcn.h>
+ 
+ enum error_code
+ process (fp, filename)
+      FILE *fp;
+      char *filename;
+ {
+   LDFILE *ldptr;
+   do {
+     if ((ldptr = ldopen(filename, ldptr)) != NULL ) {
+       
+       if (!ISCOFF( HEADER(ldptr).f_magic ) ) {
+ 	return BAD_MAGIC;
+       }
+       else {
+ 	int symbols = HEADER(ldptr).f_nsyms;
+ 	int symindex;
+ 	
+ 	for (symindex = 0; symindex < symbols; symindex++ ) {
+ 
+ 	  SYMENT symbol;
+ 	  char *symbol_name;
+ 	  extern char *ldgetname();
+ 	  
+ 	  ldtbread(ldptr, symindex, &symbol);
+ 	  symbol_name = ldgetname(ldptr, &symbol);
+ 	  
+ 	  if (! strncmp ("__GLOBAL_$", symbol_name, 10)) {
+ 	    
+ 	    if (symbol_name[10] == 'I') {
+ 	      ASM_OUTPUT_LABELREF (outfile, symbol_name+1);
+ 	    }
+ 	    else {
+ 	      struct dtor_list_elem *new
+ 		= (struct dtor_list_elem *)
+ 		  xmalloc (sizeof (struct dtor_list_elem));
+ 	      new->next = dtor_chain;
+ 	      new->name = (char *)xmalloc (strlen (symbol_name));
+ 	      strcpy (new->name, symbol_name+1);
+ 	      dtor_chain = new;
+ 	    }
+ 	  }
+ 	}
+       }
+     }
+     else {
+       return( RANDOM_ERROR );
+     }
+   } while ( ldclose(ldptr) == FAILURE ) ;
+   return ( OK );
+ }
+ 
+ /****** taken from sdbout.c ******/
+ 
+ 
+ /* Tell the assembler the source file name.
+    On systems that use SDB, this is done whether or not -g,
+    so it is called by ASM_FILE_START.
+ 
+    ASM_FILE is the assembler code output file,
+    INPUT_NAME is the name of the main input file.  */
+ 
+ /* void */
+ sdbout_filename (asm_file, input_name)
+      FILE *asm_file;
+      char *input_name;
+ {
+   int len = strlen (input_name);
+   char *na = input_name + len;
+ 
+   /* NA gets INPUT_NAME sans directory names.  */
+   while (na > input_name)
+     {
+       if (na[-1] == '/')
+ 	break;
+       na--;
+     }
+ 
+ #ifdef ASM_OUTPUT_SOURCE_FILENAME
+   ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
+ #else
+   fprintf (asm_file, "\t.file\t\"%s\"\n", na);
+ #endif
+ }
+ 
+ #else
+ 
  /* Figure out the type of file we need to process.
     Currently, only .o and .a formats are acceptable.  */
  enum error_code
! process (fp, filename)
       FILE *fp;
+      char *filename;
  {
    struct stat file_stat;
    union
***************
*** 232,244 ****
--- 360,375 ----
  
    if (fread (header.ar_form, SARMAG, 1, fp) < 1)
      return RANDOM_ERROR;
+ 
    if (strncmp (ARMAG, header.ar_form, SARMAG))
      {
        fseek (fp, 0, 0);
        if (fread (&header.a_out_form, sizeof (struct exec), 1, fp) < 1)
  	return RANDOM_ERROR;
+ 
        if (N_BADMAG (header.a_out_form))
  	return BAD_MAGIC;
+ 
        return process_o (fp, &header.a_out_form, size);
      }
    return process_a (fp);
***************
*** 257,263 ****
  #else
    struct nlist_ *nelem, *nelems, *nend;
  #endif /* hp9000s300 */
-   int to_find = 2;
  
    if (N_BADMAG (*header))
      return BAD_MAGIC;
--- 388,393 ----
***************
*** 330,338 ****
  		  strcpy (new->name, p+1);
  		  dtor_chain = new;
  		}
- 	      if (--to_find == 0)
- 		break;
- 	    }
  	}
      }
    return OK;
--- 460,465 ----
***************
*** 392,397 ****
--- 519,525 ----
      }
    return OK;
  }
+ #endif
  
  enum error_code
  coalesce ()

 
--
Dirk Grunwald
Univ. of Illinois
grunwald@flute.cs.uiuc.edu