Subject: Re: Dynamic Linking for Linux?
From: Aubrey Jaffer <[email-masked]>
Date: 1 Dec 1993 00:42:21 +0200
Newsgroups: comp.os.linux.announce

Note:  What is being talked about here might better be called dynamic
link/loading.  What it does is to load a ".o" file into a running
program and make its variables and functions accessible.

In article <[email-masked]> [email-masked] (Michael Werts) writes:

   Is there a dynamic linking capability available for
   Linux? I'm looking for something like 'dld' by Wilson
   and Ho, or I suppose something like Windows' DLLs.

I have been working on porting dld-3.2.3 to linux.  DLD is available
from prep.ai.mit.edu:pub/gnu/dld-3.2.3.tar.gz.  My patched version for
Linux is in altdorf.ai.mit.edu:archive/scm/dld3c3.tar.gz.

At least on my out-of-date Linux system (99.10), DLD cannot link
library archives (ar format).  The "simple", "overlay", and "add1"
test suites work so far.  "general" and "reload" do not.

I would be interested if anyone gets different results on more recent
versions of Linux or gcc.

Here is a diff -rc file from dld-3.2.3.  For some reason, patch screws
up applying it.
================================================================
diff -rc dld-3.2.3/Makefile dld/Makefile
*** dld-3.2.3/Makefile	Thu May 30 07:13:49 1991
--- dld/Makefile	Fri Nov 26 13:51:47 1993
***************
*** 17,22 ****
--- 17,25 ----
  	rm -f ${ARCHIVE} *.o
  	cd test; make clean
  
+ test:
+ 	cd test; make all
+ 
  .c.o:
  	${CC} -c ${CFLAGS} $*.c
  
Only in dld: Makefile~
diff -rc dld-3.2.3/defs.h dld/defs.h
*** dld-3.2.3/defs.h	Thu May 30 07:13:51 1991
--- dld/defs.h	Tue Sep  7 12:33:32 1993
***************
*** 29,34 ****
--- 29,40 ----
  #include <sys/param.h>
  #include <setjmp.h>
  #include "dld.h"
+ 
+ /* added by [email-masked] for linux */
+ #ifndef N_COMM
+ #define N_COMM 0x12		/* common (internal to ld) */
+ #endif
+ 
  
  /* Each input file, and each library member ("subfile") being loaded,
     has a `file_entry' structure for it.
Only in dld: defs.h~
diff -rc dld-3.2.3/dld.c dld/dld.c
*** dld-3.2.3/dld.c	Thu May 30 07:13:31 1991
--- dld/dld.c	Fri Nov 26 13:41:15 1993
***************
*** 289,295 ****
  _dld_malloc (size)
  int size;
  {
!     register int result = malloc (size);
      if (!result)
  	fatal (DLD_ENOMEMORY);
      return result;
--- 289,297 ----
  _dld_malloc (size)
  int size;
  {
!     register int result;
!     if (0==size) size = 1;
!     result = malloc (size);
      if (!result)
  	fatal (DLD_ENOMEMORY);
      return result;
Only in dld: dld.c~
diff -rc dld-3.2.3/find_exec.c dld/find_exec.c
*** dld-3.2.3/find_exec.c	Thu May 30 07:13:53 1991
--- dld/find_exec.c	Sat Sep  4 23:46:19 1993
***************
*** 25,30 ****
--- 25,33 ----
  #include <sys/file.h>
  #include <sys/param.h>
  #include <strings.h>
+ #ifdef linux
+ #include <unistd.h>
+ #endif
  
  #define DEFAULT_PATH ".:~/bin::/usr/local/bin:/usr/new:/usr/ucb:/usr/bin:/bin:/usr/hosts"
  
Only in dld: find_exec.c~
diff -rc dld-3.2.3/test/add1/Makefile dld/test/add1/Makefile
*** dld-3.2.3/test/add1/Makefile	Thu May 30 07:13:43 1991
--- dld/test/add1/Makefile	Thu Nov 25 23:34:49 1993
***************
*** 5,10 ****
--- 5,11 ----
  CFLAGS = -g -I../..
  
  all:	${EXEC}
+ 	call_add1
  
  clean:
  	rm -f ${EXEC} *.o
Only in dld/test/add1: Makefile~
diff -rc dld-3.2.3/test/add1/add1.c dld/test/add1/add1.c
*** dld-3.2.3/test/add1/add1.c	Thu May 30 07:13:43 1991
--- dld/test/add1/add1.c	Sat Sep  4 23:58:31 1993
***************
*** 1,5 ****
--- 1,6 ----
  extern int x;
  
  add1() {
+   printf("got here\n");
      x++;
  }
Only in dld/test/add1: add1.c~
diff -rc dld-3.2.3/test/add1/call_add1.c dld/test/add1/call_add1.c
*** dld-3.2.3/test/add1/call_add1.c	Thu May 30 07:13:43 1991
--- dld/test/add1/call_add1.c	Thu Nov 25 23:51:59 1993
***************
*** 1,3 ****
--- 1,4 ----
+ #include <stdlib.h>
  #include "dld.h"
      
  int x;
***************
*** 13,19 ****
      register void (*func) ();
  
      /* required initialization. */
!     (void) dld_init (argv[0]);
  
      x = 1;
      printf ("global variable x = %d\n", x);
--- 14,20 ----
      register void (*func) ();
  
      /* required initialization. */
!     (void) dld_init (dld_find_executable(argv[0]));
  
      x = 1;
      printf ("global variable x = %d\n", x);
***************
*** 20,25 ****
--- 21,27 ----
  
      dld_link ("add1.o");
  
+     printf("exec? %d\n",dld_function_executable_p("add1"));
      /* grap the entry point for function "add1" */
      func = (void (*) ()) dld_get_func ("add1");
  
***************
*** 26,29 ****
--- 28,32 ----
      /* invoke "add1" */
      (*func) ();
      printf ("global variable x = %d\n", x);
+     return 2==x ? EXIT_SUCCESS : EXIT_FAILURE;
  }
Only in dld/test/add1: call_add1.c~
diff -rc dld-3.2.3/test/general/read-a.out.c dld/test/general/read-a.out.c
*** dld-3.2.3/test/general/read-a.out.c	Thu May 30 07:13:37 1991
--- dld/test/general/read-a.out.c	Sat Sep  4 23:46:35 1993
***************
*** 28,36 ****
  	perror ("Can't read header");
  	exit ();
      }
! 
      printf ("Header information:\nmagic = 0%o, text size = %d, data size = %d\n",
  	    header.a_magic, header.a_text, header.a_data);
      printf ("bss size = %d, syms size = %d, entry point = 0x%x, trsize = %d, drsize = %d\n",
  	    header.a_bss, header.a_syms, header.a_entry, header.a_trsize,
  	    header.a_drsize);
--- 28,37 ----
  	perror ("Can't read header");
  	exit ();
      }
! #ifndef linux
      printf ("Header information:\nmagic = 0%o, text size = %d, data size = %d\n",
  	    header.a_magic, header.a_text, header.a_data);
+ #endif
      printf ("bss size = %d, syms size = %d, entry point = 0x%x, trsize = %d, drsize = %d\n",
  	    header.a_bss, header.a_syms, header.a_entry, header.a_trsize,
  	    header.a_drsize);
Only in dld/test/general: read-a.out.c~
diff -rc dld-3.2.3/test/overlay/Makefile dld/test/overlay/Makefile
*** dld-3.2.3/test/overlay/Makefile	Thu May 30 07:13:42 1991
--- dld/test/overlay/Makefile	Fri Nov 26 00:03:47 1993
***************
*** 5,10 ****
--- 5,11 ----
  CFLAGS = -g -I../..
  
  all:	${EXEC}
+ 	overlay
  
  clean:
  	rm -f ${EXEC} *.o
Only in dld/test/overlay: Makefile~
diff -rc dld-3.2.3/test/overlay/overlay.c dld/test/overlay/overlay.c
*** dld-3.2.3/test/overlay/overlay.c	Thu May 30 07:13:41 1991
--- dld/test/overlay/overlay.c	Fri Nov 26 00:03:24 1993
***************
*** 46,49 ****
--- 46,50 ----
  	}
  	dld_unlink_by_symbol ("chain", 0);
      } while (p);
+     return 0;
  }
Only in dld/test/overlay: overlay.c~
diff -rc dld-3.2.3/test/reload/Makefile dld/test/reload/Makefile
*** dld-3.2.3/test/reload/Makefile	Thu May 30 07:13:34 1991
--- dld/test/reload/Makefile	Fri Nov 26 00:13:08 1993
***************
*** 5,10 ****
--- 5,11 ----
  CFLAGS = -g -I../..
  
  all:	${EXEC}
+ 	reload reload-test
  
  clean:
  	rm -f ${EXEC} *.o
***************
*** 18,23 ****
  reload: $(LIB) $(INCLUDE) reload.o reload-test
  	${CC} ${CFLAGS} reload.o $(LIB) -o reload
  
! reload-test: reload-test.o
! 	ld -r reload-test.o /lib/libc.a -o reload-test
! 
--- 19,24 ----
  reload: $(LIB) $(INCLUDE) reload.o reload-test
  	${CC} ${CFLAGS} reload.o $(LIB) -o reload
  
! reload-test: reload-test.o Makefile
! #	ld -r reload-test.o /lib/libc.a -o reload-test
! 	ld -r reload-test.o /lib/libc.so.4 -o reload-test	#linux
Only in dld/test/reload: Makefile~
diff -rc dld-3.2.3/test/reload/reload.c dld/test/reload/reload.c
*** dld-3.2.3/test/reload/reload.c	Thu May 30 07:13:33 1991
--- dld/test/reload/reload.c	Fri Nov 26 00:14:56 1993
***************
*** 36,41 ****
--- 36,43 ----
  	    *new_brk = sbrk(0);
  	    (*func) ();
  	}
+ 	return 0;
      }
+     else return 1;
  #endif
  }
Only in dld/test/reload: reload.c~
diff -rc dld-3.2.3/test/simple/Makefile dld/test/simple/Makefile
*** dld-3.2.3/test/simple/Makefile	Thu May 30 07:13:43 1991
--- dld/test/simple/Makefile	Fri Nov 26 00:16:11 1993
***************
*** 5,10 ****
--- 5,11 ----
  CFLAGS = -g -I../..
  
  all:	${EXEC}
+ 	simple
  
  clean:
  	rm -f ${EXEC} *.o
Only in dld/test/simple: Makefile~
diff -rc dld-3.2.3/test/simple/simple.c dld/test/simple/simple.c
*** dld-3.2.3/test/simple/simple.c	Thu May 30 07:13:42 1991
--- dld/test/simple/simple.c	Fri Nov 26 00:16:35 1993
***************
*** 11,14 ****
--- 11,15 ----
      printf ("Hello world from %s\n", argv[0]);
      func = (void (*) ()) dld_get_func ("printf");
      (*func) ("Hello world from %s\n", argv[0]);
+     return 0;
  }
Only in dld/test/simple: simple.c~

--
Mail submissions for comp.os.linux.announce to: [email-masked]
PLEASE remember Keywords: and a short description of the software.