I am using SDCC to produce an ELF file. I then convert this ELF file to a binary file. Sadly the output is not as expected. The output is not positioned correctly and there are strange zero length sections in the elf.
The Questions(s)
- How do I get SDCC not to produce NULL type sections?
- Can I remove the strange section?
- Can I use a different way to get elf output and a custom vector table?
Example Take a look at the minimal example bellow:
makefile:
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
}
You can see from the output bellow that the out.elf.bin output contains allot of zeros padded to the beginning. Strangely there are 0x7fff of them. The correct output is the out.ihx.bin output. There are no leading zeros and the instructions are aligned correctly.
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&|
The elf also contains strange sections:
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)
I only see one zero-length section, that is standard and required by the ELF specification: the first section is required to have
SHT_NULLtype and the other values in that section don't matter.This doesn't answer your other questions, but your subject / initial premise is simply wrong.