bin/bin: rebase paddr with loadaddr

In this way, paddr will always be the physical address of something in
the file, even if the binary is in the middle of another file.
This commit is contained in:
Riccardo Schirone 2015-08-21 01:44:44 +02:00
parent 81a8b2a3d5
commit cce105056b
2 changed files with 43 additions and 29 deletions

View File

@ -15,6 +15,13 @@ R_LIB_VERSION(r_bin);
#define DB a->sdb;
#define RBINLISTFREE(x) if(x){r_list_free(x);x=NULL;}
#define REBASE_PADDR(o, l, type_t) do { \
RListIter *_it; \
type_t *_el; \
r_list_foreach ((l), _it, _el) { \
_el->paddr += (o)->loadaddr; \
} \
} while (0)
#define ARCHS_KEY "archs"
@ -417,35 +424,54 @@ static int r_bin_object_set_items(RBinFile *binfile, RBinObject *o) {
}
binfile->o = o;
if (cp->baddr) o->baddr = cp->baddr (binfile);
o->loadaddr = o->baddr;
if (cp->boffset) o->boffset = cp->boffset (binfile);
// XXX: no way to get info from xtr pluginz?
// Note, object size can not be set from here due to potential inconsistencies
if (cp->size)
o->size = cp->size (binfile);
if (cp->binsym)
for (i=0; i<R_BIN_SYM_LAST; i++)
if (cp->binsym) {
for (i = 0; i < R_BIN_SYM_LAST; i++) {
o->binsym[i] = cp->binsym (binfile, i);
if (cp->entries) o->entries = cp->entries (binfile);
if (cp->fields) o->fields = cp->fields (binfile);
if (o->binsym[i]) {
o->binsym[i]->paddr += o->loadaddr;
}
}
}
if (cp->entries) {
o->entries = cp->entries (binfile);
REBASE_PADDR (o, o->entries, RBinAddr);
}
if (cp->fields) {
o->fields = cp->fields (binfile);
REBASE_PADDR (o, o->fields, RBinField);
}
if (cp->imports) {
o->imports = cp->imports (binfile);
}
if (cp->symbols) {
o->symbols = cp->symbols (binfile);
REBASE_PADDR (o, o->symbols, RBinSymbol);
if (bin->filter)
r_bin_filter_symbols (o->symbols);
}
o->info = cp->info? cp->info (binfile): NULL;
if (cp->libs) o->libs = cp->libs (binfile);
if (cp->relocs) o->relocs = cp->relocs (binfile);
if (cp->relocs) {
o->relocs = cp->relocs (binfile);
REBASE_PADDR (o, o->relocs, RBinReloc);
}
if (cp->sections) {
o->sections = cp->sections (binfile);
REBASE_PADDR (o, o->sections, RBinSection);
if (bin->filter)
r_bin_filter_sections (o->sections);
}
if (cp->strings) o->strings = cp->strings (binfile);
else o->strings = get_strings (binfile, minlen, 0);
if (cp->strings) {
o->strings = cp->strings (binfile);
} else {
o->strings = get_strings (binfile, minlen, 0);
}
REBASE_PADDR (o, o->strings, RBinString);
if (cp->classes) {
o->classes = cp->classes (binfile);
if (bin->filter)
@ -628,7 +654,8 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
}
sz = R_MIN (file_sz, sz);
if (!buf_bytes) {
iob->desc_seek (io, desc, loadaddr);
ut64 seekaddr = is_debugger ? baseaddr : loadaddr;
iob->desc_seek (io, desc, seekaddr);
buf_bytes = iob->desc_read (io, desc, &sz);
}

View File

@ -281,13 +281,11 @@ R_API int r_core_bin_reload(RCore *r, const char *file, ut64 baseaddr) {
}
// XXX - need to handle index selection during debugging
static int r_core_file_do_load_for_debug (RCore *r, ut64 loadaddr, const char *filenameuri) {
static int r_core_file_do_load_for_debug (RCore *r, ut64 baseaddr, const char *filenameuri) {
RCoreFile *cf = r_core_file_cur (r);
RIODesc *desc = cf ? cf->desc : NULL;
RBinFile *binfile = NULL;
RBinPlugin *plugin;
ut64 baseaddr = 0;
//int va = r->io->va || r->io->debug;
int xtr_idx = 0; // if 0, load all if xtr is used
int treat_as_rawstr = R_FALSE;
@ -296,13 +294,10 @@ static int r_core_file_do_load_for_debug (RCore *r, ut64 loadaddr, const char *f
int newpid = desc->fd;
r_debug_select (r->dbg, newpid, newpid);
}
#if __linux__
baseaddr = loadaddr;
#else
#if !__linux__
baseaddr = get_base_from_maps (r, filenameuri);
if (baseaddr != UT64_MAX) {
// eprintf ("LOADING AT 0x%08llx\n", baseaddr);
r_config_set_i (r->config, "bin.laddr", baseaddr);
r_config_set_i (r->config, "bin.baddr", baseaddr);
}
#endif
// HACK if its a relative path, load from disk instead of memory
@ -311,11 +306,11 @@ static int r_core_file_do_load_for_debug (RCore *r, ut64 loadaddr, const char *f
#else
int fd = desc->fd;
#endif
if (!r_bin_load (r->bin, filenameuri, baseaddr, loadaddr, xtr_idx, fd, treat_as_rawstr)) {
if (!r_bin_load (r->bin, filenameuri, baseaddr, UT64_MAX, xtr_idx, fd, treat_as_rawstr)) {
eprintf ("Cannot open %s\n", filenameuri);
if (r_config_get_i (r->config, "bin.rawstr")) {
treat_as_rawstr = R_TRUE;
if (!r_bin_load (r->bin, filenameuri, baseaddr, loadaddr, xtr_idx, desc->fd, treat_as_rawstr)) {
if (!r_bin_load (r->bin, filenameuri, baseaddr, UT64_MAX, xtr_idx, desc->fd, treat_as_rawstr)) {
return R_FALSE;
}
}
@ -390,7 +385,6 @@ static int r_core_file_do_load_for_io_plugin (RCore *r, ut64 baseaddr, ut64 load
R_API int r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
ut64 loadaddr = 0;
RCoreFile *cf = r_core_file_cur (r);
RBinFile *binfile = NULL;
RIODesc *desc = cf ? cf->desc : NULL;
@ -410,10 +404,6 @@ R_API int r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
filenameuri, cf->desc->name);
}
}
if (cf->map) {
//XXX: a file can have more then 1 map
loadaddr = cf->map->from;
}
}
if (!filenameuri) {
@ -428,12 +418,9 @@ R_API int r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
// Fix to select pid before trying to load the binary
if ( (desc->plugin && desc->plugin->isdbg) \
|| r_config_get_i (r->config, "cfg.debug")) {
if (!loadaddr) {
loadaddr = baddr;
}
r_core_file_do_load_for_debug (r, loadaddr, filenameuri);
r_core_file_do_load_for_debug (r, baddr, filenameuri);
} else {
r_core_file_do_load_for_io_plugin (r, baddr, loadaddr);
r_core_file_do_load_for_io_plugin (r, baddr, 0);
}
// Restore original desc
r_io_use_desc (r->io, desc);