Skip to content

Commit

Permalink
Try some workaround for the libpng16 setjmp handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Jun 19, 2022
1 parent b0ea5de commit c33683c
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/wrapped/generated/functions_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions src/wrapped/generated/wrappedpng16types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions src/wrapped/wrappedlibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
63 changes: 61 additions & 2 deletions src/wrapped/wrappedpng16.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <setjmp.h>

#include "wrappedlibs.h"

Expand All @@ -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"

Expand Down Expand Up @@ -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);\
}
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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 \
Expand Down
6 changes: 3 additions & 3 deletions src/wrapped/wrappedpng16_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit c33683c

Please sign in to comment.