diff options
Diffstat (limited to 'elfutils/libebl/eblstrtab.c')
-rw-r--r-- | elfutils/libebl/eblstrtab.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/elfutils/libebl/eblstrtab.c b/elfutils/libebl/eblstrtab.c index d6ce94ae..4222cfd5 100644 --- a/elfutils/libebl/eblstrtab.c +++ b/elfutils/libebl/eblstrtab.c @@ -101,9 +101,11 @@ struct Ebl_Strtab }; -/* Cache for the pagesize. We correct this value a bit so that `malloc' - is not allocating more than a page. */ +/* Cache for the pagesize. */ static size_t ps; +/* We correct this value a bit so that `malloc' is not allocating more + than a page. */ +#define MALLOC_OVERHEAD (2 * sizeof (void *)) struct Ebl_Strtab * @@ -111,8 +113,8 @@ ebl_strtabinit (bool nullstr) { if (ps == 0) { - ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); - assert (sizeof (struct memoryblock) < ps); + ps = sysconf (_SC_PAGESIZE); + assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD); } struct Ebl_Strtab *ret @@ -135,8 +137,11 @@ ebl_strtabinit (bool nullstr) static int morememory (struct Ebl_Strtab *st, size_t len) { - if (len < ps) - len = ps; + size_t overhead = offsetof (struct memoryblock, memory); + len += overhead + MALLOC_OVERHEAD; + + /* Allocate nearest multiple of pagesize >= len. */ + len = ((len / ps) + (len % ps != 0)) * ps - MALLOC_OVERHEAD; struct memoryblock *newmem = (struct memoryblock *) malloc (len); if (newmem == NULL) @@ -145,7 +150,7 @@ morememory (struct Ebl_Strtab *st, size_t len) newmem->next = st->memory; st->memory = newmem; st->backp = newmem->memory; - st->left = len - offsetof (struct memoryblock, memory); + st->left = len - overhead; return 0; } @@ -352,7 +357,8 @@ ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data) the offset members of the elfstrent records. */ char *endp = (char *) data->d_buf + nulllen; size_t copylen = nulllen; - copystrings (st->root, &endp, ©len); + if (st->root) + copystrings (st->root, &endp, ©len); assert (copylen == st->total + nulllen); } |