Embedding binary blobs using gcc mingw - c

I am trying to embed binary blobs into an exe file. I am using mingw gcc.
I make the object file like this:
ld -r -b binary -o binary.o input.txt
I then look objdump output to get the symbols:
objdump -x binary.o
And it gives symbols named:
_binary_input_txt_start
_binary_input_txt_end
_binary_input_txt_size
I then try and access them in my C program:
#include <stdlib.h>
#include <stdio.h>
extern char _binary_input_txt_start[];
int main (int argc, char *argv[])
{
char *p;
p = _binary_input_txt_start;
return 0;
}
Then I compile like this:
gcc -o test.exe test.c binary.o
But I always get:
undefined reference to _binary_input_txt_start
Does anyone know what I am doing wrong?

In your C program remove the leading underscore:
#include <stdlib.h>
#include <stdio.h>
extern char binary_input_txt_start[];
int main (int argc, char *argv[])
{
char *p;
p = binary_input_txt_start;
return 0;
}
C compilers often (always?) seem to prepend an underscore to extern names. I'm not entirely sure why that is - I assume that there's some truth to this wikipedia article's claim that
It was common practice for C compilers to prepend a leading underscore to all external scope program identifiers to avert clashes with contributions from runtime language support
But it strikes me that if underscores were prepended to all externs, then you're not really partitioning the namespace very much. Anyway, that's a question for another day, and the fact is that the underscores do get added.

From ld man page:
--leading-underscore
--no-leading-underscore
For most targets default symbol-prefix is an underscore and is defined in target's description. By this option it is possible to disable/enable the default underscore symbol-prefix.
so
ld -r -b binary -o binary.o input.txt --leading-underscore
should be solution.

I tested it in Linux (Ubuntu 10.10).
Resouce file:
input.txt
gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 [generates ELF executable, for Linux]
Generates symbol _binary__input_txt_start.
Accepts symbol _binary__input_txt_start (with underline).
i586-mingw32msvc-gcc (GCC) 4.2.1-sjlj (mingw32-2) [generates PE executable, for Windows]
Generates symbol _binary__input_txt_start.
Accepts symbol binary__input_txt_start (without underline).

Apparently this feature is not present in OSX's ld, so you have to do it totally differently with a custom gcc flag that they added, and you can't reference the data directly, but must do some runtime initialization to get the address.
So it might be more portable to make yourself an assembler source file which includes the binary at build time, a la this answer.

Related

No output from split up source, but no warnings either, when omitting an included file

I ran into an issue invoking gcc where if I omit a library .c file, I got no output from the binary (unexpected behavior change) but since this is a missing dependency, I kind of expected the compile to fail (or at least warn)...
Example for this issue is from Head First C page 185 (but is not errata, see my compile mis-step below):
encrypt.h:
void encrypt(char *message);
encrypt.c:
#include "encrypt.h"
void encrypt(char *message)
{
// char c; errata
while (*message) {
*message = *message ^ 31;
message++;
}
}
message_hider.c:
#include <stdio.h>
#include "encrypt.h"
int main() {
char msg[80];
while (fgets(msg, 80, stdin)) {
encrypt(msg);
printf("%s", msg);
}
}
NOW, everything works fine IF I faithfully compile as per exercise instruction:
gcc message_hider.c encrypt.c -o message_hider
... but bad fortune led me to compile only the main .c file, like so:
$ gcc message_hider.c -o message_hider
This surprisingly successfully builds, even if I added -Wall -Wextra -Wshadow -g.
Also surprisingly, it silently fails, with no output from encrypt() function:
$ ./message_hider < ./encrypt.h
$
my gcc is:
$ /usr/bin/gcc --version
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Mindful that even with a Makefile, I could "still" end up with a missing .c file due to a mistake in the recipe.
Q: Is it possible to force a hard error if I forget to tell gcc about a .c file?
As I noted in a (misspelled) comment:
There is probably a function encrypt() in the system library.
On a Mac, man -s 3 encrypt shows:
CRYPT(3) BSD Library Functions Manual CRYPT(3)
NAME
crypt, encrypt, setkey -- DES encryption
SYNOPSIS
#include <unistd.h>
char *
crypt(const char *key, const char *salt);
void
encrypt(char *block, int edflag);
#include <stdlib.h>
void
setkey(const char *key);
…
The encrypt() and setkey() functions are part of POSIX, so they'll be available on most POSIX-like systems. Curiously, as shown in the manual page extract, the functions are declared in separate headers — <unistd.h> for encrypt() and
<stdlib.h> for setkey(). There's probably a good (enough) historical reason for the disconnect.
You should have received a compiler warning about the function being undeclared — if you didn't, you are presumably compiling using the C90 standard. That is very old and should not still be being taught; you need to be learning C11 or C18 (almost the same).
Since C99, the C standard requires functions to be declared before use — you can define a static function without pre-declaring it, but all other functions (except main()) should be declared before they are used or defined. You can use GCC compiler warning options such as -Wmissing-prototypes -Wstrict-prototypes (along with -Wold-style-declaration and -Wold-style-definition) to trigger warnings. Of these, -Wold-style-declaration is enabled by -Wextra (and none by -Wall). Be aware: as noted in the comments, clang does not support -Wold-style-declaration though true GCC (not Apple's clang masquerading as gcc) does support it.

OCaml as C library, hello world example

I wish to call OCaml code through C++ by compiling OCaml to a static or shared library that contains a C interface. This page seems to explain how to create a C interface for OCaml. But how do I do it and compile it? And how do I obtain the .h file to load in my C++ code?
Also, could someone explain to be this part:
The OCaml runtime system comprises three main parts: the bytecode
interpreter, the memory manager, and a set of C functions that
implement the primitive operations. Some bytecode instructions are
provided to call these C functions, designated by their offset in a
table of functions (the table of primitives).
I thougth OCaml could be compiled to native machine language. Why it is compiled to bytecode and interpreted at runtime? Is it always like that, or only for OCaml libraries compiled with C interface?
Most of that page describes how to call C from OCaml. You want to do the reverse, which is described in Advanced Topics: callbacks from C to OCaml, closer to the bottom of the page.
When you do native compilation there is no bytecode involved, just as you say. The native compiler (ocamlopt) produces ordinary object (.o in Unix) files and extra files containing OCaml metadata.
If you look at Advanced Example with callbacks, you'll see an example where the main program is in C, with calls to two functions defined in OCaml. Things should work similarly in C++. (I have only done this in C myself, however.)
Update
Here is the worked-out example using the code from Advanced example with callbacks. I am running this code on Ubuntu 18.04.4 (x86_64).
The OCaml code looks like this:
$ cat mod.ml
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 1)
let format_result n = Printf.sprintf "Result is: %d\n" n
let () = Callback.register "fib" fib
let () = Callback.register "format_result" format_result
Compile this code and ask for a complete object file:
$ ocamlopt -output-obj -o bigmod.o mod.ml
Rename the C code to modwrap.cc. (The code is given in the OCaml manual section.)
$ head -6 modwrap.cc
#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
int fib(int n)
Note that the OCaml include files are conditionalized as to whether they're being included from C or C++ (as are almost all header files these days).
The main function from the OCaml manual section is also valid C++; rename it to main.cc:
$ head -7 main.cc
#include <stdio.h>
#include <caml/callback.h>
extern int fib(int n);
extern char * format_result(int n);
int main(int argc, char ** argv)
Now compile and link everything:
$ g++ -c modwrap.cc
$ g++ -o myprog -I $(ocamlopt -where) \
main.cc modwrap.o bigmod.o $(ocamlopt -where)/libasmrun.a -ldl
$
Now run the program
$ ./myprog
fib(10) = Result is: 89
There is no automatic generation of header files. In this example the extern lines of main.cc are the header file in essence. If you want a header file you'll have to write something like this yourself.
Update 2
Here are the commands for creating an actual static library containing the OCaml functions and their wrappers. This assumes that you have done the compiles above to create bigmod.o and modwrap.o:
$ cp $(ocamlopt -where)/libasmrun.a libmyoc.a
$ ar r libmyoc.a bigmod.o modwrap.o
Now you can use this library in your C++ code (represented by main.cc):
$ g++ -o myprog -I $(ocamlopt -where) main.cc -L . -lmyoc -ldl
$ ./myprog
fib(10) = Result is: 89
Update 3
(I updated the above commands to work on Unbuntu.)

c++ struct declaration collect2: ld returned 1 exit status

I managed to solve this issue, but I don't understand why this works like this, so I'm looking for only an clarification for this and any explanations are welcome.
I'm doing the excercises from Bruce Eckel's book: Thinking in C++.
Excercise 13 in Vol 1., Chapter 4 is creating "abstract data type that represents a videotape in a video rental store"
As per the topic of this chapter I assume this should be a struct, like this very simple one:
//video.h
typedef struct {
unsigned id;
char* title;
float length;
int inRent;
void printout();
} Video;
with a dummy implementation, like:
//video.cpp
#include "stdio.h"
#include "video.h"
void Video::printout(){
printf("id:%u, title:%s, length:%f\n",this->id,this->title,this->length);
}
and with a main.cpp like this:
//main.cpp
#include "video.h"
#include "stdio.h"
int main(){
Video first;
first.id=1;
first.title="Some title";
first.length=1.5;
first.printout();
return 0;
}
When trying to compile and link with gcc -o main.exe main.cpp video.cpp -lstdc++, I get this error below at linking. I get the same result with g++ too
C:\Users\jani\AppData\Local\Temp\cc1KIhpp.o:main.cpp:(.text+0x2e): undefined reference to `Video::printout()'
When I use struct identifier - like: typedef struct some_id {...} Video; - compiles and runs without error.
How does this struct declaration work in similar cases?
Eckel says: "You’ll notice that the struct identifier has been left off at the beginning, because the goal is to create the typedef. However, there are times when you might need to refer to the struct during its definition. (...)".
In which cases does this apply?
Many thanks for the answers.
Janos
Why don't you provide the stdio or iostream header in the video.cpp file..These headers provide dynamic linking according to you system. I f you do manual linking just from a simple Makefile, it may not be os & hardware independent.
More importantly, you are not using any C/C++ library functions in the main file, so no need to include stdio.h in the main. Rather include it video.c file
you should compile with g++ (no need to link libstdc++ since all commonly available linux distributions will use libstdc++ by default) and the correct syntax for declaring struct in cpp is:
struct Video
{
std::string title; // note that you used char* for title and assigned it a string literal which is of type const char*, there is no implicit conversion for that.
...
};
Also instead of printf you should use iostream for formatted output, it's more efficient, less error prone and more readable:
#include <iostream>
void Video::printout(){
std::cout << this->id << this->title << this->length << std::endl;
}
It is just a matter of linking order. The following should work:
g++ -o main.exe video.cpp main.cpp -lstdc++
or (for the paranoid):
g++ -o main.exe video.cpp main.cpp video.cpp -lstdc++

Linking against older symbol version in a .so file

Using gcc and ld on x86_64 linux I need to link against a newer version of a library (glibc 2.14) but the executable needs to run on a system with an older version (2.5). Since the only incompatible symbol is memcpy (needing memcpy#GLIBC_2.2.5 but the library providing memcpy#GLIBC_2.14), I would like to tell the linker that instead of taking the default version for memcpy, it should take an old version I specify.
I found a quite arkward way to do it: simply specify a copy of the old .so file at the linker command line. This works fine, but I don't like the idea of having multiple .so files (I could only make it work by specifying all old libraries I link to that also have references to memcpy) checked into the svn and needed by my build system.
So I am searching for a way to tell the linker to take the old versioned symbol.
Alternatives that don't work (well) for me are:
Using asm .symver (as seen on Web Archive of Trevor Pounds' Blog) since this would require me to make sure the symver is before all the code that is using memcpy, which would be very hard (complex codebase with 3rd party code)
Maintaining a build environment with the old libraries; simply because I want to develop on my desktop system and it would be a pita to sync stuff around in our network.
When thinking about all the jobs a linker does, it doesn't seem like a hard thing to imlpement, after all it has some code to figure out the default version of a symbol too.
Any other ideas that are on the same complexity level as a simple linker command line (like creating a simple linker script etc.) are welcome too, as long as they are not weird hacks like editing the resulting binary...
edit:
To conserve this for the future readers, additionally to the below ideas I found the option --wrap to the linker, which might be useful sometimes too.
I found the following working solution. First create file memcpy.c:
#include <string.h>
/* some systems do not have newest memcpy##GLIBC_2.14 - stay with old good one */
asm (".symver memcpy, memcpy#GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
No additional CFLAGS needed to compile this file. Then link your program with -Wl,--wrap=memcpy.
Just link memcpy statically - pull memcpy.o out of libc.a ar x /path/to/libc.a memcpy.o (whatever version - memcpy is pretty much a standalone function) and include it in your final link. Note that static linking may complicate licensing issues if your project is distributed to the public and not open-source.
Alternatively, you could simply implement memcpy yourself, though the hand-tuned assembly version in glibc is likely to be more efficient
Note that memcpy#GLIBC_2.2.5 is mapped to memmove (old versions of memcpy consistently copied in a predictable direction, which led to it sometimes being misused when memmove should have been used), and this is the only reason for the version bump - you could simply replace memcpy with memmove in your code for this specific case.
Or you could go to static linking, or you could ensure that all systems on your network have the same or better version than your build machine.
I had a similar issue. A third party library we use needs the old memcpy#GLIBC_2.2.5. My solution is an extended approach #anight posted.
I also warp the memcpy command, but i had to use a slightly different approach, since the solution #anight posted did not work for me.
memcpy_wrap.c:
#include <stddef.h>
#include <string.h>
asm (".symver wrap_memcpy, memcpy#GLIBC_2.2.5");
void *wrap_memcpy(void *dest, const void *src, size_t n) {
return memcpy(dest, src, n);
}
memcpy_wrap.map:
GLIBC_2.2.5 {
memcpy;
};
Build the wrapper:
gcc -c memcpy_wrap.c -o memcpy_wrap.o
Now finally when linking the program add
-Wl,--version-script memcpy_wrap.map
memcpy_wrap.o
so that you will end up with something like:
g++ <some flags> -Wl,--version-script memcpy_wrap.map <some .o files> memcpy_wrap.o <some libs>
I had a similar problem. Trying to install some oracle components on RHEL 7.1, I got this:
$ gcc -o /some/oracle/bin/foo .... -L/some/oracle/lib ...
/some/oracle/lib/libfoo.so: undefined reference to `memcpy#GLIBC_2.14'
It seems that (my) RHEL's glibc only defines memcpy#GLIBC_2.2.5:
$ readelf -Ws /usr/lib/x86_64-redhat-linux6E/lib64/libc_real.so | fgrep memcpy#
367: 000000000001bfe0 16 FUNC GLOBAL DEFAULT 8 memcpy##GLIBC_2.2.5
1166: 0000000000019250 16 FUNC WEAK DEFAULT 8 wmemcpy##GLIBC_2.2.5
So, I managed to get around this, by first creating a memcpy.c file without wrapping, as follows:
#include <string.h>
asm (".symver old_memcpy, memcpy#GLIBC_2.2.5"); // hook old_memcpy as memcpy#2.2.5
void *old_memcpy(void *, const void *, size_t );
void *memcpy(void *dest, const void *src, size_t n) // then export memcpy
{
return old_memcpy(dest, src, n);
}
and a memcpy.map file that exports our memcpy as memcpy#GLIBC_2.14:
GLIBC_2.14 {
memcpy;
};
I then compiled my own memcpy.c into a shared lib like this:
$ gcc -shared -fPIC -c memcpy.c
$ gcc -shared -fPIC -Wl,--version-script memcpy.map -o libmemcpy-2.14.so memcpy.o -lc
, moved libmemcpy-2.14.so into /some/oracle/lib (pointed to by -L arguments in my linking), and linked again by
$ gcc -o /some/oracle/bin/foo .... -L/some/oracle/lib ... /some/oracle/lib/libmemcpy-2.14.so -lfoo ...
(which compiled without errors) and verified it by:
$ ldd /some/oracle/bin/foo
linux-vdso.so.1 => (0x00007fff9f3fe000)
/some/oracle/lib/libmemcpy-2.14.so (0x00007f963a63e000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f963a428000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f963a20c000)
librt.so.1 => /lib64/librt.so.1 (0x00007f963a003000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9639c42000)
/lib64/ld-linux-x86-64.so.2 (0x00007f963aa5b000)
This worked for me. I hope it does it for you, too.
I'm clearly a little late responding to this but I recently upgraded (more reasons to never upgrade) my Linux OS to XUbuntu 14.04 which came with the new libc. I compile a shared library on my machine which is used by clients who, for whatever legitimate reasons, have not upgraded their environment from 10.04. The shared library I compiled no longer loaded in their environment because gcc put a dependency on memcpy glibc v. 2.14 (or higher). Let's leave aside the insanity of this. The workaround across my whole project was three fold:
added to my gcc cflags: -include glibc_version_nightmare.h
created the glibc_version_nightmare.h
created a perl script to verify the symbols in the .so
glibc_version_nightmare.h:
#if defined(__GNUC__) && defined(__LP64__) /* only under 64 bit gcc */
#include <features.h> /* for glibc version */
#if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 14)
/* force mempcy to be from earlier compatible system */
__asm__(".symver memcpy,memcpy#GLIBC_2.2.5");
#endif
#undef _FEATURES_H /* so gets reloaded if necessary */
#endif
perl script fragment:
...
open SYMS, "nm $flags $libname |";
my $status = 0;
sub complain {
my ($symbol, $verstr) = #_;
print STDERR "ERROR: $libname $symbol requires $verstr\n";
$status = 1;
}
while (<SYMS>) {
next unless /\#\#GLIBC/;
chomp;
my ($symbol, $verstr) = (m/^\s+.\s(.*)\#\#GLIBC_(.*)/);
die "unable to parse version from $libname in $_\n"
unless $verstr;
my #ver = split(/\./, $verstr);
complain $symbol, $verstr
if ($ver[0] > 2 || $ver[1] > 10);
}
close SYMS;
exit $status;
Minimal runnable self contained example
GitHub upstream.
main.c
#include <assert.h>
#include <stdlib.h>
#include "a.h"
#if defined(V1)
__asm__(".symver a,a#LIBA_1");
#elif defined(V2)
__asm__(".symver a,a#LIBA_2");
#endif
int main(void) {
#if defined(V1)
assert(a() == 1);
#else
assert(a() == 2);
#endif
return EXIT_SUCCESS;
}
a.c
#include "a.h"
__asm__(".symver a1,a#LIBA_1");
int a1(void) {
return 1;
}
/* ## means "default version". */
__asm__(".symver a2,a##LIBA_2");
int a2(void) {
return 2;
}
a.h
#ifndef A_H
#define A_H
int a(void);
#endif
a.map
LIBA_1{
global:
a;
local:
*;
};
LIBA_2{
global:
a;
local:
*;
};
Makefile
CC := gcc -pedantic-errors -std=c89 -Wall -Wextra
.PHONY: all clean run
all: main.out main1.out main2.out
run: all
LD_LIBRARY_PATH=. ./main.out
LD_LIBRARY_PATH=. ./main1.out
LD_LIBRARY_PATH=. ./main2.out
main.out: main.c libcirosantilli_a.so
$(CC) -L'.' main.c -o '$#' -lcirosantilli_a
main1.out: main.c libcirosantilli_a.so
$(CC) -DV1 -L'.' main.c -o '$#' -lcirosantilli_a
main2.out: main.c libcirosantilli_a.so
$(CC) -DV2 -L'.' main.c -o '$#' -lcirosantilli_a
a.o: a.c
$(CC) -fPIC -c '$<' -o '$#'
libcirosantilli_a.so: a.o
$(CC) -Wl,--version-script,a.map -L'.' -shared a.o -o '$#'
libcirosantilli_a.o: a.c
$(CC) -fPIC -c '$<' -o '$#'
clean:
rm -rf *.o *.a *.so *.out
Tested on Ubuntu 16.04.
This workaround seem not compatible with -flto compile option.
My solution is calling memmove. memove does exactly the same jobs than memcpy.
The only difference is when src and dest zone overlap, memmove is safe and memcpy is unpredictable. So we can safely always call memmove instead memcpy
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
return memmove(dest, src, n);
}
#ifdef __cplusplus
}
#endif
For nim-lang, I elaborated on a solution I found using the C compiler --include= flag as follows:
Create a file symver.h with:
__asm__(".symver fcntl,fcntl#GLIBC_2.4");
Build your program with nim c ---passC:--include=symver.h
As for me I'm cross compiling too. I compile with nim c --cpu:arm --os:linux --passC:--include=symver.h ... and I can get symbol versions using arm-linux-gnueabihf-objdump -T ../arm-libc.so.6 | grep fcntl
I had to remove ~/.cache/nim at some point. And it seems to work.
I think you can get away with making a simple C file containing the symver statement and perhaps a dummy function calling memcpy. Then you just have to ensure that the resulting object file is the first file given to linker.
I suggest you either link memcpy() statically; or find the source of memcpy( ) and compile it as your own library.
It may caused by old ld (gnu link) version.
For following simple problem:
#include <string.h>
#include <stdio.h>
int main(int argc,char **argv)
{
char buf[5];
memset(buf,0,sizeof(buf));
printf("ok\n");
return 0;
}
When I use ld 2.19.1, memset is relocated to: memset##GLIBC_2.0, and cause crash.
After upgraded to 2.25, it is: memset#plt, and crash solved.
We had a similar issue, but instead of one older GLIBC symbol, we have to provide in our .so libs a mix of newer ones with necessary functionality and older ones our libs may be referencing but are not available. This situation occurs because we are shipping to customers high performance codec libs with vectorized math functions and we cannot impose requirements on what version of OS distro, gcc, or glibc they use. As long as their machine has appropriate SSE and AVX extensions, the libs should work. Here is what we did:
Include glibc 2.35 libmvec.so.1 and libm.so.6 files in a separate subfolder. These contain the necessary vectorized math functions. In a "hello codec" application example, we reference these in the link target depending on what distro, gcc, and glibc versions are found by the Makefile. More or less, for anything with glibc v2.35 or higher the high performance libs are referenced, otherwise slower libs are referenced.
To deal with missing symbols -- the subject of this thread -- we used a modification of Ortwin Anermeier's solution, in turn based on anight's solution, but without using the -Wl,--wrap=xxx option.
The .map file looks like:
GLIBC_2.35 {
hypot;
:
: (more function symbols as needed)
};
GLIBC_2.32 {
exp10;
:
: (more function symbols as needed)
};
:
: (more version nodes as needed)
and in a "stublib" .so we have:
#define _GNU_SOURCE
#include <math.h>
asm(".symver hypot_235, hypot#GLIBC_2.35");
asm(".symver exp10_232, exp10f#GLIBC_2.32");
/* ... more as needed */
double hypot_235(double x, double y) { return hypot(x, y); }
double exp10_232(double x) { return exp10(x); }
/* ... more as needed */
-lstublib.so is then included in the app build as the last link item, even after -lm.
This answer and this one also offer clues, but they not handling the general case of a .so flexible enough to be used on a wide variety of systems.

Data-only static libraries with GCC

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?
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.
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).

Resources