Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
beetle-pce-libretro
Commits
a2658eec
Commit
a2658eec
authored
Nov 01, 2020
by
Romain TISSERAND
Browse files
Fix alignment issue on zlib/lzma chunks in chd
parent
f7879637
Changes
1
Hide whitespace changes
Inline
Side-by-side
deps/libchdr/chd.c
View file @
a2658eec
...
...
@@ -214,6 +214,7 @@ typedef struct _zlib_allocator zlib_allocator;
struct
_zlib_allocator
{
UINT32
*
allocptr
[
MAX_ZLIB_ALLOCS
];
UINT32
*
allocptr2
[
MAX_ZLIB_ALLOCS
];
};
typedef
struct
_zlib_codec_data
zlib_codec_data
;
...
...
@@ -233,6 +234,7 @@ struct _lzma_allocator
void
(
*
Free
)(
void
*
p
,
void
*
address
);
/* address can be 0 */
void
(
*
FreeSz
)(
void
*
p
,
void
*
address
,
size_t
size
);
/* address can be 0 */
uint32_t
*
allocptr
[
MAX_LZMA_ALLOCS
];
uint32_t
*
allocptr2
[
MAX_LZMA_ALLOCS
];
};
typedef
struct
_lzma_codec_data
lzma_codec_data
;
...
...
@@ -385,37 +387,41 @@ static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes);
static
void
cdfl_codec_free
(
void
*
codec
);
static
chd_error
cdfl_codec_decompress
(
void
*
codec
,
const
uint8_t
*
src
,
uint32_t
complen
,
uint8_t
*
dest
,
uint32_t
destlen
);
//**************************************************************************
// LZMA ALLOCATOR HELPER
//**************************************************************************
/***************************************************************************
* LZMA ALLOCATOR HELPER
***************************************************************************
*/
void
*
lzma_fast_alloc
(
void
*
p
,
size_t
size
);
void
lzma_fast_free
(
void
*
p
,
void
*
address
);
static
void
*
lzma_fast_alloc
(
void
*
p
,
size_t
size
);
static
void
lzma_fast_free
(
void
*
p
,
void
*
address
);
//-------------------------------------------------
// lzma_allocator_init
//-------------------------------------------------
/*-------------------------------------------------
* lzma_allocator_init
*-------------------------------------------------
*/
void
lzma_allocator_init
(
void
*
p
)
static
void
lzma_allocator_init
(
void
*
p
)
{
lzma_allocator
*
codec
=
(
lzma_allocator
*
)(
p
);
/
/
reset pointer list
/
*
reset pointer list
*/
memset
(
codec
->
allocptr
,
0
,
sizeof
(
codec
->
allocptr
));
memset
(
codec
->
allocptr2
,
0
,
sizeof
(
codec
->
allocptr2
));
codec
->
Alloc
=
lzma_fast_alloc
;
codec
->
Free
=
lzma_fast_free
;
}
//-------------------------------------------------
// lzma_allocator_free
//-------------------------------------------------
/*-------------------------------------------------
* lzma_allocator_free
*-------------------------------------------------
*/
void
lzma_allocator_free
(
void
*
p
)
static
void
lzma_allocator_free
(
void
*
p
)
{
int
i
;
int
i
;
lzma_allocator
*
codec
=
(
lzma_allocator
*
)(
p
);
/
/
free our memory
/
*
free our memory
*/
for
(
i
=
0
;
i
<
MAX_LZMA_ALLOCS
;
i
++
)
{
if
(
codec
->
allocptr
[
i
]
!=
NULL
)
...
...
@@ -423,74 +429,91 @@ void lzma_allocator_free(void* p )
}
}
//-------------------------------------------------
// lzma_fast_alloc - fast malloc for lzma, which
// allocates and frees memory frequently
//-------------------------------------------------
/*-------------------------------------------------
* lzma_fast_alloc - fast malloc for lzma, which
* allocates and frees memory frequently
*-------------------------------------------------
*/
/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
#define LZMA_MIN_ALIGNMENT_BITS 512
#define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8)
void
*
lzma_fast_alloc
(
void
*
p
,
size_t
size
)
static
void
*
lzma_fast_alloc
(
void
*
p
,
size_t
size
)
{
int
scan
;
uint32_t
*
addr
=
NULL
;
int
scan
;
uint32_t
*
addr
=
NULL
;
lzma_allocator
*
codec
=
(
lzma_allocator
*
)(
p
);
uintptr_t
vaddr
=
0
;
/
/
compute the size, rounding to the nearest 1k
/
*
compute the size, rounding to the nearest 1k
*/
size
=
(
size
+
0x3ff
)
&
~
0x3ff
;
/
/
reuse a hunk if we can
/
*
reuse a hunk if we can
*/
for
(
scan
=
0
;
scan
<
MAX_LZMA_ALLOCS
;
scan
++
)
{
uint32_t
*
ptr
=
codec
->
allocptr
[
scan
];
if
(
ptr
!=
NULL
&&
size
==
*
ptr
)
{
/
/
set the low bit of the size so we don't match next time
/
*
set the low bit of the size so we don't match next time
*/
*
ptr
|=
1
;
return
ptr
+
1
;
/* return aligned address of the block */
return
codec
->
allocptr2
[
scan
];
}
}
/
/
alloc a new one and put it into the list
addr
=
(
uint32_t
*
)
malloc
(
size
of
(
uint8_t
)
*
(
size
+
sizeof
(
uint32_t
))
);
/
*
alloc a new one and put it into the list
*/
addr
=
(
uint32_t
*
)
malloc
(
size
+
sizeof
(
uint32_t
)
+
LZMA_MIN_ALIGNMENT_BYTES
);
if
(
addr
==
NULL
)
return
NULL
;
for
(
scan
=
0
;
scan
<
MAX_LZMA_ALLOCS
;
scan
++
)
{
if
(
codec
->
allocptr
[
scan
]
==
NULL
)
{
/* store block address */
codec
->
allocptr
[
scan
]
=
addr
;
/* compute aligned address, store it */
vaddr
=
(
uintptr_t
)
addr
;
vaddr
=
(
vaddr
+
sizeof
(
uint32_t
)
+
(
LZMA_MIN_ALIGNMENT_BYTES
-
1
))
&
(
~
(
LZMA_MIN_ALIGNMENT_BYTES
-
1
));
codec
->
allocptr2
[
scan
]
=
(
uint32_t
*
)
vaddr
;
break
;
}
}
/
/
set the low bit of the size so we don't match next time
/
*
set the low bit of the size so we don't match next time
*/
*
addr
=
size
|
1
;
return
addr
+
1
;
}
/* return aligned address */
return
(
void
*
)
vaddr
;
}
//-------------------------------------------------
// lzma_fast_free - fast free for lzma, which
// allocates and frees memory frequently
//-------------------------------------------------
/*-------------------------------------------------
* lzma_fast_free - fast free for lzma, which
* allocates and frees memory frequently
*-------------------------------------------------
*/
void
lzma_fast_free
(
void
*
p
,
void
*
address
)
static
void
lzma_fast_free
(
void
*
p
,
void
*
address
)
{
int
scan
;
uint32_t
*
ptr
;
lzma_allocator
*
codec
;
int
scan
;
uint32_t
*
ptr
=
NULL
;
lzma_allocator
*
codec
=
NULL
;
if
(
address
==
NULL
)
return
;
codec
=
(
lzma_allocator
*
)(
p
);
/
/
find the hunk
ptr
=
(
uint32_t
*
)
(
address
)
-
1
;
/
*
find the hunk
*/
ptr
=
(
uint32_t
*
)
address
;
for
(
scan
=
0
;
scan
<
MAX_LZMA_ALLOCS
;
scan
++
)
{
if
(
ptr
==
codec
->
allocptr
[
scan
])
if
(
ptr
==
codec
->
allocptr
2
[
scan
])
{
/
/
clear the low bit of the size to allow matches
*
ptr
&=
~
1
;
/
*
clear the low bit of the size to allow matches
*/
*
codec
->
allocptr
[
scan
]
&=
~
1
;
return
;
}
}
...
...
@@ -2391,9 +2414,14 @@ static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t
allocates and frees memory frequently
-------------------------------------------------*/
/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
#define ZLIB_MIN_ALIGNMENT_BITS 512
#define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
static
voidpf
zlib_fast_alloc
(
voidpf
opaque
,
uInt
items
,
uInt
size
)
{
zlib_allocator
*
alloc
=
(
zlib_allocator
*
)
opaque
;
uintptr_t
paddr
=
0
;
UINT32
*
ptr
;
int
i
;
...
...
@@ -2408,12 +2436,14 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
{
/* set the low bit of the size so we don't match next time */
*
ptr
|=
1
;
return
ptr
+
1
;
/* return aligned block address */
return
(
voidpf
)(
alloc
->
allocptr2
[
i
]);
}
}
/* alloc a new one */
ptr
=
(
UINT32
*
)
malloc
(
size
+
sizeof
(
UINT32
));
ptr
=
(
UINT32
*
)
malloc
(
size
+
sizeof
(
UINT32
)
+
ZLIB_MIN_ALIGNMENT_BYTES
);
if
(
!
ptr
)
return
NULL
;
...
...
@@ -2422,14 +2452,17 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
if
(
!
alloc
->
allocptr
[
i
])
{
alloc
->
allocptr
[
i
]
=
ptr
;
paddr
=
(((
uintptr_t
)
ptr
)
+
sizeof
(
UINT32
)
+
(
ZLIB_MIN_ALIGNMENT_BYTES
-
1
))
&
(
~
(
ZLIB_MIN_ALIGNMENT_BYTES
-
1
));
alloc
->
allocptr2
[
i
]
=
(
uint32_t
*
)
paddr
;
break
;
}
/* set the low bit of the size so we don't match next time */
*
ptr
=
size
|
1
;
return
ptr
+
1
;
}
/* return aligned block address */
return
(
voidpf
)
paddr
;
}
/*-------------------------------------------------
zlib_fast_free - fast free for ZLIB, which
...
...
@@ -2439,15 +2472,15 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
static
void
zlib_fast_free
(
voidpf
opaque
,
voidpf
address
)
{
zlib_allocator
*
alloc
=
(
zlib_allocator
*
)
opaque
;
UINT32
*
ptr
=
(
UINT32
*
)
address
-
1
;
UINT32
*
ptr
=
(
UINT32
*
)
address
;
int
i
;
/* find the hunk */
for
(
i
=
0
;
i
<
MAX_ZLIB_ALLOCS
;
i
++
)
if
(
ptr
==
alloc
->
allocptr
[
i
])
if
(
ptr
==
alloc
->
allocptr
2
[
i
])
{
/* clear the low bit of the size to allow matches */
*
ptr
&=
~
1
;
*
(
alloc
->
allocptr
[
i
])
&=
~
1
;
return
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment