[systemd-devel] [RFC 04/12] build: add target to link binary sources
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
Re: [systemd-devel] [RFC 04/12] build: add target to link binary sources
On Wed, Nov 27, 2013 at 07:48:39PM +0100, David Herrmann wrote: 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.. That's crazy, very nice job in doing this :) I tried to do this a while ago, and gave up and just used a perl script and a .c file with a big array, like 'xxd -i' can create. I think I'll steal this idea for other projects if you don't mind, as it makes things easier just to use the linker. greg k-h ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC 04/12] build: add target to link binary sources
Hi On Wed, Nov 27, 2013 at 10:31 PM, Greg KH gre...@linuxfoundation.org wrote: On Wed, Nov 27, 2013 at 07:48:39PM +0100, David Herrmann wrote: 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.. That's crazy, very nice job in doing this :) I tried to do this a while ago, and gave up and just used a perl script and a .c file with a big array, like 'xxd -i' can create. I think I'll steal this idea for other projects if you don't mind, as it makes things easier just to use the linker. I figured that out about 1 year ago, took me way too long to get working. Please, go ahead and copy it! And if any issue comes up, let me know. Thanks David ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel