From: Ross Lagerwall Date: Fri, 6 Nov 2015 12:55:25 +0000 (+0000) Subject: Implement run-time linking X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=d1c9e3524f8b80cd51aea512c93081ffc2f1a18b;p=livepatch-build-tools.git Implement run-time linking Implement run-time linking and link at run-time by default. Still keep the option to link at compile time. --- diff --git a/create-diff-object.c b/create-diff-object.c index fb9ef0b..b542ee9 100644 --- a/create-diff-object.c +++ b/create-diff-object.c @@ -1457,7 +1457,7 @@ static struct section *create_section_pair(struct xsplice_elf *kelf, static void xsplice_create_patches_sections(struct xsplice_elf *kelf, struct lookup_table *table, - char *hint) + char *hint, int resolve) { int nr, index; struct section *sec, *relasec; @@ -1504,7 +1504,11 @@ static void xsplice_create_patches_sections(struct xsplice_elf *kelf, ERROR("%s too small to patch", sym->name); /* add entry in text section */ - funcs[index].old_addr = result.value; + if (resolve) + funcs[index].old_addr = result.value; + else + /* This will be filled in at module load time */ + funcs[index].old_addr = 0; funcs[index].old_size = result.size; funcs[index].new_addr = 0; funcs[index].new_size = sym->sym.st_size; @@ -1598,12 +1602,14 @@ static void xsplice_reindex_elements(struct xsplice_elf *kelf) struct arguments { char *args[4]; int debug; + int resolve; }; static char args_doc[] = "original.o patched.o kernel-object output.o"; static struct argp_option options[] = { {"debug", 'd', 0, 0, "Show debug output" }, + {"resolve", 'r', 0, 0, "Resolve to-be-patched function addresses" }, { 0 } }; @@ -1618,6 +1624,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) case 'd': arguments->debug = 1; break; + case 'r': + arguments->resolve = 1; + break; case ARGP_KEY_ARG: if (state->arg_num >= 4) /* Too many arguments. */ @@ -1648,6 +1657,7 @@ int main(int argc, char *argv[]) char *hint = NULL; arguments.debug = 0; + arguments.resolve = 0; argp_parse (&argp, argc, argv, 0, 0, &arguments); if (arguments.debug) loglevel = DEBUG; @@ -1763,7 +1773,8 @@ int main(int argc, char *argv[]) log_debug("Create strings elements\n"); xsplice_create_strings_elements(kelf_out); log_debug("Create patches sections\n"); - xsplice_create_patches_sections(kelf_out, lookup, hint); + xsplice_create_patches_sections(kelf_out, lookup, hint, + arguments.resolve); xsplice_build_strings_section_data(kelf_out); /* diff --git a/xsplice-build b/xsplice-build index f5495c0..a67ebc0 100755 --- a/xsplice-build +++ b/xsplice-build @@ -30,6 +30,7 @@ DEBUG=n XEN_DEBUG=n SKIP= DEPENDS= +PRELINK= XENSYMS=xen-syms warn() { @@ -111,7 +112,7 @@ function create_patch() mkdir -p "output/$(dirname $i)" || die echo "Processing ${i}" echo "Run create-diff-object on $i" >> "${OUTPUT}/create-diff-object.log" - "${SCRIPTDIR}"/create-diff-object $debugopt "original/$i" "patched/$i" "$XENSYMS" "output/$i" &>> "${OUTPUT}/create-diff-object.log" + "${SCRIPTDIR}"/create-diff-object $debugopt $PRELINK "original/$i" "patched/$i" "$XENSYMS" "output/$i" &>> "${OUTPUT}/create-diff-object.log" rc="${PIPESTATUS[0]}" if [[ $rc = 139 ]]; then warn "create-diff-object SIGSEGV" @@ -143,8 +144,13 @@ function create_patch() fi echo "Creating patch module..." - ld -r -o output.o --build-id=sha1 $(find output -type f -name "*.o") || die - "${SCRIPTDIR}"/prelink $debugopt output.o "${PATCHNAME}.xsplice" "$XENSYMS" &>> "${OUTPUT}/prelink.log" || die + if [ -z "$PRELINK" ]; then + ld -r -o "${PATCHNAME}.xsplice" --build-id=sha1 $(find output -type f -name "*.o") || die + chmod +x "${PATCHNAME}.xsplice" + else + ld -r -o output.o --build-id=sha1 $(find output -type f -name "*.o") || die + "${SCRIPTDIR}"/prelink $debugopt output.o "${PATCHNAME}.xsplice" "$XENSYMS" &>> "${OUTPUT}/prelink.log" || die + fi objcopy --add-section .xsplice.depends=depends.bin "${PATCHNAME}.xsplice" objcopy --set-section-flags .xsplice.depends=alloc,readonly "${PATCHNAME}.xsplice" @@ -162,9 +168,10 @@ usage() { echo " --xen-debug Build debug Xen" >&2 echo " --xen-syms Build against a xen-syms" >&2 echo " --depends Required build-id" >&2 + echo " --prelink Prelink" >&2 } -options=$(getopt -o hs:p:o:j:k:d -l "help,srcdir:patch:output:cpus:,skip:,debug,xen-debug,xen-syms:,depends:" -- "$@") || die "getopt failed" +options=$(getopt -o hs:p:o:j:k:d -l "help,srcdir:patch:output:cpus:,skip:,debug,xen-debug,xen-syms:,depends:,prelink" -- "$@") || die "getopt failed" eval set -- "$options" @@ -218,6 +225,10 @@ while [[ $# -gt 0 ]]; do DEPENDS="$1" shift ;; + --prelink) + PRELINK=--resolve + shift + ;; --) shift break