views:

479

answers:

3

I am compiling a C program with the SPARC RTEMS C compiler.

Using the Xlinker -M option, I am able to get a large memory map with a lot of things I don't recognize.

I have also tried using the RCC nm utility, which returns a slightly more readable symbol table. I assume that the location given by this utility for, say, printf, is the location where printf is in memory and that every program that calls printf will reach that location during execution. Is this a valid assumption?

Is there any way to get a list of locations for all the library/system functions? Also, when the linking is done, does it link just the functions that the executable calls, or is it all functions in the library? It seems to me to be the latter, given the number of things I found in the symbol table and memory map. Can I make it link only the required functions?

Thanks for your help.

+3  A: 

Most often, when using a dynamic library, the nm utility will not be able to give you the exact answer. Binaries these days use what is known as relocatable addresses. These addresses change when they are mapped to the process' address space.

Using the Xlinker -M option, I am able to get a large memory map with a lot of things I don't recognize.

The linker map will usually have all symbols -- yours, the standard libraries, runtime hooks etc.

Is there any way to get a list of locations for all the library/system functions?

The headers are a good place to look.

Also, when the linking is done, does it link just the functions that the executable calls, or is it all functions in the library?

Linking does not necessarily mean that all symbols will be resolved (i.e. given an address). It depends on the type of binary you are creating.

Some compilers like gcc however, does allow you whether to create a non-relocatable binary or not. (For gcc you may check out exp files, dlltool etc.) Check with the appropriate documentation.

dirkgently
If I use the -static option for the linker to make it avoid using shared libraries, will that avoid the problems associated with dynamic libraries?
mandaleeka
What problems? I am assuming you are having duplicate symbol definition. In that case no. You have to hide/rename to avoid the name clash.
dirkgently
Sorry, I meant would nm give me the exact answer or is the address still relocatable?
mandaleeka
No. If a shared library will load a copy of the standard library into your process space instead of sharing an already available copy (loaded in memory because some other program uses a dll version).
dirkgently
A: 

With dynamic linking, 1. your executable has a special place for all external calls (PLT table). 2. your executable has a list of libraries it depends on

These two things are independent. It is impossible to say which external function lives in which library.

When a program does an external function call, what actually happens it calls an entry in the PLT table, which does a jump into the dynamic loader. The dynamic loader looks which function was called (via PLT), looks its name (via symbol table in the executable) and looks up that name in ALL libraries that are mapped (all that given executable is dependant on). Once the name is found, the address of the corresponding function is written back to the PLT, so next time the call is made directly bypassing the dynamic linker.

To answer your question, you should do the same job as dynamic linker does: get a list of dependent libs, and lookup all names in them. This could be done using 'nm' or 'readelf' utility.

As for static linkage, I think all symbols in given object file within libXXX.a get linked in. For example, static library libXXX.a consists of object files a.o, b.o and c.o. If you need a function foo(), and it resides in a.o, then a.o will be linked to your app - together with function foo() and all other data defined in it. This is the reason why for example C library functions are split per file.

valenok
A: 

If you want to dynamically link you use dlopen/dlsym to resolve UNIX .so shared library entry points.

http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html

Assuming you know the names of the functions you want to call, and which .so they are in. It is fairly simple.

void    *handle;
int     *iptr, (*fptr)(int);

/* open the needed object */
handle = dlopen("/usr/home/me/libfoo.so", RTLD_LOCAL | RTLD_LAZY);

/* find the address of function and data objects */
*(void **)(&fptr) = dlsym(handle, "my_function");
iptr = (int *)dlsym(handle, "my_object");

/* invoke function, passing value of integer as a parameter */
(*fptr)(*iptr);

If you want to get a list of all dynamic symbols, objdump -T file.so is your best bet. (objdump -t file.a if your looking for statically bound functions). Objdump is cross platform, part of binutils, so in a pinch, you can copy your binary files to another system and interrorgate them with objdump on a different platform.

If you want dynamic linking to be optimal, you should take a look at your ld.so.conf, which specifie's the search order for the ld.so.cache (so.cache right ;).

RandomNickName42