Elegant way to set base address of ELF image with Linux binutils?
The ELF entry point can be set in the linker response file, which can be passed to ld with -T
Doing a bogus link with --verbose will show you the default linker responsefile (which might be system specific, but in reality it is not that bad, one per arch per OS for the most).
Note that there might be additional constraints (like the entry point residing in a text/codesegment)
For a practical example of lugging along custom linker files, see the Free Pascal project, which does this to implement resources.
Why is the ELF entry point 0x8048000 not changeable with the ld -e option?
why cannot I make ld use a different entry point than the default with ld -e
You sure can. This:
int foo(int argc, char *argv[]) { return 0; }
gcc main.c -Wl,-e,foo
wouldn't work, because the execution doesn't start at main. It starts at _start
, which is linked from crt0.o
(part of glibc) and arranges for things like dynamic linking, etc. to start up properly. By redirecting _start
to foo
, you've bypassed all that required glibc initialization, and so things don't work.
But if you don't need dynamic linking, and are willing to do what glibc normally does for you, then you can name the entry point whatever you want. Example:
#include <syscall.h>
int foo()
{
syscall(SYS_write, 1, "Hello, world\n", 13);
syscall(SYS_exit, 0);
}
gcc t.c -static -nostartfiles -Wl,-e,foo && ./a.out
Hello, world
Oh, and your title of this question doesn't match your actual question (bad idea(TM)).
To answer the question in the title, you sure can change the address your executable is linked at. By default, you get 0x8048000
load address (only in 32-bits; 64-bit default is 0x400000
).
You can easily change that to e.g. 0x80000
by adding -Wl,-Ttext-segment=0x80000
to the link line.
Update:
However, when I try to link with ld -N -e0x400082 -Ttext=0x400082 program.o -o program (moving text segment and entry point by 4 bytes), the program will be killed.
Well, it is impossible to assign Ttext
to 0x400082
without violating .text
section alignment constraint (which is 4). You must keep the .text address aligned on at least 4-byte boundary (or change the required alignment of .text
).
When I set the start address to 0x400078, 0x40007c, 0x400080, 0x400084, ..., 0x400098 and use GNU-ld 2.20.1, the program works.
However, when I use current CVS snapshot of binutils, the program works for 0x400078, 0x40007c, 0x400088, 0x40008c, and gets Killed for 0x400080, 0x400084, 0x400090, 0x400094, 0x400098. This might be a bug in the linker, or I am violating some other constraint (I don't see which though).
At this point, if you are really interested, I suggest downloading binutils sources, building ld
, and figuring out what exactly causes it to create two PT_LOAD
segments instead of one.
Update 2:
Force new segment for sections with overlapping LMAs.
Ah! That just means you need to move .data
out of the way. This makes a working executable:
ld -N -o t t.o -e0x400080 -Ttext=0x400080 -Tdata=0x400180
MIPS emulator cannot run mips executable due to invalid ELF header
You have forgotten to link your code. The assembler as
only produces object file, you need to link it. Presumably you want something like:
mipsel-linux-gnu-as test.asm -o test.o
mipsel-linux-gnu-ld test.o -o test
If you do it correctly, the file
command output should include executable
, such as:
ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, not stripped
Related Topics
Fail If a Script Expects Input or Entering Passwords
How to Solve "Bash: Ls: Command Not Found"
Rust Linux Version Glibc Not Found - Compile for Different Glibc/Libc6 Version
File Glob Patterns in Linux Terminal
Terminal Closes When I Source My Script (Run with Dot at the Start)
Shell Script: Hexadecimal Loop
Can Someone Explain How This "Shellshock" Code Works in Shell
Linux Ipc: Shared Memory Recovery
Differentiate Between Exit and Session Timeout
Why Ln -Sf Does Not Overwrite Existing Link to Directory
Linux, Serial Port, Non-Buffering Mode
Print the Output of Strace Command in a Text File
Linux Randomly Deleted My File While Compiling What Do I Do
Docker in Wsl2 Alpine Without Docker Desktop