summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2023-09-25 12:36:48 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-09-25 12:36:48 +0200
commitb674fcfbf465c08b5d5b445c308fc0101cdd1f74 (patch)
tree4dc12088451551c5f618a3e73313a6b4b5c418e8 /lib
parent93eb4971be7045571e612ff240c55293d4bf139f (diff)
parent290960f33d0ca45a9263e87f5107ca4133fb6ed6 (diff)
downloadbarebox-b674fcfbf465c08b5d5b445c308fc0101cdd1f74.tar.gz
barebox-b674fcfbf465c08b5d5b445c308fc0101cdd1f74.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/decompress_unxz.c6
-rw-r--r--lib/jsmn.c54
-rw-r--r--lib/xz/xz_dec_bcj.c54
-rw-r--r--lib/xz/xz_private.h5
5 files changed, 115 insertions, 8 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index a6b91e69e6..fbc9fff865 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -42,6 +42,7 @@ config XZ_DECOMPRESS
select XZ_DEC_ARM
select XZ_DEC_ARMTHUMB
select XZ_DEC_SPARC
+ select XZ_DEC_ARM64
config XZ_DEC_X86
bool
@@ -61,6 +62,9 @@ config XZ_DEC_ARMTHUMB
config XZ_DEC_SPARC
bool
+config XZ_DEC_ARM64
+ bool
+
config REED_SOLOMON
bool
diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
index a7e2d331ab..132ab4a239 100644
--- a/lib/decompress_unxz.c
+++ b/lib/decompress_unxz.c
@@ -131,7 +131,11 @@
# define XZ_DEC_POWERPC
#endif
#ifdef CONFIG_ARM
-# define XZ_DEC_ARM
+# ifdef CONFIG_CPU_64
+# define XZ_DEC_ARM64
+# else
+# define XZ_DEC_ARM
+# endif
#endif
#ifdef CONFIG_IA64
# define XZ_DEC_IA64
diff --git a/lib/jsmn.c b/lib/jsmn.c
index 7bdcc90f2f..10a77886a8 100644
--- a/lib/jsmn.c
+++ b/lib/jsmn.c
@@ -370,9 +370,45 @@ JSMN_API void jsmn_init(jsmn_parser *parser) {
parser->toksuper = -1;
}
+/**
+ * Parse JSON string and fill tokens into self-allocated buffer.
+ */
+JSMN_API jsmntok_t *jsmn_parse_alloc(const char *js, const size_t len,
+ unsigned int *num_tokens)
+{
+
+ ssize_t token_count;
+ jsmn_parser parser;
+ jsmntok_t *tokens;
+ int ret;
+
+ jsmn_init(&parser);
+
+ /* Figure out how many tokens we need. */
+ ret = jsmn_parse(&parser, js, len, NULL, 0);
+ if (ret < 0)
+ return NULL;
+
+ token_count = ret;
+
+ tokens = kmalloc_array(token_count, sizeof(jsmntok_t), GFP_KERNEL);
+ if (!tokens)
+ return NULL;
+
+ jsmn_init(&parser);
+ ret = jsmn_parse(&parser, js, len, tokens, token_count);
+ if (ret < 0) {
+ free(tokens);
+ return NULL;
+ }
+
+ if (num_tokens)
+ *num_tokens = ret;
+ return tokens;
+}
JSMN_API bool jsmn_eq(const char *val, const char *json, const jsmntok_t *token)
{
- size_t token_size = token->end - token->start;
+ size_t token_size = jsmn_token_size(token);
return strlen(val) == token_size
&& strncmp(json + token->start, val, token_size) == 0;
}
@@ -382,6 +418,18 @@ JSMN_API bool jsmn_str_eq(const char *str, const char *json, const jsmntok_t *to
return token->type == JSMN_STRING && jsmn_eq(str, json, token);
}
+static bool jsmn_case_eq(const char *val, const char *json, const jsmntok_t *token)
+{
+ size_t token_size = jsmn_token_size(token);
+ return strlen(val) == token_size
+ && strncasecmp(json + token->start, val, token_size) == 0;
+}
+
+JSMN_API bool jsmn_strcase_eq(const char *str, const char *json, const jsmntok_t *token)
+{
+ return token->type == JSMN_STRING && jsmn_case_eq(str, json, token);
+}
+
JSMN_API const jsmntok_t *jsmn_skip_value(const jsmntok_t *tokens)
{
int max_index = tokens[0].end;
@@ -435,7 +483,7 @@ JSMN_API const jsmntok_t *jsmn_locate(const char *path[], const char *json,
return tokens;
}
-JSMN_API char *jsmn_strcpy(const char *path[], const char *json,
+JSMN_API char *jsmn_strdup(const char *path[], const char *json,
const jsmntok_t *tokens)
{
const jsmntok_t *node;
@@ -446,7 +494,7 @@ JSMN_API char *jsmn_strcpy(const char *path[], const char *json,
if (!node || node->type != JSMN_STRING)
return NULL;
- value_size = node->end - node->start;
+ value_size = jsmn_token_size(node);
value = malloc(value_size + 1);
if (value) {
strncpy(value, json + node->start, value_size);
diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c
index d268adbc65..d40fae3416 100644
--- a/lib/xz/xz_dec_bcj.c
+++ b/lib/xz/xz_dec_bcj.c
@@ -2,7 +2,7 @@
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
- * Igor Pavlov <http://7-zip.org/>
+ * Igor Pavlov <https://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
@@ -24,7 +24,8 @@ struct xz_dec_bcj {
BCJ_IA64 = 6, /* Big or little endian */
BCJ_ARM = 7, /* Little endian only */
BCJ_ARMTHUMB = 8, /* Little endian only */
- BCJ_SPARC = 9 /* Big or little endian */
+ BCJ_SPARC = 9, /* Big or little endian */
+ BCJ_ARM64 = 10 /* AArch64 */
} type;
/*
@@ -334,6 +335,45 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
}
#endif
+#ifdef XZ_DEC_ARM64
+static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+ size_t i;
+ uint32_t instr;
+ uint32_t addr;
+
+ for (i = 0; i + 4 <= size; i += 4) {
+ instr = get_unaligned_le32(buf + i);
+
+ if ((instr >> 26) == 0x25) {
+ /* BL instruction */
+ addr = instr - ((s->pos + (uint32_t)i) >> 2);
+ instr = 0x94000000 | (addr & 0x03FFFFFF);
+ put_unaligned_le32(instr, buf + i);
+
+ } else if ((instr & 0x9F000000) == 0x90000000) {
+ /* ADRP instruction */
+ addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
+
+ /* Only convert values in the range +/-512 MiB. */
+ if ((addr + 0x020000) & 0x1C0000)
+ continue;
+
+ addr -= (s->pos + (uint32_t)i) >> 12;
+
+ instr &= 0x9000001F;
+ instr |= (addr & 3) << 29;
+ instr |= (addr & 0x03FFFC) << 3;
+ instr |= (0U - (addr & 0x020000)) & 0xE00000;
+
+ put_unaligned_le32(instr, buf + i);
+ }
+ }
+
+ return i;
+}
+#endif
+
/*
* Apply the selected BCJ filter. Update *pos and s->pos to match the amount
* of data that got filtered.
@@ -381,6 +421,11 @@ static void bcj_apply(struct xz_dec_bcj *s,
filtered = bcj_sparc(s, buf, size);
break;
#endif
+#ifdef XZ_DEC_ARM64
+ case BCJ_ARM64:
+ filtered = bcj_arm64(s, buf, size);
+ break;
+#endif
default:
/* Never reached but silence compiler warnings. */
filtered = 0;
@@ -422,7 +467,7 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
/*
* Flush pending already filtered data to the output buffer. Return
- * immediatelly if we couldn't flush everything, or if the next
+ * immediately if we couldn't flush everything, or if the next
* filter in the chain had already returned XZ_STREAM_END.
*/
if (s->temp.filtered > 0) {
@@ -554,6 +599,9 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
#ifdef XZ_DEC_SPARC
case BCJ_SPARC:
#endif
+#ifdef XZ_DEC_ARM64
+ case BCJ_ARM64:
+#endif
break;
default:
diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h
index 85f79635f0..b14a262c92 100644
--- a/lib/xz/xz_private.h
+++ b/lib/xz/xz_private.h
@@ -37,6 +37,9 @@
# ifdef CONFIG_XZ_DEC_SPARC
# define XZ_DEC_SPARC
# endif
+# ifdef CONFIG_XZ_DEC_ARM64
+# define XZ_DEC_ARM64
+# endif
# define memeq(a, b, size) (memcmp(a, b, size) == 0)
# define memzero(buf, size) memset(buf, 0, size)
# define FREE free
@@ -98,7 +101,7 @@
#ifndef XZ_DEC_BCJ
# if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
|| defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
- || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
+ || defined(XZ_DEC_ARM64) || defined(XZ_DEC_ARMTHUMB) \
|| defined(XZ_DEC_SPARC)
# define XZ_DEC_BCJ
# endif