[systemd-devel] [RFC 04/12] build: add target to link binary sources

2013-11-27 Thread David Herrmann
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

2013-11-27 Thread Greg KH
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

2013-11-27 Thread David Herrmann
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