[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/3] Add necessary functions as glue code for unikraft



Most of the glue code added comes from the compat.c source file in
the library. Because of the separate build system, it could not
choose only what functions are needed by unikraft, so they needed
to be added by hand. All of these are below their copyright header.

Some additional function stubs were needed for a successful
compilation. These one are placed first.

The global variable stderr is not initialized in a fully correct way.
It was added because library object files used stderr as a variable
and newlib used stderr as a define.
Right now, in certain situations, printing to stderr does not work,
but it only happens when errors were met, anyway.

Signed-off-by: Cezar Craciunoiu <cezar.craciunoiu@xxxxxxxxx>
---
 glue.c | 337 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 337 insertions(+)
 create mode 100644 glue.c

diff --git a/glue.c b/glue.c
new file mode 100644
index 0000000..5d71dd7
--- /dev/null
+++ b/glue.c
@@ -0,0 +1,337 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <assert.h>
+#include <setjmp.h>
+
+/* Needed because unikraft does not include a stderr variable in newlib */
+#define stderr_redefined stderr
+#undef stderr
+FILE *stderr;
+
+void __assert_fail(const char *assertion, const char *file,
+               unsigned int line, const char *function)
+{
+       /* Workaround */
+       stderr = stderr_redefined;
+       if (function)
+               fprintf(stderr, "%s:%d: %s: %s", file, line,
+                       function, assertion);
+       else
+               fprintf(stderr, "%s:%d: %s", file, line, assertion);
+       abort();
+}
+
+int *__errno_location(void)
+{
+       return NULL;
+}
+
+unsigned short int **__ctype_b_loc(void)
+{
+       return NULL;
+}
+
+const char *getprogname(void)
+{
+       return NULL;
+}
+
+/* Stack guard empty calls for KVM */
+#ifdef PLAT_KVM
+void _setjmp(jmp_buf buf)
+{
+       ;
+}
+
+void __stack_chk_fail(void)
+{
+       /* Workaround */
+       stderr = stderr_redefined;
+}
+
+void __stack_chk_guard(void)
+{
+       /* Workaround */
+       stderr = stderr_redefined;
+}
+#endif
+
+int stat64(const char *path, struct stat *buf)
+{
+       return stat(path, buf);
+}
+
+/* No varargs support */
+int open64(const char *pathname, int oflag, ...)
+{
+       return open(pathname, oflag);
+}
+
+/* No varargs support */
+int fcntl64(int fd, int cmd, ...)
+{
+       return fcntl(fd, cmd);
+}
+
+FILE *fopen64(const char *filename, const char *type)
+{
+       return fopen(filename, type);
+}
+
+int mkstemp64(char *template)
+{
+       return mkstemp(template);
+}
+
+/*
+ * Copyright (c) 2011 Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the
+ *       following disclaimer.
+ *     * Redistributions in binary form must reproduce the
+ *       above copyright notice, this list of conditions and
+ *       the following disclaimer in the documentation and/or
+ *       other materials provided with the distribution.
+ *     * The names of contributors to this software may not be
+ *       used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@xxxxxxxxxxxxxxx>
+ *
+ * THE DISCLAIMER ABOVE APPLIES TO ALL THE FUNCTIONS BELOW IT.
+ */
+
+char *strconcat(const char *first, ...)
+{
+       size_t length = 0;
+       const char *arg;
+       char *result, *at;
+       va_list va;
+
+       va_start(va, first);
+
+       for (arg = first; arg; arg = va_arg(va, const char *)) {
+               size_t old_length = length;
+
+               length += strlen(arg);
+               if (length < old_length) {
+                       va_end(va);
+                       return NULL;
+               }
+       }
+
+       va_end(va);
+
+       at = result = malloc(length + 1);
+       if (result == NULL)
+               return NULL;
+
+       va_start(va, first);
+
+       for (arg = first; arg; arg = va_arg(va, const char *)) {
+               length = strlen(arg);
+               memcpy(at, arg, length);
+               at += length;
+       }
+
+       va_end(va);
+
+       *at = 0;
+       return result;
+}
+
+void *memdup(const void *data, size_t length)
+{
+       void *dup;
+
+       if (!data)
+               return NULL;
+
+       dup = malloc(length);
+       if (dup != NULL)
+               memcpy(dup, data, length);
+
+       return dup;
+}
+
+int p11_ascii_tolower(int c)
+{
+       if (c >= 'A' && c <= 'Z')
+               return 'a' + (c - 'A');
+       return c;
+}
+
+int p11_ascii_toupper(int c)
+{
+       if (c >= 'a' && c <= 'z')
+               return 'A' + (c - 'a');
+       return c;
+}
+
+struct _p11_mmap {
+       int fd;
+       void *data;
+       size_t size;
+};
+
+typedef struct _p11_mmap p11_mmap;
+
+p11_mmap *p11_mmap_open(const char *path, struct stat *sb,
+                       void **data, size_t *size)
+{
+       struct stat stb;
+       p11_mmap *map;
+
+       map = calloc(1, sizeof(p11_mmap));
+       if (map == NULL)
+               return NULL;
+
+       map->fd = open(path, O_RDONLY | O_CLOEXEC);
+       if (map->fd == -1) {
+               free(map);
+               return NULL;
+       }
+
+       if (sb == NULL) {
+               sb = &stb;
+               if (fstat(map->fd, &stb) < 0) {
+                       close(map->fd);
+                       free(map);
+                       return NULL;
+               }
+       }
+
+       /* Workaround for broken ZFS on Linux */
+       if (S_ISDIR(sb->st_mode)) {
+               errno = EISDIR;
+               close(map->fd);
+               free(map);
+               return NULL;
+       }
+
+       if (sb->st_size == 0) {
+               *data = "";
+               *size = 0;
+               return map;
+       }
+
+       map->size = sb->st_size;
+       map->data = mmap(NULL, map->size, PROT_READ, MAP_PRIVATE, map->fd, 0);
+       if (map->data == MAP_FAILED) {
+               close(map->fd);
+               free(map);
+               return NULL;
+       }
+
+       *data = map->data;
+       *size = map->size;
+       return map;
+}
+
+void p11_mmap_close(p11_mmap *map)
+{
+       if (map->size)
+               munmap(map->data, map->size);
+       close(map->fd);
+       free(map);
+}
+
+void p11_dl_close(void *dl)
+{
+       (void) dlclose(dl);
+}
+
+char *p11_dl_error(void)
+{
+       const char *msg = dlerror();
+
+       return msg ? strdup(msg) : NULL;
+}
+
+int fdwalk(int (*cb) (void *data, int fd), void *data)
+{
+       int open_max;
+       int res = 0;
+       int fd;
+       struct rlimit rl;
+
+       /* No /proc, brute force */
+       if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)
+               open_max = rl.rlim_max;
+       else
+               open_max = sysconf(_SC_OPEN_MAX);
+
+       for (fd = 0; fd < open_max; fd++) {
+               res = cb(data, fd);
+               if (res != 0)
+                       break;
+       }
+
+       return res;
+}
+
+#define AT_SECURE 23
+
+unsigned long getauxval(unsigned long type)
+{
+       static unsigned long secure;
+       static unsigned char check_secure_initialized;
+
+       /*
+        * This is the only one our stand-in impl supports and is
+        * also the only type we define in compat.h header
+        */
+       assert(type == AT_SECURE);
+
+       if (!check_secure_initialized) {
+               uid_t ruid, euid, suid;
+               gid_t rgid, egid, sgid;
+
+               if (getresuid(&ruid, &euid, &suid) != 0 ||
+                   getresgid(&rgid, &egid, &sgid) != 0) {
+                       suid = ruid = getuid();
+                       sgid = rgid = getgid();
+                       euid = geteuid();
+                       egid = getegid();
+               }
+
+               secure = (ruid != euid || ruid != suid ||
+                       rgid != egid || rgid != sgid);
+               check_secure_initialized = 1;
+       }
+
+       return secure;
+}
+
+char *secure_getenv(const char *name)
+{
+       if (getauxval(AT_SECURE))
+               return NULL;
+       return getenv(name);
+}
-- 
2.20.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.