From patchwork Thu Apr 7 03:49:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konrad Rzeszutek Wilk X-Patchwork-Id: 8768441 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 941F29F3D1 for ; Thu, 7 Apr 2016 03:52:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 06443201ED for ; Thu, 7 Apr 2016 03:52:39 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 67078201CD for ; Thu, 7 Apr 2016 03:52:37 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ao0xH-0004mL-T2; Thu, 07 Apr 2016 03:50:03 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ao0xG-0004jk-NR for xen-devel@lists.xenproject.org; Thu, 07 Apr 2016 03:50:02 +0000 Received: from [85.158.139.211] by server-6.bemta-5.messagelabs.com id 56/25-02479-AE8D5075; Thu, 07 Apr 2016 03:50:02 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprAIsWRWlGSWpSXmKPExsUyZ7p8oO7LG6z hBhOXCFl83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBn7/zkWfKyqmHKtuIFxRkwXIxeHkEArk0T3 n42MEM5XRokVj9exdTFyAjnrGSXePPaBSHQzSsw9tw0qUSRxZMYuIJuDg03AROLNKkeQGhGB5 YwSnftWg9UwC5RLrJ7xHswWFgiXaFw3iR3EZhFQlZi0AMLmFXCXuDZpISvIHAkBOYkFF9JBwp xA4X9tu9khVrlJLP3ewwpiSwgYSpx+uI1xAiP/AkaGVYzqxalFZalFuiZ6SUWZ6RkluYmZObq GBqZ6uanFxYnpqTmJScV6yfm5mxiBocMABDsYb/U5H2KU5GBSEuV1rWQNF+JLyk+pzEgszogv Ks1JLT7EKMPBoSTBqwwMRSHBotT01Iq0zBxgEMOkJTh4lER4N14HSvMWFyTmFmemQ6ROMepyH Nmy6SSTEEtefl6qlDjvBpAiAZCijNI8uBGwiLrEKCslzMsIdJQQT0FqUW5mCar8K0ZxDkYlYV 4DkEt4MvNK4Da9AjqCCeiIemEmkCNKEhFSUg2M0q7HHFRe8i+5bLvjIm/JfWPtTkWr3z6feNU Cdt7KXPK380W++bnu7Yxbgqw1cietDzniwdCqmGYhL3xGtU5sdc99joqsiX2Ob1qKlq8+Vdwu dUzlJ8vZmCshC0puuPDxGr+Xs7i+ZMaR1Fklr663eGxt6UjfzpNRdmKjZ/QEif9hQofd7scqs RRnJBpqMRcVJwIAyBENcaMCAAA= X-Env-Sender: konrad@char.us.oracle.com X-Msg-Ref: server-7.tower-206.messagelabs.com!1460000999!33164855!1 X-Originating-IP: [156.151.31.81] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTU2LjE1MS4zMS44MSA9PiAyODgzMzk=\n X-StarScan-Received: X-StarScan-Version: 8.28; banners=-,-,- X-VirusChecked: Checked Received: (qmail 39176 invoked from network); 7 Apr 2016 03:50:00 -0000 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by server-7.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 7 Apr 2016 03:50:00 -0000 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u373nqdR004227 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 7 Apr 2016 03:49:52 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id u373nplZ010722 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 7 Apr 2016 03:49:52 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id u373npGT020017; Thu, 7 Apr 2016 03:49:51 GMT Received: from char.us.oracle.com (/10.137.176.158) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 06 Apr 2016 20:49:51 -0700 Received: by char.us.oracle.com (Postfix, from userid 1000) id 5CAB76A0107; Wed, 6 Apr 2016 23:49:49 -0400 (EDT) From: Konrad Rzeszutek Wilk To: xen-devel@lists.xenproject.org, konrad@kernel.org, ross.lagerwall@citrix.com, mpohlack@amazon.de, sasha.levin@oracle.com, andrew.cooper3@citrix.com Date: Wed, 6 Apr 2016 23:49:31 -0400 Message-Id: <1460000983-28170-13-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1460000983-28170-1-git-send-email-konrad.wilk@oracle.com> References: <1460000983-28170-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: userv0021.oracle.com [156.151.31.71] Cc: Keir Fraser , Jan Beulich , Konrad Rzeszutek Wilk Subject: [Xen-devel] [PATCH v6 12/24] xsplice, symbols: Implement symbol name resolution on address. X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ross Lagerwall If in the payload we do not have the old_addr we can resolve the virtual address based on the UNDEFined symbols. We also use an boolean flag: new_symbol to track symbols. The usual case this is used is by: * A payload may introduce a new symbol * A payload may override an existing symbol (introduced in Xen or another payload) * Overriding symbols must exist in the symtab for backtraces. * A payload must always link against the object which defines the new symbol. Considering that payloads may be loaded in any order it would be incorrect to link against a payload which simply overrides a symbol because you could end up with a chain of jumps which is inefficient and may result in the expected function not being executed. Also we include a local definition block in the symbols.c file. Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Ross Lagerwall Reviewed-by: Andrew Cooper --- Cc: Keir Fraser Cc: Jan Beulich Cc: Andrew Cooper v1: Ross original version. v2: Include test-case and document update. v2: s/size_t/ssize_t/ Include core_text_size, core_text calculation v4: Cast on dprintk to uint64_t to make ELF 32bit build. v6: Rebase where the spinlock is no more recursive. Drop the spinlock usage in xsplice_symbols_lookup_by_name --- --- xen/arch/x86/Makefile | 16 +++- xen/arch/x86/test/Makefile | 4 +- xen/arch/x86/test/xen_hello_world.c | 5 +- xen/common/symbols.c | 32 ++++++++ xen/common/xsplice.c | 156 +++++++++++++++++++++++++++++++++++- xen/common/xsplice_elf.c | 20 ++++- xen/include/xen/symbols.h | 2 + xen/include/xen/xsplice.h | 8 ++ 8 files changed, 231 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index cd4abd6..d85287d 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -72,6 +72,12 @@ efi-y := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \ -O $(BASEDIR)/include/xen/compile.h ]; then \ echo '$(TARGET).efi'; fi) +ifdef CONFIG_XSPLICE +all_symbols = --all-symbols +else +all_symbols = +endif + $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32 ./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \ `$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'` @@ -111,12 +117,14 @@ $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0 $(NM) -pa --format=sysv $(@D)/.$(@F).0 \ - | $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).0.S + | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort \ + >$(@D)/.$(@F).0.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1 $(NM) -pa --format=sysv $(@D)/.$(@F).1 \ - | $(BASEDIR)/tools/symbols --sysv --sort --warn-dup >$(@D)/.$(@F).1.S + | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort --warn-dup \ + >$(@D)/.$(@F).1.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(@D)/.$(@F).1.o -o $@ @@ -140,14 +148,14 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).$(base).0 &&) : $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S $(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).0 \ - | $(guard) $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).0s.S + | $(guard) $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).0s.S $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o $(foreach base, $(VIRT_BASE) $(ALT_BASE), \ $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \ $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o -o $(@D)/.$(@F).$(base).1 &&) : $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S $(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).1 \ - | $(guard) $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).1s.S + | $(guard) $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1s.S $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \ $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o -o $@ diff --git a/xen/arch/x86/test/Makefile b/xen/arch/x86/test/Makefile index b9cf13c..baa4820 100644 --- a/xen/arch/x86/test/Makefile +++ b/xen/arch/x86/test/Makefile @@ -26,14 +26,12 @@ clean:: # the last entry in the build target. # .PHONY: config.h -config.h: OLD_CODE=$(call CODE_ADDR,$(BASEDIR)/xen-syms,xen_extra_version) config.h: OLD_CODE_SZ=$(call CODE_SZ,$(BASEDIR)/xen-syms,xen_extra_version) config.h: NEW_CODE_SZ=$(call CODE_SZ,$<,xen_hello_world) config.h: xen_hello_world_func.o (set -e; \ echo "#define NEW_CODE_SZ $(NEW_CODE_SZ)"; \ - echo "#define OLD_CODE_SZ $(OLD_CODE_SZ)"; \ - echo "#define OLD_CODE $(OLD_CODE)") > $@ + echo "#define OLD_CODE_SZ $(OLD_CODE_SZ)") > $@ .PHONY: xsplice xsplice: config.h diff --git a/xen/arch/x86/test/xen_hello_world.c b/xen/arch/x86/test/xen_hello_world.c index 67bbe65..2b99369 100644 --- a/xen/arch/x86/test/xen_hello_world.c +++ b/xen/arch/x86/test/xen_hello_world.c @@ -10,11 +10,14 @@ static char xen_hello_world_name[] = "xen_hello_world"; extern const char *xen_hello_world(void); +/* External symbol. */ +extern const char *xen_extra_version(void); + struct xsplice_patch_func __section(".xsplice.funcs") xsplice_xen_hello_world = { .version = XSPLICE_PAYLOAD_VERSION, .name = xen_hello_world_name, .new_addr = (unsigned long)(xen_hello_world), - .old_addr = OLD_CODE, + .old_addr = (unsigned long)(xen_extra_version), .new_size = NEW_CODE_SZ, .old_size = OLD_CODE_SZ, }; diff --git a/xen/common/symbols.c b/xen/common/symbols.c index b18ddcd1..a28b1e7 100644 --- a/xen/common/symbols.c +++ b/xen/common/symbols.c @@ -207,3 +207,35 @@ int xensyms_read(uint32_t *symnum, char *type, return 0; } + +unsigned long symbols_lookup_by_name(const char *symname) +{ + char name[KSYM_NAME_LEN + 1] = {0}; + uint32_t symnum; + char type; + uint64_t addr; + int rc; + + do { + + rc = xensyms_read(&symnum, &type, &addr, name); + if ( rc ) + return rc; + + if ( !strcmp(name, symname) ) + return addr; + + } while ( name[0] != '\0' ); + + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c index 2df879e..b23560e 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,9 @@ struct payload { struct list_head applied_list; /* Linked to 'applied_list'. */ struct xsplice_patch_func_internal *funcs; /* The array of functions to patch. */ unsigned int nfuncs; /* Nr of functions to patch. */ + struct xsplice_symbol *symtab; /* All symbols. */ + char *strtab; /* Pointer to .strtab. */ + unsigned int nsyms; /* Nr of entries in .strtab and symbols. */ char name[XEN_XSPLICE_NAME_SIZE]; /* Name of it. */ }; @@ -116,6 +120,28 @@ static int verify_payload(const xen_sysctl_xsplice_upload_t *upload, char *n) return 0; } +unsigned long xsplice_symbols_lookup_by_name(const char *symname) +{ + struct payload *data; + + ASSERT(spin_is_locked(&payload_lock)); + list_for_each_entry ( data, &payload_list, list ) + { + unsigned int i; + + for ( i = 0; i < data->nsyms; i++ ) + { + if ( !data->symtab[i].new_symbol ) + continue; + + if ( !strcmp(data->symtab[i].name, symname) ) + return data->symtab[i].value; + } + } + + return 0; +} + static struct payload *find_payload(const char *name) { struct payload *data, *found = NULL; @@ -376,11 +402,129 @@ static int prepare_payload(struct payload *payload, for ( j = 0; j < ARRAY_SIZE(f->u.pad); j++ ) if ( f->u.pad[j] ) return -EINVAL; + + /* Lookup function's old address if not already resolved. */ + if ( !f->old_addr ) + { + f->old_addr = symbols_lookup_by_name(f->name); + if ( !f->old_addr ) + { + f->old_addr = xsplice_symbols_lookup_by_name(f->name); + if ( !f->old_addr ) + { + printk(XENLOG_ERR "%s%s: Could not resolve old address of %s\n", + XSPLICE, elf->name, f->name); + return -ENOENT; + } + } + dprintk(XENLOG_DEBUG, "%s%s: Resolved old address %s => 0x%"PRIx64"\n", + XSPLICE, elf->name, f->name, f->old_addr); + } } return 0; } +static bool_t is_payload_symbol(const struct xsplice_elf *elf, + const struct xsplice_elf_sym *sym) +{ + if ( sym->sym->st_shndx == SHN_UNDEF || + sym->sym->st_shndx >= elf->hdr->e_shnum ) + return 0; + + return (elf->sec[sym->sym->st_shndx].sec->sh_flags & SHF_ALLOC) && + (ELF64_ST_TYPE(sym->sym->st_info) == STT_OBJECT || + ELF64_ST_TYPE(sym->sym->st_info) == STT_FUNC); +} + +static int build_symbol_table(struct payload *payload, + const struct xsplice_elf *elf) +{ + unsigned int i, j, nsyms = 0; + size_t strtab_len = 0; + struct xsplice_symbol *symtab; + char *strtab; + + ASSERT(payload->nfuncs); + + /* Recall that section @0 is always NULL. */ + for ( i = 1; i < elf->nsym; i++ ) + { + if ( is_payload_symbol(elf, elf->sym + i) ) + { + nsyms++; + strtab_len += strlen(elf->sym[i].name) + 1; + } + } + + symtab = xmalloc_array(struct xsplice_symbol, nsyms); + strtab = xmalloc_array(char, strtab_len); + + if ( !strtab || !symtab ) + { + xfree(strtab); + xfree(symtab); + return -ENOMEM; + } + + nsyms = 0; + strtab_len = 0; + for ( i = 1; i < elf->nsym; i++ ) + { + if ( is_payload_symbol(elf, elf->sym + i) ) + { + symtab[nsyms].name = strtab + strtab_len; + symtab[nsyms].size = elf->sym[i].sym->st_size; + symtab[nsyms].value = elf->sym[i].sym->st_value; + symtab[nsyms].new_symbol = 0; /* To be checked below. */ + strtab_len += strlcpy(strtab + strtab_len, elf->sym[i].name, + KSYM_NAME_LEN) + 1; + nsyms++; + } + } + + for ( i = 0; i < nsyms; i++ ) + { + bool_t found = 0; + + for ( j = 0; j < payload->nfuncs; j++ ) + { + if ( symtab[i].value == payload->funcs[j].new_addr ) + { + found = 1; + break; + } + } + + if ( !found ) + { + if ( xsplice_symbols_lookup_by_name(symtab[i].name) ) + { + printk(XENLOG_ERR XSPLICE "%s: duplicate new symbol: %s\n", + elf->name, symtab[i].name); + xfree(symtab); + xfree(strtab); + return -EEXIST; + } + symtab[i].new_symbol = 1; + dprintk(XENLOG_DEBUG, XSPLICE "%s: new symbol %s\n", + elf->name, symtab[i].name); + } + else + { + /* new_symbol is not set. */ + dprintk(XENLOG_DEBUG, XSPLICE "%s: overriding symbol %s\n", + elf->name, symtab[i].name); + } + } + + payload->symtab = symtab; + payload->strtab = strtab; + payload->nsyms = nsyms; + + return 0; +} + /* We MUST be holding the payload_lock spinlock. */ static void free_payload(struct payload *data) { @@ -389,6 +533,8 @@ static void free_payload(struct payload *data) payload_cnt--; payload_version++; free_payload_data(data); + xfree(data->symtab); + xfree(data->strtab); xfree(data); } @@ -421,6 +567,10 @@ static int load_payload_data(struct payload *payload, void *raw, size_t len) if ( rc ) goto out; + rc = build_symbol_table(payload, &elf); + if ( rc ) + goto out; + rc = secure_payload(payload, &elf); out: @@ -493,8 +643,12 @@ static int xsplice_upload(xen_sysctl_xsplice_upload_t *upload) vfree(raw_data); - if ( rc ) + if ( rc && data ) + { + xfree(data->symtab); + xfree(data->strtab); xfree(data); + } return rc; } diff --git a/xen/common/xsplice_elf.c b/xen/common/xsplice_elf.c index 59323b8c..d08c687 100644 --- a/xen/common/xsplice_elf.c +++ b/xen/common/xsplice_elf.c @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -274,9 +275,22 @@ int xsplice_elf_resolve_symbols(struct xsplice_elf *elf) break; case SHN_UNDEF: - printk(XENLOG_ERR XSPLICE "%s: Unknown symbol: %s\n", - elf->name, elf->sym[i].name); - rc = -ENOENT; + elf->sym[i].sym->st_value = symbols_lookup_by_name(elf->sym[i].name); + if ( !elf->sym[i].sym->st_value ) + { + elf->sym[i].sym->st_value = + xsplice_symbols_lookup_by_name(elf->sym[i].name); + if ( !elf->sym[i].sym->st_value ) + { + printk(XENLOG_ERR XSPLICE "%s: Unknown symbol: %s\n", + elf->name, elf->sym[i].name); + rc = -ENOENT; + break; + } + } + dprintk(XENLOG_DEBUG, XSPLICE "%s: Undefined symbol resolved: %s => %#"PRIx64"\n", + elf->name, elf->sym[i].name, + (uint64_t)elf->sym[i].sym->st_value); break; case SHN_ABS: diff --git a/xen/include/xen/symbols.h b/xen/include/xen/symbols.h index f58e611..d9bd35f 100644 --- a/xen/include/xen/symbols.h +++ b/xen/include/xen/symbols.h @@ -23,4 +23,6 @@ const char *symbols_lookup(unsigned long addr, int xensyms_read(uint32_t *symnum, char *type, uint64_t *address, char *name); +unsigned long symbols_lookup_by_name(const char *symname); + #endif /*_XEN_SYMBOLS_H*/ diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h index 71d7939..86d272e 100644 --- a/xen/include/xen/xsplice.h +++ b/xen/include/xen/xsplice.h @@ -40,8 +40,16 @@ struct xsplice_patch_func_internal { /* Convenience define for printk. */ #define XSPLICE "xsplice: " +struct xsplice_symbol { + const char *name; + uint64_t value; + size_t size; + bool_t new_symbol; +}; + int xsplice_op(struct xen_sysctl_xsplice_op *); void check_for_xsplice_work(void); +unsigned long xsplice_symbols_lookup_by_name(const char *symname); /* Arch hooks. */ int arch_xsplice_verify_elf(const struct xsplice_elf *elf);