linking arbitrary data using GCC ARM toolchain

我们两清 提交于 2019-11-27 19:32:42

The following example works for me:

$ dd if=/dev/urandom of=binblob bs=1024k count=1
$ objcopy -I binary -O elf32-little binblob binblob.o
$ file binblob.o
binblob.o: ELF 32-bit LSB relocatable, no machine, version 1 (SYSV), not stripped
$ nm  -S -t d binblob.o
0000000001048576 D _binary_binblob_end
0000000001048576 A _binary_binblob_size
0000000000000000 D _binary_binblob_start

I.e. no need to specify the BFD arch for binary data (it's only useful / necessary for code). Just say "the input is binary", and "the output is ...", and it'll create you the file. Since pure binary data isn't architecture-specific, all you need to tell it is whether the output is 32bit (elf32-...) or 64bit (elf64-...), and whether it's little endian / LSB (...-little, as on ARM/x86) or big endian / MSB (...-big, as e.g. on SPARC/m68k).

Edit: Clarification on the options for objcopy:

  • the usage of the -O ... option controls:
    • bit width (whether the ELF file will be 32-bit or 64-bit)
    • endianness (whether the ELF file will be LSB or MSB)
  • the usage of the -B ... option controls the architecture the ELF file will request

You have to specifiy the -O ... but the -B ... is optional. The difference is best illustrated by a little example:

$ objcopy -I binary -O elf64-x86-64 foobar foobar.o
$ file foobar.o
foobar.o: ELF 64-bit LSB relocatable, no machine, version 1 (SYSV), not stripped

$ objcopy -I binary -O elf64-x86-64 -B i386 foobar foobar.o
$ file foobar.o
foobar.o: ELF 64-bit LSB relocatable, AMD x86-64, version 1 (SYSV), not stripped

I.e. just the output format specifier elf64-x86-64 doesn't tie the generated binary to a specific architecture (that's why file says no machine). The usage if -B i386 does so - and in that case, you're told this is now AMD x86-64.

The same would apply to ARM; -O elf32-little vs. -O elf32-littlearm -B arm is that in the former case, you end up with a ELF 32-bit LSB relocatable, no machine, ... while in the latter, it'll be an ELF 32-bit LSB relocatable, ARM....

There's some interdependency here as well; you have to use -O elf{32|64}-<arch> (not the generic elf{32|64}-{little|big}) output option to be able to make -B ... recognized.

See objcopy --info for the list of ELF formats / BFD types that your binutils can deal with.

Another approach might be to use xxd.

xxd -i your_data your_data.c

In the file you'll get two symbols unsigned char your_data[] and unsigned int your_data_len. First one will be a huge array containing your data, second one will be the lenght of that array.

Compilation of created C file might be time taking, so if you are using a build system / Makefile handle it properly avoiding unnecessary recompilations.

xxd should be part of vim (vim-common) package for your Linux distribution.

A quick way to do it would be to put the data in its own .c file (.c not .h) so that it becomes a .o by itself then in the linker script you can define a specific memory space and section entry for that .o file and put it wherever you want.

MEMORY
{
...
BOB : ORIGIN = 0x123400, length = 0x200
...
}
SECTIONS
{
...
TED : { mydata.o } > BOB
...
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!