From c33683c9dfbbf77003484a136e13e9653da7eee5 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 19 Jun 2022 14:37:51 +0200 Subject: [PATCH] Try some workaround for the libpng16 setjmp handling --- src/wrapped/generated/functions_list.txt | 3 ++ src/wrapped/generated/wrappedpng16types.h | 3 ++ src/wrapped/wrappedlibc.c | 4 ++ src/wrapped/wrappedpng16.c | 63 ++++++++++++++++++++++- src/wrapped/wrappedpng16_private.h | 6 +-- 5 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index 531432bec0..ced636271f 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -3737,14 +3737,17 @@ wrappedpng12: - png_create_write_struct_2 wrappedpng16: - vFpp: + - png_destroy_write_struct - png_set_read_user_transform_fn - vFppp: + - png_destroy_read_struct - png_set_read_fn - vFpppp: - png_set_error_fn - png_set_write_fn - pFpppp: - png_create_read_struct + - png_create_write_struct - vFppppp: - png_set_progressive_read_fn - pFppppppp: diff --git a/src/wrapped/generated/wrappedpng16types.h b/src/wrapped/generated/wrappedpng16types.h index 38158790dc..a7e0c01d27 100644 --- a/src/wrapped/generated/wrappedpng16types.h +++ b/src/wrapped/generated/wrappedpng16types.h @@ -19,11 +19,14 @@ typedef void (*vFppppp_t)(void*, void*, void*, void*, void*); typedef void* (*pFppppppp_t)(void*, void*, void*, void*, void*, void*, void*); #define SUPER() ADDED_FUNCTIONS() \ + GO(png_destroy_write_struct, vFpp_t) \ GO(png_set_read_user_transform_fn, vFpp_t) \ + GO(png_destroy_read_struct, vFppp_t) \ GO(png_set_read_fn, vFppp_t) \ GO(png_set_error_fn, vFpppp_t) \ GO(png_set_write_fn, vFpppp_t) \ GO(png_create_read_struct, pFpppp_t) \ + GO(png_create_write_struct, pFpppp_t) \ GO(png_set_progressive_read_fn, vFppppp_t) \ GO(png_create_read_struct_2, pFppppppp_t) \ GO(png_create_write_struct_2, pFppppppp_t) diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 44d402041e..4f0aeb76c5 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2528,8 +2528,12 @@ EXPORT int32_t my__setjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void * { return my___sigsetjmp(emu, p, 0); } +int png16_setjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p); // in wrappedpng16.c EXPORT int32_t my_setjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) { + int ret; + if((ret = png16_setjmp(emu, p))) + return ret; return my___sigsetjmp(emu, p, 1); } diff --git a/src/wrapped/wrappedpng16.c b/src/wrapped/wrappedpng16.c index 30e6f17911..d5848a2cfe 100755 --- a/src/wrapped/wrappedpng16.c +++ b/src/wrapped/wrappedpng16.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "wrappedlibs.h" @@ -26,7 +27,10 @@ const char* png16Name = ; #define LIBNAME png16 +typedef void (*vFp_t)(void*); + #define ADDED_FUNCTIONS() \ + GO(png_free, vFp_t) #include "generated/wrappedpng16types.h" @@ -85,7 +89,7 @@ static void* finduser_flushFct(void* fct) // user_read #define GO(A) \ static uintptr_t my_user_read_fct_##A = 0; \ -static void my_user_read_##A(void* png_ptr, void* data, int32_t length) \ +static void my_user_read_##A(void* png_ptr, void* data, size_t length) \ { \ RunFunction(my_context, my_user_read_fct_##A, 3, png_ptr, data, length);\ } @@ -288,6 +292,39 @@ static void* finduser_transformFct(void* fct) #undef SUPER +typedef struct png_setjmp_def_s { + jmp_buf jmp_buf_local; + void* longjmp_fn; + jmp_buf *jmp_buf_ptr; + size_t jmp_buf_size; +} png_setjmp_def_t; + +static void* current_png_struct = NULL; +static int current_jmpbuf[12] = {0}; +int32_t my_setjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p); +void my_longjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val); +int png16_setjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) +{ + if(!current_png_struct) + return 0; + png_setjmp_def_t * png = (png_setjmp_def_t*)current_png_struct; + if(!png->jmp_buf_ptr || (uintptr_t)png->jmp_buf_ptr<0x1000) + return 0; + if(p!=*png->jmp_buf_ptr) + return 0; + printf_log(LOG_DEBUG, " (Hack for setjmp inside png16 struct) "); + if(png->jmp_buf_size) { + my->png_free(png->jmp_buf_ptr); + png->jmp_buf_size = 0; + png->jmp_buf_ptr = &png->jmp_buf_local; + } + my_setjmp(emu, current_jmpbuf); + if(setjmp(png->jmp_buf_local)) { + my_longjmp(emu, current_jmpbuf, 1); + } + return 1; +} + EXPORT void my16_png_set_read_fn(x86emu_t *emu, void* png_ptr, void* io_ptr, void* read_data_fn) { my->png_set_read_fn(png_ptr, io_ptr, finduser_readFct(read_data_fn)); @@ -325,7 +362,29 @@ EXPORT void my16_png_set_progressive_read_fn(x86emu_t* emu, void* png_ptr, void* EXPORT void* my16_png_create_read_struct(x86emu_t* emu, void* png_ptr, void* user_ptr, void* errorfn, void* warnfn) { - return my->png_create_read_struct(png_ptr, user_ptr, finderrorFct(errorfn), findwarningFct(warnfn)); + void* ret = my->png_create_read_struct(png_ptr, user_ptr, finderrorFct(errorfn), findwarningFct(warnfn)); + current_png_struct = ret; + return ret; +} + +EXPORT void* my16_png_create_write_struct(x86emu_t* emu, void* png_ptr, void* user_ptr, void* errorfn, void* warnfn) +{ + void* ret = my->png_create_write_struct(png_ptr, user_ptr, finderrorFct(errorfn), findwarningFct(warnfn)); + current_png_struct = ret; + return ret; +} + +EXPORT void my16_png_destroy_read_struct(x86emu_t* emu, void** png_ptr, void** info_ptr, void** end_info_ptr) +{ + if(png_ptr && *png_ptr==current_png_struct) + current_png_struct = NULL; + my->png_destroy_read_struct(png_ptr, info_ptr, end_info_ptr); +} +EXPORT void my16_png_destroy_write_struct(x86emu_t* emu, void** png_ptr, void** info_ptr) +{ + if(png_ptr && *png_ptr==current_png_struct) + current_png_struct = NULL; + my->png_destroy_write_struct(png_ptr, info_ptr); } #define CUSTOM_INIT \ diff --git a/src/wrapped/wrappedpng16_private.h b/src/wrapped/wrappedpng16_private.h index 19eb44648b..b561295495 100755 --- a/src/wrapped/wrappedpng16_private.h +++ b/src/wrapped/wrappedpng16_private.h @@ -5,9 +5,9 @@ GO(png_convert_from_time_t, vFpu) GOM(png_create_read_struct, pFEpppp) GO(png_create_info_struct, pFp) -GO(png_create_write_struct, pFpppp) -GO(png_destroy_read_struct, vFppp) -GO(png_destroy_write_struct, vFpp) +GOM(png_create_write_struct, pFEpppp) +GOM(png_destroy_read_struct, vFEppp) +GOM(png_destroy_write_struct, vFEpp) GO(png_error, vFpp) GO(png_free, vFpp) GO(png_get_bit_depth, CFpp)