]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/uklibid: Embedded library information
authorSimon Kuenzer <simon@unikraft.io>
Fri, 15 Sep 2023 10:57:10 +0000 (12:57 +0200)
committerRazvan Deaconescu <razvand@unikraft.io>
Fri, 20 Oct 2023 16:35:55 +0000 (19:35 +0300)
This commit introduces the `.uk_libinfo` section which is used to store
additional library information in library object files. We define the data
structure of the section and declare it as layout version 1. For each
library the build system will generate a single header and each header can
contain an individual number of records to store values.
Layout version 1 also supports storing of information related to the image
as a whole and not to a specific library. A single header is created for
global information, which differs from the library headers in that it does
not contain a record for a library name (LIBNAME).

When a final Unikraft image is linked, the individual sections of each
library are merged into one section.

By default, a minimal set of library and global information is enabled. The
motivation behind this is that library objects are instrumented with
uk_libinfo from now on. In a future commit, the build system could provide
an option to remove this section from (non-debug) images if it is not used
by Unikraft code itself.

Signed-off-by: Simon Kuenzer <simon@unikraft.io>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Robert Kuban <robert.kuban@opensynergy.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1117

lib/uklibid/Config.uk
lib/uklibid/Makefile.uk
lib/uklibid/include/uk/libid/info.h [new file with mode: 0644]
lib/uklibid/infosec.ld [new file with mode: 0644]
lib/uklibid/libinfo.S [new file with mode: 0644]

index 059757d6fbfe62a990fb2ec14cdb46bcb65b4fa8..c9aa633839ca234c0a40d80d8557c6623b060db5 100644 (file)
@@ -1,6 +1,6 @@
-config LIBUKLIBID
+menuconfig LIBUKLIBID
        bool "uklibid: Library identifier"
-       default n
+       default y
        # FIXME: We actually depend on <uk/assert.h> but lib/ukdebug also
        #        depends on us. If we specify the dependency here, it creates a
        #        circular dependency that KConfig doesn't like. However, we
@@ -8,3 +8,64 @@ config LIBUKLIBID
        #        build, so we comment out the dependency here. Of course, this
        #        is not accurate.
        #select LIBUKDEBUG
+
+if LIBUKLIBID
+config LIBUKLIBID_INFO
+       bool "Embedded library metadata"
+       default y
+
+       if LIBUKLIBID_INFO
+       menu "Global metadata"
+               config LIBUKLIBID_INFO_UKFULLVERSION
+                       bool "Full unikraft version"
+                       default y
+                       help
+                               If enabled, the full Unikraft version including
+                               Git SHA is embedded. Otherwise, only the short
+                               Unikraft version is stored.
+
+               config LIBUKLIBID_INFO_UKCODENAME
+                       bool "Unikraft codename"
+                       help
+                               If enabled, the Unikraft release codename is
+                               stored as part of the global metadata
+                               information.
+
+               config LIBUKLIBID_INFO_COMPILER
+                       bool "Compiler (CC) information"
+                       help
+                               Enables storing the C compiler ($(CC)) that was
+                               used for during compilation for the unikernel
+                               image.
+       endmenu
+
+       menu "Per library metadata"
+               config LIBUKLIBID_INFO_LIB_UKVERSION
+                       bool "Unikraft version"
+                       help
+                               If enabled, the Unikraft version is included
+                               to each library.
+
+               config LIBUKLIBID_INFO_LIB_UKFULLVERSION
+                       bool "Full version"
+                       depends on LIBUKLIBID_INFO_LIB_UKVERSION
+                       help
+                               Instead of the short Unikraft version, the full
+                               Unikraft version including Git SHA is embedded
+                               to each library.
+
+               config LIBUKLIBID_INFO_LIB_UKCODENAME
+                       bool "Unikraft codename"
+                       help
+                               If enabled, the Unikraft release codename is
+                               stored as part of each library metadata
+                               information.
+
+               config LIBUKLIBID_INFO_LIB_COMPILER
+                       bool "Compiler (CC) information"
+                       default y
+                       help
+                               Enables storing the C compiler ($(CC)) that was
+                               used for each library.
+       endmenu
+endif
index 2090a1267a2b06dbae68cdb9062017931cd65ba4..3d94d938effcc101490ee7907cc12b4518d89e70 100644 (file)
@@ -38,4 +38,10 @@ LIBUKLIBID_SRCS-y += $(LIBUKLIBID_BASE)/exportsyms.awk>.uk
 LIBUKLIBID_EXPORTSYMS_AWKINCLUDES-y += $(LIBUKLIBID_BUILD)/libraries.in
 LIBUKLIBID_EXPORTS-y += $(LIBUKLIBID_BUILD)/exportsyms.uk
 
+EACHOLIB_SRCS-$(CONFIG_LIBUKLIBID_INFO) += $(LIBUKLIBID_BASE)/libinfo.S|libuklibid
+ASFLAGS += -D__LIBUKLIBID_COMPILER__="$(CC_INFO)"
+LIBUKLIBID_SRCS-$(CONFIG_LIBUKLIBID_INFO) +=  $(LIBUKLIBID_BASE)/infosec.ld
+LIBUKLIBID_SRCS-$(CONFIG_LIBUKLIBID_INFO) += $(LIBUKLIBID_BASE)/libinfo.S|global
+LIBUKLIBID_LIBINFO_GLOBAL_FLAGS-y += -D__GLOBALINFO__
+
 UK_PREPARE-$(CONFIG_LIBUKLIBID) += $(LIBUKLIBID_BUILD)/libraries.in.new
diff --git a/lib/uklibid/include/uk/libid/info.h b/lib/uklibid/include/uk/libid/info.h
new file mode 100644 (file)
index 0000000..9168d3b
--- /dev/null
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors.
+ * Licensed under the BSD-3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ */
+#ifndef __UK_LIBID_INFO_H__
+#define __UK_LIBID_INFO_H__
+
+#include <uk/arch/types.h>
+#include <uk/essentials.h>
+
+/*
+ * Library information is stored in the special section " .uk_libinfo". For
+ * each library there is one `struct uk_libid_info_hdr` generated. Each header
+ * can contain multiple `struct uk_libid_info_rec` records. A library name
+ * record (`UKLI_REC_LIBNAME`) is the only mandatory record type for each
+ * library.
+ * Additionally, a single header is created for global information, which
+ * differs from the library headers in that it does not contain a record for a
+ * library name.
+ *
+ * Layout for each information header:
+ *
+ *                              _____________
+ *  +--------------------------+             \
+ *  | struct uk_libid_info_hdr |              |
+ *  |                          |               > hdr->len
+ *  +--------------------------+              |
+ *  | struct uk_libid_info_rec |              |
+ *  +--------------------------+ -.           |
+ *  | struct uk_libid_info_rec |   > rec->len |
+ *  |                          |  |           |
+ *  +--------------------------+ -`           |
+ *  :          . . .           :              :
+ *  +--------------------------+              |
+ *  | struct uk_libid_info_rec |              |
+ *  |                          |              |
+ *  +--------------------------+ ____________/
+ */
+
+/*
+ * NOTE: The layout version needs only be updated if the structs
+ *       `uk_libid_info_rec` and `uk_libid_info_hdr` are updated.
+ */
+ #define UKLI_LAYOUT              0x0001
+
+/*
+ * NOTE: In order to keep backwards compatibility with pre-compiled
+ *       libraries, this list should only be extended with new entries.
+ */
+#define UKLI_REC_LIBNAME          0x0001 /* C-string, absent for global hdr */
+#define UKLI_REC_COMMENT          0x0002 /* C-string */
+#define UKLI_REC_VERSION          0x0003 /* C-string */
+#define UKLI_REC_LICENSE          0x0004 /* C-string */
+#define UKLI_REC_GITDESC          0x0005 /* C-string */
+#define UKLI_REC_UKVERSION        0x0006 /* C-string, Unikraft version only */
+#define UKLI_REC_UKFULLVERSION    0x0007 /* C-string, UK version with gitsha */
+#define UKLI_REC_UKCODENAME       0x0008 /* C-string */
+#define UKLI_REC_UKCONFIG         0x0009 /* binary data */
+#define UKLI_REC_UKCONFIGGZ       0x000A /* binary data */
+#define UKLI_REC_COMPILER         0x000B /* C-string */
+#define UKLI_REC_COMPILEDATE      0x000C /* C-string */
+#define UKLI_REC_COMPILEDBY       0x000D /* C-string */
+#define UKLI_REC_COMPILEDBYASSOC  0x000E /* C-string */
+#define UKLI_REC_COMPILEOPTS      0x000F /* __u32 flags */
+
+#if !__ASSEMBLY__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct uk_libid_info_rec {
+       __u16 type;    /* record type */
+       __u32 len;     /* including record header */
+       char  data[];  /* raw data */
+} __packed __align(1);
+
+/*
+ * NOTE: Due to binary cross-compatibility, the sizes, offsets, data types and
+ *       meanings must remain the same regardless of the layout version:
+ *       `len` and `version`.
+ */
+struct uk_libid_info_hdr {
+       __u32 len;     /* including header */
+       __u16 version; /* layout version */
+       struct uk_libid_info_rec recs[];
+} __packed __align(1);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !__ASSEMBLY__ */
+#endif /* __UK_LIBID_INFO_H__ */
diff --git a/lib/uklibid/infosec.ld b/lib/uklibid/infosec.ld
new file mode 100644 (file)
index 0000000..7639c2b
--- /dev/null
@@ -0,0 +1,9 @@
+SECTIONS
+{
+       . = ALIGN(1);
+       .uk_libinfo :
+       {
+               KEEP (*(.uk_libinfo))
+       }
+}
+INSERT AFTER .rodata;
diff --git a/lib/uklibid/libinfo.S b/lib/uklibid/libinfo.S
new file mode 100644 (file)
index 0000000..bde6e74
--- /dev/null
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors.
+ * Licensed under the BSD-3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ */
+#include <uk/config.h>
+#include <uk/libid/info.h>
+#include <uk/arch/types.h>
+
+#define RECORD(type, data)                               \
+       .align 1                                        ; \
+1:     .__u16 type                     /* type */      ; \
+       .__u32 2f - 1b                  /* len */       ; \
+       data                            /* data[] */    ; \
+2:     .align 1
+
+.pushsection .uk_libinfo, "a"
+       .align 1
+3:     .__u32 4f - 3b                  /* len */
+       .__u16 UKLI_LAYOUT              /* version */
+
+#if __GLOBALINFO__
+       /* Only one global header per unikernel is generated */
+       /* NOTE: Global metadata do not have a libname record */
+#if CONFIG_LIBUKLIBID_INFO_UKFULLVERSION
+       RECORD(UKLI_REC_UKFULLVERSION, .asciz STRINGIFY(UK_FULLVERSION))
+#else /* !CONFIG_LIBUKLIBID_INFO_UKFULLVERSION */
+       RECORD(UKLI_REC_UKVERSION,     .asciz STRINGIFY(UK_VERSION))
+#endif /* !CONFIG_LIBUKLIBID_INFO_UKFULLVERSION */
+#if CONFIG_LIBUKLIBID_INFO_UKCODENAME
+       RECORD(UKLI_REC_UKCODENAME,    .asciz STRINGIFY(UK_CODENAME))
+#endif /* CONFIG_LIBUKLIBID_INFO_UKCODENAME */
+#if CONFIG_LIBUKLIBID_INFO_COMPILER
+       RECORD(UKLI_REC_COMPILER,
+              .asciz STRINGIFY(__LIBUKLIBID_COMPILER__))
+#endif /* CONFIG_LIBUKLIBID_INFO_COMPILER */
+
+#else /* !__GLOBALINFO__ */
+       /* Records per library */
+       /* NOTE: The libname record is mandatory */
+       RECORD(UKLI_REC_LIBNAME,       .asciz STRINGIFY(__LIBNAME__))
+#if CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION
+#if CONFIG_LIBUKLIBID_INFO_LIB_UKFULLVERSION
+       RECORD(UKLI_REC_UKFULLVERSION, .asciz STRINGIFY(UK_FULLVERSION))
+#else /* !CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION */
+       RECORD(UKLI_REC_UKVERSION,     .asciz STRINGIFY(UK_VERSION))
+#endif /* !CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION */
+#endif /* CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION */
+#if CONFIG_LIBUKLIBID_INFO_LIB_UKCODENAME
+       RECORD(UKLI_REC_UKCODENAME,    .asciz STRINGIFY(UK_CODENAME))
+#endif /* CONFIG_LIBUKLIBID_INFO_LIB_UKCODENAME */
+#if CONFIG_LIBUKLIBID_INFO_LIB_COMPILER
+       RECORD(UKLI_REC_COMPILER,
+              .asciz STRINGIFY(__LIBUKLIBID_COMPILER__))
+#endif /* CONFIG_LIBUKLIBID_INFO_COMPILER */
+#endif /* !__GLOBALINFO__ */
+
+4:     .align 1
+.popsection