diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2017-08-29 17:33:34 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2017-08-30 09:47:05 +0100 |
commit | 93dd1288081497146b3a7ad98e40c5b2635c3148 (patch) | |
tree | f0744452c3ec5e8606122ad65620b4ff1a4ff5b5 | |
parent | 23a9388e9f20d81a3752b78f698f542cb6338a10 (diff) | |
download | kvmtool-93dd1288081497146b3a7ad98e40c5b2635c3148.tar.gz |
Makefile: avoid using linker for embedding guest_init binaries
At the moment we use the linker to convert the compiled guest_init binary
into an ELF object file, so it can be embedded into the kvmtool binary
and accessed later easily at runtime.
Now this has two problems:
1) This approach does not work for MIPS, because the linker defaults to
a different ABI than the compiler, so the GCC generated object files are
not compatible with this converted binary.
2) The size symbol as it's used at the moment in the object file is subject
to relocation, which leads to wrong results when using PIE builds, which is
now the default for some distributions.
Fix those two problems at once by using some shell tools to create a C
source file containing the guest_init binary, which then gets compiled into
a proper object file with the normal compiler and its flags.
The size of the guest init binaries is now simply a variable, which does
not get mangled at all.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | builtin-setup.c | 18 | ||||
-rw-r--r-- | config/utilities.mak | 8 |
3 files changed, 21 insertions, 14 deletions
@@ -392,18 +392,18 @@ $(GUEST_PRE_INIT): $(ARCH_PRE_INIT) $(E) " COMPILE " $@ $(Q) $(CC) -s $(PIE_FLAGS) -nostdlib $< -o $@ -guest/guest_pre_init.o: $(GUEST_PRE_INIT) +guest/guest_pre_init.c: $(GUEST_PRE_INIT) $(E) " CONVERT " $@ - $(Q) $(LD) -r -b binary -o $@ $< + $(Q) $(call binary-to-C,$<,pre_init_binary,$@) endif $(GUEST_INIT): guest/init.c $(E) " COMPILE " $@ $(Q) $(CC) $(GUEST_INIT_FLAGS) $< -o $@ -guest/guest_init.o: $(GUEST_INIT) +guest/guest_init.c: $(GUEST_INIT) $(E) " CONVERT " $@ - $(Q) $(LD) -r -b binary -o $@ $< + $(Q) $(call binary-to-C,$<,init_binary,$@) %.s: %.c $(Q) $(CC) -o $@ -S $(CFLAGS) -fverbose-asm $< @@ -494,6 +494,7 @@ clean: $(Q) rm -f tests/boot/boot_test.iso $(Q) rm -rf tests/boot/rootfs/ $(Q) rm -f $(DEPS) $(STATIC_DEPS) $(OBJS) $(OTHEROBJS) $(OBJS_DYNOPT) $(STATIC_OBJS) $(PROGRAM) $(PROGRAM_ALIAS) $(PROGRAM)-static $(GUEST_INIT) $(GUEST_PRE_INIT) $(GUEST_OBJS) + $(Q) rm -f guest/guest_init.c guest/guest_pre_init.c $(Q) rm -f cscope.* $(Q) rm -f tags $(Q) rm -f TAGS diff --git a/builtin-setup.c b/builtin-setup.c index 8be8d628..b24d2a18 100644 --- a/builtin-setup.c +++ b/builtin-setup.c @@ -123,7 +123,7 @@ static const char *guestfs_symlinks[] = { #ifdef CONFIG_GUEST_INIT static int extract_file(const char *guestfs_name, const char *filename, - const void *data, const void *_size) + const void *data, size_t size) { char path[PATH_MAX]; int fd, ret; @@ -138,7 +138,7 @@ static int extract_file(const char *guestfs_name, const char *filename, die("Fail to setup %s", path); } - ret = xwrite(fd, data, (size_t)_size); + ret = xwrite(fd, data, size); if (ret < 0) die("Fail to setup %s", path); close(fd); @@ -146,10 +146,10 @@ static int extract_file(const char *guestfs_name, const char *filename, return 0; } -extern char _binary_guest_init_start; -extern char _binary_guest_init_size; -extern char _binary_guest_pre_init_start; -extern char _binary_guest_pre_init_size; +extern unsigned char init_binary[]; +extern unsigned long init_binary_size; +extern unsigned char pre_init_binary[]; +extern unsigned long pre_init_binary_size; int kvm_setup_guest_init(const char *guestfs_name) { @@ -157,14 +157,12 @@ int kvm_setup_guest_init(const char *guestfs_name) #ifdef CONFIG_GUEST_PRE_INIT err = extract_file(guestfs_name, "virt/pre_init", - &_binary_guest_pre_init_start, - &_binary_guest_pre_init_size); + pre_init_binary, pre_init_binary_size); if (err) return err; #endif err = extract_file(guestfs_name, "virt/init", - &_binary_guest_init_start, - &_binary_guest_init_size); + init_binary, init_binary_size); return err; } #else diff --git a/config/utilities.mak b/config/utilities.mak index 92af49bf..612ed1fc 100644 --- a/config/utilities.mak +++ b/config/utilities.mak @@ -194,3 +194,11 @@ try-build = $(shell sh -c \ echo "$(1)" | \ $(CC) -x c - $(2) $(3) -o "$$TMP" > /dev/null 2>&1 && echo y; \ rm -f "$$TMP"') + +# binary-to-C +# create a C source file describing the binary input file as an array +# Usage: $(call binary-to-C,binary-file,C-symbol-name,C-output-file) +binary-to-C = stat -c "unsigned long $(2)_size = %s;" $1 > $3; \ + echo "unsigned char $(2)[] = {" >> $3; \ + od -v -tx1 -An -w12 $1 | sed -e "s/ \(..\)/0x\1, /g" >> $3; \ + echo "};" >> $3 |