home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / unix / aix / 12894 < prev    next >
Encoding:
Text File  |  1992-12-29  |  6.2 KB  |  241 lines

  1. Newsgroups: comp.unix.aix
  2. Path: sparky!uunet!cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!unixhub!courant.SLAC.Stanford.EDU!alhy
  3. From: alhy@courant.SLAC.Stanford.EDU (J. Scott Berg)
  4. Subject: Re: problem load()-ing shared object
  5. Message-ID: <C0084n.y2@unixhub.SLAC.Stanford.EDU>
  6. Sender: news@unixhub.SLAC.Stanford.EDU
  7. Reply-To: ALHY@slac.stanford.edu
  8. Organization: Stanford University, dept of Physics / SLAC
  9. References:  <609@bertha.HyperDesk.com>
  10. Date: Tue, 29 Dec 1992 04:50:46 GMT
  11. Lines: 228
  12.  
  13. In article <609@bertha.HyperDesk.com>, adennie@ibm3.hyperdesk.com (Andy Dennie) writes:
  14. |> I've been playing around with shared objects on AIX 3.2, and although I
  15. |> can successfully load and execute a simple function in a shared object,
  16. |> I'm stumped on the following problem: how do you load a shared object
  17. |> that contains references to globals defined in the program doing the
  18. |> loading?  Below is a simple test case that illustrates the problem.
  19. |> 
  20. |> Any help would be greatly appreciated!
  21. |> 
  22. |> foo2.c contains:
  23. |> ----------------------------------------------------------------------
  24. |> #include <errno.h>
  25. |> #include <stdio.h>
  26. |> #include <sys/ldr.h>
  27. |> 
  28. |> char global_string[] = "hello, world\n";  /* here's the global */
  29. |> 
  30. |> main() {
  31. |>     int (*pfunc)() = load("bar.so", 0, (char*)NULL);
  32. |> 
  33. |>     if (pfunc == 0) {
  34. |>         printf("load failed, errno=%d\n", errno);
  35. |>     }
  36. |> }
  37. |> ----------------------------------------------------------------------
  38. |> 
  39. |> 
  40. |> bar2.c contains:
  41. |> ----------------------------------------------------------------------
  42. |> extern char *global_string;
  43. |> 
  44. |> void bar () {
  45. |>     printf("%s", global_string);
  46. |> }
  47. |> ----------------------------------------------------------------------
  48. |> 
  49. |> bar2.exp contains:
  50. |> ------------------
  51. |> bar
  52. |> ------------------
  53. |> 
  54. |> bar2.imp contains:
  55. |> ------------------
  56. |> global_string
  57. |> ------------------
  58. |> 
  59. |> % make foo2 bar2.so
  60. |>         xlc -o foo2 -D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE foo2.c
  61. |>         xlc -o bar2.so -bM:SRE -bE:bar2.exp -bI:bar2.imp -e _nostart bar2.c
  62. |> % foo2
  63. |> load failed, errno=8
  64. |> 
  65. |> 
  66. |> BTW, $LIBPATH contains the current directory, where bar2.so resides.  I
  67. |> think I'm probably doing something wrong with bar2.imp.  I've tried
  68. |> adding
  69. |> 
  70. |> #!/pathname/of/foo
  71. |> 
  72. |> to the beginning of it, but that didn't help.  I also tried creating a
  73. |> foo2.exp file and linking foo2 with the -bE:foo2.exp switch (same
  74. |> results).  Any ideas? 
  75.  
  76. I hacked around on this for a while, and here's what I could figure out:
  77.  
  78. To get it to load, you need to put something in the import file telling it
  79. what to do about finding the external references.
  80.  
  81. If you put 
  82.  
  83. #!
  84.  
  85. as the first line, it treats it as a "delayed resolve", which as far
  86. as I can tell is not resolved by the load() function call.  You need
  87. to call loadbind() to resolve it.  But you need another load()'ed
  88. program to do the resolve with.  It seems (it's hard to tell) that you
  89. can give loadbind a symbol name within your code and it will try to do
  90. the resolve.  You need to tell foo2 to export the global_string (I
  91. think).  When you do this, the load call works fine, it resolves the
  92. symbol to something, but that something happens to be garbage.  Beats
  93. me why.  If you instead put
  94.  
  95. #!./foo2
  96.  
  97. in your bar2.inp, the same thing happens (you don't even have to do
  98. the loadbind() call).  If you use the #! alone, but don't do the
  99. loadbind call, it segment faults even trying to figure out the value
  100. of the pointer global_string.  It ALWAYS segment faults when you try
  101. to reference the pointer (i.e., print the string).
  102.  
  103. Anyhow, I'm sure this isn't making much sense to you, because it
  104. certainly doesn't make any sense to me.  Enclosed is my current
  105. version of your test code which basically has more diagnostics and
  106. gets past the load part.
  107.  
  108. Good luck!  If you figure out how to do this, I'd love to know.  God
  109. bless
  110.  
  111.                     -Scott Berg
  112.  
  113. When executed, my foo2 outputs:
  114.  
  115. Err: 0
  116. 10000000 5761 20041800 104
  117. foo2
  118. d07ea000 1749 20047400 24
  119. bar2.so
  120. Test: hello, world
  121.  
  122. 20041810
  123. Got here!
  124. 68656c6c           <---- Wouldn't have printed this without the loadbind()
  125. Segmentation fault
  126.  
  127.  
  128.  
  129. ==============
  130.  
  131. foo2.c:
  132.  
  133. ==============
  134.  
  135. #include <errno.h>
  136. #include <stdio.h>
  137. #include <sys/ldr.h>
  138.  
  139. char global_string[] = "hello, world\n";  /* here's the global */
  140.  
  141. main() {
  142.  
  143.   char *buffer[1024];
  144.   char *yo;
  145.  
  146.     int (*pfunc)() = load("bar2.so", 0, (char*)NULL);
  147.  
  148.   printf("Err: %d\n",loadbind(0,global_string,pfunc));
  149.  
  150.   loadquery(L_GETINFO,buffer,sizeof buffer);
  151.   yo = (char *) buffer;
  152.   while (((struct ld_info *)yo)->ldinfo_next != 0) {
  153.     printf("%p %u %p %u\n",((struct ld_info *)yo)->ldinfo_textorg,
  154.        ((struct ld_info *)yo)->ldinfo_textsize,
  155.        ((struct ld_info *)yo)->ldinfo_dataorg,
  156.        ((struct ld_info *)yo)->ldinfo_datasize);
  157.     printf(((struct ld_info *)yo)->ldinfo_filename);
  158.     printf("\n");
  159.     yo += ((struct ld_info *)yo)->ldinfo_next;
  160.   }
  161.   
  162.  
  163.   printf("Test: %s\n",global_string);
  164.   printf("%p\n",global_string);
  165.   
  166.     if (pfunc == 0) {
  167.         printf("load failed, errno=%d\n", errno);
  168.     perror("Yo!");
  169.     buffer[0] = "execerror";
  170.     buffer[1] = "foo2";
  171.     loadquery(L_GETMESSAGES, &buffer[2], sizeof buffer -8);
  172.     execvp("/etc/execerror",buffer);
  173.     }
  174.  
  175.   pfunc();
  176. }
  177.  
  178. ==============
  179.  
  180. foo2.exp:
  181.  
  182. ==============
  183.  
  184. global_string
  185.  
  186. ==============
  187.  
  188. bar2.c:
  189.  
  190. ==============
  191.  
  192. extern char *global_string;
  193.  
  194. void bar () {
  195.   printf("Got here!\n");
  196.   printf("%p\n",global_string);
  197.     printf("%s", global_string);
  198. }
  199.  
  200. =============
  201.  
  202. bar2.inp
  203.  
  204. =============
  205.  
  206. #!
  207. global_string
  208.  
  209. =============
  210.  
  211. bar2.exp
  212.  
  213. =============
  214.  
  215. bar
  216.  
  217. =============
  218.  
  219. Makefile
  220.  
  221. =============
  222.  
  223. foo2 :  foo2.c foo2.exp
  224.     xlc -bE:foo2.exp -L. -o foo2 -D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE foo2.c
  225.  
  226. bar2.so : bar2.c bar2.inp bar2.exp
  227.     xlc -L. -o bar2.so -bM:SRE -bE:bar2.exp -bI:bar2.inp -e _nostart bar2.c
  228.  
  229. -- 
  230. -------------------------------------------------------------------------------
  231. The opinions expressed here are, of course, my own and nobody else's.
  232. -------------------------------------------------------------------------------
  233. J. Scott Berg
  234. email: ALHY@slac.stanford.edu
  235. real mail: Varian Physics
  236.            Stanford  CA  94305-4060
  237. phone:    (415) 926-4732 (w)
  238.      (415) 326-2631 (h)
  239. -------------------------------------------------------------------------------
  240.  
  241.