Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking symbols to fixed addresses on Linux

How would one go about linking (some) symbols to specific fixed addresses using GNU ld so that the binary could still be executed as normal in Linux (x86)? There will not be any accesses to those symbols, but their addresses are important.

For example, I'd have the following structure:

struct FooBar {
    Register32 field_1;
    Register32 field_2;
    //...
};

struct FooBar foobar;

I'd like to link foobar to address 0x76543210, but link the standard libraries and the rest of the application normally. The application will then make use of the address of foobar, but will not reference the (possibly non-existent) memory behind it.

The rationale for this request is that this same source can be used on two platforms: On the native platform, Register32 can simply be a volatile uint32_t, but on Linux Register32 is a C++ object with the same size as a uint32_t that defines e.g. operator=, which will then use the address of the object and sends a request to a communication framework with that address (and the data) to perform the actual access on remote hardware. The linker would thus ensure the Register32 fields of the struct refer to the correct "addresses".

like image 933
Tomi Junnila Avatar asked Jan 30 '09 11:01

Tomi Junnila


People also ask

What is symbol resolution in linking?

In symbol resolution, weak defined symbols are silently overridden by any global definition of the same name. Another form of simple symbol resolution, interposition, occurs between relocatable objects and shared objects, or between multiple shared objects.

What is a symbol linker?

Linker symbols have a name and a value. The value is a 32-bit unsigned integer, even if it represents a pointer value on a target that has pointers smaller than 32 bits. The most common kind of symbol is generated by the compiler for each function and variable.

How does a linker use a symbol table?

The linker resolves symbol references by associating each reference with exactly one symbol definition from the symbol tables of its input relocatable object files. Symbol resolution is straightforward for references to local symbols that are defined in the same module as the reference.

What is the linker flag?

The flag tells the linker to link in the produced binary only the libraries containing symbols actually used by the binary itself. This binary can be either a final executable or another library. In theory, when linking something, only the needed libraries are passed to the command line used to invoke the linker.


3 Answers

The suggestion by litb to use --defsym symbol=address does work, but is a bit cumbersome when you have a few dozen such instances to map. However, --just-symbols=symbolfile does just the trick. It took me a while to find out the syntax of the symbolfile, which is

symbolname1 = address;
symbolname2 = address;
...

The spaces seem to be required, as otherwise ld reports file format not recognized; treating as linker script.

like image 66
Tomi Junnila Avatar answered Oct 25 '22 18:10

Tomi Junnila


Try it with

--defsym symbol=expression

As with this:

gcc -Wl,--defsym,foobar=0x76543210 file.c

And make foobar in your code an extern declaration:

extern struct FooBar foobar;

This looks promising. However, it's a bad idea to do such a thing (unless you really know what you do). Why do you need it?

like image 38
Johannes Schaub - litb Avatar answered Oct 25 '22 18:10

Johannes Schaub - litb


I'll give you the hot tip... GNU LD can do this (assuming the system libs don't need the address you want). You just need to build your own linker script instead of using the compiler's autogenerated one. Read the man page for ld. Also, building a linker script for a complex piece of software is no easy task when you involve the GLIBC too.

like image 28
Adam Hawes Avatar answered Oct 25 '22 18:10

Adam Hawes