[systemd-devel] [RFC 04/12] build: add target to link binary sources
David Herrmann
dh.herrmann at gmail.com
Wed Nov 27 10:48:39 PST 2013
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
More information about the systemd-devel
mailing list