* Some work for r_bininfo library

- Extend API to get file and line numbers from a virtual address
  - Added addr2line-like test program 'rabini'
  - Added 'addr2line' plugin
* Add r_file_slurp_line helper in r_util
* Added initial work to support multiple compilers (gcc only atm)
  - tcc support under development
  - Make HAVE_REGEXP be optional
This commit is contained in:
pancake 2009-03-22 04:37:46 +00:00
parent a14d5f1656
commit 99f284f358
18 changed files with 220 additions and 7 deletions

1
TODO
View File

@ -1,3 +1,4 @@
* Import the spp's getopt owns implementation in r_util
* Add maxrows option for r_print (fix visual problem)
* Drop #if conditionals to use #ifdef ones
- fits better with plan9 compiler

View File

@ -3,6 +3,9 @@ RELEASE=0
DESTDIR=
OSTYPE=gnulinux
#COMPILER=gcc
COMPILER=tcc
ifeq (${RELEASE},1)
PREFIX=/usr/local
else

View File

@ -1,3 +1,5 @@
include ../../../config.mk
OBJ_ARM=asm_arm.o
OBJ_ARM+=../arch/arm/gnu/arm-dis.o

2
libr/bininfo/README Normal file
View File

@ -0,0 +1,2 @@
LIBDWARF:
http://reality.sgiweb.org/davea/dwarf.html

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com>, pancake<@nopcode.org> */
#include <stdio.h>
#include <string.h>
@ -28,6 +28,7 @@ int r_bininfo_init(struct r_bininfo_t *bin)
int i;
bin->cur = NULL;
bin->user = NULL;
bin->path = NULL;
INIT_LIST_HEAD(&bin->bins);
for(i=0;bininfo_static_plugins[i];i++)
r_bininfo_add(bin, bininfo_static_plugins[i]);
@ -77,6 +78,39 @@ int r_bininfo_set(struct r_bininfo_t *bin, const char *name)
return R_FALSE;
}
int r_bininfo_get_line(struct r_bininfo_t *bin, u64 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;
}
char *r_bininfo_get_file_line(struct r_bininfo_t *bin, const char *file, int line)
{
char *linestr;
char path[1024];
sprintf(path, "%s/%s", bin->path, file);
linestr = r_file_slurp_line(path, line, 1);
return linestr;
}
char *r_bininfo_get_source_path(struct r_bininfo_t *bin)
{
if (bin->path == NULL) {
if (bin&&bin->cur&&bin->cur->get_path) {
bin->path = bin->cur->get_path(bin);
}
}
return bin->path;
}
int r_bininfo_set_source_path(struct r_bininfo_t *bi, char *path)
{
free(bi->path);
bi->path = strdup(path);
return R_TRUE;
}
/*XXX*/
int r_bininfo_autoset(struct r_bininfo_t *bin)
{

11
libr/bininfo/p/Makefile Normal file
View File

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

View File

@ -0,0 +1,9 @@
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

@ -0,0 +1,45 @@
/* radare - LGPL - Copyright 2009 pancake<@nopcode.org> */
#include <r_bininfo.h>
#include <r_lib.h>
static char *get_path(struct r_bininfo_t *bi)
{
return strdup("");
}
static char *get_function_name(struct r_bininfo_t *bi, u64 addr, char *file, int len)
{
char buf[1024];
sprintf(buf, "addr2line -f -e %s 0x%08llx | head -n 1", file, addr);
printf("==>%s\n", buf);
system(buf);
}
static char *get_line(struct r_bininfo_t *bi, u64 addr, char *file, int line)
{
char buf[1024];
sprintf(buf, "addr2line -e %s 0x%08llx", addr);
printf("==>%s\n", buf);
system(buf);
// TODO: get output and dump it back to file buffer
}
struct r_bininfo_handle_t r_bininfo_plugin_addr2line = {
.name = "addr2line",
.desc = "addr2line based dwarf utility",
.get_path = get_path,
.get_line = get_line,
.get_function_name = get_function_name,
.init = NULL,
.fini = NULL,
.open = NULL,
.close = NULL,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bininfo_plugin_addr2line
};
#endif

6
libr/bininfo/t/Makefile Normal file
View File

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

30
libr/bininfo/t/rabini.c Normal file
View File

@ -0,0 +1,30 @@
/* 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;
}
file[0]='\0';
bi = r_bininfo_new(argv[1], R_FALSE);
if (bi == NULL) {
eprintf("Cannot open file\n");
return 1;
}
r_bininfo_list(bi);
r_bininfo_set(bi, "bininfo_addr2line");
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

@ -9,10 +9,12 @@ USE_RIO=1
# static plugins
STATIC_ASM_PLUGINS=p/x86olly.mk p/mips.mk p/java.mk
STATIC_BIN_PLUGINS=
STATIC_BININFO_PLUGINS=
STATIC_BININFO_PLUGINS=p/addr2line.mk
ifneq (${BINDEPS},)
include ../../../config.mk
include ../../../mk/${COMPILER}.mk
else
include ../../config.mk
include ../../mk/${COMPILER}.mk
endif

View File

@ -4,6 +4,7 @@
#define _INCLUDE_R_BININFO_H_
#include <r_types.h>
#include <r_util.h>
#include <list.h>
#define R_BININFO_DBG_STRIPPED(x) x & 0x01
@ -20,6 +21,7 @@ struct r_bininfo_t {
int fd;
int rw;
void *bin_obj;
char *path;
void *user;
struct r_bininfo_handle_t *cur;
struct list_head bins;
@ -30,6 +32,9 @@ struct r_bininfo_handle_t {
char *desc;
int (*init)(void *user);
int (*fini)(void *user);
char *(*get_path)(void *user);
int (*get_line)(void *user, u64 addr, char *file, int len, int *line);
char (*get_function_name)(struct r_bininfo_t *bi, u64 addr, char *file, int len);
int (*open)(struct r_bininfo_t *bin);
int (*close)(struct r_bininfo_t *bin);
struct list_head list;
@ -48,6 +53,12 @@ int r_bininfo_autoset(struct r_bininfo_t *bin);
int r_bininfo_set_file(struct r_bininfo_t *bin, const char *file, int rw);
int r_bininfo_open(struct r_bininfo_t *bin);
int r_bininfo_close(struct r_bininfo_t *bin);
int r_bininfo_get_line(struct r_bininfo_t *bin, u64 addr, char *file, int len, int *line);
char *r_bininfo_get_source_path(struct r_bininfo_t *bin);
int r_bininfo_set_source_path(struct r_bininfo_t *bi, char *path);
/* TODO : move this to r_util!! */
char *r_bininfo_get_file_line(struct r_bininfo_t *bin, const char *file, int line);
/* plugin pointers */
extern struct r_bininfo_handle_t r_bininfo_plugin_elf;

View File

@ -83,5 +83,6 @@ char *r_file_slurp_random_line(const char *file);
int r_file_dump(const char *file, const u8 *buf, int len);
int r_file_rm(const char *file);
int r_file_exist(const char *str);
char *r_file_slurp_line(const char *file, int line, int context);
#endif

View File

@ -9,11 +9,11 @@ BOO=-Wl,-R../../
LDFLAGS+=$(subst r_,${BOO},$(BINDEPS))
# Compiler
CC?=gcc
CFLAGS+=-fPIC
CC_LIB=${CC} -shared -o ${LIBSO}
CC_AR=ar -r ${LIBAR}
LINK?=
#CC?=gcc
#CFLAGS+=-fPIC
#CC_LIB=${CC} -shared -o ${LIBSO}
#CC_AR=ar -r ${LIBAR}
#LINK?=
# Debug
CFLAGS+=-g -Wall
@ -43,6 +43,7 @@ LIBSO=${LIB}.${EXT_SO}
ifeq (${BINDEPS},)
ifneq ($(NAME),)
include ../../config.mk
include ../../mk/${COMPILER}.mk
CFLAGS+=-I../include
all: ${LIBSO}
@ -70,6 +71,7 @@ endif
else
include ../../config.mk
include ../../../mk/${COMPILER}.mk
CFLAGS+=-I../../include
all: ${BIN}

View File

@ -110,6 +110,28 @@ char *r_file_slurp_random_line(const char *file)
return ptr;
}
char *r_file_slurp_line(const char *file, int line, int context)
{
int i, lines = 0;
int sz;
char *ptr, *str = r_file_slurp(file, &sz);
// TODO: Implement context
if (str) {
for(i=0;str[i];i++)
if (str[i]=='\n')
lines++;
lines = line;
for(i=0;str[i]&&lines;i++)
if (str[i]=='\n')
lines--;
ptr = str+i;
for(i=0;ptr[i];i++) if (ptr[i]=='\n') { ptr[i]='\0'; break; }
ptr = strdup(ptr);
free(str);
}
return ptr;
}
int r_file_dump(const char *file, const u8 *buf, int len)
{
FILE *fd = fopen(file, "wb");

View File

@ -1,20 +1,26 @@
/* radare - LGPL - Copyright 2007-2009 pancake<nopcode.org> */
#define HAVE_REGEXP 1
#include <r_util.h>
#include <sys/types.h>
#if HAVE_REGEXP
#include <regex.h>
/* XXX: This code uses POSIX 2001 . can be nonportable */
#define NUM_MATCHES 16
#endif
/* returns 1 if 'str' matches 'reg' regexp */
int r_str_re_match(const char *str, const char *reg)
{
#if HAVE_REGEXP
regex_t preg;
regmatch_t pmatch[NUM_MATCHES];
if (regcomp(&preg, reg, REG_EXTENDED))
return -1;
return (regexec (&preg, str, NUM_MATCHES, pmatch, 0))?1:0;
#endif
}
int r_str_re_replace(const char *str, const char *reg, const char *sub)

13
mk/gcc.mk Normal file
View File

@ -0,0 +1,13 @@
CC?=gcc
LINK=
CC_AR=ar -r ${LIBAR}
CFLAGS+=-fPIC
CC_LIB=${CC} -shared -o ${LIBSO}
CFLAGS_INCLUDE=-I
LDFLAGS_LINK=-l
LDFLAGS_LINKPATH=-Wl,-R
CFLAGS_OPT0=-O0
CFLAGS_OPT1=-O1
CFLAGS_OPT2=-O2
CFLAGS_OPT3=-O3
CFLAGS_DEBUG=-g

13
mk/tcc.mk Normal file
View File

@ -0,0 +1,13 @@
CC=tcc
LINK=
CC_AR=ar -r ${LIBAR}
CFLAGS+=-fPIC
CC_LIB=${CC} -shared -o ${LIBSO}
CFLAGS_INCLUDE=-I
LDFLAGS_LINK=-l
LDFLAGS_LINKPATH=-Wl,-R
CFLAGS_OPT0=-O0
CFLAGS_OPT1=-O1
CFLAGS_OPT2=-O2
CFLAGS_OPT3=-O3
CFLAGS_DEBUG=-g