Module Name: src
Committed By: rillig
Date: Fri Jan 13 19:41:50 UTC 2023
Modified Files:
src/usr.bin/xlint/common: externs.h mem.c
src/usr.bin/xlint/lint1: externs1.h init.c lint1.h main1.c mem1.c
tree.c
src/usr.bin/xlint/lint2: externs2.h main2.c mem2.c
Log Message:
lint: remove custom memory allocator
Besides adding complexity, the custom memory allocator didn't invalidate
freed memory, which made it harder to find possible use-after-free bugs.
To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/usr.bin/xlint/common/externs.h
cvs rdiff -u -r1.20 -r1.21 src/usr.bin/xlint/common/mem.c
cvs rdiff -u -r1.170 -r1.171 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.237 -r1.238 src/usr.bin/xlint/lint1/init.c
cvs rdiff -u -r1.158 -r1.159 src/usr.bin/xlint/lint1/lint1.h
cvs rdiff -u -r1.65 -r1.66 src/usr.bin/xlint/lint1/main1.c
cvs rdiff -u -r1.63 -r1.64 src/usr.bin/xlint/lint1/mem1.c
cvs rdiff -u -r1.489 -r1.490 src/usr.bin/xlint/lint1/tree.c
cvs rdiff -u -r1.16 -r1.17 src/usr.bin/xlint/lint2/externs2.h
cvs rdiff -u -r1.24 -r1.25 src/usr.bin/xlint/lint2/main2.c
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/xlint/lint2/mem2.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/xlint/common/externs.h
diff -u src/usr.bin/xlint/common/externs.h:1.24 src/usr.bin/xlint/common/externs.h:1.25
--- src/usr.bin/xlint/common/externs.h:1.24 Sat Sep 4 14:48:27 2021
+++ src/usr.bin/xlint/common/externs.h Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: externs.h,v 1.24 2021/09/04 14:48:27 rillig Exp $ */
+/* $NetBSD: externs.h,v 1.25 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -45,7 +45,6 @@ extern const char *tspec_name(tspec_t);
/*
* mem.c
*/
-extern size_t mem_block_size(void);
extern void *xmalloc(size_t);
extern void *xcalloc(size_t, size_t);
extern void *xrealloc(void *, size_t);
Index: src/usr.bin/xlint/common/mem.c
diff -u src/usr.bin/xlint/common/mem.c:1.20 src/usr.bin/xlint/common/mem.c:1.21
--- src/usr.bin/xlint/common/mem.c:1.20 Fri May 20 21:18:54 2022
+++ src/usr.bin/xlint/common/mem.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: mem.c,v 1.20 2022/05/20 21:18:54 rillig Exp $ */
+/* $NetBSD: mem.c,v 1.21 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,27 +37,15 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: mem.c,v 1.20 2022/05/20 21:18:54 rillig Exp $");
+__RCSID("$NetBSD: mem.c,v 1.21 2023/01/13 19:41:50 rillig Exp $");
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include "lint.h"
-#if defined(IS_LINT1) || defined(IS_LINT2)
-size_t
-mem_block_size(void)
-{
- unsigned int pagesize;
-
- pagesize = (unsigned int)getpagesize();
- return (MBLKSIZ + pagesize - 1) / pagesize * pagesize;
-}
-#endif
-
static void *
not_null(void *ptr)
{
Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.170 src/usr.bin/xlint/lint1/externs1.h:1.171
--- src/usr.bin/xlint/lint1/externs1.h:1.170 Sat Oct 1 09:59:40 2022
+++ src/usr.bin/xlint/lint1/externs1.h Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: externs1.h,v 1.170 2022/10/01 09:59:40 rillig Exp $ */
+/* $NetBSD: externs1.h,v 1.171 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -99,8 +99,6 @@ extern int get_filename_id(const char *)
extern void add_directory_replacement(char *);
extern const char *transform_filename(const char *, size_t);
-extern void initmem(void);
-
extern void *block_zero_alloc(size_t);
extern void *level_zero_alloc(size_t, size_t);
extern void level_free_all(size_t);
@@ -108,8 +106,8 @@ extern void level_free_all(size_t);
extern void *expr_zero_alloc(size_t);
extern tnode_t *expr_alloc_tnode(void);
extern void expr_free_all(void);
-extern struct memory_block *expr_save_memory(void);
-extern void expr_restore_memory(struct memory_block *);
+extern memory_pool expr_save_memory(void);
+extern void expr_restore_memory(memory_pool);
/*
* debug.c
Index: src/usr.bin/xlint/lint1/init.c
diff -u src/usr.bin/xlint/lint1/init.c:1.237 src/usr.bin/xlint/lint1/init.c:1.238
--- src/usr.bin/xlint/lint1/init.c:1.237 Sun Aug 28 12:04:47 2022
+++ src/usr.bin/xlint/lint1/init.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: init.c,v 1.237 2022/08/28 12:04:47 rillig Exp $ */
+/* $NetBSD: init.c,v 1.238 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: init.c,v 1.237 2022/08/28 12:04:47 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.238 2023/01/13 19:41:50 rillig Exp $");
#endif
#include <stdlib.h>
@@ -309,7 +309,6 @@ check_init_expr(const type_t *ltp, sym_t
tnode_t *ln;
type_t *lutp;
tspec_t lt, rt;
- struct memory_block *tmem;
lutp = expr_unqualified_type(ltp);
@@ -334,9 +333,9 @@ check_init_expr(const type_t *ltp, sym_t
* Preserve the tree memory. This is necessary because otherwise
* expr() would free it.
*/
- tmem = expr_save_memory();
+ memory_pool saved_mem = expr_save_memory();
expr(rn, true, false, true, false);
- expr_restore_memory(tmem);
+ expr_restore_memory(saved_mem);
check_bit_field_init(ln, lt, rt);
Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.158 src/usr.bin/xlint/lint1/lint1.h:1.159
--- src/usr.bin/xlint/lint1/lint1.h:1.158 Sat Oct 1 09:42:40 2022
+++ src/usr.bin/xlint/lint1/lint1.h Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.158 2022/10/01 09:42:40 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.159 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -36,6 +36,18 @@
#include "err-msgs.h"
#include "op.h"
+/*
+ * A memory pool collects allocated objects that must be available until:
+ * - the end of a block,
+ * - the end of an expression, or
+ * - the end of the translation unit.
+ */
+typedef struct memory_pool {
+ void **items;
+ size_t len;
+ size_t cap;
+} memory_pool;
+
/* See saved_lwarn in cgram.y. */
#define LWARN_ALL (-2)
#define LWARN_NONE (-1)
@@ -426,7 +438,7 @@ typedef struct control_statement {
tnode_t *c_switch_expr;
case_label_t *c_case_labels; /* list of case values */
- struct memory_block *c_for_expr3_mem; /* saved memory for end of loop
+ memory_pool c_for_expr3_mem; /* saved memory for end of loop
* expression in for() */
tnode_t *c_for_expr3; /* end of loop expr in for() */
pos_t c_for_expr3_pos; /* position of end of loop expr */
Index: src/usr.bin/xlint/lint1/main1.c
diff -u src/usr.bin/xlint/lint1/main1.c:1.65 src/usr.bin/xlint/lint1/main1.c:1.66
--- src/usr.bin/xlint/lint1/main1.c:1.65 Tue Jul 5 22:50:41 2022
+++ src/usr.bin/xlint/lint1/main1.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: main1.c,v 1.65 2022/07/05 22:50:41 rillig Exp $ */
+/* $NetBSD: main1.c,v 1.66 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: main1.c,v 1.65 2022/07/05 22:50:41 rillig Exp $");
+__RCSID("$NetBSD: main1.c,v 1.66 2023/01/13 19:41:50 rillig Exp $");
#endif
#include <sys/types.h>
@@ -259,7 +259,6 @@ main(int argc, char *argv[])
#endif
(void)signal(SIGFPE, sigfpe);
- initmem();
initdecl();
initscan();
Index: src/usr.bin/xlint/lint1/mem1.c
diff -u src/usr.bin/xlint/lint1/mem1.c:1.63 src/usr.bin/xlint/lint1/mem1.c:1.64
--- src/usr.bin/xlint/lint1/mem1.c:1.63 Fri May 20 21:18:55 2022
+++ src/usr.bin/xlint/lint1/mem1.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: mem1.c,v 1.63 2022/05/20 21:18:55 rillig Exp $ */
+/* $NetBSD: mem1.c,v 1.64 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: mem1.c,v 1.63 2022/05/20 21:18:55 rillig Exp $");
+__RCSID("$NetBSD: mem1.c,v 1.64 2023/01/13 19:41:50 rillig Exp $");
#endif
#include <sys/param.h>
@@ -160,74 +160,60 @@ get_filename_id(const char *s)
return fn->fn_id;
}
-/*
- * Memory for declarations and other things that must be available
- * until the end of a block (or the end of the translation unit)
- * is associated with the corresponding mem_block_level, which may be 0.
- * Because this memory is allocated in large blocks associated with
- * a given level it can be freed easily at the end of a block.
- */
-typedef struct memory_block {
- void *start; /* beginning of memory block */
- void *first_free; /* first free byte */
- size_t nfree; /* # of free bytes */
- struct memory_block *next;
-} memory_block;
-
+/* Array of memory pools, indexed by mem_block_level. */
+typedef struct memory_pools {
+ struct memory_pool *pools;
+ size_t cap;
+} memory_pools;
-static size_t mblk_size; /* size of newly allocated memory blocks */
+static memory_pools mpools;
-/* Array of lists of memory blocks, indexed by mem_block_level. */
-static memory_block **mblks;
-static size_t nmblks; /* number of elements in *mblks */
-#define ML_INC ((size_t)32) /* Increment for length of *mblks */
+/* The pool for the current expression is independent of any block level. */
+static memory_pool expr_pool;
-
-/* Allocate new memory, initialized with zero. */
-static void *
-xgetblk(memory_block **mbp, size_t s)
+static void
+mpool_add(memory_pool *pool, void *item)
{
- memory_block *mb;
- void *p;
-
- size_t worst_align = 2 * sizeof(long) - 1;
- s = (s + worst_align) & ~worst_align;
- if ((mb = *mbp) == NULL || mb->nfree < s) {
- size_t block_size = s > mblk_size ? s : mblk_size;
- mb = xmalloc(sizeof(*mb));
- mb->start = xmalloc(block_size);
- mb->first_free = mb->start;
- mb->nfree = block_size;
- mb->next = *mbp;
- *mbp = mb;
+ if (pool->len >= pool->cap) {
+ pool->cap = 2 * pool->len + 16;
+ pool->items = xrealloc(pool->items,
+ sizeof(*pool->items) * pool->cap);
}
-
- p = mb->first_free;
- mb->first_free = (char *)mb->first_free + s;
- mb->nfree -= s;
- (void)memset(p, 0, s);
- return p;
+ pool->items[pool->len++] = item;
}
-/* Free all blocks from list *fmbp. */
static void
-xfreeblk(memory_block **fmbp)
+mpool_free(memory_pool *pool)
{
- memory_block *mb;
- while ((mb = *fmbp) != NULL) {
- *fmbp = mb->next;
- free(mb);
- }
+ for (; pool->len > 0; pool->len--)
+ free(pool->items[pool->len - 1]);
}
-void
-initmem(void)
+static void *
+mpool_zero_alloc(memory_pool *pool, size_t size)
+{
+
+ void *mem = xmalloc(size);
+ memset(mem, 0, size);
+ mpool_add(pool, mem);
+ return mem;
+}
+
+static memory_pool *
+mpool_at(size_t level)
{
- mblk_size = mem_block_size();
- mblks = xcalloc(nmblks = ML_INC, sizeof(*mblks));
+ if (level >= mpools.cap) {
+ size_t prev_cap = mpools.cap;
+ mpools.cap = level + 16;
+ mpools.pools = xrealloc(mpools.pools,
+ sizeof(*mpools.pools) * mpools.cap);
+ for (size_t i = prev_cap; i < mpools.cap; i++)
+ mpools.pools[i] = (memory_pool){ NULL, 0, 0 };
+ }
+ return mpools.pools + level;
}
@@ -236,12 +222,7 @@ void *
level_zero_alloc(size_t l, size_t s)
{
- while (l >= nmblks) {
- mblks = xrealloc(mblks, (nmblks + ML_INC) * sizeof(*mblks));
- (void)memset(&mblks[nmblks], 0, ML_INC * sizeof(*mblks));
- nmblks += ML_INC;
- }
- return xgetblk(&mblks[l], s);
+ return mpool_zero_alloc(mpool_at(l), s);
}
/* Allocate memory that is freed at the end of the current block. */
@@ -256,18 +237,15 @@ void
level_free_all(size_t level)
{
- xfreeblk(&mblks[level]);
+ mpool_free(mpool_at(level));
}
-
-static memory_block *tmblk;
-
/* Allocate memory that is freed at the end of the current expression. */
void *
expr_zero_alloc(size_t s)
{
- return xgetblk(&tmblk, s);
+ return mpool_zero_alloc(&expr_pool, s);
}
static bool
@@ -307,22 +285,21 @@ void
expr_free_all(void)
{
- xfreeblk(&tmblk);
+ mpool_free(&expr_pool);
}
/*
* Save the memory which is used by the current expression. This memory
- * is not freed by the next expr_free_all() call. The pointer returned can be
+ * is not freed by the next expr_free_all() call. The returned value can be
* used to restore the memory.
*/
-memory_block *
+memory_pool
expr_save_memory(void)
{
- memory_block *tmem;
- tmem = tmblk;
- tmblk = NULL;
- return tmem;
+ memory_pool saved_pool = expr_pool;
+ expr_pool = (memory_pool){ NULL, 0, 0 };
+ return saved_pool;
}
/*
@@ -331,13 +308,10 @@ expr_save_memory(void)
* expr_free_all() frees the restored memory.
*/
void
-expr_restore_memory(memory_block *tmem)
+expr_restore_memory(memory_pool saved_pool)
{
expr_free_all();
- if (tmblk != NULL) {
- free(tmblk->start);
- free(tmblk);
- }
- tmblk = tmem;
+ free(expr_pool.items);
+ expr_pool = saved_pool;
}
Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.489 src/usr.bin/xlint/lint1/tree.c:1.490
--- src/usr.bin/xlint/lint1/tree.c:1.489 Sun Jan 8 18:37:12 2023
+++ src/usr.bin/xlint/lint1/tree.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.489 2023/01/08 18:37:12 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.490 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.489 2023/01/08 18:37:12 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.490 2023/01/13 19:41:50 rillig Exp $");
#endif
#include <float.h>
@@ -4883,7 +4883,7 @@ check_precedence_confusion(tnode_t *tn)
}
typedef struct stmt_expr {
- struct memory_block *se_mem;
+ memory_pool se_mem;
sym_t *se_sym;
struct stmt_expr *se_enclosing;
} stmt_expr;
Index: src/usr.bin/xlint/lint2/externs2.h
diff -u src/usr.bin/xlint/lint2/externs2.h:1.16 src/usr.bin/xlint/lint2/externs2.h:1.17
--- src/usr.bin/xlint/lint2/externs2.h:1.16 Tue Nov 16 22:03:12 2021
+++ src/usr.bin/xlint/lint2/externs2.h Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: externs2.h,v 1.16 2021/11/16 22:03:12 rillig Exp $ */
+/* $NetBSD: externs2.h,v 1.17 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -69,7 +69,6 @@ extern void mkstatic(hte_t *);
/*
* mem2.c
*/
-extern void initmem(void);
extern void *xalloc(size_t);
/*
Index: src/usr.bin/xlint/lint2/main2.c
diff -u src/usr.bin/xlint/lint2/main2.c:1.24 src/usr.bin/xlint/lint2/main2.c:1.25
--- src/usr.bin/xlint/lint2/main2.c:1.24 Fri May 20 21:18:55 2022
+++ src/usr.bin/xlint/lint2/main2.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: main2.c,v 1.24 2022/05/20 21:18:55 rillig Exp $ */
+/* $NetBSD: main2.c,v 1.25 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: main2.c,v 1.24 2022/05/20 21:18:55 rillig Exp $");
+__RCSID("$NetBSD: main2.c,v 1.25 2023/01/13 19:41:50 rillig Exp $");
#endif
#include <stdio.h>
@@ -153,8 +153,6 @@ main(int argc, char *argv[])
if (argc == 0)
usage();
- initmem();
-
symtab_init();
for (i = 0; i < argc; i++)
Index: src/usr.bin/xlint/lint2/mem2.c
diff -u src/usr.bin/xlint/lint2/mem2.c:1.15 src/usr.bin/xlint/lint2/mem2.c:1.16
--- src/usr.bin/xlint/lint2/mem2.c:1.15 Fri May 20 21:18:55 2022
+++ src/usr.bin/xlint/lint2/mem2.c Fri Jan 13 19:41:50 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: mem2.c,v 1.15 2022/05/20 21:18:55 rillig Exp $ */
+/* $NetBSD: mem2.c,v 1.16 2023/01/13 19:41:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,51 +37,19 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: mem2.c,v 1.15 2022/05/20 21:18:55 rillig Exp $");
+__RCSID("$NetBSD: mem2.c,v 1.16 2023/01/13 19:41:50 rillig Exp $");
#endif
-#include <sys/param.h>
#include <string.h>
#include "lint2.h"
-/* length of new allocated memory blocks */
-static size_t mblklen;
-
-/* offset of next free byte in mbuf */
-static size_t nxtfree;
-
-/* current buffer to server memory requests from */
-static void *mbuf;
-
-void
-initmem(void)
-{
-
- mblklen = mem_block_size();
- nxtfree = mblklen;
-}
-
-/*
- * Allocate memory in large chunks to avoid space and time overhead of
- * malloc(). This is possible because memory allocated by xalloc()
- * need never to be freed.
- */
+/* Allocate zero-initialized memory that doesn't need to be freed. */
void *
xalloc(size_t sz)
{
- void *ptr;
-
- /* Align to at least 8 bytes. */
- sz = (sz + 7) & ~7L;
- if (nxtfree + sz > mblklen) {
- mbuf = xmalloc(mblklen);
- (void)memset(mbuf, 0, mblklen);
- nxtfree = 0;
- }
-
- ptr = (char *)mbuf + nxtfree;
- nxtfree += sz;
+ void *ptr = xmalloc(sz);
+ (void)memset(ptr, 0, sz);
return ptr;
}