about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/include/myalign32.h31
-rwxr-xr-xsrc/libtools/myalign32.c77
-rw-r--r--src/libtools/obstack.c10
3 files changed, 116 insertions, 2 deletions
diff --git a/src/include/myalign32.h b/src/include/myalign32.h
index 9ae11ecb..08b9d3ad 100755
--- a/src/include/myalign32.h
+++ b/src/include/myalign32.h
@@ -626,4 +626,35 @@ typedef	struct my_ns_rr_32_s {
 	ptr_t	      rdata;  //const unsigned char *
 } my_ns_rr_32_t;
 
+struct my_obstack_chunk_32_t
+{
+  ptr_t  limit; //char *
+  ptr_t  prev;  //struct _obstack_chunk *
+  char contents[4];
+};
+
+struct my_obstack_32_t
+{
+  long_t chunk_size;
+  ptr_t  chunk; //struct _obstack_chunk *
+  ptr_t  object_base; //char*
+  ptr_t  next_free; //char*
+  ptr_t  chunk_limit; //char*
+  union
+  {
+    int tempint;
+    ptr_t tempptr;  //void*
+  } temp;
+  int alignment_mask;
+  ptr_t chunkfun; //struct _obstack_chunk *(*chunkfun) (void *, long);
+  ptr_t freefun; //void (*freefun) (void *, struct _obstack_chunk *);
+  ptr_t extra_arg;//void *
+  unsigned use_extra_arg : 1;
+  unsigned maybe_empty_object : 1;
+  unsigned alloc_failed : 1;
+};
+
+void convert_obstack_to_32(void* d, void* s);
+void convert_obstack_to_64(void* d, void* s);
+
 #endif//__MY_ALIGN32__H_
\ No newline at end of file
diff --git a/src/libtools/myalign32.c b/src/libtools/myalign32.c
index 0ce60bfc..c3228714 100755
--- a/src/libtools/myalign32.c
+++ b/src/libtools/myalign32.c
@@ -6,6 +6,7 @@
 #include <sys/epoll.h>
 #include <fts.h>
 #include <sys/socket.h>
+#include <obstack.h>
 
 #include "x64emu.h"
 #include "emu/x64emu_private.h"
@@ -1614,3 +1615,79 @@ void convert_regext_to_64(void* d, void* s)
     dst->re_nsub = from_ulong(src->re_nsub);
     dst->flags = src->flags;
 }
+
+void* inplace_obstack_chunk_shrink(void* a)
+{
+    if(a) {
+        struct my_obstack_chunk_32_t* dst = a;
+        struct _obstack_chunk* src = a;
+        dst->limit = to_ptrv(src->limit);
+        dst->prev = to_ptrv(src->prev);
+        memcpy(dst->contents, src->contents, sizeof(dst->contents));
+    }
+    return a;
+}
+void* inplace_obstack_chunk_enlarge(void* a)
+{
+    if(a) {
+        struct my_obstack_chunk_32_t* src = a;
+        struct _obstack_chunk* dst = a;
+        memcpy(dst->contents, src->contents, sizeof(dst->contents));
+        dst->prev = from_ptrv(src->prev);
+        dst->limit = from_ptrv(src->limit);
+    }
+    return a;
+}
+
+void convert_obstack_to_32(void* d, void* s)
+{
+    if(!d || !s) return;
+    struct my_obstack_32_t* dst = d;
+    struct obstack *src = s;
+    // chunks
+    struct _obstack_chunk* chunk = src->chunk;
+    while(chunk) {
+        struct _obstack_chunk* prev = chunk->prev;
+        inplace_obstack_chunk_shrink(chunk);
+        chunk = prev;
+    }
+    // struture
+    dst->chunk_size = to_long(src->chunk_size);
+    dst->chunk = to_ptrv(src->chunk);
+    dst->object_base = to_ptrv(src->object_base);
+    dst->next_free = to_ptrv(src->next_free);
+    dst->chunk_limit = to_ptrv(src->chunk_limit);
+    dst->temp.tempptr = to_ptrv(src->temp.tempptr);
+    dst->chunkfun = to_ptrv(src->chunkfun);
+    dst->freefun = to_ptrv(src->freefun);
+    dst->extra_arg = to_ptrv(src->extra_arg);
+    dst->use_extra_arg = src->use_extra_arg;
+    dst->maybe_empty_object = src->maybe_empty_object;
+    dst->alloc_failed = src->alloc_failed;
+}
+void convert_obstack_to_64(void* d, void* s)
+{
+    if(!d || !s) return;
+    struct my_obstack_32_t* src = s;
+    struct obstack *dst = d;
+    // struture
+    dst->alloc_failed = src->alloc_failed;
+    dst->maybe_empty_object = src->maybe_empty_object;
+    dst->use_extra_arg = src->use_extra_arg;
+    dst->extra_arg = from_ptrv(src->extra_arg);
+    dst->freefun = from_ptrv(src->freefun);
+    dst->chunkfun = from_ptrv(src->chunkfun);
+    dst->temp.tempptr = from_ptrv(src->temp.tempptr);
+    dst->chunk_limit = from_ptrv(src->chunk_limit);
+    dst->next_free = from_ptrv(src->next_free);
+    dst->object_base = from_ptrv(src->object_base);
+    dst->chunk = from_ptrv(src->chunk);
+    dst->chunk_size = from_long(src->chunk_size);
+    // chunks
+    struct _obstack_chunk* chunk = dst->chunk;
+    while(chunk) {
+        struct _obstack_chunk* prev = chunk->prev;
+        inplace_obstack_chunk_enlarge(chunk);
+        chunk = prev;
+    }
+}
diff --git a/src/libtools/obstack.c b/src/libtools/obstack.c
index 3f923f8a..93d47fbf 100644
--- a/src/libtools/obstack.c
+++ b/src/libtools/obstack.c
@@ -224,7 +224,10 @@ EXPORT void my__obstack_newchunk(x64emu_t* emu, struct obstack* obstack, int s)
 #ifdef BOX32
 EXPORT void my32__obstack_newchunk(x64emu_t* emu, struct obstack* obstack, int s)
 {
-    _obstack_newchunk(obstack, s);
+    struct obstack obstack_l = {0};
+    convert_obstack_to_64(&obstack_l, obstack);
+    _obstack_newchunk(&obstack_l, s);
+    convert_obstack_to_32(obstack, &obstack_l);
 }
 #endif
 
@@ -242,9 +245,12 @@ EXPORT int32_t my_obstack_vprintf(x64emu_t* emu, struct obstack* obstack, void*
 #ifdef BOX32
 EXPORT int32_t my32_obstack_vprintf(x64emu_t* emu, struct obstack* obstack, void* fmt, void* b)
 {
+    struct obstack obstack_l = {0};
+    convert_obstack_to_64(&obstack_l, obstack);
     myStackAlign32((const char*)fmt, b, emu->scratch);
     PREPARE_VALIST_32;
-    int r = obstack_vprintf(obstack, (const char*)fmt, VARARGS_32);
+    int r = obstack_vprintf(&obstack_l, (const char*)fmt, VARARGS_32);
+    convert_obstack_to_32(obstack, &obstack_l);
     return r;
 }
 #endif