2

I have a project that requires a bunch of graphic files in the executable. Since there is no file system at the target I cant just use the fopen function. One way would converting the file content to a C source code that contains the variable definition like this

unsigned char file1_content[] = {
   0x01, 0x02, ...
};

It's cumbersome to build such files even with a converter tool.

Is there any way to add binary files to the rdata section while specifying a variable name for each file? I think about using the linker script for this but didn't find a way.

2 Answers 2

2

It's not particularly cumbersome with a tool, and that's the classic solution. Search for "bin2c" to find some.

You simply need to include these "asset-building" steps in your build process, i.e. call the tool from the Makefile. This also means that the tool is only run if the source data has changed, which is nice.

At least the GNU linker (LD) seems capable of placing files in the sections of the output file (see the Section Placement documentation, like so:

.data : { afile.o bfile.o cfile.o }

But this sounds quite cumbersome, and it needs you to think about the sections of your executable file which often a bit too low-level. Also, it seems to require the input(s) to be object files, which kind of makes the problem circular since a generic binary asset isn't a linker-compatible object file.

I would recommend going with the bin2c approach.

Sign up to request clarification or add additional context in comments.

Comments

1

You may use linker option --format along with -Wl, to pass it to linker, like:

gcc -Wl,--format=binary -Wl,myfile.bin -Wl,--format=default

Last setting format to default allows you to switch linker back to standard input format.

You may access your binary resources from sources via simple _binary_myfile_bin_start assembler symbol (for myfile.bin, for xxx.yyy it will be _binary_xxx_yyy_start and _binary_xxx_yyy_end) like:

extern uint8_t data[] asm("_binary_myfile_bin_start");

And next use data. It is much better then do objcopy by yourself, or use resource hacking.

UPD: Expanding with a little example -- main outputs first four bytes of its own object file:

#include "stdio.h"
#include "stdint.h"

extern uint8_t data[] asm("_binary_main_o_start");

int
main(void)
{
  fprintf(stdout, "0x%x, 0x%x, 0x%x, 0x%x\n", data[0], data[1], data[2], data[3]);
  return 0;
}

Now compile an run:

$ gcc -o main.o -c main.c 
$ gcc -o main main.o -Wl,--format=binary -Wl,main.o -Wl,--format=default
$ ./main 
0x7f, 0x45, 0x4c, 0x46

3 Comments

How does I get the xxx_end symbol or the size of the binary?
End of data is marked by linker as _binary_xxx_yyy_end and size is marked as _binary_xxx_yyy_size
Can I create a library (.ar) that contain elements build from the binary files? Finally I would like to link this library of binaries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.