home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.aix
- Path: sparky!uunet!gatech!news.ans.net!newsgate.watson.ibm.com!yktnews!admin!minnie!gerth
- From: gerth@watson.ibm.com (John Gerth)
- Subject: Re: Help with nlist(), XCOFF, and memory architecture...
- Summary: repost article 6210 with sample code
- Sender: news@watson.ibm.com (NNTP News Poster)
- Message-ID: <1992Aug16.173811.32916@watson.ibm.com>
- Date: Sun, 16 Aug 1992 17:38:11 GMT
- Disclaimer: This posting represents the poster's views, not necessarily those of IBM
- References: <PAVEL.92Aug15180402@pixel.SLAC.Stanford.EDU>
- Nntp-Posting-Host: minnie.watson.ibm.com
- Organization: IBM T.J. Watson Research Center
- Keywords: nlist dynamic load
- Lines: 224
-
- Here's a recent bit of sample code (below ===CUT HERE===) which claims
- to illustrate how to do the run-time resolution you are looking for.
- I haven't actually run it yet myself (it's still too far down the priority
- list) so caveat emptor.
-
- --
- John Gerth gerth@watson.ibm.com (914) 784-7639
- --------------------- referenced article --------------------------
- Article: 6210 of comp.unix.aix
- From: pgainer@vnet.ibm.com (Patrick Gainer)
- Message-ID: <19920729.053004.4@almaden.ibm.com>
- Date: Wed, 29 Jul 92 08:00:02 EDT
- Newsgroups: comp.unix.aix
- Subject: Re: more dynamic loading problems...
- Organization: IBM - Toronto Lab
- Disclaimer: This posting represents the poster's views, not those of IBM
- News-Software: UReply 3.0
- References: <45808@shamash.cdc.com>
- Lines: 207
-
- In <45808@shamash.cdc.com> Paul Dokas x4629 writes:
- >I thought that I had solved my problems with dynamic loading, but things
- >still aren't working properly. It seems that when I create a dynamically
- >loadable module, that the value returned by nlist() is not always the
- >correct offset to the begining of the routine. The included code for
- >example creates a dynamically loadable module with 2 functions 'a_function()'
- >and 'b_function()'. Using nm, I find that the symbol 'a_function' has
- >a value of 0x54. But if I use dbx to look at the location pointed to by
- >fn_ptr, I find that the value of 'a_function' should really be 0x18!
-
- Also, I have posted this from a VM system (gasp) and the left and right
- square brackets may be corrupted (I can't tell from here but it has happened
- before).
-
- ================================CUT HERE====================================
- /*=========================================================================*/
- /* */
- /* DESCRIPTION: A quick and dirty prototype of runtime loading and */
- /* binding. */
- /* */
- /* */
- /* Usage: cc -g -o dyload dyload.c = builds this executable */
- /* ld -T512 -H512 -e entry_point -lc -o object_file object_file.o */
- /* */
- /*=========================================================================*/
-
- #include <stdio.h>
- #include <nlist.h>
- #include <malloc.h>
-
-
- /* Type definitions */
- typedef struct function_t
- {
- char name[128]; /* function name */
- int (*code)(); /* function pointer */
- int arr[3]; /* 12 bytes for func descriptor */
- } Function;
-
- typedef struct nlist n_list;
-
-
- /* Function prototype */
- int
- load_and_bind(Function *flist, char *file);
-
-
- main(int argc, char **argv)
- {
- char *libpath="/u/patrick/tools/dyload:.";
- int result;
- int loop_control=1;
- char file_name[128];
- char func_name[128];
- Function flist[2];
-
- /* optional arg for object file name */
- if (argc < 2)
- {
- printf("Enter name of object file to be loaded.\n");
- result = fgets(file_name, 128, stdin);
-
- /* remove carriage return from file name */
- file_name[strlen(file_name)-1] = 0x00;
- }
- else
- {
- strcpy(file_name,argv[1]);
- }
-
- /* load object module, resolve entry point information */
- flist[0].code = load(file_name,0,libpath);
- if (!flist[0].code)
- {
- printf("load call failed. Exiting.\n");
- exit(-1);
- }
-
- do /* until user quits by setting loop_control == 0 */
- {
- /* get function to execute from user, preface name by a '.' */
- printf("Enter name of function you wish to execute.\n");
- flist[1].name[0] = '.';
- result = fgets(&(flist[1].name[1]), 128, stdin);
-
- /* remove carriage return from file name (added by fgets) */
- flist[1].name[strlen(flist[1].name)-1] = 0x00;
-
- /* hardcode function entry point - bad programming practise */
- strcpy(flist[0].name,".ibm_start");
-
- /* resolve function name and generate a function pointer */
- result = load_and_bind(flist,file_name);
- if (result != 0)
- {
- printf("function name resolving failed. Exiting.\n");
- exit(-2);
- }
-
- /* execute function */
- (flist[1].code)("Test input string",17);
-
- printf("Continue? (Yes == 1)\n");
- fflush(stdin);
- scanf("%d",&loop_control);
- fflush(stdin);
-
- } while (loop_control);
-
- }
-
-
-
- /*
- * Given a function name (string), this routine generates a function
- * descriptor and a function pointer to that descriptor. All addresses
- * are resolved so that the function pointer can be directly executed
- * by the calling procedure.
- *
- * Parameters:
- * flist - contains two entries. The first holds the name of the entry
- * point for the entire module. This is used to calculate a base
- * address for the function to be resolved. The second contains
- * the name of the function to be resolved.
- * file - contains the name of the object module containing the functions.
- */
- int
- load_and_bind(Function *flist, char *file)
- {
- int i;
- n_list *nlptr;
- int result;
-
-
- /*===================================================================*/
- /* allocate array of 3 nlist structure - 1 for object module header, */
- /* 1 for function we wish to find, and 1 to NULL terminate array. */
- /*===================================================================*/
- nlptr = (n_list *) calloc(3,sizeof(n_list));
- if (!nlptr)
- {
- return(-3);
- }
-
- /* set nlist name field for object module entry point */
- nlptr[0]._n._n_name = flist[0].name;
-
- /* set nlist name field for function name to be resolved */
- nlptr[1]._n._n_name = flist[1].name;
-
- /* set nlist name field terminator (NULL name) */
- nlptr[2]._n._n_name = "";
-
- /* call nlist to get function offsets from a name list */
- result = nlist(file, nlptr);
- if (result == -1)
- {
- perror("nlist");
- return(-4);
- }
-
- /*=========================================================================*/
- /* Here is where the addresses are resolved. Basically, the nlist call */
- /* returns with the offsets from the entry point for each function. The */
- /* entry point address was obtained via the load() call in main. */
- /* */
- /* Each function is associated with something called a function descriptor. */
- /* This structure (12 bytes) contains the function's virtual address in */
- /* bytes 0 to 3 and the Table Of Contents address for the module in bytes */
- /* 4-7. Bytes 8-11 are not used. A function pointer is just a pointer to */
- /* this structure. To resolve a function's runtime address, The TOC entry */
- /* from the entry point is used (since the TOC is the same for all funcs */
- /* in a module) but the virtual address must be calculated. The entry_point */
- /* offset (obtained from nlist) is subtracted from the function-to-be- */
- /* resolved's virtual address. This gives a base address. Then, the */
- /* function-to-be-resolved's nlist offset is added to this base address to */
- /* get the function's virtual address. Finally, the function pointer is set */
- /* to point to the function descriptor structure just created. */
- /*==========================================================================*/
-
- /* copy entry point function descriptor to func-to-be-resolved's descriptor */
- memcpy(flist[1].arr,flist[0].code,12);
-
- /* set function pointer to point to newly obtained function descriptor */
- flist[1].code = (int(*)()) flist[1].arr;
-
- /*==============================================================*/
- /* Subtract the nlist offset for the module from the ptr value */
- /* in flist[1].arr[0-3]. This will yield a base virtual address.*/
- /*==============================================================*/
- *((int *)flist[1].arr) = *((int *) flist[1].arr) - nlptr[0].n_value;
-
- /*==============================================================*/
- /* Add the nlist offset for this particular symbol to the base */
- /* virtual address. */
- /*==============================================================*/
- *((int *)flist[1].arr) = *((int *) flist[1].arr) + nlptr[1].n_value;
-
- /* done - free memory and return */
- free(nlptr);
- return(0);
- }
- --
- John Gerth gerth@watson.ibm.com (914) 784-7639
-