arch_library_init and arch_library_clone should be able to signal failure
- This then trickles to library_init, which needs to return int
- Callers of library_init were updated to unroll their transactions
upon failure
- PPC and ARM backends were updated to match the updated interface
diff --git a/backend.h b/backend.h
index 80e5c07..6edc948 100644
--- a/backend.h
+++ b/backend.h
@@ -238,10 +238,11 @@
/* The following callbacks have to be implemented in backend if arch.h
* defines ARCH_HAVE_LIBRARY_DATA. Those are used to init, destroy
- * and clone LIB->arch. */
-void arch_library_init(struct library *lib);
+ * and clone LIB->arch. arch_library_init and arch_library_clone
+ * return 0 on success or a negative value on failure. */
+int arch_library_init(struct library *lib);
void arch_library_destroy(struct library *lib);
-void arch_library_clone(struct library *retp, struct library *lib);
+int arch_library_clone(struct library *retp, struct library *lib);
/* The following callbacks have to be implemented in backend if arch.h
* defines ARCH_HAVE_LIBRARY_SYMBOL_DATA. Those are used to init,
diff --git a/library.c b/library.c
index 0c9ce3a..27477fd 100644
--- a/library.c
+++ b/library.c
@@ -32,9 +32,10 @@
#include "backend.h" // for arch_library_symbol_init, arch_library_init
#ifndef ARCH_HAVE_LIBRARY_DATA
-void
+int
arch_library_init(struct library *lib)
{
+ return 0;
}
void
@@ -42,9 +43,10 @@
{
}
-void
+int
arch_library_clone(struct library *retp, struct library *lib)
{
+ return 0;
}
#endif
@@ -238,11 +240,11 @@
lib->type = type;
}
-void
+int
library_init(struct library *lib, enum library_type type)
{
private_library_init(lib, type);
- arch_library_init(lib);
+ return arch_library_init(lib);
}
static int
@@ -275,7 +277,6 @@
private_library_init(retp, lib->type);
library_set_soname(retp, soname, lib->own_soname);
library_set_pathname(retp, pathname, lib->own_pathname);
- arch_library_clone(retp, lib);
retp->key = lib->key;
@@ -317,6 +318,9 @@
*nnamep = NULL;
}
+ if (arch_library_clone(retp, lib) < 0)
+ goto fail;
+
return 0;
}
diff --git a/library.h b/library.h
index 8c26a48..0e18c45 100644
--- a/library.h
+++ b/library.h
@@ -1,6 +1,6 @@
/*
* This file is part of ltrace.
- * Copyright (C) 2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
* Copyright (C) 2006 Paul Gilliam, IBM Corporation
*
* This program is free software; you can redistribute it and/or
@@ -165,7 +165,7 @@
};
/* Init LIB. */
-void library_init(struct library *lib, enum library_type type);
+int library_init(struct library *lib, enum library_type type);
/* Initialize RETP to a library identical to LIB. Symbols are not
* shared, but copied over. Returns 0 on success and a negative value
diff --git a/ltrace-elf.c b/ltrace-elf.c
index 78b1245..19cae88 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -1007,9 +1007,10 @@
ltelf_read_main_binary(struct process *proc, const char *path)
{
struct library *lib = malloc(sizeof(*lib));
- if (lib == NULL)
+ if (lib == NULL || library_init(lib, LT_LIBTYPE_MAIN) < 0) {
+ free(lib);
return NULL;
- library_init(lib, LT_LIBTYPE_MAIN);
+ }
library_set_pathname(lib, path, 0);
/* There is a race between running the process and reading its
diff --git a/sysdeps/linux-gnu/arm/fetch.c b/sysdeps/linux-gnu/arm/fetch.c
index 0064d91..5081d78 100644
--- a/sysdeps/linux-gnu/arm/fetch.c
+++ b/sysdeps/linux-gnu/arm/fetch.c
@@ -208,9 +208,10 @@
{
}
-void
+int
arch_library_init(struct library *lib)
{
+ return 0;
}
void
@@ -218,10 +219,11 @@
{
}
-void
+int
arch_library_clone(struct library *retp, struct library *lib)
{
retp->arch = lib->arch;
+ return 0;
}
enum {
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index fe1602a..2d285ab 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -890,9 +890,10 @@
}
}
-void
+int
arch_library_init(struct library *lib)
{
+ return 0;
}
void
@@ -900,9 +901,10 @@
{
}
-void
+int
arch_library_clone(struct library *retp, struct library *lib)
{
+ return 0;
}
int
diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c
index 2e177f3..770d392 100644
--- a/sysdeps/linux-gnu/proc.c
+++ b/sysdeps/linux-gnu/proc.c
@@ -534,17 +534,20 @@
struct library *lib = malloc(sizeof(*lib));
if (lib == NULL) {
fail:
- if (lib != NULL)
- library_destroy(lib);
+ free(lib);
fprintf(stderr, "Couldn't load ELF object %s: %s\n",
lib_name, strerror(errno));
continue;
}
- library_init(lib, LT_LIBTYPE_DSO);
- if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0)
+ if (library_init(lib, LT_LIBTYPE_DSO) < 0)
goto fail;
+ if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0) {
+ library_destroy(lib);
+ goto fail;
+ }
+
lib->key = key;
proc_add_library(proc, lib);
}