pr0gma pr0gma - 1 year ago 68
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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download