aboutsummaryrefslogtreecommitdiff
path: root/handle_event.c
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2013-10-23 00:39:23 +0200
committerPetr Machata <pmachata@redhat.com>2013-10-23 00:39:23 +0200
commit82f748d1bc2b95d594327ad15f3a6908070dd5c3 (patch)
treebca73acc5b6bfd5390e800d678a3868993f489ed /handle_event.c
parent71025328700158770edf84cbce64d977298b6e88 (diff)
downloadltrace-82f748d1bc2b95d594327ad15f3a6908070dd5c3.tar.gz
System calls are now part of dedicated symbol library
- This symbol library is still special in that symbols are created on demand and never actually added. It just serves as a link to protolibrary with system call prototypes, and has a name (SYS). - Prototypes for system calls were moved to a dedicated prototype library called syscalls.conf. - Because it's undesirable to look up syscall prototypes in anything but the dedicated syscall protolib, prototype.c/.h now understand that some lookups shouldn't be done recursively (and so we never pick the definition from -F file that just happens to have the same name as a system call). The good thing is that now libraries can actually use symbols named SYS_something without clashing with system call prototypes. - One test case needed to be updated, because we now display system calls as something@SYS instead of SYS_something.
Diffstat (limited to 'handle_event.c')
-rw-r--r--handle_event.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/handle_event.c b/handle_event.c
index b7a755c..ae61ade 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
+#include <stdbool.h>
#include "backend.h"
#include "breakpoint.h"
@@ -41,6 +42,7 @@
#include "library.h"
#include "proc.h"
#include "value_dict.h"
+#include "prototype.h"
static void handle_signal(Event *event);
static void handle_exit(Event *event);
@@ -379,9 +381,7 @@ sysname(struct process *proc, int sysnum)
sprintf(result, "SYS_%d", sysnum);
return result;
} else {
- sprintf(result, "SYS_%s",
- syscallents[proc->personality][sysnum]);
- return result;
+ return syscallents[proc->personality][sysnum];
}
}
@@ -445,8 +445,40 @@ output_syscall(struct process *proc, const char *name, enum tof tof,
void (*output)(enum tof, struct process *,
struct library_symbol *))
{
+ static struct library syscall_lib;
+ if (syscall_lib.protolib == NULL) {
+ struct protolib *protolib
+ = protolib_cache_search(&g_protocache, "syscalls", 0, 1);
+ if (protolib == NULL) {
+ fprintf(stderr, "Couldn't load system call prototypes:"
+ " %s.\n", strerror(errno));
+
+ /* Instead, get a fake one just so we can
+ * carry on, limping. */
+ protolib = malloc(sizeof *protolib);
+ if (protolib == NULL) {
+ fprintf(stderr, "Couldn't even allocate a fake "
+ "prototype library: %s.\n",
+ strerror(errno));
+ abort();
+ }
+ protolib_init(protolib);
+ }
+
+ assert(protolib != NULL);
+ if (library_init(&syscall_lib, LT_LIBTYPE_SYSCALL) < 0) {
+ fprintf(stderr, "Couldn't initialize system call "
+ "library: %s.\n", strerror(errno));
+ abort();
+ }
+
+ library_set_soname(&syscall_lib, "SYS", 0);
+ syscall_lib.protolib = protolib;
+ }
+
struct library_symbol syscall;
if (library_symbol_init(&syscall, 0, name, 0, LS_TOPLT_NONE) >= 0) {
+ syscall.lib = &syscall_lib;
(*output)(tof, proc, &syscall);
library_symbol_destroy(&syscall);
}