ld problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
sancho1980
Member
Member
Posts: 199
Joined: Fri Jul 13, 2007 6:37 am
Location: Stuttgart/Germany
Contact:

ld problem

Post by sancho1980 »

hi
suppose i have a a couple object files and want to link them together with ld. also suppose that this binary program is not going to be loaded at address 0, how do i tell the linker to add the appropriate offset to each memory reference in the code?
the ld man page has got the following to say:
--image-base value
Use value as the base address of your program or dll. This is the
lowest memory location that will be used when your program or dll
is loaded. To reduce the need to relocate and improve performance
of your dlls, each should have a unique base address and not over-
lap any other dlls. The default is 0x400000 for executables, and
0x10000000 for dlls. [This option is specific to the i386 PE tar-
geted port of the linker]
but i do:

Code: Select all

sancho@Kiste:~/assembly/boot$ ld boot.o -o boot.bin -e main --oformat binary -N --image-base 0x123
and get

Code: Select all

ld: unrecognized option '--image-base'
ld: use the --help option for usage information
Am I choosing the wrong option?
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

-Ttext 0x123

Regards,
John.
sancho1980
Member
Member
Posts: 199
Joined: Fri Jul 13, 2007 6:37 am
Location: Stuttgart/Germany
Contact:

Post by sancho1980 »

jnc100 wrote:-Ttext 0x123

Regards,
John.
I had tried that before but it doesnt do what I want. In fact, "-Ttext 0x123" pads the executable file with 0x123 bytes of zero at the start before placing any executable code. I simply want that the offset 0x123 be added to all memory references within the code...
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

Have you tried a linker script?
sancho1980
Member
Member
Posts: 199
Joined: Fri Jul 13, 2007 6:37 am
Location: Stuttgart/Germany
Contact:

Post by sancho1980 »

ive had a look at the manual, but all i an find is this -Tsection option, even for scripts..the problem is as follows:

suppose you have a bunch of .o files and want to link them together to a single binary..the linker would for example place the text section first and then append the data section
if varible x is the very first variable in the data section and the text section is 0x10 bytes long, then

Code: Select all

mov x, eax
would be linked to

Code: Select all

mov [0x10], eax
but of course, suppose this binary file instead of being loaded at address 0x0, is loaded at address 0x10000. then of course i would want the linker to write

Code: Select all

mov [0x100010], eax
instead of

Code: Select all

mov [0x10], eax
How would I achieve that? How is this "normally done" (relocation sure is a fairly common thing, isnt it?)
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Looking at the ".bin" extension on your linker output file I am assuming you are outputting in plain binary format. As this format has no section headers it does not support relocation of any segment - that's why when relocating the .text segment ld actually just pads the file.

You have 2 options:

(1) - Use ELF. ELF has headers and thus you can change the address of any section without using padding.

(2) - Use position independent code - compile with -fPIC.

JamesM
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

It is possible to force a binary to think that it is going to be running at a certain address. That's what I do in my OS. However it is pretty impossible to relocate a flat binary. So what I do is link every one of my programs at 0x40000000 and load them there using virtual memory. Here is the linker script that I do that with:

Code: Select all

ENTRY( app_entry )

OUTPUT_FORMAT( binary )

SECTIONS
{
        .text 0x40000000 : AT( 0x40000000 )
        {
                *(.text)
                *(.text.*)
                *(.gnu.linkonce.t*)
                *(.const*)
                *(.ro*)
                *(.gnu.linkonce.r*)
        }
        .data :
        {
                *(.data)
                *(.gnu.linkonce.d*)
        }
        
        /* The uninitialized data section */
        .bss :
        {
                bss_start = ABSOLUTE( . );

                *(.bss .bss.* .gnu.linkonce.b.*)

                *(COMMON)

                bss_end = ABSOLUTE( . );

                bss_length = bss_end - bss_start;
                
        }
        }

You can just change 0x40000000 to whatever address you load the binary to and it should work.
Post Reply