[SYSCSE]: System Call Sign Extender

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2007-06-12 15:53:46 -03:00
parent 3d010109c8
commit 1382ee83da
4 changed files with 161 additions and 1 deletions

View File

@ -24,6 +24,7 @@ if (NOT CMAKE_BUILD_TYPE)
endif (NOT CMAKE_BUILD_TYPE)
find_package(DWARF REQUIRED)
find_package(Sqlite REQUIRED)
_set_fancy(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}${CMAKE_INSTALL_PREFIX}/${__LIB}" "libdir")
@ -74,8 +75,12 @@ set(prefcnt_SRCS prefcnt.c)
add_executable(prefcnt ${prefcnt_SRCS})
target_link_libraries(prefcnt dwarves)
set(syscse_SRCS syscse.c)
add_executable(syscse ${syscse_SRCS})
target_link_libraries(syscse dwarves)
install(TARGETS codiff ctracer dtagnames pahole pdwtags
pfunct pglobal prefcnt RUNTIME DESTINATION
pfunct pglobal prefcnt syscse RUNTIME DESTINATION
${CMAKE_INSTALL_PREFIX}/bin)
install(TARGETS dwarves LIBRARY DESTINATION ${LIB_INSTALL_DIR})
install(TARGETS dwarves dwarves_emit dwarves_reorganize LIBRARY DESTINATION ${LIB_INSTALL_DIR})

View File

@ -16,6 +16,7 @@ pdwtags.c
pfunct.c
pglobal.c
prefcnt.c
syscse.c
NEWS
README
README.ctracer

View File

@ -73,6 +73,7 @@ rm -rf %{buildroot}
%{_bindir}/pfunct
%{_bindir}/pglobal
%{_bindir}/prefcnt
%{_bindir}/syscse
%{_bindir}/ostra-cg
%dir %{_datadir}/dwarves/runtime/
%dir %{_datadir}/dwarves/runtime/python/

153
syscse.c Normal file
View File

@ -0,0 +1,153 @@
/*
Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
System call sign extender
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
*/
#define _GNU_SOURCE
#include <argp.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dwarves.h"
static const char *prefix = "sys_";
static size_t prefix_len = 4;
static struct tag *filter(struct tag *self, struct cu *cu,
void *cookie __unused)
{
if (self->tag == DW_TAG_subprogram) {
struct function *f = tag__function(self);
if (f->proto.nr_parms != 0) {
const char *name = function__name(f, cu);
if (strlen(name) > prefix_len &&
memcmp(name, prefix, prefix_len) == 0)
return self;
}
}
return NULL;
}
static void zero_extend(const int regparm, const struct base_type *bt,
const char *parm)
{
const char *instr = "INVALID";
switch (bt->size) {
case 4: /* 32 bits */
instr = "sll";
break;
case 2: /* 16 bits */
instr = "slw";
break;
case 1: /* 8 bits */
instr = "slb";
break;
}
printf("\t%s\t$a%d, $a%d, 0"
"\t/* zero extend $a%d(%s %s) from %d to 64-bit */\n",
instr, regparm, regparm, regparm, bt->name, parm, bt->size * 8);
}
static int emit_wrapper(struct tag *self, struct cu *cu, void *cookie __unused)
{
struct parameter *parm;
struct function *f = tag__function(self);
const char *name = function__name(f, cu);
int regparm = 0, needs_wrapper = 0;
function__for_each_parameter(f, parm) {
const Dwarf_Off type_id = parameter__type(parm, cu);
struct tag *type = cu__find_tag_by_id(cu, type_id);
assert(type != NULL);
if (type->tag == DW_TAG_base_type) {
struct base_type *bt = tag__base_type(type);
if (bt->size < 8 &&
strncmp(bt->name, "unsigned", 8) == 0) {
if (!needs_wrapper) {
printf("wrap_%s:\n", name);
needs_wrapper = 1;
}
zero_extend(regparm, bt,
parameter__name(parm, cu));
}
}
++regparm;
}
if (needs_wrapper)
printf("\tj\t%s\n\n", name);
return 0;
}
static int cu__emit_wrapper(struct cu *self, void *cookie __unused)
{
return cu__for_each_tag(self, emit_wrapper, NULL, filter);
}
static void cus__emit_wrapper(struct cus *self)
{
cus__for_each_cu(self, cu__emit_wrapper, NULL, NULL);
}
static const struct argp_option options[] = {
{
.key = 'p',
.name = "prefix",
.arg = "PREFIX",
.doc = "function prefix",
},
{
.name = NULL,
}
};
static error_t options_parser(int key, char *arg, struct argp_state *state)
{
switch (key) {
case ARGP_KEY_INIT: state->child_inputs[0] = state->input; break;
case 'p': prefix = arg; break;
default: return ARGP_ERR_UNKNOWN;
}
return 0;
}
static const char args_doc[] = "[FILE]";
static struct argp argp = {
.options = options,
.parser = options_parser,
.args_doc = args_doc,
};
int main(int argc, char *argv[])
{
int err;
struct cus *cus = cus__new(NULL, NULL);
if (cus == NULL) {
fprintf(stderr, "%s: insufficient memory\n", argv[0]);
return EXIT_FAILURE;
}
err = cus__loadfl(cus, &argp, argc, argv);
if (err != 0)
return EXIT_FAILURE;
cus__emit_wrapper(cus);
return EXIT_SUCCESS;
}