1

How can I make static libraries with only binary data, that is without any object code, and make that data available to a C program? Here's the build process and simplified code I'm trying to make work:

./datafile:

abcdefghij

Makefile:

libdatafile.a:
  ar [magic] datafile

main: libdatafile.a
  gcc main.c libdatafile.a -o main

main.c:

#define TEXTPTR [more magic]

int main(){
  char mystring[11];
  memset(mystring, '\0', 11);
  memcpy(TEXTPTR, mystring, 10);

  puts(mystring);
  puts(mystring);
  return 0;
}

The output I'm expecting from running main is, of course:

abcdefghijabcdefghij

My question is: what should [magic] and [more magic] be?

1
  • I should possibly add that in my actual use of this, there is more than one datafile, but just getting this far would be a huge step. Commented Mar 8, 2011 at 16:06

2 Answers 2

6

You can convert a binary file to a .o file using objcopy; the generated file then defines symbols for the start address, end address and size of the binary data.

objcopy -I binary -O elf32-little data data.o

The data can be referenced from a program via

extern char const _binary_data_start[];
extern char const _binary_data_end[];

The data lives between those two pointers (note that declaring them as pointers does not work).

The "elf32-little" part needs to be adapted according to your target platform. There are many other options for fine control over the processing.

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

5 Comments

Worth noting: the part right after _binary_ is the name of the input binary file, not the constant string data.
ISTR that there are arguments to objcopy which allows to use other names.
Hm. That's clearly the process I'm looking for, but I can't find what "elf32-little" should be. I'm on a bog-standard x86_64 system, but none of the available bfd names work, giving me "/usr/bin/ld.bfd.real: unknown architecture of input file `myfile.o' is incompatible with i386:x86-64 output" errors. Is there some link incantation I'm missing?
Ah, got it. I also need the -B i386 option to objcopy.
Just a note that the symbols seem to be named based on the input file rather than the output file. The man page is somewhat confusing on this point.
0

Put the data in global variables.

char const text[] = "abcdefghij";

Don't forget to declare text in a header. If the data is currently in a file, the FreeBSD file2c tool can convert it to C source code for you (manpage).

5 Comments

That's non-ideal, although I guess I could bodge it. The datafiles I'm using are the product of another part of the build process, so I'd need another intermediate step to get them into that format.
@regularfry: updated with a link to a tool that will do the conversion. If you don't have this tool, you can compile it or rewrite it in a scripting language pretty easily.
The type you're advising is very suboptimal. You should use `const char text[] = "abcdefghij"; Storing a pointer to the data wastes space, makes generated code less efficient, and could involve a relocation at runtime if your program is compiled as a position-indepenedent executable.
There is another issue with this - how big is the data (or, more accurately, how does the program know how big the data is). One answer might be: const size_t text_size = sizeof(text);.
By the way, one caveat to my recommended change: it actually makes things much worse if you want to store the text in a shared library rather than a static one. Unless the main program is position-independent, it will result in a copy relocation for the whole array, and the program will fail to run if the size of the array in the shared library ever changes. For these reasons your original version with the pointer may be preferable, if there's any chance of ever switching to a shared library.

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.