pkg2: ini patches: reduce heap fragmentation/pressure
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -8,12 +24,12 @@
|
||||
|
||||
#define KPS(x) ((u32)(x) << 29)
|
||||
|
||||
static u8 *_htoa(u8 *result, const char *ptr, u8 byte_len)
|
||||
static u8 *_htoa(u8 *result, const char *ptr, u8 byte_len, u8 *buf)
|
||||
{
|
||||
char ch = *ptr;
|
||||
u32 ascii_len = byte_len * 2;
|
||||
if (!result)
|
||||
result = malloc(byte_len);
|
||||
result = buf;
|
||||
u8 *dst = result;
|
||||
|
||||
while (ch == ' ' || ch == '\t')
|
||||
@@ -46,24 +62,11 @@ static u8 *_htoa(u8 *result, const char *ptr, u8 byte_len)
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *_strdup(char *str)
|
||||
{
|
||||
if (!str)
|
||||
return NULL;
|
||||
if (str[0] == ' ' && (strlen(str) > 1))
|
||||
str++;
|
||||
char *res = (char *)malloc(strlen(str) + 1);
|
||||
strcpy(res, str);
|
||||
if (res[strlen(res) - 1] == ' ' && (strlen(res) > 1))
|
||||
res[strlen(res) - 1] = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static u32 _find_patch_section_name(char *lbuf, u32 lblen, char schar)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
// Depends on 'FF_USE_STRFUNC 2' that removes \r.
|
||||
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
@@ -75,12 +78,16 @@ static ini_kip_sec_t *_ini_create_kip_section(link_t *dst, ini_kip_sec_t *ksec,
|
||||
if (ksec)
|
||||
list_append(dst, &ksec->link);
|
||||
|
||||
ksec = (ini_kip_sec_t *)calloc(sizeof(ini_kip_sec_t), 1);
|
||||
u32 i = _find_patch_section_name(name, strlen(name), ':') + 1;
|
||||
ksec->name = _strdup(name);
|
||||
// Calculate total allocation size.
|
||||
u32 len = strlen(name);
|
||||
char *buf = calloc(sizeof(ini_kip_sec_t) + len + 1, 1);
|
||||
|
||||
ksec = (ini_kip_sec_t *)buf;
|
||||
u32 i = _find_patch_section_name(name, len, ':') + 1;
|
||||
ksec->name = strcpy_ns(buf + sizeof(ini_kip_sec_t), name);
|
||||
|
||||
// Get hash section.
|
||||
_htoa(ksec->hash, &name[i], 8);
|
||||
_htoa(ksec->hash, &name[i], 8, NULL);
|
||||
|
||||
return ksec;
|
||||
}
|
||||
@@ -89,13 +96,15 @@ int ini_patch_parse(link_t *dst, char *ini_path)
|
||||
{
|
||||
FIL fp;
|
||||
u32 lblen;
|
||||
char lbuf[512];
|
||||
char *lbuf;
|
||||
ini_kip_sec_t *ksec = NULL;
|
||||
|
||||
// Open ini.
|
||||
if (f_open(&fp, ini_path, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
|
||||
lbuf = malloc(512);
|
||||
|
||||
do
|
||||
{
|
||||
// Fetch one line.
|
||||
@@ -111,37 +120,47 @@ int ini_patch_parse(link_t *dst, char *ini_path)
|
||||
{
|
||||
_find_patch_section_name(lbuf, lblen, ']');
|
||||
|
||||
// Set patchset kip name and hash.
|
||||
ksec = _ini_create_kip_section(dst, ksec, &lbuf[1]);
|
||||
list_init(&ksec->pts);
|
||||
}
|
||||
else if (ksec && lbuf[0] == '.') //Extract key/value.
|
||||
else if (ksec && lbuf[0] == '.') // Extract key/value.
|
||||
{
|
||||
u32 tmp = 0;
|
||||
u32 i = _find_patch_section_name(lbuf, lblen, '=');
|
||||
u32 str_start = 0;
|
||||
u32 pos = _find_patch_section_name(lbuf, lblen, '=');
|
||||
|
||||
ini_patchset_t *pt = (ini_patchset_t *)calloc(sizeof(ini_patchset_t), 1);
|
||||
// Calculate total allocation size.
|
||||
char *buf = calloc(sizeof(ini_patchset_t) + strlen(&lbuf[1]) + 1, 1);
|
||||
ini_patchset_t *pt = (ini_patchset_t *)buf;
|
||||
|
||||
pt->name = _strdup(&lbuf[1]);
|
||||
// Set patch name.
|
||||
pt->name = strcpy_ns(buf + sizeof(ini_patchset_t), &lbuf[1]);
|
||||
|
||||
u8 kip_sidx = lbuf[i + 1] - '0';
|
||||
u8 kip_sidx = lbuf[pos + 1] - '0';
|
||||
pos += 3;
|
||||
|
||||
if (kip_sidx < 6)
|
||||
{
|
||||
// Set patch offset.
|
||||
pt->offset = KPS(kip_sidx);
|
||||
tmp = _find_patch_section_name(&lbuf[i + 3], lblen, ':');
|
||||
pt->offset |= strtol(&lbuf[i + 3], NULL, 16);
|
||||
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ':');
|
||||
pt->offset |= strtol(&lbuf[pos], NULL, 16);
|
||||
pos += str_start + 1;
|
||||
|
||||
i += tmp + 4;
|
||||
// Set patch size.
|
||||
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ':');
|
||||
pt->length = strtol(&lbuf[pos], NULL, 16);
|
||||
pos += str_start + 1;
|
||||
|
||||
tmp = _find_patch_section_name(&lbuf[i], lblen, ':');
|
||||
pt->length = strtol(&lbuf[i], NULL, 16);
|
||||
u8 *buf = malloc(pt->length * 2);
|
||||
|
||||
i += tmp + 1;
|
||||
// Set patch source data.
|
||||
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ',');
|
||||
pt->srcData = _htoa(NULL, &lbuf[pos], pt->length, buf);
|
||||
pos += str_start + 1;
|
||||
|
||||
tmp = _find_patch_section_name(&lbuf[i], lblen, ',');
|
||||
pt->srcData = _htoa(NULL, &lbuf[i], pt->length);
|
||||
i += tmp + 1;
|
||||
pt->dstData = _htoa(NULL, &lbuf[i], pt->length);
|
||||
// Set patch destination data.
|
||||
pt->dstData = _htoa(NULL, &lbuf[pos], pt->length, buf + pt->length);
|
||||
}
|
||||
|
||||
list_append(&ksec->pts, &pt->link);
|
||||
@@ -153,5 +172,7 @@ int ini_patch_parse(link_t *dst, char *ini_path)
|
||||
if (ksec)
|
||||
list_append(dst, &ksec->link);
|
||||
|
||||
free(lbuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user