pr0gma pr0gma - 1 year ago 46
C Question

Referencing external global variables fails miserably

I'm trying to embed binary file

into executable
at linking time, on Linux (64bit).

is a simple text file...

Hi, I'm a text file in plain ASCII.

...which is turned into a relocatable object with
ld -r -bbinary -oB.o B
. Its
reports three global variables, the names of which are pretty self-explanatory:

  1. _binary_B_start

  2. _binary_B_end

  3. _binary_B_size

This is

#include <stdio.h>

extern const size_t _binary_B_size;

int main(int argc, char * * argv)
printf("size: %zu\n", _binary_B_size);
return 0;

...which is compiled and linked with
gcc -oA A.c B.o
Unfortunately, as soon as executable
tries to access
, it gets abruptly terminated with a

What am I doing wrong?

Answer Source

Apparently you are misunderstanding the semantics of _binary_B_size. It is not a size_t lvalue, as you seem to believe. It is a zero size absolutely positioned section (a label), whose address equals the size of your binary blob data. Try objdump -t on your file an you will see *ABS* in the corresponding column.

So the proper usage would be

extern unsigned char _binary_B_size[];

int main()
    printf("size: %zu\n", (size_t) _binary_B_size);

You can also use end - start method and get the same result

extern unsigned char _binary_B_start[];
extern unsigned char _binary_B_end[];

int main()
    printf("size: %zu\n", (size_t) (_binary_B_end - _binary_B_start));

Basically, the main consideration here is that there's no reason for _binary_B_size to be a size_t lvalue. It is effectively a constant with value pre-determined at compile time. There's no reason for it to occupy storage. And what you see above is one way to encode such constant values in object files.