Chapter 3 71
Linker Tasks
Using Linker commands
foo_ptr = (void (*)()) dyn_load(base_prog, addr, obj_files,
dest_file, entry_pt);
/*
STEP 3: Get the addresses of all desired routines using
nlist(3C):
*/
nl[0].n_name = “bar”;
nl[1].n_name = “counter”;
nl[2].n_name = NULL;
if (nlist(dest_file, nl)) {
fprintf(stderr, “error obtaining namelist for %s\n”,
dest_file);
exit(1);
}
/*
* Assign the addresses to meaningful variable names:
*/
bar_ptr = (void (*)()) nl[0].n_value;
counter_ptr = (int *) nl[1].n_value;
/*
* Now you can call the routines and modify the variables:
*/
glorp(“main”);
(*foo_ptr) ();
(*bar_ptr) ();
(*counter_ptr) ++;
printf(“counter = %d\n”, *counter_ptr);
}
void glorp(const char * from)
{
printf(“glorp called from %s\n”, from);
}
file1.o and file2.o . “Source for file1.c and file2.c” shows the source for
file1.o and file2.o. Notice that foo and bar call glorp in
dynprog.c. Also, both functions update the variable counter in
file2.o; however, foo updates counter through the pointer
(counter_ptr) defined in dynprog.c.
Source for file1.c and file2.c
/****************************************************************
* file1.c - Contains routines foo() and bar().
****************************************************************/
extern int * counter_ptr; /* defined in dynprog.c */
extern int counter; /* defined in file2.c */
extern void glorp(const char * from); /* defined in dynprog.c */
void foo()
{