Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/client/auditclient/auditclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void spindle_la_activity (uintptr_t *cookie, unsigned int flag)
"???");
restore_pathpatch();
if (flag == LA_ACT_CONSISTENT) {
mark_startup_done();
patchDTV_check();
lookup_libc_symbols();
updateDataBindingQueue(0);
Expand Down
2 changes: 1 addition & 1 deletion src/client/auditclient/fixlocale.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#if defined(NEWTHREAD_LOCALE_BUG)
#include <sys/syscall.h>

static __thread int fixed_locale __attribute__((tls_model("local-dynamic"))) = 0;
static __thread int fixed_locale __attribute__((tls_model("initial-exec"))) = 0;

static pid_t gettid()
{
Expand Down
6 changes: 3 additions & 3 deletions src/client/auditclient/patch_bad_dtv.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ Place, Suite 330, Boston, MA 02111-1307 USA

/**
* This file works around a glibc problem when LD_AUDIT is enable, where the DTV (dynamic thread vector)
* gets allocated using ld.so's rtld_malloc function, then later gets resized by libc.so's realloc function
* gets allocated using ld.so's rtld_malloc function, then later gets resized by the application's realloc function
* (SPINDLE_SRC/scripts/dtvtest/ has a reproducer that can make this happen--you need lots of libraries with TLS).
*
* We'll work around this problem by A) recognizing when this will happen, and B) copying the DTV to a
* memory region properly controlled by libc.so's malloc.
* memory region properly controlled by the application's malloc.
* We recognize this because in the buggy case, the DTV will change values twice before libc.so enters a
* consistent state.
* We copy the DTV to a proper malloc region by getting its pointer out of TLS space. DTV is a vector, and
Expand Down Expand Up @@ -120,7 +120,7 @@ void patchDTV_check()

debug_printf2("Reallocating dtv to work around glibc bug. initial_dtv = %p ; dtv = %p\n",
initial_dtv, dtv);
malloc_sig_t app_malloc = get_libc_malloc();
malloc_sig_t app_malloc = get_app_malloc();
if (!app_malloc) {
debug_printf("Warning: Could not lookup up application malloc to realloc dtv. App may be prone to crashes during dlopen's\n");
return;
Expand Down
2 changes: 1 addition & 1 deletion src/client/auditclient/patch_linkmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void patch_on_linkactivity(struct link_map *lmap)
strcpy(lmap->l_name, last_orig_name);
}
else {
malloc_sig_t app_malloc = get_libc_malloc();
malloc_sig_t app_malloc = get_app_malloc();
if (app_malloc) {
len = strlen(last_orig_name) + 2;
oname = (char *) app_malloc(len);
Expand Down
3 changes: 2 additions & 1 deletion src/client/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ extern int intercept_fork;
extern void int_spindle_test_log_msg(char *buffer);

typedef void* (*malloc_sig_t)(size_t);
malloc_sig_t get_libc_malloc();
malloc_sig_t get_app_malloc();
void mark_startup_done();

void *get_libc_abort_msg();

Expand Down
60 changes: 43 additions & 17 deletions src/client/client/lookup_libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct gnu_hash_header {
};

static malloc_sig_t mallocfunc = NULL;
static int startup_done = 0;

static void *volatile abort_msg_addr = NULL;

Expand Down Expand Up @@ -203,21 +204,6 @@ int lookup_libc_symbols()
found++;
}

result = -1;
if (gnu_hash)
result = lookup_gnu_hash_symbol("malloc", symtab, strtab, (struct gnu_hash_header *) gnu_hash);
if (elf_hash && result == -1)
result = lookup_elf_hash_symbol("malloc", symtab, strtab, (ElfW(Word) *) elf_hash);
if (result == -1) {
debug_printf3("Warning, Could not find symbol malloc in libc\n");
not_found++;
}
else {
mallocfunc = (malloc_sig_t) (symtab[result].st_value + libc->l_addr);
debug_printf3("Bound mallocfunc to %p\n", mallocfunc);
found++;
}

result = -1;
if (gnu_hash)
result = lookup_gnu_hash_symbol("__abort_msg", symtab, strtab, (struct gnu_hash_header *) gnu_hash);
Expand Down Expand Up @@ -292,14 +278,54 @@ int lookup_libdl_symbols()
return found;
}

malloc_sig_t get_libc_malloc()
static int lookup_defined_symbol(struct link_map *lmap, const char *name, void **addr)
{
signed long result = -1;
INIT_DYNAMIC(lmap);

if (gnu_hash)
result = lookup_gnu_hash_symbol(name, symtab, strtab, (struct gnu_hash_header *) gnu_hash);
if (elf_hash && result == -1)
result = lookup_elf_hash_symbol(name, symtab, strtab, (ElfW(Word) *) elf_hash);
/* We only want to find a defined symbol; check if it's undefined */
if (result == -1 || symtab[result].st_shndx == SHN_UNDEF)
return -1;
*addr = (void *) (symtab[result].st_value + lmap->l_addr);
return 0;
}

malloc_sig_t get_app_malloc()
{
struct link_map *l;
void *addr;

/* If we haven't gotten LA_ACT_CONSISTENT yet, it's not safe to call the app's malloc */
if (!startup_done)
return NULL;

if (mallocfunc)
return mallocfunc;
lookup_libc_symbols();

/* Iterate over the link map looking for a library that defines malloc. */
for (l = _r_debug.r_map; l != NULL; l = l->l_next) {
/* Skip vDSO when iterating as symbol lookup crashes in it */
if (l->l_name && (strstr(l->l_name, "linux-vdso") || strstr(l->l_name, "linux-gate")))
continue;
if (lookup_defined_symbol(l, "malloc", &addr) == 0) {
debug_printf3("Bound app malloc to %p in %s\n", addr,
(l->l_name && *l->l_name) ? l->l_name : "executable");
mallocfunc = (malloc_sig_t) addr;
break;
}
}
return mallocfunc;
}

void mark_startup_done()
{
startup_done = 1;
}

void *get_libc_abort_msg()
{
return abort_msg_addr;
Expand Down
2 changes: 1 addition & 1 deletion src/client/client/realpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static char *spindlerp_ext_strdup(const char *s)
size_t len;
malloc_sig_t mallocf;

mallocf = get_libc_malloc();
mallocf = get_app_malloc();
if (!mallocf) {
err_printf("Could not lookup malloc function for realpath result\n");
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/client/crash_handler/crash_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static int crash_query_server(const char *site, const char *corepath,
static void crash_handler_entry(int sig, siginfo_t *info, void *uctx)
{
/* Reentrancy flag to detect if we crash again while handling the crash. */
static __thread sig_atomic_t reentering = 0;
static __thread sig_atomic_t reentering __attribute__((tls_model("initial-exec"))) = 0;

/* We need to restore errno before returning. */
int saved_errno = errno;
Expand Down
27 changes: 25 additions & 2 deletions testsuite/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
noinst_PROGRAMS = libgenerator

ABS_TEST_DIR = $(abspath $(top_builddir)/testsuite)
BUILT_SOURCES = libtest10.so libtest11.so libtest12.so libtest13.so libtest14.so libtest15.so libtest16.so libtest17.so libtest18.so libtest19.so libtest20.so libtest50.so libtest100.so libtest500.so libtest1000.so libtest2000.so libtest4000.so libtest6000.so libtest8000.so libtest10000.so libtls1.c libtls2.c libtls3.c libtls4.c libtls5.c libtls6.c libtls7.c libtls8.c libtls9.c libtls10.c libtls11.c libtls12.c libtls13.c libtls14.c libtls15.c libtls16.c libtls17.c libtls18.c libtls19.c libtls20.c libsymlink.so libdepC.so libdepB.so libdepA.so libcxxexceptB.so libcxxexceptA.so origin_dir/liboriginlib.so origin_dir/origin_subdir/liborigintarget.so libtestoutput.so libfuncdict.so runTests run_driver run_driver_rm spindle.rc preload_file_list test_driver test_driver_libs retzero_rx retzero_r retzero_x retzero_ badinterp hello_r.py hello_x.py hello_rx.py hello_.py hello_l.py badlink.py spindle_exec_test spindle_deactivated.sh liblocal.so symbind_test interpreter_test interpreter_test_dir/interpreter_test_perl alias/aliastest.py exec_shell.sh exec_shell.tcsh exec_shell_expected_output exec_shell exec_shell_env.sh libbigtls1024.so libbigtls204800.so libbigtls1048576.so close_range_test
BUILT_SOURCES = libtest10.so libtest11.so libtest12.so libtest13.so libtest14.so libtest15.so libtest16.so libtest17.so libtest18.so libtest19.so libtest20.so libtest50.so libtest100.so libtest500.so libtest1000.so libtest2000.so libtest4000.so libtest6000.so libtest8000.so libtest10000.so libtls1.c libtls2.c libtls3.c libtls4.c libtls5.c libtls6.c libtls7.c libtls8.c libtls9.c libtls10.c libtls11.c libtls12.c libtls13.c libtls14.c libtls15.c libtls16.c libtls17.c libtls18.c libtls19.c libtls20.c libsymlink.so libdepC.so libdepB.so libdepA.so libcxxexceptB.so libcxxexceptA.so origin_dir/liboriginlib.so origin_dir/origin_subdir/liborigintarget.so libtestoutput.so libfuncdict.so runTests run_driver run_driver_rm spindle.rc preload_file_list test_driver test_driver_libs retzero_rx retzero_r retzero_x retzero_ badinterp hello_r.py hello_x.py hello_rx.py hello_.py hello_l.py badlink.py spindle_exec_test spindle_deactivated.sh liblocal.so symbind_test interpreter_test interpreter_test_dir/interpreter_test_perl alias/aliastest.py exec_shell.sh exec_shell.tcsh exec_shell_expected_output exec_shell exec_shell_env.sh libbigtls1024.so libbigtls204800.so libbigtls1048576.so close_range_test libtagmalloc.so long_needed_path_test long_needed_app_malloc_test long_needed_lib_malloc_test realpath_free_test realpath_free_lib_test

BUILT_SOURCES += crash_test crash_test_fixedaddr crash_test_pie libcrashfuncs.so libcrashctor.so libcrashfixed.so run_crash_tests.sh

Expand Down Expand Up @@ -482,5 +482,28 @@ exec_shell: $(srcdir)/exec_shell.c
close_range_test: $(srcdir)/close_range_test.c
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $<

CLEANFILES = libtest10.c libtest11.c libtest12.c libtest13.c libtest14.c libtest15.c libtest16.c libtest17.c libtest18.c libtest19.c libtest20.c libtest10.so libtest50.c libtest50.so libtest100.c libtest100.so libtest500.c libtest500.so libtest1000.c libtest1000.so libtest2000.c libtest2000.so libtest4000.c libtest4000.so libtest6000.c libtest6000.so libtest8000.c libtest8000.so libtest10000.c libtest10000.so libsymlink.so libdepA.so libdepB.so libdepC.so libcxxexceptA.so libcxxexceptB.so libtestoutput.so libfuncdict.so runTests run_driver run_driver_rm spindle.rc test_driver test_driver_libs preload_file_list retzero_rx retzero_r retzero_x retzero_ badinterp hello_r.py hello_x.py hello_rx.py hello_.py hello_l.py badlink.py libtls1.c libtls2.c libtls3.c libtls4.c libtls5.c libtls6.c libtls7.c libtls8.c libtls9.c libtls10.c libtls11.c libtls12.c libtls13.c libtls14.c libtls15.c libtls16.c libtls17.c libtls18.c libtls19.c libtls20.c libtls1.so libtls2.so libtls3.so libtls4.so libtls5.so libtls6.so libtls7.so libtls8.so libtls9.so libtls10.so libtls11.so libtls12.so libtls13.so libtls14.so libtls15.so libtls16.so libtls17.so libtls18.so libtls19.so libtls20.so symbind_test libsymbind_a.so libsymbind_b.so libsymbind_c.so libsymbind_d.so libsymbind_e.so libsymbind_f.so libsymbind_g.so interpreter_test interpreter_test_dir/interpreter_test_perl alias exec_shell.sh exec_shell.tcsh exec_shell_env.sh exec_shell_expected_output exec_shell crash_test crash_test_fixedaddr crash_test_pie libcrashfuncs.so libcrashctor.so libcrashfixed.so run_crash_tests.sh libbigtls204800.so libbigtls1048576.so close_range_test
LONG_NEEDED_TARGET = origin_dir/origin_subdir/liborigintarget.so
LONG_NEEDED_LIBS = -Wl,--no-as-needed -lc "$$(printf '/%.0s' $$(seq 300))$(abs_builddir)/$(LONG_NEEDED_TARGET)"

TAGMALLOC_LIBS = -L. -Wl,--no-as-needed -ltagmalloc -Wl,-rpath,$(abs_builddir)

libtagmalloc.so: $(srcdir)/tagmalloc.c
$(AM_V_CCLD)$(CC) $(CFLAGS) -fno-builtin -o $@ -shared -fPIC $<

long_needed_path_test: $(srcdir)/long_needed_path_test.c $(LONG_NEEDED_TARGET)
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $(srcdir)/long_needed_path_test.c $(LONG_NEEDED_LIBS)

long_needed_app_malloc_test: $(srcdir)/long_needed_path_test.c $(srcdir)/tagmalloc.c $(LONG_NEEDED_TARGET)
$(AM_V_CCLD)$(CC) $(CFLAGS) -fno-builtin -fPIE -pie -o $@ $(srcdir)/long_needed_path_test.c $(srcdir)/tagmalloc.c $(LONG_NEEDED_LIBS)

long_needed_lib_malloc_test: $(srcdir)/long_needed_path_test.c libtagmalloc.so $(LONG_NEEDED_TARGET)
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $(srcdir)/long_needed_path_test.c $(TAGMALLOC_LIBS) $(LONG_NEEDED_LIBS)

realpath_free_test: $(srcdir)/realpath_free_test.c $(srcdir)/tagmalloc.c
$(AM_V_CCLD)$(CC) $(CFLAGS) -fno-builtin -o $@ $(srcdir)/realpath_free_test.c $(srcdir)/tagmalloc.c

realpath_free_lib_test: $(srcdir)/realpath_free_test.c libtagmalloc.so
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $(srcdir)/realpath_free_test.c $(TAGMALLOC_LIBS)

CLEANFILES = libtest10.c libtest11.c libtest12.c libtest13.c libtest14.c libtest15.c libtest16.c libtest17.c libtest18.c libtest19.c libtest20.c libtest10.so libtest50.c libtest50.so libtest100.c libtest100.so libtest500.c libtest500.so libtest1000.c libtest1000.so libtest2000.c libtest2000.so libtest4000.c libtest4000.so libtest6000.c libtest6000.so libtest8000.c libtest8000.so libtest10000.c libtest10000.so libsymlink.so libdepA.so libdepB.so libdepC.so libcxxexceptA.so libcxxexceptB.so libtestoutput.so libfuncdict.so runTests run_driver run_driver_rm spindle.rc test_driver test_driver_libs preload_file_list retzero_rx retzero_r retzero_x retzero_ badinterp hello_r.py hello_x.py hello_rx.py hello_.py hello_l.py badlink.py libtls1.c libtls2.c libtls3.c libtls4.c libtls5.c libtls6.c libtls7.c libtls8.c libtls9.c libtls10.c libtls11.c libtls12.c libtls13.c libtls14.c libtls15.c libtls16.c libtls17.c libtls18.c libtls19.c libtls20.c libtls1.so libtls2.so libtls3.so libtls4.so libtls5.so libtls6.so libtls7.so libtls8.so libtls9.so libtls10.so libtls11.so libtls12.so libtls13.so libtls14.so libtls15.so libtls16.so libtls17.so libtls18.so libtls19.so libtls20.so symbind_test libsymbind_a.so libsymbind_b.so libsymbind_c.so libsymbind_d.so libsymbind_e.so libsymbind_f.so libsymbind_g.so interpreter_test interpreter_test_dir/interpreter_test_perl alias exec_shell.sh exec_shell.tcsh exec_shell_env.sh exec_shell_expected_output exec_shell crash_test crash_test_fixedaddr crash_test_pie libcrashfuncs.so libcrashctor.so libcrashfixed.so run_crash_tests.sh libbigtls204800.so libbigtls1048576.so close_range_test libtagmalloc.so long_needed_path_test long_needed_app_malloc_test long_needed_lib_malloc_test realpath_free_test realpath_free_lib_test

33 changes: 29 additions & 4 deletions testsuite/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,11 @@ BUILT_SOURCES = libtest10.so libtest11.so libtest12.so libtest13.so \
alias/aliastest.py exec_shell.sh exec_shell.tcsh \
exec_shell_expected_output exec_shell exec_shell_env.sh \
libbigtls1024.so libbigtls204800.so libbigtls1048576.so \
close_range_test crash_test crash_test_fixedaddr \
crash_test_pie libcrashfuncs.so libcrashctor.so \
libcrashfixed.so run_crash_tests.sh
close_range_test libtagmalloc.so long_needed_path_test \
long_needed_app_malloc_test long_needed_lib_malloc_test \
realpath_free_test realpath_free_lib_test crash_test \
crash_test_fixedaddr crash_test_pie libcrashfuncs.so \
libcrashctor.so libcrashfixed.so run_crash_tests.sh
@BGQ_BLD_FALSE@DYNAMIC_FLAG =
@BGQ_BLD_TRUE@DYNAMIC_FLAG = -dynamic
@BGQ_BLD_FALSE@IS_BLUEGENE = false
Expand All @@ -379,6 +381,9 @@ test_driver_libsLDFLAGS = -Wl,-E -L$(top_builddir)/testsuite $(MPI_CLDFLAGS) -L$
REGLIB_SRC = $(srcdir)/registerlib.c
LD_FUNCDICT = -L$(top_builddir)/testsuite -lfuncdict
EXTRA_DIST = run_crash_tests_template.sh crash_test.c crash_functions.c crash_functions.h libcrashfuncs.c libcrashctor.c libcrashfixed.c
LONG_NEEDED_TARGET = origin_dir/origin_subdir/liborigintarget.so
LONG_NEEDED_LIBS = -Wl,--no-as-needed -lc "$$(printf '/%.0s' $$(seq 300))$(abs_builddir)/$(LONG_NEEDED_TARGET)"
TAGMALLOC_LIBS = -L. -Wl,--no-as-needed -ltagmalloc -Wl,-rpath,$(abs_builddir)
CLEANFILES = libtest10.c libtest11.c libtest12.c libtest13.c \
libtest14.c libtest15.c libtest16.c libtest17.c libtest18.c \
libtest19.c libtest20.c libtest10.so libtest50.c libtest50.so \
Expand Down Expand Up @@ -408,7 +413,9 @@ CLEANFILES = libtest10.c libtest11.c libtest12.c libtest13.c \
exec_shell crash_test crash_test_fixedaddr crash_test_pie \
libcrashfuncs.so libcrashctor.so libcrashfixed.so \
run_crash_tests.sh libbigtls204800.so libbigtls1048576.so \
close_range_test
close_range_test libtagmalloc.so long_needed_path_test \
long_needed_app_malloc_test long_needed_lib_malloc_test \
realpath_free_test realpath_free_lib_test
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am

Expand Down Expand Up @@ -1166,6 +1173,24 @@ exec_shell: $(srcdir)/exec_shell.c
close_range_test: $(srcdir)/close_range_test.c
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $<

libtagmalloc.so: $(srcdir)/tagmalloc.c
$(AM_V_CCLD)$(CC) $(CFLAGS) -fno-builtin -o $@ -shared -fPIC $<

long_needed_path_test: $(srcdir)/long_needed_path_test.c $(LONG_NEEDED_TARGET)
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $(srcdir)/long_needed_path_test.c $(LONG_NEEDED_LIBS)

long_needed_app_malloc_test: $(srcdir)/long_needed_path_test.c $(srcdir)/tagmalloc.c $(LONG_NEEDED_TARGET)
$(AM_V_CCLD)$(CC) $(CFLAGS) -fno-builtin -fPIE -pie -o $@ $(srcdir)/long_needed_path_test.c $(srcdir)/tagmalloc.c $(LONG_NEEDED_LIBS)

long_needed_lib_malloc_test: $(srcdir)/long_needed_path_test.c libtagmalloc.so $(LONG_NEEDED_TARGET)
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $(srcdir)/long_needed_path_test.c $(TAGMALLOC_LIBS) $(LONG_NEEDED_LIBS)

realpath_free_test: $(srcdir)/realpath_free_test.c $(srcdir)/tagmalloc.c
$(AM_V_CCLD)$(CC) $(CFLAGS) -fno-builtin -o $@ $(srcdir)/realpath_free_test.c $(srcdir)/tagmalloc.c

realpath_free_lib_test: $(srcdir)/realpath_free_test.c libtagmalloc.so
$(AM_V_CCLD)$(CC) $(CFLAGS) -o $@ $(srcdir)/realpath_free_test.c $(TAGMALLOC_LIBS)

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
6 changes: 6 additions & 0 deletions testsuite/long_needed_path_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int origin_target();

int main(void)
{
return origin_target() == 2 ? 0 : 1;
}
10 changes: 10 additions & 0 deletions testsuite/realpath_free_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <stdlib.h>

int main(void)
{
char *r = realpath("/proc/self/exe", NULL);
if (!r || r[0] != '/')
return 1;
free(r);
return 0;
}
15 changes: 15 additions & 0 deletions testsuite/runTests_template
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,21 @@ CHECK_RETCODE
./run_driver --serial ./close_range_test
CHECK_RETCODE

./run_driver --serial ./long_needed_path_test
CHECK_RETCODE

./run_driver --serial ./long_needed_app_malloc_test
CHECK_RETCODE

./run_driver --serial ./long_needed_lib_malloc_test
CHECK_RETCODE

./run_driver --serial ./realpath_free_test
CHECK_RETCODE

./run_driver --serial ./realpath_free_lib_test
CHECK_RETCODE

if [[ $GLOBAL_RESULT != 0 ]]; then
echo SOME TESTS FAILED
exit -1
Expand Down
54 changes: 54 additions & 0 deletions testsuite/tagmalloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* malloc/free wrapper which tags allocated memory in order
* to check that it came from this malloc implementation rather
* than a different one. free() exits if given an untagged pointer */
#include <stddef.h>
#include <unistd.h>

#define TAG 0xabcdef1234567890UL
#define HEADER 16

void *__libc_malloc(size_t n);
void *__libc_calloc(size_t n, size_t m);
void *__libc_realloc(void *p, size_t n);
void __libc_free(void *p);

static void *tag(char *block)
{
if (!block)
return NULL;
*(unsigned long *) block = TAG;
return block + HEADER;
}

static char *untag(void *p)
{
char *block = (char *) p - HEADER;
if (*(unsigned long *) block != TAG) {
/* We got an untagged pointer */
_exit(5);
}
return block;
}

void *malloc(size_t n)
{
return tag(__libc_malloc(n + HEADER));
}

void *calloc(size_t n, size_t m)
{
return tag(__libc_calloc(1, n * m + HEADER));
}

void *realloc(void *p, size_t n)
{
if (!p)
return malloc(n);
return tag(__libc_realloc(untag(p), n + HEADER));
}

void free(void *p)
{
if (p)
__libc_free(untag(p));
}
Loading