How can I get arm-none-eabi-objcopy to copy/translate my .axf file into a .bin suitable for flashing to the device with lm4tools?
I have a ~20KB .axf file compiled and linked with arm-none-eabi-*. For anyone interested, this is with the Stellaris Launchpad.
I'm trying to modify the example provided with the stellaris-launchpad-template-gcc project to compile with C++ code. I've managed to get it to produce a .axf file in elf32-littlearm format (according to the .lst file), however when I try to do
arm-none-eabi-objcopy -v -O binary main.axf foo.bin
to translate it into a programmable file, the .bin file output has a size of 0 bytes. This question describes a similar problem. I'm confident the .axf file is complete, so why isn't my .bin file being populated with anything? If I remove -O binary, the file is copied fine. The directory is writeable and all permissions are fine. I've tried searching both on SO and the rest of the internet with various terms, all of which turned up nothing of use. It seems nobody's had this problem before.
Running arm-none-eabi-objdump -D main.axf yields a dump of the file in what appears to be assembler:
main.axf: file format elf32-littlearm
Disassembly of section .debug_info:
00000000 <_end_text>:
0: 00000082 andeq r0, r0, r2, lsl #1
4: 00000002 andeq r0, r0, r2
8: 01040000 mrseq r0, (UNDEF: 4)
c: 00000057 andeq r0, r0, r7, asr r0
10: 00000c04 andeq r0, r0, r4, lsl #24
14: 00002300 andeq r2, r0, r0, lsl #6
...
28: 08010200 stmdaeq r1, {r9}
2c: 00000015 andeq r0, r0, r5, lsl r0
30: 00410103 subeq r0, r1, r3, lsl #2
34: 32010000 andcc r0, r1, #0
38: 00000048 andeq r0, r0, r8, asr #32
...
48: 69050404 stmdbvs r5, {r2, sl}
4c: 0500746e streq r7, [r0, #-1134] ; 0x46e
50: 00000001 andeq r0, r0, r1
54: 46430100 strbmi r0, [r3], -r0, lsl #2
...
Is this correct, or am I not even compiling properly, seeing as this appears to be some kind of assembler?
Some info about the .axf file:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 20372 (bytes into file)
Flags: 0x5000000, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 14
Section header string table index: 11
After running arm-none-eabi-readelf -lS main.axf, no program headers are returned:
There are 14 section headers, starting at offset 0x4f94:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .debug_info PROGBITS 00000000 000034 0019a6 00 0 0 1
[ 2] .debug_abbrev PROGBITS 00000000 0019da 0005ad 00 0 0 1
[ 3] .debug_loc PROGBITS 00000000 001f87 001796 00 0 0 1
[ 4] .debug_aranges PROGBITS 00000000 003720 000088 00 0 0 8
[ 5] .debug_ranges PROGBITS 00000000 0037a8 000130 00 0 0 1
[ 6] .debug_line PROGBITS 00000000 0038d8 00077d 00 0 0 1
[ 7] .debug_str PROGBITS 00000000 004055 000aa8 01 MS 0 0 1
[ 8] .comment PROGBITS 00000000 004afd 00003a 01 MS 0 0 1
[ 9] .ARM.attributes ARM_ATTRIBUTES 00000000 004b37 000039 00 0 0 1
[10] .debug_frame PROGBITS 00000000 004b70 000388 00 0 0 4
[11] .shstrtab STRTAB 00000000 004ef8 00009a 00 0 0 1
[12] .symtab SYMTAB 00000000 0051c4 000200 10 13 18 4
[13] .strtab STRTAB 00000000 0053c4 0000e0 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no program headers in this file.
Related
First I synthesized a CPU that supports RISCV32IM using verilog, but I can't test if the CPU is working properly. I hope a compiler(such as GCC) can generate instructions to help me test, but normal compilers can only generate EXE files that require the operating system. Obviously, my FPGA can't do this.
I only need a series of RISCV32IM instructions that can run on FPGA and can implement the corresponding functions. If I can, I want his first instruction to be the program entry, which will save me energy.
Of course you can it is somewhat trivial, you did or someone selected baremetal tab for you, it is a baremetal program I assume you want to run.
so.s
lui x2,0x22222
lui x3,0x33333
lui x4,0x44444
lui x5,0x55555
lui x6,0x66666
j .
riscv32-none-elf-as so.s -o so.o
riscv32-none-elf-objdump -d -Mnumeric so.o
so.o: file format elf32-littleriscv
Disassembly of section .text:
00000000 <.text>:
0: 22222137 lui x2,0x22222
4: 333331b7 lui x3,0x33333
8: 44444237 lui x4,0x44444
c: 555552b7 lui x5,0x55555
10: 66666337 lui x6,0x66666
14: 0000006f j 14 <.text+0x14>
now you can just
riscv32-none-elf-ld -Ttext=0 so.o -o so.elf
riscv32-none-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000000000
riscv32-none-elf-objdump -d -Mnumeric so.elf
so.elf: file format elf32-littleriscv
Disassembly of section .text:
00000000 <__BSS_END__-0x1018>:
0: 22222137 lui x2,0x22222
4: 333331b7 lui x3,0x33333
8: 44444237 lui x4,0x44444
c: 555552b7 lui x5,0x55555
10: 66666337 lui x6,0x66666
14: 0000006f j 14 <__BSS_END__-0x1004>
but at least with arm and not sure about other binutils targets there are very very old, longstanding bugs in the tools when used like that (get gaps in the binary, etc). So
memmap
MEMORY
{
hello : ORIGIN = 0x00000000, LENGTH = 0x3000
}
SECTIONS
{
.text : { *(.text*) } > hello
.rodata : { *(.rodata*) } > hello
.bss : { *(.bss*) } > hello
.data : { *(.data*) } > hello
}
and
riscv32-none-elf-ld -T memmap so.o -o so.elf
riscv32-none-elf-objdump -d -Mnumeric so.elf
so.elf: file format elf32-littleriscv
Disassembly of section .text:
00000000 <.text>:
0: 22222137 lui x2,0x22222
4: 333331b7 lui x3,0x33333
8: 44444237 lui x4,0x44444
c: 555552b7 lui x5,0x55555
10: 66666337 lui x6,0x66666
14: 0000006f j 14 <.text+0x14>
so now you have an elf (or exe or whatever) you can
riscv32-none-elf-objcopy so.elf -O binary so.bin
hexdump -C so.bin
00000000 37 21 22 22 b7 31 33 33 37 42 44 44 b7 52 55 55 |7!"".1337BDD.RUU|
00000010 37 63 66 66 6f 00 00 00 |7cffo...|
00000018
or
riscv32-none-elf-objcopy --srec-forceS3 so.elf -O srec so.srec
cat so.srec
S00A0000736F2E7372656338
S3150000000037212222B731333337424444B75255554C
S30D00000010376366666F0000000D
S70500000000FA
or
riscv32-none-elf-objcopy so.elf -O ihex so.ihex
cat so.ihex
:1000000037212222B731333337424444B752555552
:08001000376366666F00000013
and so on.
Then you can also...
so.s
lui x2,0x00002
jal notmain
j .
.globl hello
hello:
ret
notmain.c
void hello ( unsigned int );
void notmain ( void )
{
unsigned int r;
for (r=0;r<32;r++)
{
hello(r);
}
}
build with commands like these
riscv32-none-elf-as -march=rv32im so.s -o so.o
riscv32-none-elf-gcc -O2 -c -fomit-frame-pointer -march=rv32im -mabi=ilp32 notmain.c -o notmain.o
riscv32-none-elf-ld -T memmap so.o notmain.o -o so.elf
riscv32-none-elf-objdump -D -Mnumeric so.elf
riscv32-none-elf-objcopy -O binary so.elf so.bin
giving
Disassembly of section .text:
00000000 <hello-0xc>:
0: 00002137 lui x2,0x2
4: 00c000ef jal x1,10 <notmain>
8: 0000006f j 8 <hello-0x4>
0000000c <hello>:
c: 00008067 ret
00000010 <notmain>:
10: ff010113 addi x2,x2,-16 # 1ff0 <notmain+0x1fe0>
14: 00812423 sw x8,8(x2)
18: 00912223 sw x9,4(x2)
1c: 00112623 sw x1,12(x2)
20: 00000413 li x8,0
24: 02000493 li x9,32
28: 00040513 mv x10,x8
2c: 00140413 addi x8,x8,1
30: fddff0ef jal x1,c <hello>
34: fe941ae3 bne x8,x9,28 <notmain+0x18>
38: 00c12083 lw x1,12(x2)
3c: 00812403 lw x8,8(x2)
40: 00412483 lw x9,4(x2)
44: 01010113 addi x2,x2,16
48: 00008067 ret
and you can use the .bin file or .srec or whatever you prefer.
basic bare metal stuff...gnu works great for this, very easy to use. llvm/clang is more complicated to figure out but technically will work as well.
I changed the line to
for (r=0;r<3200;r++)
because it was unrolling the loop. I gave up trying to keep track of the ever changing generic llvm tool command line options, so now I build specific for riscv32 and can then use the generic program names as cross tools...
clang -c -march=rv32im so.s -o so.o
clang -c -O2 -march=rv32im notmain.c -o notmain.o
ld.lld -T memmap so.o notmain.o -o so.elf
llvm-objcopy -O binary so.elf so.bin
llvm-objdump -D -Mnumeric so.elf
so.elf: file format elf32-littleriscv
Disassembly of section .text:
00000000 <.text>:
0: 37 21 00 00 lui x2, 2
4: ef 00 c0 00 jal 0x10 <notmain>
8: 6f 00 00 00 j 0x8 <.text+0x8>
0000000c <hello>:
c: 67 80 00 00 ret
00000010 <notmain>:
10: 13 01 01 ff addi x2, x2, -16
14: 23 26 11 00 sw x1, 12(x2)
18: 23 24 81 00 sw x8, 8(x2)
1c: 23 22 91 00 sw x9, 4(x2)
20: 13 04 00 00 li x8, 0
24: 37 15 00 00 lui x10, 1
28: 93 04 05 c8 addi x9, x10, -896
0000002c <.LBB0_1>:
2c: 13 05 04 00 mv x10, x8
30: ef f0 df fd jal 0xc <hello>
34: 13 04 14 00 addi x8, x8, 1
38: e3 1a 94 fe bne x8, x9, 0x2c <.LBB0_1>
3c: 83 20 c1 00 lw x1, 12(x2)
40: 03 24 81 00 lw x8, 8(x2)
44: 83 24 41 00 lw x9, 4(x2)
48: 13 01 01 01 addi x2, x2, 16
4c: 67 80 00 00 ret
Here is the output of readelf -a test.elf
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 0000000040000000 010000 00007c 00 AX 0 0 8
[ 2] .rodata PROGBITS 0000000040000080 010080 000016 00 A 0 0 8
[ 3] .debug_info PROGBITS 0000000000000000 010096 0000af 00 0 0 1
[ 4] .debug_abbrev PROGBITS 0000000000000000 010145 000086 00 0 0 1
[ 5] .debug_aranges PROGBITS 0000000000000000 0101cb 000030 00 0 0 1
The .text section starts at 0x40000000. With debugger, I could see the PC value is starting from 0x40000000, and the code there is the startup.s which is meant to be there. But I'm not sure why the value 'Off' for that section is 0x10000. What does this 'Off' value mean? Isn't Address and Size enough for a section?
The Offset field denotes the location of that segment in the file. Here the .text segment starts at location 0x10000 and is 0x7c bytes long, then next segment .rodata starts at 0x10080 etc.
I have a .i file which I have compiled but not linked using the SiFive risc-v compiler as follows:
../riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc clock.i
However when I do a readelf -S on the compiled object file the .text section is 0 bytes:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .text.getTime PROGBITS 00000000 000034 00003a 00 AX 0 0 2
[ 5] .rela.text.ge RELA 00000000 000484 0000c0 0c I 18 4 4
[ 6] .text.timeGap PROGBITS 00000000 00006e 00002e 00 AX 0 0 2
[ 7] .rela.text.ti RELA 00000000 000544 000024 0c I 18 6 4
[ 8] .text.applyTO PROGBITS 00000000 00009c 000038 00 AX 0 0 2
[ 9] .rela.text.ap RELA 00000000 000568 0000c0 0c I 18 8 4
[10] .text.clearTO PROGBITS 00000000 0000d4 000038 00 AX 0 0 2
[11] .rela.text.cl RELA 00000000 000628 0000c0 0c I 18 10 4
[12] .rodata.getTi PROGBITS 00000000 00010c 00000c 01 AMS 0 0 4
[13] .rodata.__func__. PROGBITS 00000000 000118 00000c 00 A 0 0 4
[14] .rodata.__func__. PROGBITS 00000000 000124 00000c 00 A 0 0 4
[15] .rodata.__func__. PROGBITS 00000000 000130 00000c 00 A 0 0 4
[16] .comment PROGBITS 00000000 00013c 000029 01 MS 0 0 1
[17] .riscv.attributes LOPROC+0x3 00000000 000165 00001f 00 0 0 1
[18] .symtab SYMTAB 00000000 000184 000240 10 19 31 4
[19] .strtab STRTAB 00000000 0003c4 0000be 00 0 0 1
[20] .shstrtab STRTAB 00000000 0006e8 000100 00 0 0 1
If I do a size on the compiled object file I get a size of 264 bytes:
text data bss dec hex filename
264 0 0 264 108 clock.o
If I do an nm --print-size I get the following:
U __assert_func
00000000 0000000c r __func__.3507
00000000 0000000c r __func__.3518
00000000 0000000c r __func__.3522
0000000c t .L11
00000036 t .L12
00000034 t .L14
00000036 t .L18
00000034 t .L2
00000034 t .L20
00000032 t .L3
0000001e t .L8
00000000 r .LANCHOR0
00000000 r .LANCHOR1
00000000 r .LANCHOR2
00000000 r .LC0
00000004 r .LC1
00000000 00000038 T applyTO
00000000 00000038 T clearTO
00000000 0000003a T getTime
00000000 0000002e T timeGap
Which to me the size would be 0x38 + 0x38 + 0x3A + 0x2E = 0xD8 (216) bytes.
How can I calculate the size of a compiled object file?
Your object file is compiled with -ffunction-sections, a special flag which allocates each function to it's dedicated section. You can see individual .texts for each function in readelf's output:
[ 4] .text.getTime PROGBITS 00000000 000034 00003a 00 AX 0 0 2
...
[ 6] .text.timeGap PROGBITS 00000000 00006e 00002e 00 AX 0 0 2
...
To get full code size you'll need to sum sizes for each section starting with ".text". A Perl one-liner:
$ readelf ... | perl -ne 'if(/ \.text/) { s/^.*\] *//; $sz += hex((split(/ +/))[4]); print "$sz\n"; }' 0
58
104
160
216 <-- Full size
There appear to be some similar-looking long alphanumeric strings that commonly occur in Mach-O 64 bit executables and ELF 64-bit LSB executables among other symbols that are not alphanumeric:
cat /bin/bash | grep -c "AWAVAUATSH"
has 181 results, and
cat /usr/bin/gzip | grep -c "AWAVAUATSH"
has 9 results.
What are these strings?
Interesting question. Since I didn't know the answer, here are the steps I took to figure it out:
Where in the file does the string occur?
strings -otx /bin/gzip | grep AWAVAUATUSH
35e0 AWAVAUATUSH
69a0 AWAVAUATUSH
7920 AWAVAUATUSH
8900 AWAVAUATUSH
92a0 AWAVAUATUSH
Which section is that in?
readelf -WS /bin/gzip
There are 28 section headers, starting at offset 0x16860:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 0000000000400238 000238 00001c 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 000254 000020 00 A 0 0 4
[ 3] .note.gnu.build-id NOTE 0000000000400274 000274 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 000298 000038 00 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002d0 0002d0 000870 18 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400b40 000b40 000360 00 A 0 0 1
[ 7] .gnu.version VERSYM 0000000000400ea0 000ea0 0000b4 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000400f58 000f58 000080 00 A 6 1 8
[ 9] .rela.dyn RELA 0000000000400fd8 000fd8 000090 18 A 5 0 8
[10] .rela.plt RELA 0000000000401068 001068 0007e0 18 A 5 12 8
[11] .init PROGBITS 0000000000401848 001848 00001a 00 AX 0 0 4
[12] .plt PROGBITS 0000000000401870 001870 000550 10 AX 0 0 16
[13] .text PROGBITS 0000000000401dc0 001dc0 00f1ba 00 AX 0 0 16
[14] .fini PROGBITS 0000000000410f7c 010f7c 000009 00 AX 0 0 4
... etc.
From above output, we see that all instances of AWAVAUATUSH are in .text section (which covers [0x1dc0, 0x10f7a) offsets of the file.
Since this is .text, we expect to find executable instructions there. The address we are interested in is 0x401dc0 (.text address) + 0x35e0 (offset of AWAVAUATUSH in the file) - 0x1dc0 (offset of .text in the file) == 0x4035e0.
First, let's check that the above arithmetic is correct:
gdb -q /bin/gzip
(gdb) x/s 0x4035e0
0x4035e0: "AWAVAUATUSH\203\354HdH\213\004%("
Yes, it is. Next, what are the instructions there?
(gdb) x/20i 0x4035e0
0x4035e0: push %r15
0x4035e2: push %r14
0x4035e4: push %r13
0x4035e6: push %r12
0x4035e8: push %rbp
0x4035e9: push %rbx
0x4035ea: sub $0x48,%rsp
0x4035ee: mov %fs:0x28,%rax
0x4035f7: mov %rax,0x38(%rsp)
0x4035fc: xor %eax,%eax
0x4035fe: mov 0x213363(%rip),%rax # 0x616968
0x403605: mov %rdi,(%rsp)
0x403609: mov %rax,0x212cf0(%rip) # 0x616300
0x403610: cmpb $0x7a,(%rax)
0x403613: je 0x403730
0x403619: mov $0x616300,%ebx
0x40361e: mov (%rsp),%rdi
0x403622: callq 0x4019f0 <strlen#plt>
0x403627: cmp $0x20,%eax
0x40362a: mov %rax,0x8(%rsp)
These indeed look like normal executable instructions. What is the opcode of push %r15? This table shows that 0x41, 0x57 is indeed push %r15, and these opcodes just happen to spell AW in ASCII. Similarly, push %r14 is encoded as 0x41, 0x56, which just happens spell AV. Etc.
P.S. My version of gzip is fully stripped, which is why GDB shows no symbols in the above disassembly. If I use a non-stripped version instead, I see:
strings -o -tx gzip | grep AWAVAUATUSH | head -1
6be0 AWAVAUATUSH
readelf -WS gzip | grep text
[13] .text PROGBITS 0000000000401b00 001b00 00d102 00 AX 0 0 16
So the string is still in .text.
gdb -q ./gzip
(gdb) p/a 0x0000000000401b00 + 0x6be0 - 0x001b00
$1 = 0x406be0 <inflate_dynamic>
(gdb) disas/r 0x406be0
Dump of assembler code for function inflate_dynamic:
0x0000000000406be0 <+0>: 41 57 push %r15
0x0000000000406be2 <+2>: 41 56 push %r14
0x0000000000406be4 <+4>: 41 55 push %r13
0x0000000000406be6 <+6>: 41 54 push %r12
0x0000000000406be8 <+8>: 55 push %rbp
0x0000000000406be9 <+9>: 53 push %rbx
0x0000000000406bea <+10>: 48 81 ec 38 05 00 00 sub $0x538,%rsp
...
Now you can clearly see the ASCII 0x4157415641554154... sequence of opcodes.
P.P.S. The original question asks about AWAVAUATSH, which does appear in my Mach-O bash and gzip, but not in Linux ones. Conversely, AWAVAUATUSH does not appear in my Mach-O binaries.
The answer is however the same. The AWAVAUATSH sequence is the same as AWAVAUATUSH, but with push %rbp omitted.
P.P.P.S Here are some other "fun" strings of the same nature:
strings /bin/bash | grep '^A.A.A.' | sort | uniq -c | sort -nr | head
44 AWAVAUATUSH
27 AVAUATUSH
16 AWAVAUA
15 AVAUATUH
14 AWAVAUI
14 AWAVAUATUH
12 AWAVAUATI
8 AWAVAUE1
8 AVAUATI
6 AWAVAUATU
I have a C struct that is compiled by GCC into a special section and placed at the beginning of an output binary via a linker script. It contains file metadata, including a magic value at the beginning.
Here's a simplified example using just a string as the struct.
const char __magic_value[9] __attribute__((section(".the_header"))) = "MAGICVAL";
GCC places this value into its own section, as we can see with readelf -S:
There are 10 section headers, starting at offset 0x190:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .the_header PROGBITS 00000000 000034 000009 00 A 0 0 1
[ 5] .comment PROGBITS 00000000 00003d 00001e 01 MS 0 0 1
[ 6] .ARM.attributes ARM_ATTRIBUTES 00000000 00005b 000033 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 00008e 000051 00 0 0 1
[ 8] .symtab SYMTAB 00000000 0000e0 000090 10 9 8 4
[ 9] .strtab STRTAB 00000000 000170 00001e 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
(Note section #4.)
Now, if I specify -flto to the GCC invocation, this section is no longer emitted!
There are 19 section headers, starting at offset 0x730:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
[ 4] .gnu.lto_.profile PROGBITS 00000000 000034 00000f 00 E 0 0 1
[ 5] .gnu.lto_.icf.93e PROGBITS 00000000 000043 000017 00 E 0 0 1
[ 6] .gnu.lto_.jmpfunc PROGBITS 00000000 00005a 00000f 00 E 0 0 1
[ 7] .gnu.lto_.inline. PROGBITS 00000000 000069 00000f 00 E 0 0 1
[ 8] .gnu.lto_.purecon PROGBITS 00000000 000078 00000f 00 E 0 0 1
[ 9] .gnu.lto_.symbol_ PROGBITS 00000000 000087 000022 00 E 0 0 1
[10] .gnu.lto_.refs.93 PROGBITS 00000000 0000a9 00000f 00 E 0 0 1
[11] .gnu.lto_.decls.9 PROGBITS 00000000 0000b8 000239 00 E 0 0 1
[12] .gnu.lto_.symtab. PROGBITS 00000000 0002f1 00001d 00 E 0 0 1
[13] .gnu.lto_.opts PROGBITS 00000000 00030e 0000e8 00 E 0 0 1
[14] .comment PROGBITS 00000000 0003f6 00001e 01 MS 0 0 1
[15] .ARM.attributes ARM_ATTRIBUTES 00000000 000414 000033 00 0 0 1
[16] .shstrtab STRTAB 00000000 000447 00018c 00 0 0 1
[17] .symtab SYMTAB 00000000 0005d4 000130 10 18 17 4
[18] .strtab STRTAB 00000000 000704 00002c 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
My linker script does not find the .the_header section, resulting in a corrupt binary.
I have tried specifying __attribute__((used)) for the header variable, with no effect.
Here's the relevant part of the linker script:
ENTRY(main)
MEMORY
{
APP (rwx) : ORIGIN = 0, LENGTH = 65536
}
SECTIONS
{
.header :
{
KEEP(*(.the_header))
} > APP
...
}
How do I tell GCC to emit .the_header into the final binary when using link time optimization and the above linker script snippet?