#include <sys/times.h>
#include <sys/wait.h>
-#include <obstack.h>
-
#include <gelf.h>
#include <xxhash.h>
#include "args.h"
#include "util.h"
#include "pool.h"
+#include "obstack-wrapper.h"
#ifndef SHF_COMPRESSED
/* Glibc elf.h contains SHF_COMPRESSED starting v2.22. Libelf libelf.h has
}
}
-#define obstack_chunk_alloc malloc
-#define obstack_chunk_free free
-
/* Where to longjmp on OOM. */
static jmp_buf oom_buf;
}
arr[i]->die_remove = 0;
}
- obstack_free (&ob, (void *) arr);
+ obstack_free (&ob, arr);
return ret;
}
tail_offset_list[k++] = 0;
assert (k == tail_offset_list_count);
}
- obstack_free (&ob, (void *) arr);
+ obstack_free (&ob, arr);
return tail_offset_list;
}
htab_delete (macro_htab);
macro_htab = NULL;
}
- obstack_free (&ob, (void *) to_free);
+ obstack_free (&ob, to_free);
}
}
*slot = arr[i];
}
}
- obstack_free (&ob, (void *) arr);
- obstack_free (&ob2, (void *) intracuarr);
+ obstack_free (&ob, arr);
+ obstack_free (&ob2, intracuarr);
if (cu->cu_kind == CU_TYPES)
{
cu->cu_new_offset = types_size;
}
if (wr_multifile)
total_size += 11; /* See the end of write_info. */
- obstack_free (&ob2, (void *) t);
+ obstack_free (&ob2, t);
cuarr = (dw_cu_ref *) obstack_alloc (&ob2, ncus * sizeof (dw_cu_ref));
for (cu = first_cu, i = 0; cu; cu = cu->cu_next)
if (cu->u1.cu_new_abbrev_owner == NULL
cuarr[i]->u1.cu_new_abbrev_owner = cuarr[j];
break;
}
- obstack_free (&ob2, (void *) arr);
+ obstack_free (&ob2, arr);
continue;
}
/* Don't search all CUs, that might be too expensive. So just search
cuarr[i]->u1.cu_new_abbrev_owner = cuarr[j];
}
}
- obstack_free (&ob2, (void *) arr);
+ obstack_free (&ob2, arr);
}
- obstack_free (&ob2, (void *) cuarr);
+ obstack_free (&ob2, cuarr);
for (cu = first_cu; cu; cu = cu->cu_next)
{
struct abbrev_tag **arr;
abbrev_size += 2;
}
abbrev_size += 1;
- obstack_free (&ob, (void *) arr);
+ obstack_free (&ob, arr);
}
for (cu = first_cu; cu; cu = cu->cu_next)
if (unlikely (fi_multifile)
*ptr++ = 0;
}
*ptr++ = 0;
- obstack_free (&ob, (void *) arr);
+ obstack_free (&ob, arr);
if (likely (!low_mem))
{
htab_delete (cu->cu_new_abbrev);
&intracuvec);
assert (*intracuvec == NULL);
}
- obstack_free (&ob2, (void *) t);
+ obstack_free (&ob2, t);
assert (off == cu_size);
}
if (buf_read_ule64 (inptr) != cu->cu_offset)
{
if (cumap)
- obstack_free (&ob2, (void *) cumap);
+ obstack_free (&ob2, cumap);
if (file)
error (0, 0, "%s: unexpected cu cu_offset in .gdb_index", file);
return;
if (tuindices[2 * tuidx] != cu->cu_offset)
{
if (cumap)
- obstack_free (&ob2, (void *) cumap);
+ obstack_free (&ob2, cumap);
else
- obstack_free (&ob2, (void *) tuindices);
+ obstack_free (&ob2, tuindices);
if (file)
error (0, 0, "%s: unexpected tui cu_offset in .gdb_index", file);
return;
}
}
if (cumap)
- obstack_free (&ob2, (void *) cumap);
+ obstack_free (&ob2, cumap);
else if (tuindices)
- obstack_free (&ob2, (void *) tuindices);
+ obstack_free (&ob2, tuindices);
if (fail)
{
if (file)
saved_new_data[i] = NULL;
}
- obstack_free (&ob2, NULL);
- obstack_free (&ob, NULL);
+ obstack_destroy (&ob2);
+ obstack_destroy (&ob);
memset (&ob2, '\0', sizeof (ob2));
memset (&ob, '\0', sizeof (ob2));
die_nontoplevel_freelist = NULL;
&& ret == 0
&& write (multi_str_fd, buf, buf_size) != (ssize_t) buf_size)
ret = 1;
- obstack_free (&ob, (void *) arr);
+ obstack_free (&ob, arr);
return ret;
}
if (multi_line_off + len < multi_line_off)
{
if (line_htab)
- obstack_free (&ob, (void *) filearr);
+ obstack_free (&ob, filearr);
return 1;
}
else
multi_line_off += len;
if (line_htab)
- obstack_free (&ob, (void *) filearr);
+ obstack_free (&ob, filearr);
else if (line != buf)
- obstack_free (&ob, (void *) line);
+ obstack_free (&ob, line);
}
else if (line_htab)
- obstack_free (&ob, (void *) filearr);
+ obstack_free (&ob, filearr);
return ret;
}
--- /dev/null
+/* Copyright (C) 2001-2021 Red Hat, Inc.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 SUSE LLC.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that 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; see the file COPYING. If not, write to
+ the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* Wrapper around obstack.h that changes obstack_free (obstack_ptr, object) to
+ also nullify object. Since that breaks obstack_free (obstack_ptr, NULL), a
+ new function obstack_destroy is added to support that functionaliy. */
+
+#include <obstack.h>
+
+/* Required definitions for obstack use. */
+#define obstack_chunk_alloc malloc
+#define obstack_chunk_free free
+
+/* Free *OBJECT, and assign NULL to it. */
+static inline void
+obstack_free_and_nullify (struct obstack *obstack_ptr, void **object)
+{
+ /* Don't attempt to free nullified *OBJECT. */
+ assert (*object != NULL);
+
+ obstack_free (obstack_ptr, *object);
+
+ /* Nullify *OBJECT to prevent use-after-free. */
+ *object = NULL;
+}
+
+/* Free all objects in OBSTACK_PTR, and leave the obstack uninitialized. */
+static inline void
+obstack_destroy (struct obstack *obstack_ptr)
+{
+ obstack_free (obstack_ptr, NULL);
+}
+
+/* In case obstack_free is implemented as a macro, undefine it in order to be
+ able to redefine it. */
+#undef obstack_free
+
+/* Redefine obstack_free to nullify OBJECT. */
+#define obstack_free(obstack_ptr, object) \
+ obstack_free_and_nullify (obstack_ptr, (void **)&object)