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;
 }

Reply via email to