While reading the book "Operating Systems From 0 to 1", i'm currently trying to build a debuggable program on bare metal.
I'm compiling the following program:
void main() {}
using gcc -ffreestanding -nostdlib -gdwarf-4 -m32 -ggdb3 -c os.c -o os.o
without an error.
But when running ld -m elf_i386 -nmagic -T os.ld os.o -o os.o
on the output,
os.ld being:
ENTRY(main);
PHDRS
{
headers PT_PHDR PHDRS;
code PT_LOAD FILEHDR PHDRS;
}
SECTIONS
{
.text 0x600: ALIGN(0x100) { *(.text) } :code
.data : { *(.data) }
.bss : { *(.bss) }
/DISCARD/ : { *(.eh_frame) }
}
it throws the following error:
ld: warning: cannot find entry symbol main; not setting start address
Altough according to readelf os.o contains the symbol "main".
output of readelf -s os.o
:
Symbol table '.symtab' contains 23 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS os.c
2: 00000000 0 SECTION LOCAL DEFAULT 3
3: 00000000 0 SECTION LOCAL DEFAULT 5
4: 00000000 0 SECTION LOCAL DEFAULT 6
5: 00000000 0 SECTION LOCAL DEFAULT 7
6: 00000000 0 SECTION LOCAL DEFAULT 8
7: 00000000 0 SECTION LOCAL DEFAULT 10
8: 00000000 0 SECTION LOCAL DEFAULT 11
9: 00000000 0 SECTION LOCAL DEFAULT 13
10: 00000000 0 SECTION LOCAL DEFAULT 17
11: 00000000 0 SECTION LOCAL DEFAULT 19
12: 00000000 0 SECTION LOCAL DEFAULT 21
13: 00000000 0 SECTION LOCAL DEFAULT 22
14: 00000000 0 SECTION LOCAL DEFAULT 15
15: 00000000 0 SECTION LOCAL DEFAULT 23
16: 00000000 0 NOTYPE LOCAL DEFAULT 2 wm4.0.5fa2ff0e40930321219
17: 00000000 0 SECTION LOCAL DEFAULT 20
18: 00000000 0 SECTION LOCAL DEFAULT 1
19: 00000000 0 SECTION LOCAL DEFAULT 2
20: 00000000 20 FUNC GLOBAL DEFAULT 3 main
21: 00000000 0 FUNC GLOBAL HIDDEN 7 __x86.get_pc_thunk.ax
22: 00000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
Any idea what the problem might be?
You are trashing your os.o
(input same as output)
Change:
ld -m elf_i386 -nmagic -T os.ld os.o -o os.o
Into:
ld -m elf_i386 -nmagic -T os.ld os.o -o osx
Thanks, that fixed it. I was trying to overwrite it on purpose. Can you explain why it caused that error? – Felix B.
ld
[and most such build commands] do not allow an input file to be specified as an output file.
ld
may have to read os.o
several times while writing the -o osx
output file.
The simple construction is that we open a file for read and an output file for writing when the program starts.
For what you wanted, the program would have to detect that infile and outfile are the same and create a temp copy of infile.
Too difficult to guarantee in the general case. It's rarely used and would slow things down.
Also, if you put the commands in a makefile:
all: osx
os.o: os.c
gcc -ffreestanding -nostdlib -gdwarf-4 -m32 -ggdb3 -c os.c -o os.o
osx: os.o os.ld
ld -m elf_i386 -nmagic -T os.ld os.o -o osx
If ld
produced an error, make
would remove the osx
file.
Consider that if os.o
was the the output file, this would mess up the dependencies that make
relies on.