about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-03-28 14:05:07 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-03-28 14:05:07 +0200
commit07a65d4827a8d71d43c072f0279689e5abe9751f (patch)
tree28632a5add4e192cddc724a515e7a1a940ab1767 /src
parent35e35ec5db52c96e71f8ed207265941e8734d8a1 (diff)
downloadbox64-07a65d4827a8d71d43c072f0279689e5abe9751f.tar.gz
box64-07a65d4827a8d71d43c072f0279689e5abe9751f.zip
Added some obstack_XXX wrapped function (ported from box86)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/include/myalign.h4
-rwxr-xr-xsrc/libtools/obstack.c224
-rw-r--r--src/wrapped/generated/functions_list.txt2
-rw-r--r--src/wrapped/generated/wrappedlibctypes.h2
-rwxr-xr-xsrc/wrapped/wrappedlibc_private.h4
5 files changed, 234 insertions, 2 deletions
diff --git a/src/include/myalign.h b/src/include/myalign.h
index d627b25d..264c71eb 100755
--- a/src/include/myalign.h
+++ b/src/include/myalign.h
@@ -1,3 +1,5 @@
+#ifndef __MY_ALIGN__H_
+#define __MY_ALIGN__H_
 #include <stdint.h>
 
 typedef struct x64_va_list_s {
@@ -171,3 +173,5 @@ void UnalignSemidDs(void *dest, const void* source);
 void AlignSemidDs(void *dest, const void* source);
 
 uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N);
+
+#endif  //__MY_ALIGN__H_
\ No newline at end of file
diff --git a/src/libtools/obstack.c b/src/libtools/obstack.c
new file mode 100755
index 00000000..c090005a
--- /dev/null
+++ b/src/libtools/obstack.c
@@ -0,0 +1,224 @@
+#define _LARGEFILE_SOURCE 1
+#define _FILE_OFFSET_BITS 64
+#define _GNU_SOURCE         /* See feature_test_macros(7) */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <obstack.h>
+
+#include "wrappedlibs.h"
+
+#include "box64stack.h"
+#include "x64emu.h"
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "callback.h"
+#include "librarian.h"
+#include "librarian/library_private.h"
+#include "emu/x64emu_private.h"
+#include "box64context.h"
+#include "myalign.h"
+#include "signals.h"
+#include "fileutils.h"
+#include "auxval.h"
+#include "elfloader.h"
+#include "bridge.h"
+
+typedef void    (*vFv_t)    ();
+typedef int32_t (*iFppp_t)  (void*, void*, void*);
+typedef int32_t (*iFpLLpp_t)(void*, size_t, size_t, void*, void*);
+
+// utility functions
+#define SUPER() \
+GO(0)   \
+GO(1)   \
+GO(2)   \
+GO(3)   \
+GO(4)
+
+// chunkfun
+#define GO(A)   \
+static uintptr_t my_chunkfun_fct_##A = 0;                                      \
+static void* my_chunkfun_##A(size_t a) \
+{                                                                               \
+    return (void*)RunFunction(my_context, my_chunkfun_fct_##A, 1, a);            \
+}
+SUPER()
+#undef GO
+static void* findchunkfunFct(void* fct)
+{
+    if(!fct) return NULL;
+    void* p;
+    if((p = GetNativeFnc((uintptr_t)fct))) return p;
+    #define GO(A) if(my_chunkfun_fct_##A == (uintptr_t)fct) return my_chunkfun_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_chunkfun_fct_##A == 0) {my_chunkfun_fct_##A = (uintptr_t)fct; return my_chunkfun_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libc chunkfun callback\n");
+    return NULL;
+}
+static void* reverse_chunkfunFct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->priv.w.bridge, fct))
+        return (void*)CheckBridged(lib->priv.w.bridge, fct);
+    #define GO(A) if(my_chunkfun_##A == fct) return (void*)my_chunkfun_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddBridge(lib->priv.w.bridge, pFL, fct, 0, NULL);
+}
+// freefun
+#define GO(A)   \
+static uintptr_t my_freefun_fct_##A = 0;                \
+static void my_freefun_##A(void* a)                     \
+{                                                       \
+    RunFunction(my_context, my_freefun_fct_##A, 1, a);  \
+}
+SUPER()
+#undef GO
+static void* findfreefunFct(void* fct)
+{
+    if(!fct) return NULL;
+    void* p;
+    if((p = GetNativeFnc((uintptr_t)fct))) return p;
+    #define GO(A) if(my_freefun_fct_##A == (uintptr_t)fct) return my_freefun_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_freefun_fct_##A == 0) {my_freefun_fct_##A = (uintptr_t)fct; return my_freefun_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libc freefun callback\n");
+    return NULL;
+}
+static void* reverse_freefunFct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->priv.w.bridge, fct))
+        return (void*)CheckBridged(lib->priv.w.bridge, fct);
+    #define GO(A) if(my_freefun_##A == fct) return (void*)my_freefun_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddBridge(lib->priv.w.bridge, vFp, fct, 0, NULL);
+}
+
+#undef SUPER
+
+struct i386_obstack
+{
+  long	chunk_size;
+  struct _obstack_chunk *chunk;
+  char	*object_base;
+  char	*next_free;
+  char	*chunk_limit;
+  union
+  {
+    uintptr_t tempint;
+    void *tempptr;
+  } temp;
+  int   alignment_mask;
+  struct _obstack_chunk *(*chunkfun) (void *, long);
+  void (*freefun) (void *, struct _obstack_chunk *);
+  void *extra_arg;
+  unsigned use_extra_arg:1;
+  unsigned maybe_empty_object:1;
+  unsigned alloc_failed:1;
+} __attribute__((packed));
+
+#define SUPER() \
+GO(chunk_size)  \
+GO(chunk)       \
+GO(object_base) \
+GO(next_free)   \
+GO(chunk_limit) \
+GO(temp.tempint)\
+GO(alignment_mask)      \
+GO(extra_arg)           \
+GO(use_extra_arg)       \
+GO(maybe_empty_object)  \
+GO(alloc_failed)
+
+void to_i386_obstack(struct i386_obstack *_i386, struct obstack *native)
+{
+    #define GO(A)   _i386->A = native->A;
+    SUPER();
+    #undef GO
+    _i386->chunkfun = findchunkfunFct(native->chunkfun);
+    _i386->freefun = findfreefunFct(native->freefun);
+}
+
+void from_i386_obstack(struct i386_obstack *_i386, struct obstack *native)
+{
+    #define GO(A)   native->A = _i386->A;
+    SUPER();
+    #undef GO
+    native->chunkfun = reverse_chunkfunFct(my_context->libclib, _i386->chunkfun);
+    native->freefun = reverse_freefunFct(my_context->libclib, _i386->freefun);
+}
+#undef SUPER
+
+EXPORT int my__obstack_begin(struct i386_obstack * obstack, size_t size, size_t alignment, void* chunkfun, void* freefun)
+{
+    struct obstack native = {0};
+    from_i386_obstack(obstack, &native);    // is this needed?
+    int ret = _obstack_begin(&native, size, alignment, findchunkfunFct(chunkfun), findfreefunFct(freefun));
+    to_i386_obstack(obstack, &native);
+    return ret;
+}
+
+EXPORT void my_obstack_free(struct i386_obstack * obstack, void* block)
+{
+    struct obstack native = {0};
+    from_i386_obstack(obstack, &native);
+    obstack_free(&native, block);
+    to_i386_obstack(obstack, &native);  // usefull??
+}
+EXPORT void my__obstack_free(struct i386_obstack * obstack, void* block) __attribute__((alias("my_obstack_free")));
+
+EXPORT void my__obstack_newchunk(x64emu_t* emu, struct i386_obstack* obstack, int s)
+{
+    struct obstack native = {0};
+    from_i386_obstack(obstack, &native);
+    _obstack_newchunk(&native, s);
+    to_i386_obstack(obstack, &native);  //usefull??
+}
+
+EXPORT int32_t my_obstack_vprintf(x64emu_t* emu, struct i386_obstack* obstack, void* fmt, x64_va_list_t V)
+{
+    struct obstack native = {0};
+    from_i386_obstack(obstack, &native);
+    #ifdef CONVERT_VALIST
+    CONVERT_VALIST(V);
+    #else
+    myStackAlignValist(emu, (const char*)fmt, emu->scratch, V);
+    PREPARE_VALIST;
+    #endif
+    int r = obstack_vprintf(&native, (const char*)fmt, VARARGS);
+    to_i386_obstack(obstack, &native);  //usefull??
+    return r;
+}
+
+EXPORT void* my_obstack_alloc_failed_handler = NULL;
+void* ref_obstack_alloc_failed_handler = NULL;
+vFv_t real_obstack_alloc_failed_handler = NULL;
+void actual_obstack_alloc_failed_handler()
+{
+    if(ref_obstack_alloc_failed_handler == my_obstack_alloc_failed_handler)
+        real_obstack_alloc_failed_handler();
+    RunFunction(my_context, (uintptr_t)my_obstack_alloc_failed_handler, 0);
+}
+void obstackSetup()
+{
+    // save the real function
+    real_obstack_alloc_failed_handler = obstack_alloc_failed_handler;
+    // bridge the real function for x64 world
+    my_obstack_alloc_failed_handler = (void*)AddCheckBridge(my_context->system, vFv, real_obstack_alloc_failed_handler, 0, NULL);
+    ref_obstack_alloc_failed_handler = my_obstack_alloc_failed_handler;
+    // setup our version of the function
+    obstack_alloc_failed_handler = actual_obstack_alloc_failed_handler;
+
+}
diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt
index e97edea4..a95b0fef 100644
--- a/src/wrapped/generated/functions_list.txt
+++ b/src/wrapped/generated/functions_list.txt
@@ -2659,6 +2659,7 @@ wrappedlibc:
 - vFpi:
   - __longjmp_chk
   - _longjmp
+  - _obstack_newchunk
   - longjmp
   - siglongjmp
 - vFpu:
@@ -2754,6 +2755,7 @@ wrappedlibc:
   - sscanf
   - swscanf
 - iFppA:
+  - obstack_vprintf
   - vasprintf
   - vfprintf
   - vfscanf
diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h
index 31559808..98f053fe 100644
--- a/src/wrapped/generated/wrappedlibctypes.h
+++ b/src/wrapped/generated/wrappedlibctypes.h
@@ -101,6 +101,7 @@ typedef int64_t (*iFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*
 	GO(mallinfo, pFp_t) \
 	GO(__longjmp_chk, vFpi_t) \
 	GO(_longjmp, vFpi_t) \
+	GO(_obstack_newchunk, vFpi_t) \
 	GO(longjmp, vFpi_t) \
 	GO(siglongjmp, vFpi_t) \
 	GO(_ITM_registerTMCloneTable, vFpu_t) \
@@ -171,6 +172,7 @@ typedef int64_t (*iFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*
 	GO(sprintf, iFppV_t) \
 	GO(sscanf, iFppV_t) \
 	GO(swscanf, iFppV_t) \
+	GO(obstack_vprintf, iFppA_t) \
 	GO(vasprintf, iFppA_t) \
 	GO(vfprintf, iFppA_t) \
 	GO(vfscanf, iFppA_t) \
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index 39871a47..a3691d83 100755
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -1262,10 +1262,10 @@ GOW(ntp_adjtime, iFp)
 //GO(_obstack_free, 
 //GO(obstack_free, 
 //GO(_obstack_memory_used, 
-//GO(_obstack_newchunk, 
+GOM(_obstack_newchunk, vFEpi)
 //GOW(obstack_printf, iFppV)
 //GO(__obstack_printf_chk, 
-//GOW(obstack_vprintf, iFppA)
+GOWM(obstack_vprintf, iFEppA)
 //GO(__obstack_vprintf_chk, 
 //GOW(on_exit, iF@p)
 GOWM(__open, iFEpOu)