]> xenbits.xensource.com Git - xen.git/commitdiff
libelf: Tidy up logging and remove dependency on stdio.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 28 May 2010 08:27:40 +0000 (09:27 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 28 May 2010 08:27:40 +0000 (09:27 +0100)
libelf now permits callers to specify logging callback functions,
rather than a FILE*.  libelf's non-Xen callers are all libxc users, so
the stdio dependency and the default logging callback function (which
calls vfprintf) is now in libxc.

Xen's use of libxc is unaffected in this patch.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
tools/libxc/xc_dom_elfloader.c
tools/libxc/xenctrl.h
tools/xcutils/readnotes.c
xen/common/libelf/libelf-loader.c
xen/common/libelf/libelf-private.h
xen/common/libelf/libelf-relocate.c
xen/include/xen/libelf.h

index f9bbd85ba3e20b2125c1fc53d8dfbd4baa415ca6..280f722d30fd099c9ad0ca9a7b78a4321fdb82c3 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <inttypes.h>
 
 #include "xg_private.h"
 
 /* ------------------------------------------------------------------------ */
 
+static void log_callback(struct elf_binary *elf, void *caller_data,
+                         int iserr, const char *fmt, va_list al) {
+    vfprintf(caller_data,fmt,al);
+}
+
+void xc_elf_set_logfile(struct elf_binary *elf, FILE *f, int verbose) {
+    elf_set_log(elf, log_callback, f, verbose);
+}
+
+/* ------------------------------------------------------------------------ */
+
 static char *xc_dom_guest_type(struct xc_dom_image *dom,
                                struct elf_binary *elf)
 {
@@ -137,8 +149,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
     }
     if ( elf_init(&syms, hdr + sizeof(int), size - sizeof(int)) )
         return -1;
+
     if ( xc_dom_logfile )
-        elf_set_logfile(&syms, xc_dom_logfile, 1);
+        xc_elf_set_logfile(&syms, xc_dom_logfile, 1);
 
     symtab = dom->bsd_symtab_start + sizeof(int);
     maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) +
@@ -231,7 +244,7 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
     dom->private_loader = elf;
     rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
     if ( xc_dom_logfile )
-        elf_set_logfile(elf, xc_dom_logfile, 1);
+        xc_elf_set_logfile(elf, xc_dom_logfile, 1);
     if ( rc != 0 )
     {
         xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n",
index 2d01467d82e2c521bb95155eabcf5e6680ce3178..f63f96deb71ead0c78a355186a1791aa05050cd5 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <xen/xen.h>
 #include <xen/domctl.h>
 #include <xen/physdev.h>
@@ -1474,4 +1475,8 @@ int xc_memshr_debug_gref(int xc_handle,
                          uint32_t domid,
                          grant_ref_t gref);
 
+struct elf_binary;
+void xc_elf_set_logfile(struct elf_binary *elf, FILE *f, int verbose);
+/* Useful for callers who also use libelf. */
+
 #endif /* XENCTRL_H */
index b770f56fe9f6bc748494cbf43f1e68ce5885ffa8..270c48b01776a5574c0bc02a2b68b87776b0550e 100644 (file)
@@ -170,7 +170,7 @@ int main(int argc, char **argv)
                fprintf(stderr, "File %s is not an ELF image\n", f);
                return 1;
        }
-       elf_set_logfile(&elf, stderr, 0);
+       xc_elf_set_logfile(&elf, stderr, 0);
 
        count = elf_phdr_count(&elf);
        for ( h=0; h < count; h++)
index 5e865558171136fa9876a6310e623186e8b2a23a..f50524f69082383a7e5731c1b72a815f39564c50 100644 (file)
@@ -2,6 +2,8 @@
  * parse and load elf binaries
  */
 
+#include <stdarg.h>
+
 #include "libelf-private.h"
 
 /* ------------------------------------------------------------------------ */
@@ -72,9 +74,25 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
 }
 
 #ifndef __XEN__
-void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose)
+void elf_call_log_callback(struct elf_binary *elf, int iserr,
+                           const char *fmt,...) {
+    va_list al;
+
+    if (!elf->log_callback)
+        return;
+    if (!(iserr || elf->verbose))
+        return;
+
+    va_start(al,fmt);
+    elf->log_callback(elf, elf->log_caller_data, iserr, fmt, al);
+    va_end(al);
+}
+    
+void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
+                 void *log_caller_data, int verbose)
 {
-    elf->log = log;
+    elf->log_callback = log_callback;
+    elf->log_caller_data = log_caller_data;
     elf->verbose = verbose;
 }
 #else
index e207b690c428c014ec0d0dfc83e02523684a5b8c..fcce9e331af982d533c63b742d290ddc024633a8 100644 (file)
@@ -11,6 +11,8 @@
 #include <asm/byteorder.h>
 #include <public/elfnote.h>
 
+/* we would like to use elf->log_callback but we can't because
+ * there is no vprintk in Xen */
 #define elf_msg(elf, fmt, args ... ) \
    if (elf->verbose) printk(fmt, ## args )
 #define elf_err(elf, fmt, args ... ) \
 #include "xenctrl.h"
 #include "xc_private.h"
 
-#define elf_msg(elf, fmt, args ... ) \
-    if (elf->log && elf->verbose) fprintf(elf->log, fmt , ## args )
-#define elf_err(elf, fmt, args ... ) do {               \
-    if (elf->log)                                       \
-        fprintf(elf->log, fmt , ## args );              \
-    xc_set_error(XC_INVALID_KERNEL, fmt , ## args );    \
-} while (0)
+#define elf_msg(elf, fmt, args ... )                    \
+    elf_call_log_callback(elf, 0, fmt , ## args );
+#define elf_err(elf, fmt, args ... )                    \
+    elf_call_log_callback(elf, 1, fmt , ## args );
+
+void elf_call_log_callback(struct elf_binary*, int iserr, const char *fmt,...);
 
 #define safe_strcpy(d,s)                        \
 do { strncpy((d),(s),sizeof((d))-1);            \
index 89cea4411b4bc2d3bdb117de764ecbfba73b281c..fe9891da702c25a1eabc7141ecaa7e92f3a0b635 100644 (file)
@@ -289,7 +289,7 @@ static int elf_reloc_section(struct elf_binary *elf,
         value = elf_uval(elf, sym, st_value);
         value += r_addend;
 
-        if ( elf->log && (elf->verbose > 1) )
+        if ( elf->log_callback && (elf->verbose > 1) )
         {
             uint64_t st_name = elf_uval(elf, sym, st_name);
             const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*";
index 1c92a73f1d1d036cecee4c9f17c446ff451d639c..584d8b3b2dc551e9df0a7b77d230a923058fc069 100644 (file)
 #else
 #include <xen/elfnote.h>
 #include <xen/features.h>
+
+#include <stdarg.h>
+
+struct elf_binary;
+typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+                              int iserr, const char *fmt, va_list al);
+
 #endif
 
 /* ------------------------------------------------------------------------ */
@@ -99,7 +106,8 @@ struct elf_binary {
 
 #ifndef __XEN__
     /* misc */
-    FILE *log;
+    elf_log_callback *log_callback;
+    void *log_caller_data;
 #endif
     int verbose;
 };
@@ -183,7 +191,8 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size);
 #ifdef __XEN__
 void elf_set_verbose(struct elf_binary *elf);
 #else
-void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose);
+void elf_set_log(struct elf_binary *elf, elf_log_callback*,
+                 void *log_caller_pointer, int verbose);
 #endif
 
 void elf_parse_binary(struct elf_binary *elf);