* Include r_bininfo features in r_bin

* Remove r_bininfo
* Add test bin/t/test_meta.c
This commit is contained in:
Nibble 2010-02-22 04:30:34 +01:00
parent 0efc6402ec
commit f3af308727
30 changed files with 167 additions and 396 deletions

View File

@ -11,7 +11,7 @@ CFLAGS+=-D__UNIX__=1 -DLIL_ENDIAN=1
include ../config.mk
include ${STATIC_BIN_PLUGINS}
STATIC_OBJS=$(subst ..,p/..,$(subst bin_,p/bin_,$(STATIC_OBJ)))
OBJ=bin.o ${STATIC_OBJS}
OBJ=bin.o bin_meta.o ${STATIC_OBJS}
pre:
if [ ! -e libr_bin.${EXT_SO} ]; then rm -f ${STATIC_OBJS} ; fi

View File

@ -3,8 +3,6 @@
/* TODO:
* Linked libraries
* dlopen library and show address
* XRefs
* Generic resize
*/
#include <stdio.h>

15
libr/bin/bin_meta.c Normal file
View File

@ -0,0 +1,15 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
#include <r_types.h>
#include <r_util.h>
#include <r_bin.h>
R_API int r_bin_meta_get_line(RBin *bin, ut64 addr, char *file, int len, int *line) {
if (bin && bin->cur && bin->cur->meta && bin->cur->meta->get_line)
return bin->cur->meta->get_line (bin, addr, file, len, line);
return R_FALSE;
}
R_API char *r_bin_meta_get_file_line(RBin *bin, const char *file, int line) {
return r_file_slurp_line(file, line, 1);
}

View File

@ -128,6 +128,21 @@ static int r_bin_mach0_parse_dysymtab(struct r_bin_mach0_obj_t* bin, ut64 off)
return R_TRUE;
}
static int r_bin_mach0_parse_thread(struct r_bin_mach0_obj_t* bin, ut64 off)
{
int len;
len = r_buf_fread_at(bin->b, off, (ut8*)&bin->thread, bin->endian?"2I":"2i", 1);
if (len == -1) {
ERR("Error: read (dysymtab)\n");
return R_FALSE;
}
ERR ("%x\n", off);
ERR ("cmd: %x\n", bin->thread.cmd);
ERR ("cmdsize: %x\n", bin->thread.cmdsize);
return R_TRUE;
}
static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
{
struct load_command lc = {0, 0};
@ -154,6 +169,11 @@ static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
if (!r_bin_mach0_parse_dysymtab(bin, off))
return R_FALSE;
break;
case LC_UNIXTHREAD:
case LC_THREAD:
if (!r_bin_mach0_parse_thread(bin, off))
return R_FALSE;
break;
}
}
return R_TRUE;
@ -161,18 +181,6 @@ static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
static int r_bin_mach0_init(struct r_bin_mach0_obj_t* bin)
{
bin->segs = NULL;
bin->nsegs = 0;
bin->sects = NULL;
bin->nsects = 0;
bin->symtab = NULL;
bin->symstr = NULL;
bin->nsymtab = 0;
bin->toc = NULL;
bin->ntoc = 0;
bin->modtab = NULL;
bin->nmodtab = 0;
bin->baddr = 0;
if (!r_bin_mach0_init_hdr(bin)) {
ERR("Warning: File is not MACH0\n");
return R_FALSE;
@ -211,6 +219,7 @@ struct r_bin_mach0_obj_t* r_bin_mach0_new(const char* file)
if (!(bin = malloc(sizeof(struct r_bin_mach0_obj_t))))
return NULL;
memset (bin, 0, sizeof (struct r_bin_mach0_obj_t));
bin->file = file;
if (!(buf = (ut8*)r_file_slurp(file, &bin->size)))
return r_bin_mach0_free(bin);

View File

@ -60,6 +60,7 @@ struct r_bin_mach0_obj_t {
int ntoc;
struct dylib_module* modtab;
int nmodtab;
struct thread_command thread;
int size;
ut64 baddr;
int endian;

View File

@ -46,6 +46,7 @@ struct r_bin_handle_t r_bin_plugin_dummy = {
.strings = NULL,
.info = NULL,
.fields = NULL,
.meta = NULL,
};
#ifndef CORELIB

View File

@ -225,6 +225,8 @@ static int check(RBin *bin)
return ret;
}
extern struct r_bin_meta_t r_bin_meta_elf;
struct r_bin_handle_t r_bin_plugin_elf = {
.name = "elf",
.desc = "ELF format r_bin plugin",
@ -241,6 +243,7 @@ struct r_bin_handle_t r_bin_plugin_elf = {
.strings = NULL,
.info = &info,
.fields = &fields,
.meta = &r_bin_meta_elf,
};
#ifndef CORELIB

View File

@ -17,6 +17,8 @@ static int check(RBin *bin)
return ret;
}
extern struct r_bin_meta_t r_bin_meta_elf64;
struct r_bin_handle_t r_bin_plugin_elf64 = {
.name = "elf64",
.desc = "elf64 bin plugin",
@ -33,6 +35,7 @@ struct r_bin_handle_t r_bin_plugin_elf64 = {
.strings = NULL,
.info = &info,
.fields = &fields,
.meta = &r_bin_meta_elf64,
};
#ifndef CORELIB

View File

@ -150,6 +150,7 @@ struct r_bin_handle_t r_bin_plugin_java = {
.strings = &strings,
.info = &info,
.fields = NULL,
.meta = NULL,
};
#ifndef CORELIB

View File

@ -146,6 +146,7 @@ struct r_bin_handle_t r_bin_plugin_mach0 = {
.strings = NULL,
.info = NULL,
.fields = NULL,
.meta = NULL,
};
#ifndef CORELIB

45
libr/bin/p/bin_meta_elf.c Normal file
View File

@ -0,0 +1,45 @@
/* radare - GPL3 - Copyright 2009 nibble<.ds@gmail.com> */
#include <r_types.h>
#include <r_bin.h>
static int cmd_to_str(const char *cmd, char *out, int len)
{
int ret;
FILE *fd = popen(cmd, "r");
if (fd == NULL) {
fprintf(stderr, "Cannot find 'addr2line' program\n");
return R_FALSE;
}
ret = fread(out, 1, len, fd);
if (ret>0) {
if (out[ret-1]=='\n')
out[ret-1]='\0';
} else *out = '\0';
pclose(fd);
return R_TRUE;
}
static int get_line(RBin *bin, ut64 addr, char *file, int len, int *line) {
char *p, buf[1024];
snprintf(buf, 1023, "addr2line -e '%s' 0x%08llx", bin->file, addr);
memset(file,'\0', len);
if (!cmd_to_str(buf, file, len))
return R_FALSE;
p = strchr(file, ':');
if (p) {
*p='\0';
*line = atoi(p+1);
}
return R_TRUE;
}
#if !R_BIN_ELF64
struct r_bin_meta_t r_bin_meta_elf = {
.get_line = &get_line,
};
#endif

View File

@ -0,0 +1,8 @@
/* radare - GPL3 - Copyright 2009 nibble<.ds@gmail.com> */
#define R_BIN_ELF64 1
#include "bin_meta_elf.c"
struct r_bin_meta_t r_bin_meta_elf64 = {
.get_line = &get_line,
};

View File

@ -222,6 +222,7 @@ struct r_bin_handle_t r_bin_plugin_pe = {
.strings = NULL,
.info = &info,
.fields = NULL,
.meta = NULL,
};
#ifndef CORELIB

View File

@ -34,6 +34,7 @@ struct r_bin_handle_t r_bin_plugin_pe64 = {
.strings = NULL,
.info = &info,
.fields = NULL,
.meta = NULL,
};
#ifndef CORELIB

View File

@ -1,4 +1,4 @@
OBJ_ELF=bin_elf.o ../format/elf/elf.o
OBJ_ELF=bin_elf.o bin_meta_elf.o ../format/elf/elf.o
STATIC_OBJ+=${OBJ_ELF}
TARGET_ELF=bin_elf.${EXT_SO}

View File

@ -1,4 +1,4 @@
OBJ_ELF64=bin_elf64.o ../format/elf/elf64.o
OBJ_ELF64=bin_elf64.o bin_meta_elf64.o ../format/elf/elf64.o
STATIC_OBJ+=${OBJ_ELF64}
TARGET_ELF64=bin_elf64.${EXT_SO}

View File

@ -6,4 +6,15 @@ BINDEPS=r_lib r_bin r_flags r_util r_cons
CFLAGS+=-DLIBDIR=\"${PREFIX}/lib\"
LIBS+=${DL_LIBS}
LDPATH=-L.. -L../../util
LDPATH+=-lr_util
all: ${BIN} test_meta${EXT_EXE}
test_meta${EXT_EXE}: test_meta.o
${CC} test_meta.o ${LDPATH} ${LDFLAGS} -o test_meta${EXT_EXE}
myclean:
rm -f test_meta test_meta.o
include ../../rules.mk

40
libr/bin/t/test_meta.c Normal file
View File

@ -0,0 +1,40 @@
/* radare - LGPL - Copyright 2010 nibble <.ds@gmail.com> */
#include <r_types.h>
#include <r_util.h>
#include <r_bin.h>
int main(int argc, char **argv)
{
char file[1024];
char *fileline;
int line = 0;
RBin *bin;
if (argc <3) {
eprintf("Usage: %s [file] [addr]\n", argv[0]);
return 1;
}
bin = r_bin_new ();
if (!r_bin_load (bin, argv[1], NULL)) {
ERR ("r_bin: Cannot open '%s'\n", argv[1]);
return 1;
}
file[0]='\0';
if (!r_bin_meta_get_line(bin, r_num_get(NULL, argv[2]), file, 1023, &line)) {
ERR ("Cannot get metadata\n");
return 1;
}
if (!(fileline = r_bin_meta_get_file_line(bin, file, line))) {
ERR ("Cannot get file line\n");
return 1;
}
printf("FILE: %s\n", file);
printf("LINE: %d\n", line);
printf ("FILE LINE: %s\n", fileline);
free (fileline);
r_bin_free(bin);
return 0;
}

View File

@ -1,21 +0,0 @@
NAME=r_bininfo
DEPS=r_lib r_util
include ../config.mk
foo: pre libr_bininfo.${EXT_SO} plugins
CFLAGS+=-DCORELIB -Iformat
#XXX
CFLAGS+=-DLIL_ENDIAN=1
include ${STATIC_BININFO_PLUGINS}
STATIC_OBJS=$(subst ..,p/..,$(subst bininfo_,p/bininfo_,$(STATIC_OBJ)))
OBJ=bininfo.o ${STATIC_OBJS}
pre:
if [ ! -e libr_bininfo.${EXT_SO} ]; then rm -f ${STATIC_OBJS} ; fi
plugins:
cd p && ${MAKE} all
include ../rules.mk

View File

@ -1,4 +0,0 @@
LIBDWARF:
http://reality.sgiweb.org/davea/dwarf.html
* use r_db to cache line info

View File

@ -1,135 +0,0 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com>, pancake<@nopcode.org> */
#include <stdio.h>
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_bininfo.h>
#include "../config.h"
/* plugin pointers */
//extern struct r_bininfo_handle_t r_bininfo_plugin_elf;
//extern struct r_bininfo_handle_t r_bininfo_plugin_elf64;
//extern struct r_bininfo_handle_t r_bininfo_plugin_pe;
//extern struct r_bininfo_handle_t r_bininfo_plugin_pe64;
//extern struct r_bininfo_handle_t r_bininfo_plugin_java;
extern struct r_bininfo_handle_t r_bininfo_plugin_addr2line;
static struct r_bininfo_handle_t *bininfo_static_plugins[] =
{ R_BININFO_STATIC_PLUGINS };
R_API struct r_bininfo_t *r_bininfo_new()
{
struct r_bininfo_t *bin = MALLOC_STRUCT(struct r_bininfo_t);
return r_bininfo_init(bin);
}
R_API struct r_bininfo_t *r_bininfo_free(struct r_bininfo_t *bin)
{
free(bin);
return NULL;
}
R_API struct r_bininfo_t *r_bininfo_init(struct r_bininfo_t *bin)
{
int i;
if (bin) {
bin->cur = NULL;
bin->user = NULL;
bin->path = NULL;
bin->file = NULL;
bin->rw = 0;
INIT_LIST_HEAD(&bin->bins);
for(i=0;bininfo_static_plugins[i];i++)
r_bininfo_add(bin, bininfo_static_plugins[i]);
}
return bin;
}
R_API void r_bininfo_set_user_ptr(struct r_bininfo_t *bin, void *user)
{
bin->user = user;
}
R_API int r_bininfo_add(struct r_bininfo_t *bin, struct r_bininfo_handle_t *foo)
{
struct list_head *pos;
if (foo->init)
foo->init(bin->user);
/* avoid dupped plugins */
list_for_each_prev(pos, &bin->bins) {
struct r_bininfo_handle_t *h = list_entry(pos, struct r_bininfo_handle_t, list);
if (!strcmp(h->name, foo->name))
return R_FALSE;
}
list_add_tail(&(foo->list), &(bin->bins));
return R_TRUE;
}
R_API int r_bininfo_get_line(struct r_bininfo_t *bin, ut64 addr, char *file, int len, int *line)
{
if (bin&&bin->cur&&bin->cur->get_line)
return bin->cur->get_line(bin, addr, file, len, line);
return R_FALSE;
}
R_API char *r_bininfo_get_file_line(struct r_bininfo_t *bin, const char *file, int line)
{
char path[1024];
snprintf(path, 1023, "%s/%s", bin->path, file);
return r_file_slurp_line(path, line, 1);
}
R_API char *r_bininfo_get_source_path(struct r_bininfo_t *bin)
{
if (bin && bin->path == NULL && bin->cur && bin->cur->get_path)
bin->path = bin->cur->get_path(bin);
return bin->path;
}
R_API int r_bininfo_set_source_path(struct r_bininfo_t *bi, char *path)
{
free(bi->path);
bi->path = strdup(path);
return R_TRUE;
}
R_API int r_bininfo_open(struct r_bininfo_t *bin, const char *file, int rw, char *plugin_name)
{
if (file != NULL)
bin->file = strdup(file);
else return R_FALSE;
bin->rw = rw;
struct list_head *pos;
list_for_each_prev(pos, &bin->bins) {
struct r_bininfo_handle_t *h = list_entry(pos, struct r_bininfo_handle_t, list);
if ((plugin_name && !strcmp(h->name, plugin_name)) ||
(h->check && h->check(bin)))
bin->cur = h;
}
if (bin->cur && bin->cur->open)
return bin->cur->open(bin);
return R_FALSE;
}
R_API int r_bininfo_close(struct r_bininfo_t *bin)
{
if (bin->cur && bin->cur->close)
return bin->cur->close(bin);
return R_FALSE;
}
// TODO: Deprecate list methods
R_API int r_bininfo_list(struct r_bininfo_t *bin)
{
struct list_head *pos;
list_for_each_prev(pos, &bin->bins) {
struct r_bininfo_handle_t *h = list_entry(pos, struct r_bininfo_handle_t, list);
printf(" %s: %s\n", h->name, h->desc);
}
return R_FALSE;
}

View File

@ -1,13 +0,0 @@
include ../../config.mk
CFLAGS=-I../../include -Wall
BINDEPS=
all: bininfo_addr2line.${EXT_SO}
@true
bininfo_addr2line.${EXT_SO}: bininfo_addr2line.o
${CC} ${CFLAGS} ${PIC_CFLAGS} -shared -o bininfo_addr2line.${EXT_SO} bininfo_addr2line.c
clean:
-rm -f *.so *.o

View File

@ -1,9 +0,0 @@
OBJ_ADDR2LINE=bininfo_addr2line.o
TARGET_ADDR2LINE=bininfo_addr2line.so
ALL_TARGETS+=${TARGET_ADDR2LINE}
STATIC_OBJ+=${OBJ_ADDR2LINE}
${TARGET_ADDR2LINE}: ${OBJ_ADDR2LINE}
${CC} ${CFLAGS} -o ${TARGET_ADDR2LINE} ${OBJ_ADDR2LINE}
@#strip -s asm_x86.so

View File

@ -1,80 +0,0 @@
/* radare - LGPL - Copyright 2009 pancake<@nopcode.org> */
#include <r_bininfo.h>
#include <r_lib.h>
static char *a2l_get_path(struct r_bininfo_t *bi)
{
return strdup("");
}
static int cmd_to_str(const char *cmd, char *out, int len)
{
int ret;
FILE *fd = popen(cmd, "r");
if (fd == NULL) {
fprintf(stderr, "Cannot find 'addr2line' program\n");
return R_FALSE;
}
ret = fread(out, len, 1, fd);
if (ret>0) {
if (out[ret-1]=='\n')
out[ret-1]='\0';
} else *out = '\0';
pclose(fd);
return R_TRUE;
}
/* XXX: Bad signature */
static char *a2l_get_function_name(struct r_bininfo_t *bi, ut64 addr, char *file, int len)
{
static char buf[1024];
snprintf(buf, 1023, "addr2line -f -e '%s' 0x%08llx | head -n 1", file, addr);
if (!cmd_to_str(buf, file, len))
return R_FALSE;
return buf;
}
static int a2l_get_line(struct r_bininfo_t *bi, ut64 addr, char *file, int len, int *line)
{
char *p, buf[1024];
// TODO: move to r_util
snprintf(buf, 1023, "addr2line -e '%s' 0x%08llx", bi->file, addr);
memset(file,'\0', len);
if (!cmd_to_str(buf, file, len))
return R_FALSE;
p = strchr(file, ':');
if (p) {
*p='\0';
*line = atoi(p+1);
}
return R_TRUE;
}
static int a2l_open(struct r_bininfo_t *bi)
{
return R_TRUE;
}
struct r_bininfo_handle_t r_bininfo_plugin_addr2line = {
.name = "bininfo_addr2line",
.desc = "addr2line based dwarf utility",
.get_path = a2l_get_path,
.get_line = a2l_get_line,
.get_function_name = a2l_get_function_name,
.init = NULL,
.fini = NULL,
.open = &a2l_open,
.close = NULL,
.check = NULL,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BININFO,
.data = &r_bininfo_plugin_addr2line
};
#endif

View File

@ -1,6 +0,0 @@
OBJ=rabini.o
BINDEPS=r_bininfo r_util r_lib
BIN=rabini
#LIBS=../*.o ../../line/*.a ../../util/*.a
include ../../rules.mk

View File

@ -1,31 +0,0 @@
/* radare - LGPL - Copyright 2009 pancake<@nopcode.org> */
#include <r_bininfo.h>
int main(int argc, char **argv)
{
char file[1024];
int line = 0;
struct r_bininfo_t *bi;
if (argc <3) {
eprintf("Usage: rabini [file] [addr]\n");
return 1;
}
bi = r_bininfo_new();
if (!r_bininfo_open(bi, argv[1], R_FALSE, "bininfo_addr2line")) {
eprintf("Cannot open file\n");
return 1;
}
printf("List of plugins:\n");
r_bininfo_list(bi);
printf("--\n");
file[0]='\0';
r_bininfo_get_line(bi, r_num_get(NULL, argv[2]), file, 1023, &line);
printf("FILE: %s\n", file);
printf("LINE: %d\n", line);
r_bininfo_free(bi);
return 0;
}

View File

@ -58,9 +58,14 @@ typedef struct r_bin_handle_t {
struct r_bin_info_t* (*info)(RBin *bin);
RFList (*fields)(RBin *bin);
RFList (*libs)(RBin *bin);
struct r_bin_meta_t *meta;
struct list_head list;
} RBinHandle;
typedef struct r_bin_meta_t {
int (*get_line)(RBin *bin, ut64 addr, char *file, int len, int *line);
} RBinMeta;
typedef struct r_bin_entry_t {
ut64 rva;
ut64 offset;
@ -125,6 +130,8 @@ typedef struct r_bin_field_t {
} RBinField;
#ifdef R_API
/* bin.c */
R_API int r_bin_add(RBin *bin, RBinHandle *foo);
R_API void* r_bin_free(RBin *bin);
R_API int r_bin_init(RBin *bin);
@ -144,6 +151,11 @@ R_API RFList r_bin_get_strings(RBin *bin);
R_API RFList r_bin_get_symbols(RBin *bin);
R_API RBin* r_bin_new();
R_API void r_bin_set_user_ptr(RBin *bin, void *user);
/* bin_dbg.c */
R_API int r_bin_meta_get_line(RBin *bin, ut64 addr, char *file, int len, int *line);
R_API char *r_bin_meta_get_file_line(RBin *bin, const char *file, int line);
#endif
#endif

View File

@ -1,64 +0,0 @@
/* radare - LGPL - Copyright 2008-2010 nibble, pancake */
#ifndef _INCLUDE_R_BININFO_H_
#define _INCLUDE_R_BININFO_H_
#include <r_types.h>
#include <r_util.h>
#include <list.h>
#define R_BININFO_DBG_STRIPPED(x) x & 0x01
#define R_BININFO_DBG_STATIC(x) x & 0x02
#define R_BININFO_DBG_LINENUMS(x) x & 0x04
#define R_BININFO_DBG_SYMS(x) x & 0x08
#define R_BININFO_DBG_RELOCS(x) x & 0x10
#define R_BININFO_SIZEOF_NAMES 256
// XXX: rename to rBinMeta...rBinDwarf..rBinFoo ??? RBininfo can be confusing with rBinInfo
/* types */
typedef struct r_bininfo_t {
const char *file;
int fd;
int rw;
void *bin_obj;
char *path;
void *user;
struct r_bininfo_handle_t *cur;
struct list_head bins;
} RBininfo;
typedef struct r_bininfo_handle_t {
char *name;
char *desc;
int (*init)(void *user);
int (*fini)(void *user);
char *(*get_path)(struct r_bininfo_t *user);
int (*get_line)(struct r_bininfo_t *user, ut64 addr, char *file, int len, int *line);
char *(*get_function_name)(struct r_bininfo_t *bi, ut64 addr, char *file, int len);
int (*open)(struct r_bininfo_t *bin);
int (*close)(struct r_bininfo_t *bin);
int (*check)(struct r_bininfo_t *bin);
struct list_head list;
} RBininfoHandle;
#ifdef R_API
/* bininfo.c */
R_API struct r_bininfo_t *r_bininfo_new();
R_API struct r_bininfo_t *r_bininfo_free(struct r_bininfo_t *bin);
R_API struct r_bininfo_t *r_bininfo_init(struct r_bininfo_t *bin);
R_API void r_bininfo_set_user_ptr(struct r_bininfo_t *bin, void *user);
R_API int r_bininfo_add(struct r_bininfo_t *bin, struct r_bininfo_handle_t *foo);
R_API int r_bininfo_list(struct r_bininfo_t *bin);
R_API int r_bininfo_open(struct r_bininfo_t *bin, const char *file, int rw, char *plugin_name);
R_API int r_bininfo_close(struct r_bininfo_t *bin);
R_API int r_bininfo_get_line(struct r_bininfo_t *bin, ut64 addr, char *file, int len, int *line);
R_API char *r_bininfo_get_source_path(struct r_bininfo_t *bin);
R_API int r_bininfo_set_source_path(struct r_bininfo_t *bi, char *path);
#endif
/* TODO : move this to r_util!! */
char *r_bininfo_get_file_line(struct r_bininfo_t *bin, const char *file, int line);
#endif

View File

@ -19,7 +19,6 @@
#include "r_flags.h"
#include "r_config.h"
#include "r_bin.h"
#include "r_bininfo.h"
#define R_CORE_BLOCKSIZE 64
#define R_CORE_BLOCKSIZE_MAX 0x40000 /* 4 MB */
@ -58,7 +57,6 @@ typedef struct r_core_t {
struct r_parse_t parser;
struct r_print_t print;
struct r_bin_t bin;
struct r_bininfo_t bininfo;
struct r_meta_t meta;
struct r_lang_t lang;
struct r_debug_t dbg;

View File

@ -1,14 +0,0 @@
/* radare - LGPL - Copyright 2009 pancake<@nopcode.org> */
[CCode (cheader_filename="r_bininfo.h", cprefix="r_bininfo_", lower_case_cprefix="r_bininfo_")]
namespace Radare {
[Compact]
[CCode (cname="struct r_bininfo_t", free_function="r_bininfo_free", cprefix="r_bininfo_")]
public class RBininfo {
public RBininfo ();
// XXX bad signature?
public int get_line (uint64 addr, out string file, int len, int *line);
public bool set_source_path (string path);
public string get_source_path ();
}
}