fix test-redef2:
authorespie <espie@openbsd.org>
Sun, 21 Dec 2014 09:33:12 +0000 (09:33 +0000)
committerespie <espie@openbsd.org>
Sun, 21 Dec 2014 09:33:12 +0000 (09:33 +0000)
- introduce explicit STORAGE classes for the shadow stack entries
- delay freeing definitions if they're in-use, keep them in a simple array.

okay millert@

usr.bin/m4/look.c
usr.bin/m4/main.c
usr.bin/m4/mdef.h
usr.bin/m4/misc.c

index eeec656..ac50457 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: look.c,v 1.23 2014/05/12 19:11:19 espie Exp $ */
+/*     $OpenBSD: look.c,v 1.24 2014/12/21 09:33:12 espie Exp $ */
 
 /*
  * Copyright (c) 1989, 1993
@@ -53,6 +53,9 @@ static void hash_free(void *, void *);
 static void *element_alloc(size_t, void *);
 static void setup_definition(struct macro_definition *, const char *,
     const char *);
+static void free_definition(char *);
+static void keep(char *);
+static int string_in_use(const char *);
 
 static struct ohash_info macro_info = {
        offsetof(struct ndblock, name),
@@ -152,7 +155,7 @@ macro_define(const char *name, const char *defn)
        ndptr n = create_entry(name);
        if (n->d != NULL) {
                if (n->d->defn != null)
-                       free(n->d->defn);
+                       free_definition(n->d->defn);
        } else {
                n->d = xalloc(sizeof(struct macro_definition), NULL);
                n->d->next = NULL;
@@ -270,3 +273,64 @@ macro_getbuiltin(const char *name)
        else
                return p;
 }
+
+/* XXX things are slightly more complicated than they seem.
+ * a macro may actually be "live" (in the middle of an expansion
+ * on the stack.
+ * So we actually may need to place it in an array for later...
+ */
+
+static int kept_capacity = 0;
+static int kept_size = 0;
+static char **kept = NULL;
+
+static void
+keep(char *ptr)
+{
+       if (kept_capacity <= kept_size) {
+               if (kept_capacity)
+                       kept_capacity *= 2;
+               else
+                       kept_capacity = 50;
+               kept = xreallocarray(kept, kept_capacity, 
+                   sizeof(char *), "Out of memory while saving %d strings\n", 
+                   kept_capacity);
+       }
+       kept[kept_size++] = ptr;
+}
+
+static int
+string_in_use(const char *ptr) 
+{
+       int i;
+       for (i = 0; i <= sp; i++) {
+               if (sstack[i] == STORAGE_MACRO && mstack[i].sstr == ptr)
+                       return 1;
+               }
+       return 0;
+}
+
+
+static void
+free_definition(char *ptr)
+{
+       int i;
+
+       /* first try to free old strings */
+       for (i = 0; i < kept_size; i++) {
+               if (!string_in_use(kept[i])) {
+                       kept_size--;
+                       free(kept[i]);
+                       if (i != kept_size) 
+                               kept[i] = kept[kept_size];
+                       i--;
+               }
+       }
+
+       /* then deal with us */
+       if (string_in_use(ptr))
+               keep(ptr);
+       else
+               free(ptr);
+}
+
index 1dce48e..b75877f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.83 2014/05/12 19:11:19 espie Exp $ */
+/*     $OpenBSD: main.c,v 1.84 2014/12/21 09:33:12 espie Exp $ */
 /*     $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $    */
 
 /*-
@@ -397,7 +397,7 @@ macro(void)
                /*
                 * now push the string arguments:
                 */
-                               pushs1(macro_getdef(p)->defn);  /* defn string */
+                               pushdef(p);                     /* defn string */
                                pushs1((char *)macro_name(p));  /* macro name  */
                                pushs(ep);                      /* start next..*/
 
index a4a2bbd..3185dcb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdef.h,v 1.31 2011/09/27 07:24:02 espie Exp $ */
+/*     $OpenBSD: mdef.h,v 1.32 2014/12/21 09:33:12 espie Exp $ */
 /*     $NetBSD: mdef.h,v 1.7 1996/01/13 23:25:27 pk Exp $      */
 
 /*
@@ -163,6 +163,10 @@ struct input_file {
        int             c;
 };
 
+#define STORAGE_STRSPACE 0
+#define STORAGE_MACRO 1
+#define STORAGE_OTHER 2
+
 #define CURRENT_NAME   (infile[ilevel].name)
 #define CURRENT_LINE   (infile[ilevel].lineno)
 /*
@@ -178,7 +182,7 @@ struct input_file {
                if (++sp == STACKMAX)   \
                        enlarge_stack();\
                mstack[sp].sfra = (x);  \
-               sstack[sp] = 0; \
+               sstack[sp] = STORAGE_OTHER; \
        } while (0)
 
 #define pushs(x)                       \
@@ -186,7 +190,7 @@ struct input_file {
                if (++sp == STACKMAX)   \
                        enlarge_stack();\
                mstack[sp].sstr = (x);  \
-               sstack[sp] = 1; \
+               sstack[sp] = STORAGE_STRSPACE; \
        } while (0)
 
 #define pushs1(x)                      \
@@ -194,8 +198,17 @@ struct input_file {
                if (++sp == STACKMAX)   \
                        enlarge_stack();\
                mstack[sp].sstr = (x);  \
-               sstack[sp] = 0; \
+               sstack[sp] = STORAGE_OTHER; \
+       } while (0)
+
+#define pushdef(p)                     \
+       do {                            \
+               if (++sp == STACKMAX)   \
+                       enlarge_stack();\
+               mstack[sp].sstr = macro_getdef(p)->defn;\
+               sstack[sp] = STORAGE_MACRO; \
        } while (0)
+               
 
 /*
  *         .                              .
index 556ecd6..122cf0b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: misc.c,v 1.44 2014/05/12 19:11:19 espie Exp $ */
+/*     $OpenBSD: misc.c,v 1.45 2014/12/21 09:33:12 espie Exp $ */
 /*     $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $     */
 
 /*
@@ -184,7 +184,7 @@ enlarge_strspace()
                errx(1, "string space overflow");
        memcpy(newstrspace, strspace, strsize/2);
        for (i = 0; i <= sp; i++)
-               if (sstack[i])
+               if (sstack[i] == STORAGE_STRSPACE)
                        mstack[i].sstr = (mstack[i].sstr - strspace)
                            + newstrspace;
        ep = (ep-strspace) + newstrspace;