Kernel in ELF Format - Potential Linker Issue?
Posted: Thu Jan 07, 2016 6:21 pm
Just to see if it is possible, I decided to try to build the Bare Bones kernel using only tools from the LLVM project (i.e., clang instead of gcc and lld instead of ld). After much battling with the toolchain, I was able to link a kernel binary together, package an iso with GRUB, and attempted to execute it in virtualbox. This resulted in
After getting more information about the binary via readelf and objdump, I believe what I'm seeing is a bug in the lld linker, but I am trying to make sure I fully understand exactly what went wrong.
I found two things of note from readelf, the first is the program header table:
From what I understand, it looks like the executable section is set up to load at 0x00000000 which is what is causing the Error 7 mentioned above (if my understanding is correct).
Second, the .symtab appears to be corrupted:
and the symbols that I would have expected to be there appear in a separate symbol table called .hash:
Trying to run the binary through objdump simply exits with the error
Is my understanding correct that the lld linker has not linked this binary together into a well-formed ELF executable?
(P.S. I know that I can just build a usable gcc cross-compiler to get this up and working. I'm ultimately less interested in getting this to boot than am I understanding what went wrong in the compilation/linking process.)
Code: Select all
Error 7: Loading below 1MB is not supported
I found two things of note from readelf, the first is the program header table:
Code: Select all
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
INTERP 0x0008e5 0x000008e5 0x000008e5 0x0001c 0x0001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x00000000 0x00000000 0x00b50 0x00b50 R E 0x1000
LOAD 0x001000 0x00001000 0x00001000 0x00000 0x14010 RW 0x1000
DYNAMIC 0x000b20 0x00000b20 0x00000b20 0x00030 0x00030 R 0x4
Second, the .symtab appears to be corrupted:
Code: Select all
Symbol table '.symtab' contains 1 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00010101 0 NOTYPE LOCAL DEFAULT UND <corrupt>
Code: Select all
Symbol table '.hash' contains 66 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000930 0 OBJECT LOCAL DEFAULT 11 .LCPI4_0
2: 00000940 16 OBJECT LOCAL DEFAULT 11 .LCPI4_1
3: 00000950 16 OBJECT LOCAL DEFAULT 11 .LCPI4_2
4: 00000960 16 OBJECT LOCAL DEFAULT 11 .LCPI4_3
5: 00000970 16 OBJECT LOCAL DEFAULT 11 .LCPI4_4
6: 00000980 16 OBJECT LOCAL DEFAULT 11 .LCPI4_5
7: 00000990 16 OBJECT LOCAL DEFAULT 11 .LCPI4_6
8: 000009a0 16 OBJECT LOCAL DEFAULT 11 .LCPI4_7
9: 000009b0 16 OBJECT LOCAL DEFAULT 11 .LCPI4_8
10: 000009c0 16 OBJECT LOCAL DEFAULT 11 .LCPI4_9
11: 000009d0 16 OBJECT LOCAL DEFAULT 11 .LCPI6_0
12: 000009e0 16 OBJECT LOCAL DEFAULT 11 .LCPI6_1
13: 000009f0 16 OBJECT LOCAL DEFAULT 11 .LCPI6_2
14: 00000a00 16 OBJECT LOCAL DEFAULT 11 .LCPI6_3
15: 00000a10 16 OBJECT LOCAL DEFAULT 11 .LCPI6_4
16: 00000a20 16 OBJECT LOCAL DEFAULT 11 .LCPI6_5
17: 00000a30 16 OBJECT LOCAL DEFAULT 11 .LCPI6_6
18: 00000a40 16 OBJECT LOCAL DEFAULT 11 .LCPI6_7
19: 00000a50 16 OBJECT LOCAL DEFAULT 11 .LCPI6_8
20: 00000a60 16 OBJECT LOCAL DEFAULT 11 .LCPI6_9
21: 00000a70 16 OBJECT LOCAL DEFAULT 11 .LCPI7_0
22: 00000a80 16 OBJECT LOCAL DEFAULT 11 .LCPI7_1
23: 00000a90 16 OBJECT LOCAL DEFAULT 11 .LCPI7_2
24: 00000aa0 16 OBJECT LOCAL DEFAULT 11 .LCPI7_3
25: 00000ab0 16 OBJECT LOCAL DEFAULT 11 .LCPI7_4
26: 00000ac0 16 OBJECT LOCAL DEFAULT 11 .LCPI7_5
27: 00000ad0 16 OBJECT LOCAL DEFAULT 11 .LCPI7_6
28: 00000ae0 16 OBJECT LOCAL DEFAULT 11 .LCPI7_7
29: 00000af0 16 OBJECT LOCAL DEFAULT 11 .LCPI7_8
30: 00000b00 16 OBJECT LOCAL DEFAULT 11 .LCPI7_9
31: 00000b10 0 OBJECT LOCAL DEFAULT 11 .L.str
32: 00001000 0 OBJECT LOCAL DEFAULT 14 stack_bottom
33: 00005000 65536 OBJECT LOCAL DEFAULT 14 stack_top
34: 00000000 0 OBJECT LOCAL HIDDEN ABS __preinit_array_start
35: 00000000 0 OBJECT LOCAL HIDDEN ABS __preinit_array_end
36: 00000000 0 OBJECT LOCAL HIDDEN ABS __init_array_start
37: 00000000 0 OBJECT LOCAL HIDDEN ABS __init_array_end
38: 00000000 0 OBJECT LOCAL HIDDEN ABS __fini_array_start
39: 00000000 0 OBJECT LOCAL HIDDEN ABS __fini_array_end
40: 00000001 0 OBJECT LOCAL DEFAULT ABS ALIGN
41: e4524ffb 0 OBJECT LOCAL DEFAULT ABS CHECKSUM
42: 00000003 0 OBJECT LOCAL DEFAULT ABS FLAGS
43: 1badb002 0 OBJECT LOCAL DEFAULT ABS MAGIC
44: 00000002 0 OBJECT LOCAL DEFAULT ABS MEMINFO
45: 00000000 0 OBJECT LOCAL DEFAULT ABS kernel.c
46: 000000c0 14 FUNC GLOBAL DEFAULT 1 _start
47: 000000d0 32 FUNC GLOBAL DEFAULT 1 make_color
48: 000000f0 32 FUNC GLOBAL DEFAULT 1 make_vgaentry
49: 00000110 32 FUNC GLOBAL DEFAULT 1 strlen
50: 00000130 128 FUNC GLOBAL DEFAULT 1 terminal_initialize
51: 000001b0 464 FUNC GLOBAL DEFAULT 1 move_buffer_up
52: 00000380 48 FUNC GLOBAL DEFAULT 1 terminal_write_char_at
53: 000003b0 560 FUNC GLOBAL DEFAULT 1 terminal_write_char
54: 000005e0 640 FUNC GLOBAL DEFAULT 1 terminal_write_str
55: 00000860 133 FUNC GLOBAL DEFAULT 1 kernel_main
56: 00015000 4 OBJECT GLOBAL DEFAULT 14 terminal_buffer
57: 00015004 1 OBJECT GLOBAL DEFAULT 14 terminal_color
58: 00015008 4 OBJECT GLOBAL DEFAULT 14 terminal_column
59: 0001500c 4 OBJECT GLOBAL DEFAULT 14 terminal_row
60: 00001000 0 OBJECT GLOBAL DEFAULT ABS __bss_start
61: 00015010 0 OBJECT GLOBAL DEFAULT ABS __bss_end
62: 00015010 0 OBJECT GLOBAL DEFAULT ABS _end
63: 00015010 0 OBJECT GLOBAL DEFAULT ABS end
64: 00000000 0 OBJECT GLOBAL DEFAULT ABS __rela_iplt_start
65: 00000000 0 OBJECT GLOBAL DEFAULT ABS __rela_iplt_end
Code: Select all
objdump: durian.bin: Bad value
(P.S. I know that I can just build a usable gcc cross-compiler to get this up and working. I'm ultimately less interested in getting this to boot than am I understanding what went wrong in the compilation/linking process.)