From 1430d0190684c6f78e1bce759eae240c94fba61c Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Sat, 24 Feb 2018 23:46:27 +0100 Subject: jar_xm: Workaround for unaligned pointer accesses jar_xm.h does some shady pointer casts leading to unaligned accesses and breaking strict aliasing. x86 has special circuitry for doing unaligned accesses, but on other architectures, it may trap and require kernel fix-up or crash outright. With this patch, one obstacle in porting raylib to the GameBoy Advance has been removed. Go for it ;-) To avoid having to rewrite that `mempool' code, insert padding before structs and instruct the compiler (GCC, most importantly), to be gentle when optimizing. This fixes #490 (Unless we got ourselves 256-bit pointers, if so, hello future!) --- src/external/jar_xm.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/external/jar_xm.h') diff --git a/src/external/jar_xm.h b/src/external/jar_xm.h index 15b31fd0..df199e06 100644 --- a/src/external/jar_xm.h +++ b/src/external/jar_xm.h @@ -612,6 +612,8 @@ int jar_xm_create_context(jar_xm_context_t** ctxp, const char* moddata, uint32_t return jar_xm_create_context_safe(ctxp, moddata, SIZE_MAX, rate); } +#define ALIGN(x, b) (((x) + ((b) - 1)) & ~((b) - 1)) +#define ALIGN_PTR(x, b) (void*)(((uintptr_t)(x) + ((b) - 1)) & ~((b) - 1)) int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, size_t moddata_length, uint32_t rate) { #if JAR_XM_DEFENSIVE int ret; @@ -644,9 +646,11 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz ctx->rate = rate; mempool = jar_xm_load_module(ctx, moddata, moddata_length, mempool); + mempool = ALIGN_PTR(mempool, 16); ctx->channels = (jar_xm_channel_context_t*)mempool; mempool += ctx->module.num_channels * sizeof(jar_xm_channel_context_t); + mempool = ALIGN_PTR(mempool, 16); ctx->global_volume = 1.f; ctx->amplification = .25f; /* XXX: some bad modules may still clip. Find out something better. */ @@ -671,6 +675,7 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz ch->actual_panning = .5f; } + mempool = ALIGN_PTR(mempool, 16); ctx->row_loop_count = (uint8_t*)mempool; mempool += MAX_NUM_ROWS * sizeof(uint8_t); @@ -856,9 +861,11 @@ size_t jar_xm_get_memory_needed_for_context(const char* moddata, size_t moddata_ num_patterns = READ_U16(offset + 10); memory_needed += num_patterns * sizeof(jar_xm_pattern_t); + memory_needed = ALIGN(memory_needed, 16); num_instruments = READ_U16(offset + 12); memory_needed += num_instruments * sizeof(jar_xm_instrument_t); + memory_needed = ALIGN(memory_needed, 16); memory_needed += MAX_NUM_ROWS * READ_U16(offset + 4) * sizeof(uint8_t); /* Module length */ @@ -875,6 +882,7 @@ size_t jar_xm_get_memory_needed_for_context(const char* moddata, size_t moddata_ /* Pattern header length + packed pattern data size */ offset += READ_U32(offset) + READ_U16(offset + 7); } + memory_needed = ALIGN(memory_needed, 16); /* Read instrument headers */ for(uint16_t i = 0; i < num_instruments; ++i) { @@ -940,9 +948,11 @@ char* jar_xm_load_module(jar_xm_context_t* ctx, const char* moddata, size_t modd mod->patterns = (jar_xm_pattern_t*)mempool; mempool += mod->num_patterns * sizeof(jar_xm_pattern_t); + mempool = ALIGN_PTR(mempool, 16); mod->instruments = (jar_xm_instrument_t*)mempool; mempool += mod->num_instruments * sizeof(jar_xm_instrument_t); + mempool = ALIGN_PTR(mempool, 16); uint16_t flags = READ_U32(offset + 14); mod->frequency_type = (flags & (1 << 0)) ? jar_xm_LINEAR_FREQUENCIES : jar_xm_AMIGA_FREQUENCIES; @@ -1032,6 +1042,7 @@ char* jar_xm_load_module(jar_xm_context_t* ctx, const char* moddata, size_t modd offset += packed_patterndata_size; } + mempool = ALIGN_PTR(mempool, 16); /* Read instruments */ for(uint16_t i = 0; i < ctx->module.num_instruments; ++i) { -- cgit v1.2.3 From 3f48ffb1b6a34f4eb95e4084976acfb6dae6a171 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 26 Feb 2018 00:14:19 +0100 Subject: Fix two memory leaks in jar_xm.h Found by LeakSanitizer in #494. --- src/external/jar_xm.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/external/jar_xm.h') diff --git a/src/external/jar_xm.h b/src/external/jar_xm.h index df199e06..f7750664 100644 --- a/src/external/jar_xm.h +++ b/src/external/jar_xm.h @@ -2610,6 +2610,7 @@ uint64_t jar_xm_get_remaining_samples(jar_xm_context_t* ctx) int jar_xm_create_context_from_file(jar_xm_context_t** ctx, uint32_t rate, const char* filename) { FILE* xmf; int size; + int ret; xmf = fopen(filename, "rb"); if(xmf == NULL) { @@ -2629,16 +2630,20 @@ int jar_xm_create_context_from_file(jar_xm_context_t** ctx, uint32_t rate, const } char* data = malloc(size + 1); - if(fread(data, 1, size, xmf) < size) { + if(!data || fread(data, 1, size, xmf) < size) { fclose(xmf); - DEBUG_ERR("fread() failed"); + DEBUG_ERR(data ? "fread() failed" : "malloc() failed"); + free(data); *ctx = NULL; return 5; } fclose(xmf); - switch(jar_xm_create_context_safe(ctx, data, size, rate)) { + ret = jar_xm_create_context_safe(ctx, data, size, rate); + free(data); + + switch(ret) { case 0: break; -- cgit v1.2.3 From e659336c11abbcb6bec2c2dd094431ab287e94e6 Mon Sep 17 00:00:00 2001 From: "maficccc@gmail.com" Date: Sun, 4 Mar 2018 19:31:36 +0100 Subject: Fix value stored to 'num_channels' is never read --- src/external/jar_xm.h | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'src/external/jar_xm.h') diff --git a/src/external/jar_xm.h b/src/external/jar_xm.h index f7750664..9d4f5b5b 100644 --- a/src/external/jar_xm.h +++ b/src/external/jar_xm.h @@ -855,8 +855,6 @@ size_t jar_xm_get_memory_needed_for_context(const char* moddata, size_t moddata_ uint16_t num_instruments; /* Read the module header */ - - num_channels = READ_U16(offset + 8); num_channels = READ_U16(offset + 8); num_patterns = READ_U16(offset + 10); @@ -2561,28 +2559,22 @@ uint64_t jar_xm_get_remaining_samples(jar_xm_context_t* ctx) uint64_t total = 0; uint8_t currentLoopCount = jar_xm_get_loop_count(ctx); jar_xm_set_max_loop_count(ctx, 0); - + while(jar_xm_get_loop_count(ctx) == currentLoopCount) { total += ctx->remaining_samples_in_tick; ctx->remaining_samples_in_tick = 0; jar_xm_tick(ctx); } - + ctx->loop_count = currentLoopCount; return total; } - - - - //-------------------------------------------- //FILE LOADER - TODO - NEEDS TO BE CLEANED UP //-------------------------------------------- - - #undef DEBUG #define DEBUG(...) do { \ fprintf(stderr, __VA_ARGS__); \ @@ -2668,13 +2660,7 @@ int jar_xm_create_context_from_file(jar_xm_context_t** ctx, uint32_t rate, const return 0; } - - - #endif//end of JAR_XM_IMPLEMENTATION //------------------------------------------------------------------------------- - - - #endif//end of INCLUDE_JAR_XM_H -- cgit v1.2.3