Commit 93dd1288 authored by Marc Zyngier's avatar Marc Zyngier Committed by Will Deacon
Browse files

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: default avatarMarc Zyngier <>
parent 23a9388e
......@@ -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,$@)
$(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 guest/guest_init.c guest/guest_pre_init.c
$(Q) rm -f cscope.*
$(Q) rm -f tags
$(Q) rm -f TAGS
......@@ -123,7 +123,7 @@ static const char *guestfs_symlinks[] = {
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);
......@@ -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)
err = extract_file(guestfs_name, "virt/pre_init",
pre_init_binary, pre_init_binary_size);
if (err)
return err;
err = extract_file(guestfs_name, "virt/init",
init_binary, init_binary_size);
return err;
......@@ -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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment