home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / unix / aix / 8847 < prev    next >
Encoding:
Text File  |  1992-08-16  |  9.1 KB  |  240 lines

  1. Newsgroups: comp.unix.aix
  2. Path: sparky!uunet!gatech!news.ans.net!newsgate.watson.ibm.com!yktnews!admin!minnie!gerth
  3. From: gerth@watson.ibm.com (John Gerth)
  4. Subject: Re: Help with nlist(), XCOFF, and memory architecture...
  5. Summary:  repost article 6210 with sample code
  6. Sender: news@watson.ibm.com (NNTP News Poster)
  7. Message-ID: <1992Aug16.173811.32916@watson.ibm.com>
  8. Date: Sun, 16 Aug 1992 17:38:11 GMT
  9. Disclaimer: This posting represents the poster's views, not necessarily those of IBM
  10. References: <PAVEL.92Aug15180402@pixel.SLAC.Stanford.EDU>
  11. Nntp-Posting-Host: minnie.watson.ibm.com
  12. Organization: IBM T.J. Watson Research Center
  13. Keywords: nlist dynamic load
  14. Lines: 224
  15.  
  16. Here's a recent bit of sample code (below ===CUT HERE===) which claims
  17. to illustrate how to do the run-time resolution you are looking for.
  18. I haven't actually run it yet myself (it's still too far down the priority
  19. list) so caveat emptor.         
  20.  
  21. --
  22. John Gerth     gerth@watson.ibm.com        (914) 784-7639
  23. --------------------- referenced article --------------------------
  24. Article: 6210 of comp.unix.aix
  25. From: pgainer@vnet.ibm.com (Patrick Gainer)
  26. Message-ID: <19920729.053004.4@almaden.ibm.com>
  27. Date: Wed, 29 Jul 92 08:00:02 EDT
  28. Newsgroups: comp.unix.aix
  29. Subject: Re: more dynamic loading problems...
  30. Organization: IBM - Toronto Lab
  31. Disclaimer: This posting represents the poster's views, not those of IBM
  32. News-Software: UReply 3.0
  33. References: <45808@shamash.cdc.com>
  34. Lines: 207
  35.  
  36. In <45808@shamash.cdc.com> Paul Dokas x4629 writes:
  37. >I thought that I had solved my problems with dynamic loading, but things
  38. >still aren't working properly.  It seems that when I create a dynamically
  39. >loadable module, that the value returned by nlist() is not always the
  40. >correct offset to the begining of the routine.  The included code for
  41. >example creates a dynamically loadable module with 2 functions 'a_function()'
  42. >and 'b_function()'.  Using nm, I find that the symbol 'a_function' has
  43. >a value of 0x54.  But if I use dbx to look at the location pointed to by
  44. >fn_ptr, I find that the value of 'a_function' should really be 0x18!
  45.  
  46. Also, I have posted this from a VM system (gasp) and the left and right
  47. square brackets may be corrupted (I can't tell from here but it has happened
  48. before).
  49.  
  50. ================================CUT HERE====================================
  51. /*=========================================================================*/
  52. /*                                                                         */
  53. /* DESCRIPTION:  A quick and dirty prototype of runtime loading and        */
  54. /*               binding.                                                  */
  55. /*                                                                         */
  56. /*                                                                         */
  57. /* Usage: cc -g -o dyload dyload.c  = builds this executable               */
  58. /*        ld -T512 -H512 -e entry_point -lc -o object_file object_file.o   */
  59. /*                                                                         */
  60. /*=========================================================================*/
  61.  
  62. #include <stdio.h>
  63. #include <nlist.h>
  64. #include <malloc.h>
  65.  
  66.  
  67. /* Type definitions */
  68. typedef struct function_t
  69. {
  70.   char                  name[128];       /* function name */
  71.   int                   (*code)();       /* function pointer */
  72.   int                   arr[3];          /* 12 bytes for func descriptor */
  73. } Function;
  74.  
  75. typedef struct nlist n_list;
  76.  
  77.  
  78. /* Function prototype */
  79. int
  80.   load_and_bind(Function   *flist, char   *file);
  81.  
  82.  
  83. main(int   argc, char   **argv)
  84. {
  85.   char                  *libpath="/u/patrick/tools/dyload:.";
  86.   int                   result;
  87.   int                   loop_control=1;
  88.   char                  file_name[128];
  89.   char                  func_name[128];
  90.   Function              flist[2];
  91.  
  92.   /* optional arg for object file name */
  93.   if (argc < 2)
  94.   {
  95.     printf("Enter name of object file to be loaded.\n");
  96.     result = fgets(file_name, 128, stdin);
  97.  
  98.     /* remove carriage return from file name */
  99.     file_name[strlen(file_name)-1] = 0x00;
  100.   }
  101.   else
  102.   {
  103.     strcpy(file_name,argv[1]);
  104.   }
  105.  
  106.   /* load object module, resolve entry point information */
  107.   flist[0].code = load(file_name,0,libpath);
  108.   if (!flist[0].code)
  109.   {
  110.     printf("load call failed. Exiting.\n");
  111.     exit(-1);
  112.   }
  113.  
  114.   do       /* until user quits by setting loop_control == 0 */
  115.   {
  116.     /* get function to execute from user, preface name by a '.' */
  117.     printf("Enter name of function you wish to execute.\n");
  118.     flist[1].name[0] = '.';
  119.     result = fgets(&(flist[1].name[1]), 128, stdin);
  120.  
  121.     /* remove carriage return from file name (added by fgets) */
  122.     flist[1].name[strlen(flist[1].name)-1] = 0x00;
  123.  
  124.     /* hardcode function entry point - bad programming practise */
  125.     strcpy(flist[0].name,".ibm_start");
  126.  
  127.     /* resolve function name and generate a function pointer */
  128.     result = load_and_bind(flist,file_name);
  129.     if (result != 0)
  130.     {
  131.       printf("function name resolving failed. Exiting.\n");
  132.       exit(-2);
  133.     }
  134.  
  135.     /* execute function */
  136.     (flist[1].code)("Test input string",17);
  137.  
  138.     printf("Continue? (Yes == 1)\n");
  139.     fflush(stdin);
  140.     scanf("%d",&loop_control);
  141.     fflush(stdin);
  142.  
  143.   } while (loop_control);
  144.  
  145. }
  146.  
  147.  
  148.  
  149. /*
  150.  * Given a function name (string), this routine generates a function
  151.  * descriptor and a function pointer to that descriptor. All addresses
  152.  * are resolved so that the function pointer can be directly executed
  153.  * by the calling procedure.
  154.  *
  155.  * Parameters:
  156.  *  flist - contains two entries. The first holds the name of the entry
  157.  *          point for the entire module. This is used to calculate a base
  158.  *          address for the function to be resolved. The second contains
  159.  *          the name of the function to be resolved.
  160.  *  file  - contains the name of the object module containing the functions.
  161.  */
  162. int
  163.   load_and_bind(Function   *flist, char   *file)
  164. {
  165.   int           i;
  166.   n_list        *nlptr;
  167.   int           result;
  168.  
  169.  
  170.   /*===================================================================*/
  171.   /* allocate array of 3 nlist structure - 1 for object module header, */
  172.   /* 1 for function we wish to find, and 1 to NULL terminate array.    */
  173.   /*===================================================================*/
  174.   nlptr = (n_list *) calloc(3,sizeof(n_list));
  175.   if (!nlptr)
  176.   {
  177.     return(-3);
  178.   }
  179.  
  180.   /* set nlist name field for object module entry point */
  181.   nlptr[0]._n._n_name = flist[0].name;
  182.  
  183.   /* set nlist name field for function name to be resolved */
  184.   nlptr[1]._n._n_name = flist[1].name;
  185.  
  186.   /* set nlist name field terminator (NULL name) */
  187.   nlptr[2]._n._n_name = "";
  188.  
  189.   /* call nlist to get function offsets from a name list */
  190.   result = nlist(file, nlptr);
  191.   if (result == -1)
  192.   {
  193.     perror("nlist");
  194.     return(-4);
  195.   }
  196.  
  197.   /*=========================================================================*/
  198.   /* Here is where the addresses are resolved. Basically, the nlist call      */
  199.   /* returns with the offsets from the entry point for each function. The     */
  200.   /* entry point address was obtained via the load() call in main.            */
  201.   /*                                                                          */
  202.   /* Each function is associated with something called a function descriptor. */
  203.   /* This structure (12 bytes) contains the function's virtual address in     */
  204.   /* bytes 0 to 3 and the Table Of Contents address for the module in bytes   */
  205.   /* 4-7. Bytes 8-11 are not used. A function pointer is just a pointer to    */
  206.   /* this structure. To resolve a function's runtime address, The TOC entry   */
  207.   /* from the entry point is used (since the TOC is the same for all funcs    */
  208.   /* in a module) but the virtual address must be calculated. The entry_point */
  209.   /* offset (obtained from nlist) is subtracted from the function-to-be-      */
  210.   /* resolved's virtual address. This gives a base address. Then, the         */
  211.   /* function-to-be-resolved's nlist offset is added to this base address to  */
  212.   /* get the function's virtual address. Finally, the function pointer is set */
  213.   /* to point to the function descriptor structure just created.              */
  214.   /*==========================================================================*/
  215.  
  216.   /* copy entry point function descriptor to func-to-be-resolved's descriptor */
  217.   memcpy(flist[1].arr,flist[0].code,12);
  218.  
  219.   /* set function pointer to point to newly obtained function descriptor */
  220.   flist[1].code = (int(*)()) flist[1].arr;
  221.  
  222.   /*==============================================================*/
  223.   /* Subtract the nlist offset for the module from the ptr value  */
  224.   /* in flist[1].arr[0-3]. This will yield a base virtual address.*/
  225.   /*==============================================================*/
  226.   *((int *)flist[1].arr) = *((int *) flist[1].arr) - nlptr[0].n_value;
  227.  
  228.   /*==============================================================*/
  229.   /* Add the nlist offset for this particular symbol to the base  */
  230.   /* virtual address.                                             */
  231.   /*==============================================================*/
  232.   *((int *)flist[1].arr) = *((int *) flist[1].arr) + nlptr[1].n_value;
  233.  
  234.   /* done - free memory and return */
  235.   free(nlptr);
  236.   return(0);
  237. }
  238. -- 
  239. John Gerth     gerth@watson.ibm.com        (914) 784-7639
  240.