我正在使用 SDCC 生成 ELF 文件。然后我将此 ELF 文件转换为二进制文件。遗憾的是,输出并不如预期。输出位置不正确,并且 elf 中存在奇怪的零长度部分。
问题
示例 看一下下面的最小示例:
生成文件:
all:
@echo makefile:
@cat makefile
@echo ivt.s:
@cat ivt.s
@echo btl.c:
@cat btl.c
sdasstm8 -l -o ivt.s.rel ivt.s
sdcc -DF_CPU=16000000UL -mstm8 --std-sdcc11 -I src -c btl.c -o btl.c.rel
sdcc -DF_CPU=16000000UL -mstm8 --std-sdcc11 --out-fmt-elf -Wl-bHOME=0x8080 --noivt ivt.s.rel btl.c.rel -o out.elf
objcopy -I elf32-big -O binary out.elf out.elf.bin
sdcc -DF_CPU=16000000UL -mstm8 --std-sdcc11 --out-fmt-ihx -Wl-bHOME=0x8080 --noivt ivt.s.rel btl.c.rel -o out.ihx
objcopy -I ihex -O binary out.ihx out.ihx.bin
hexdump -C out.elf.bin | head
hexdump -C out.ihx.bin | head
ivt.s:
.module IVT
.optsdcc -mstm8
; The stm8 has a fixed ivt. it has 31 interrupts. The first is reset.
; The bootloader does not use interrupts. but the ivt is locked and protected in the UBC area.
; The application still might use interrupts so the bootloader ivt just forwards them.
; The application starts at 0x8b80 and 0x8b80 happens to the the application reset vector.
; The other vectors follow in multiples of 4.
; For simplicity the bootloader is simply compiled to an offset of 0x008080 with this ivt prepended.
; Ofcourse forwarding interrupts means every interrupt is delayed by 1 int instruction.
.area IVT (ABS)
.org 0x8000
int 0x008080 ; reset - this enters the boot loader it is aproximately 0x8000 + (31*4)
int 0x008B80 + 4 ; trap - this is the trap interrupt. application reset is at 0x08b80 so the trap is +4 after that
int 0x008B80 + 8 ; int0 - etc...
int 0x008B80 + 12 ; int1
int 0x008B80 + 16 ; int2
int 0x008B80 + 20 ; int3
int 0x008B80 + 24 ; int4
int 0x008B80 + 28 ; int5
int 0x008B80 + 32 ; int6
int 0x008B80 + 36 ; int7
int 0x008B80 + 40 ; int8
int 0x008B80 + 44 ; int9
int 0x008B80 + 48 ; int10
int 0x008B80 + 52 ; int11
int 0x008B80 + 56 ; int12
int 0x008B80 + 60 ; int13
int 0x008B80 + 64 ; int14
int 0x008B80 + 68 ; int15
int 0x008B80 + 72 ; int16
int 0x008B80 + 76 ; int17
int 0x008B80 + 80 ; int18
int 0x008B80 + 84 ; int19
int 0x008B80 + 88 ; int20
int 0x008B80 + 92 ; int21
int 0x008B80 + 96 ; int22
int 0x008B80 + 100 ; int23
int 0x008B80 + 104 ; int24
int 0x008B80 + 108 ; int25
int 0x008B80 + 112 ; int26
int 0x008B80 + 116 ; int27
int 0x008B80 + 120 ; int28
btl.c:
void main(void){
//hal_disable_interrupts();
// bla bla life is pain
}
您可以从下面的输出中看到 out.elf.bin 输出包含在开头填充的零分配。奇怪的是其中有0x7fff。正确的输出是 out.ihx.bin 输出。没有前导零并且指令正确对齐。
sdasstm8 -l -o ivt.s.rel ivt.s
sdcc -DF_CPU=16000000UL -mstm8 --std-sdcc11 -I src -c btl.c -o btl.c.rel
sdcc -DF_CPU=16000000UL -mstm8 --std-sdcc11 --out-fmt-elf -Wl-bHOME=0x8080 --noivt ivt.s.rel btl.c.rel -o out.elf
at 1: warning 117: unknown compiler option '--noivt' ignored
objcopy -I elf32-big -O binary out.elf out.elf.bin
sdcc -DF_CPU=16000000UL -mstm8 --std-sdcc11 --out-fmt-ihx -Wl-bHOME=0x8080 --noivt ivt.s.rel btl.c.rel -o out.ihx
at 1: warning 117: unknown compiler option '--noivt' ignored
objcopy -I ihex -O binary out.ihx out.ihx.bin
hexdump -C out.elf.bin | head
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00007ff0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 82 |................|
00008000 00 80 80 82 00 8b 84 82 00 8b 88 82 00 8b 8c 82 |................|
00008010 00 8b 90 82 00 8b 94 82 00 8b 98 82 00 8b 9c 82 |................|
00008020 00 8b a0 82 00 8b a4 82 00 8b a8 82 00 8b ac 82 |................|
00008030 00 8b b0 82 00 8b b4 82 00 8b b8 82 00 8b bc 82 |................|
00008040 00 8b c0 82 00 8b c4 82 00 8b c8 82 00 8b cc 82 |................|
00008050 00 8b d0 82 00 8b d4 82 00 8b d8 82 00 8b dc 82 |................|
00008060 00 8b e0 82 00 8b e4 82 00 8b e8 82 00 8b ec 82 |................|
hexdump -C out.ihx.bin | head
00000000 82 00 80 80 82 00 8b 84 82 00 8b 88 82 00 8b 8c |................|
00000010 82 00 8b 90 82 00 8b 94 82 00 8b 98 82 00 8b 9c |................|
00000020 82 00 8b a0 82 00 8b a4 82 00 8b a8 82 00 8b ac |................|
00000030 82 00 8b b0 82 00 8b b4 82 00 8b b8 82 00 8b bc |................|
00000040 82 00 8b c0 82 00 8b c4 82 00 8b c8 82 00 8b cc |................|
00000050 82 00 8b d0 82 00 8b d4 82 00 8b d8 82 00 8b dc |................|
00000060 82 00 8b e0 82 00 8b e4 82 00 8b e8 82 00 8b ec |................|
00000070 82 00 8b f0 82 00 8b f4 82 00 8b f8 00 00 00 00 |................|
00000080 82 00 80 87 cc 80 a4 ae 00 00 27 07 72 4f 00 00 |..........'.rO..|
00000090 5a 26 f9 ae 00 00 27 09 d6 80 a3 d7 00 00 5a 26 |Z&....'.......Z&|
精灵还包含奇怪的部分:
readelf -S out.elf
There are 10 section headers, starting at offset 0x2c5:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] IVT0 PROGBITS 00008000 000034 00007c 00 A 0 0 0
[ 2] SSEG PROGBITS 00000001 0000b0 000001 00 A 0 0 0
[ 3] HOME PROGBITS 00008080 0000b1 000007 00 A 0 0 0
[ 4] GSINIT PROGBITS 00008087 0000b8 00001a 00 A 0 0 0
[ 5] GSFINAL PROGBITS 000080a1 0000d2 000003 00 A 0 0 0
[ 6] CODE PROGBITS 000080a4 0000d5 000001 00 A 0 0 0
[ 7] .symtab SYMTAB 00000000 0000d6 0000a0 10 8 1 0
[ 8] .strtab STRTAB 00000000 000176 000051 00 0 0 0
[ 9] .shstrtab STRTAB 00000000 0001c7 00003e 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
SDCC 生成带有 NULL 类型部分的 elf 输出
精灵中有奇怪的零长度部分。
我只看到一个零长度部分,即 standard 并且是 ELF 规范所要求的:第一部分是 required 具有
SHT_NULL
类型,该部分中的其他值并不重要。
这并不能回答你的其他问题,但你的主题/最初的前提是完全错误的。