In several situations we want to link a binary file into our executable and access it from our C code. The easiest way is to transform it into a C-array and compile it as usual. However, for large files (>1MB) such compilations can take a considerable amount of time or even fail on low-memory systems.
This adds a new automake-target to link binary sources directly. Instead of transforming it into a C-array, we simply use "ld -r" to create an object file via: ld -r -o my-source.bin.o --format=binary my-source.bin We also use "-z noexecstack" to mark "my-source.bin.o" to not require an executable stack. As we only want to support read-only data sources here, we do some post-processing to mark the object as read-only via: objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents my-source.bin.o As libtool requires "*.lo" files, we cannot link this object-file directly. Thus, we also create a fake "*.lo" file for such objects which libtool can use. Note that libtool actually *requires* the comment-section in "*.lo" files (ugh?!) so we need to fake that, too. How to use this helper? - put your binary source file into the tree as: src/somewhere/something.bin - for the library you want to link that to, add this to mylib_LIBADD: src/somewhere/something.bin.lo This causes the helper to create src/somewhere/something.bin.[o,lo] and it will be linked as a normal object file. GNU-ld automatically creates 3 symbols for such objects, but the important symbols are: extern const char _binary_src_somewhere_something_bin_start[]; extern const char _binary_src_somewhere_something_bin_end[]; Use these to access start/end of the binary section. I tested this with in-tree and out-of-tree builds, with GNU-ld and GNU-gold and cross-compilation. All worked fine.. --- Makefile.am | 19 +++++++++++++++++++ configure.ac | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/Makefile.am b/Makefile.am index 4aa2bdf..ce27e82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -632,6 +632,25 @@ EXTRA_DIST += \ xml_helper.py # ------------------------------------------------------------------------------ +CLEANFILES += *.bin.lo *.bin.o + +%.bin.lo: %.bin + $(AM_V_GEN)$(LD) -r -o "$*.bin.o" -z noexecstack --format=binary "$<" + $(AM_V_at)$(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "$*.bin.o" + $(AM_V_at)echo "# $@ - a libtool object file" >"$@" + $(AM_V_at)echo "# Generated by $(shell $(LIBTOOL) --version | head -n 1)" >>"$@" + $(AM_V_at)echo "#" >>"$@" + $(AM_V_at)echo "# Please DO NOT delete this file!" >>"$@" + $(AM_V_at)echo "# It is necessary for linking the library." >>"$@" + $(AM_V_at)echo >>"$@" + $(AM_V_at)echo "# Name of the PIC object." >>"$@" + $(AM_V_at)echo "pic_object='$(notdir $*).bin.o'" >>"$@" + $(AM_V_at)echo >>"$@" + $(AM_V_at)echo "# Name of the non-PIC object" >>"$@" + $(AM_V_at)echo "non_pic_object='$(notdir $*).bin.o'" >>"$@" + $(AM_V_at)echo >>"$@" + +# ------------------------------------------------------------------------------ noinst_LTLIBRARIES += \ libsystemd-rtnl.la diff --git a/configure.ac b/configure.ac index c0656f4..3fd05da 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,11 @@ if test -z "$GPERF" ; then AC_MSG_ERROR([*** gperf not found]) fi +AC_CHECK_TOOL([OBJCOPY], objcopy) +if test -z "$OBJCOPY" ; then + AC_MSG_ERROR([*** objcopy not found]) +fi + # ------------------------------------------------------------------------------ address_sanitizer_cflags= address_sanitizer_cppflags= -- 1.8.4.2 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel