mirror of
https://gitdl.cn/https://github.com/chakralinux/core.git
synced 2025-02-20 03:05:34 +08:00
361 lines
12 KiB
Diff
361 lines
12 KiB
Diff
From 96ad13c76002f2d54370bcb57bb6c79ca930d556 Mon Sep 17 00:00:00 2001
|
|
From: Phillip Lougher <phillip@lougher.demon.co.uk>
|
|
Date: Mon, 11 Jan 2010 16:45:50 +0000
|
|
Subject: lzma: make lzma reentrant
|
|
|
|
The error function pointer used by lzma is global (file scope) which
|
|
prevents it being used concurrently. This patch removes the global
|
|
error pointer use, and instead passes it to all functions that need it.
|
|
|
|
The error function pointer is still used by bunzip2, inflate and unlzo.
|
|
This patch moves the definition into the separate bunzip2, inflate
|
|
and unlzo header files. This prevents gcc from complaining about an
|
|
unused definition compiling lzma.
|
|
|
|
Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
|
|
---
|
|
diff --git a/include/linux/decompress/bunzip2_mm.h b/include/linux/decompress/bunzip2_mm.h
|
|
index cac6fef..863efd0 100644
|
|
--- a/include/linux/decompress/bunzip2_mm.h
|
|
+++ b/include/linux/decompress/bunzip2_mm.h
|
|
@@ -7,6 +7,7 @@
|
|
#else
|
|
/* Compile for initramfs/initrd code only */
|
|
#define INIT __init
|
|
+static void(*error)(char *m);
|
|
#endif
|
|
|
|
#endif
|
|
diff --git a/include/linux/decompress/inflate_mm.h b/include/linux/decompress/inflate_mm.h
|
|
index ca4a2ae..87a742b 100644
|
|
--- a/include/linux/decompress/inflate_mm.h
|
|
+++ b/include/linux/decompress/inflate_mm.h
|
|
@@ -7,6 +7,7 @@
|
|
#else
|
|
/* Compile for initramfs/initrd code only */
|
|
#define INIT __init
|
|
+static void(*error)(char *m);
|
|
#endif
|
|
|
|
#endif
|
|
diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
|
|
index f3f6526..df8b8b5 100644
|
|
--- a/include/linux/decompress/mm.h
|
|
+++ b/include/linux/decompress/mm.h
|
|
@@ -82,7 +82,6 @@ static void free(void *where)
|
|
#define large_malloc(a) vmalloc(a)
|
|
#define large_free(a) vfree(a)
|
|
|
|
-static void(*error)(char *m);
|
|
#define set_error_fn(x) error = x;
|
|
|
|
#define STATIC
|
|
diff --git a/include/linux/decompress/unlzo_mm.h b/include/linux/decompress/unlzo_mm.h
|
|
index e3f1573..27fe0ab 100644
|
|
--- a/include/linux/decompress/unlzo_mm.h
|
|
+++ b/include/linux/decompress/unlzo_mm.h
|
|
@@ -7,6 +7,7 @@
|
|
#else
|
|
/* Compile for initramfs/initrd code only */
|
|
#define INIT __init
|
|
+static void(*error)(char *m);
|
|
#endif
|
|
|
|
#endif
|
|
diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c
|
|
index a614b26..3e85763 100644
|
|
--- a/lib/decompress_unlzma.c
|
|
+++ b/lib/decompress_unlzma.c
|
|
@@ -89,7 +89,7 @@ static int nofill(void *buffer, unsigned int len)
|
|
}
|
|
|
|
/* Called twice: once at startup and once in rc_normalize() */
|
|
-static void INIT rc_read(struct rc *rc)
|
|
+static void INIT rc_read(struct rc *rc, void(*error)(char *x))
|
|
{
|
|
rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
|
|
if (rc->buffer_size <= 0)
|
|
@@ -116,13 +116,13 @@ static inline void INIT rc_init(struct rc *rc,
|
|
rc->range = 0xFFFFFFFF;
|
|
}
|
|
|
|
-static inline void INIT rc_init_code(struct rc *rc)
|
|
+static inline void INIT rc_init_code(struct rc *rc, void(*error)(char *x))
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
if (rc->ptr >= rc->buffer_end)
|
|
- rc_read(rc);
|
|
+ rc_read(rc, error);
|
|
rc->code = (rc->code << 8) | *rc->ptr++;
|
|
}
|
|
}
|
|
@@ -135,32 +135,33 @@ static inline void INIT rc_free(struct rc *rc)
|
|
}
|
|
|
|
/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
|
|
-static void INIT rc_do_normalize(struct rc *rc)
|
|
+static void INIT rc_do_normalize(struct rc *rc, void(*error)(char *x))
|
|
{
|
|
if (rc->ptr >= rc->buffer_end)
|
|
- rc_read(rc);
|
|
+ rc_read(rc, error);
|
|
rc->range <<= 8;
|
|
rc->code = (rc->code << 8) | *rc->ptr++;
|
|
}
|
|
-static inline void INIT rc_normalize(struct rc *rc)
|
|
+static inline void INIT rc_normalize(struct rc *rc, void(*error)(char *x))
|
|
{
|
|
if (rc->range < (1 << RC_TOP_BITS))
|
|
- rc_do_normalize(rc);
|
|
+ rc_do_normalize(rc, error);
|
|
}
|
|
|
|
/* Called 9 times */
|
|
/* Why rc_is_bit_0_helper exists?
|
|
*Because we want to always expose (rc->code < rc->bound) to optimizer
|
|
*/
|
|
-static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
|
|
+static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p,
|
|
+ void (*error)(char *x))
|
|
{
|
|
- rc_normalize(rc);
|
|
+ rc_normalize(rc, error);
|
|
rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
|
|
return rc->bound;
|
|
}
|
|
-static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
|
|
+static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p, void(*error)(char *x))
|
|
{
|
|
- uint32_t t = rc_is_bit_0_helper(rc, p);
|
|
+ uint32_t t = rc_is_bit_0_helper(rc, p, error);
|
|
return rc->code < t;
|
|
}
|
|
|
|
@@ -178,9 +179,9 @@ static inline void rc_update_bit_1(struct rc *rc, uint16_t *p)
|
|
}
|
|
|
|
/* Called 4 times in unlzma loop */
|
|
-static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
|
|
+static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol, void(*error)(char *x))
|
|
{
|
|
- if (rc_is_bit_0(rc, p)) {
|
|
+ if (rc_is_bit_0(rc, p, error)) {
|
|
rc_update_bit_0(rc, p);
|
|
*symbol *= 2;
|
|
return 0;
|
|
@@ -192,9 +193,9 @@ static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
|
|
}
|
|
|
|
/* Called once */
|
|
-static inline int INIT rc_direct_bit(struct rc *rc)
|
|
+static inline int INIT rc_direct_bit(struct rc *rc , void(*error)(char *x))
|
|
{
|
|
- rc_normalize(rc);
|
|
+ rc_normalize(rc, error);
|
|
rc->range >>= 1;
|
|
if (rc->code >= rc->range) {
|
|
rc->code -= rc->range;
|
|
@@ -205,13 +206,14 @@ static inline int INIT rc_direct_bit(struct rc *rc)
|
|
|
|
/* Called twice */
|
|
static inline void INIT
|
|
-rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
|
|
+rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol,
|
|
+ void(*error)(char *x))
|
|
{
|
|
int i = num_levels;
|
|
|
|
*symbol = 1;
|
|
while (i--)
|
|
- rc_get_bit(rc, p + *symbol, symbol);
|
|
+ rc_get_bit(rc, p + *symbol, symbol, error);
|
|
*symbol -= 1 << num_levels;
|
|
}
|
|
|
|
@@ -348,7 +350,8 @@ static inline void INIT copy_bytes(struct writer *wr,
|
|
static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
|
|
struct cstate *cst, uint16_t *p,
|
|
int pos_state, uint16_t *prob,
|
|
- int lc, uint32_t literal_pos_mask) {
|
|
+ int lc, uint32_t literal_pos_mask,
|
|
+ void(*error)(char *x)) {
|
|
int mi = 1;
|
|
rc_update_bit_0(rc, prob);
|
|
prob = (p + LZMA_LITERAL +
|
|
@@ -366,7 +369,7 @@ static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
|
|
match_byte <<= 1;
|
|
bit = match_byte & 0x100;
|
|
prob_lit = prob + 0x100 + bit + mi;
|
|
- if (rc_get_bit(rc, prob_lit, &mi)) {
|
|
+ if (rc_get_bit(rc, prob_lit, &mi, error)) {
|
|
if (!bit)
|
|
break;
|
|
} else {
|
|
@@ -377,7 +380,7 @@ static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
|
|
}
|
|
while (mi < 0x100) {
|
|
uint16_t *prob_lit = prob + mi;
|
|
- rc_get_bit(rc, prob_lit, &mi);
|
|
+ rc_get_bit(rc, prob_lit, &mi, error);
|
|
}
|
|
write_byte(wr, mi);
|
|
if (cst->state < 4)
|
|
@@ -390,7 +393,8 @@ static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
|
|
|
|
static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
struct cstate *cst, uint16_t *p,
|
|
- int pos_state, uint16_t *prob) {
|
|
+ int pos_state, uint16_t *prob,
|
|
+ void(*error)(char *x)) {
|
|
int offset;
|
|
uint16_t *prob_len;
|
|
int num_bits;
|
|
@@ -398,7 +402,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
|
|
rc_update_bit_1(rc, prob);
|
|
prob = p + LZMA_IS_REP + cst->state;
|
|
- if (rc_is_bit_0(rc, prob)) {
|
|
+ if (rc_is_bit_0(rc, prob, error)) {
|
|
rc_update_bit_0(rc, prob);
|
|
cst->rep3 = cst->rep2;
|
|
cst->rep2 = cst->rep1;
|
|
@@ -408,13 +412,13 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
} else {
|
|
rc_update_bit_1(rc, prob);
|
|
prob = p + LZMA_IS_REP_G0 + cst->state;
|
|
- if (rc_is_bit_0(rc, prob)) {
|
|
+ if (rc_is_bit_0(rc, prob, error)) {
|
|
rc_update_bit_0(rc, prob);
|
|
prob = (p + LZMA_IS_REP_0_LONG
|
|
+ (cst->state <<
|
|
LZMA_NUM_POS_BITS_MAX) +
|
|
pos_state);
|
|
- if (rc_is_bit_0(rc, prob)) {
|
|
+ if (rc_is_bit_0(rc, prob, error)) {
|
|
rc_update_bit_0(rc, prob);
|
|
|
|
cst->state = cst->state < LZMA_NUM_LIT_STATES ?
|
|
@@ -429,13 +433,13 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
|
|
rc_update_bit_1(rc, prob);
|
|
prob = p + LZMA_IS_REP_G1 + cst->state;
|
|
- if (rc_is_bit_0(rc, prob)) {
|
|
+ if (rc_is_bit_0(rc, prob, error)) {
|
|
rc_update_bit_0(rc, prob);
|
|
distance = cst->rep1;
|
|
} else {
|
|
rc_update_bit_1(rc, prob);
|
|
prob = p + LZMA_IS_REP_G2 + cst->state;
|
|
- if (rc_is_bit_0(rc, prob)) {
|
|
+ if (rc_is_bit_0(rc, prob, error)) {
|
|
rc_update_bit_0(rc, prob);
|
|
distance = cst->rep2;
|
|
} else {
|
|
@@ -453,7 +457,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
}
|
|
|
|
prob_len = prob + LZMA_LEN_CHOICE;
|
|
- if (rc_is_bit_0(rc, prob_len)) {
|
|
+ if (rc_is_bit_0(rc, prob_len, error)) {
|
|
rc_update_bit_0(rc, prob_len);
|
|
prob_len = (prob + LZMA_LEN_LOW
|
|
+ (pos_state <<
|
|
@@ -463,7 +467,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
} else {
|
|
rc_update_bit_1(rc, prob_len);
|
|
prob_len = prob + LZMA_LEN_CHOICE_2;
|
|
- if (rc_is_bit_0(rc, prob_len)) {
|
|
+ if (rc_is_bit_0(rc, prob_len, error)) {
|
|
rc_update_bit_0(rc, prob_len);
|
|
prob_len = (prob + LZMA_LEN_MID
|
|
+ (pos_state <<
|
|
@@ -479,7 +483,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
}
|
|
}
|
|
|
|
- rc_bit_tree_decode(rc, prob_len, num_bits, &len);
|
|
+ rc_bit_tree_decode(rc, prob_len, num_bits, &len, error);
|
|
len += offset;
|
|
|
|
if (cst->state < 4) {
|
|
@@ -494,7 +498,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
<< LZMA_NUM_POS_SLOT_BITS);
|
|
rc_bit_tree_decode(rc, prob,
|
|
LZMA_NUM_POS_SLOT_BITS,
|
|
- &pos_slot);
|
|
+ &pos_slot, error);
|
|
if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
|
|
int i, mi;
|
|
num_bits = (pos_slot >> 1) - 1;
|
|
@@ -507,7 +511,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
num_bits -= LZMA_NUM_ALIGN_BITS;
|
|
while (num_bits--)
|
|
cst->rep0 = (cst->rep0 << 1) |
|
|
- rc_direct_bit(rc);
|
|
+ rc_direct_bit(rc, error);
|
|
prob = p + LZMA_ALIGN;
|
|
cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
|
|
num_bits = LZMA_NUM_ALIGN_BITS;
|
|
@@ -515,7 +519,7 @@ static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
|
|
i = 1;
|
|
mi = 1;
|
|
while (num_bits--) {
|
|
- if (rc_get_bit(rc, prob + mi, &mi))
|
|
+ if (rc_get_bit(rc, prob + mi, &mi, error))
|
|
cst->rep0 |= i;
|
|
i <<= 1;
|
|
}
|
|
@@ -537,7 +541,7 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
|
|
int(*flush)(void*, unsigned int),
|
|
unsigned char *output,
|
|
int *posp,
|
|
- void(*error_fn)(char *x)
|
|
+ void(*error)(char *x)
|
|
)
|
|
{
|
|
struct lzma_header header;
|
|
@@ -553,8 +557,6 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
|
|
unsigned char *inbuf;
|
|
int ret = -1;
|
|
|
|
- set_error_fn(error_fn);
|
|
-
|
|
if (buf)
|
|
inbuf = buf;
|
|
else
|
|
@@ -577,7 +579,7 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
|
|
|
|
for (i = 0; i < sizeof(header); i++) {
|
|
if (rc.ptr >= rc.buffer_end)
|
|
- rc_read(&rc);
|
|
+ rc_read(&rc, error);
|
|
((unsigned char *)&header)[i] = *rc.ptr++;
|
|
}
|
|
|
|
@@ -622,17 +624,17 @@ STATIC int INIT unlzma(unsigned char *buf, int in_len,
|
|
for (i = 0; i < num_probs; i++)
|
|
p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
|
|
|
|
- rc_init_code(&rc);
|
|
+ rc_init_code(&rc, error);
|
|
|
|
while (get_pos(&wr) < header.dst_size) {
|
|
int pos_state = get_pos(&wr) & pos_state_mask;
|
|
uint16_t *prob = p + LZMA_IS_MATCH +
|
|
(cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
|
|
- if (rc_is_bit_0(&rc, prob))
|
|
+ if (rc_is_bit_0(&rc, prob, error))
|
|
process_bit0(&wr, &rc, &cst, p, pos_state, prob,
|
|
- lc, literal_pos_mask);
|
|
+ lc, literal_pos_mask, error);
|
|
else {
|
|
- process_bit1(&wr, &rc, &cst, p, pos_state, prob);
|
|
+ process_bit1(&wr, &rc, &cst, p, pos_state, prob, error);
|
|
if (cst.rep0 == 0)
|
|
break;
|
|
}
|
|
--
|
|
cgit v0.8.3.1
|