Skip to content

Commit

Permalink
Split out print_relocs_for_object()
Browse files Browse the repository at this point in the history
  • Loading branch information
thestr4ng3r committed Apr 2, 2021
1 parent 275fe69 commit 68f5ed0
Showing 1 changed file with 124 additions and 111 deletions.
235 changes: 124 additions & 111 deletions librz/core/cbin.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,15 +1705,129 @@ static const char *bin_reloc_type_name(RzBinReloc *reloc) {
#undef CASE
}

static int bin_relocs(RzCore *r, PJ *pj, int mode, int va) {
/**
* \brief fetche relocs for the object and print them
* \return the number of relocs or -1 on failure
*/
static int print_relocs_for_object(RzCore *r, RzBinFile *bf, RzBinObject *o, int va, int mode, PJ *pj, RzTable *table) {
bool bin_demangle = rz_config_get_i(r->config, "bin.demangle");
bool keep_lib = rz_config_get_i(r->config, "bin.demangle.libs");
const char *lang = rz_config_get(r->config, "bin.lang");

RBNode *relocs = rz_bin_object_patch_relocs(bf, o);
if (!relocs) {
relocs = rz_bin_get_relocs(r->bin);
}
if (!relocs) {
return -1;
}
int count = 0;
RBIter iter;
RzBinReloc *reloc;
rz_rbtree_foreach (relocs, iter, reloc, RzBinReloc, vrb) {
ut64 addr = rva(r->bin, reloc->paddr, reloc->vaddr, va);
if (IS_MODE_SIMPLE(mode)) {
rz_cons_printf("0x%08" PFMT64x " %s\n", addr, reloc->import ? reloc->import->name : "");
} else if (IS_MODE_RZCMD(mode)) {
char *name = reloc->import
? strdup(reloc->import->name)
: (reloc->symbol ? strdup(reloc->symbol->name) : NULL);
if (name && bin_demangle) {
char *mn = rz_bin_demangle(r->bin->cur, NULL, name, addr, keep_lib);
if (mn) {
free(name);
name = mn;
}
}
if (name) {
int reloc_size = 4;
char *n = __filterQuotedShell(name);
rz_cons_printf("\"f %s%s%s %d 0x%08" PFMT64x "\"\n",
r->bin->prefix ? r->bin->prefix : "reloc.",
r->bin->prefix ? "." : "", n, reloc_size, addr);
ut64 meta_sz;
if (meta_for_reloc(r, o, reloc, addr, &meta_sz)) {
rz_cons_printf("Cd %" PFMT64u " @ 0x%08" PFMT64x "\n", meta_sz, addr);
}
free(n);
free(name);
}
} else if (IS_MODE_JSON(mode)) {
pj_o(pj);
char *mn = NULL;
char *relname = NULL;

// take care with very long symbol names! do not use sdb_fmt or similar
if (reloc->import) {
mn = rz_bin_demangle(r->bin->cur, lang, reloc->import->name, addr, keep_lib);
relname = strdup(reloc->import->name);
} else if (reloc->symbol) {
mn = rz_bin_demangle(r->bin->cur, lang, reloc->symbol->name, addr, keep_lib);
relname = strdup(reloc->symbol->name);
}

// check if name is available
if (relname && *relname) {
pj_ks(pj, "name", relname);
}
pj_ks(pj, "demname", mn ? mn : "");
pj_ks(pj, "type", bin_reloc_type_name(reloc));
pj_kn(pj, "vaddr", reloc->vaddr);
pj_kn(pj, "paddr", reloc->paddr);
if (reloc->symbol) {
pj_kn(pj, "sym_va", reloc->symbol->vaddr);
}
pj_kb(pj, "is_ifunc", reloc->is_ifunc);
// end reloc item
pj_end(pj);

free(mn);
if (relname) {
free(relname);
}
} else if (IS_MODE_NORMAL(mode)) {
char *name = reloc->import
? strdup(reloc->import->name)
: reloc->symbol
? strdup(reloc->symbol->name)
: NULL;
if (bin_demangle) {
char *mn = rz_bin_demangle(r->bin->cur, NULL, name, addr, keep_lib);
if (mn && *mn) {
free(name);
name = mn;
}
}
char *reloc_name = construct_reloc_name(reloc, name);
RzStrBuf *buf = rz_strbuf_new(reloc_name ? reloc_name : "");
free(reloc_name);
RZ_FREE(name);
if (reloc->addend) {
if ((reloc->import || reloc->symbol) && !rz_strbuf_is_empty(buf) && reloc->addend > 0) {
rz_strbuf_append(buf, " +");
}
if (reloc->addend < 0) {
rz_strbuf_appendf(buf, " - 0x%08" PFMT64x, -reloc->addend);
} else {
rz_strbuf_appendf(buf, " 0x%08" PFMT64x, reloc->addend);
}
}
if (reloc->is_ifunc) {
rz_strbuf_append(buf, " (ifunc)");
}
char *res = rz_strbuf_drain(buf);
rz_table_add_rowf(table, "XXss", addr, reloc->paddr,
bin_reloc_type_name(reloc), res);
free(res);
}
count++;
}
return count;
}

static int bin_relocs(RzCore *r, PJ *pj, int mode, int va) {
RzTable *table = rz_core_table(r);
rz_return_val_if_fail(table, false);
RBIter iter;
RzBinReloc *reloc = NULL;
int i = 0;

RZ_TIME_PROFILE_BEGIN;

Expand All @@ -1728,112 +1842,11 @@ static int bin_relocs(RzCore *r, PJ *pj, int mode, int va) {
pj_a(pj);
}

RBNode *relocs = NULL;
int relocs_count = -1;
if (r->bin->cur && r->bin->cur->o) {
RzBinFile *bf = r->bin->cur;
RzBinObject *o = bf->o;
relocs = rz_bin_object_patch_relocs(bf, o);
if (!relocs) {
relocs = rz_bin_get_relocs(r->bin);
}
rz_rbtree_foreach (relocs, iter, reloc, RzBinReloc, vrb) {
ut64 addr = rva(r->bin, reloc->paddr, reloc->vaddr, va);
if (IS_MODE_SIMPLE(mode)) {
rz_cons_printf("0x%08" PFMT64x " %s\n", addr, reloc->import ? reloc->import->name : "");
} else if (IS_MODE_RZCMD(mode)) {
char *name = reloc->import
? strdup(reloc->import->name)
: (reloc->symbol ? strdup(reloc->symbol->name) : NULL);
if (name && bin_demangle) {
char *mn = rz_bin_demangle(r->bin->cur, NULL, name, addr, keep_lib);
if (mn) {
free(name);
name = mn;
}
}
if (name) {
int reloc_size = 4;
char *n = __filterQuotedShell(name);
rz_cons_printf("\"f %s%s%s %d 0x%08" PFMT64x "\"\n",
r->bin->prefix ? r->bin->prefix : "reloc.",
r->bin->prefix ? "." : "", n, reloc_size, addr);
ut64 meta_sz;
if (meta_for_reloc(r, o, reloc, addr, &meta_sz)) {
rz_cons_printf("Cd %" PFMT64u " @ 0x%08" PFMT64x "\n", meta_sz, addr);
}
free(n);
free(name);
}
} else if (IS_MODE_JSON(mode)) {
pj_o(pj);
char *mn = NULL;
char *relname = NULL;

// take care with very long symbol names! do not use sdb_fmt or similar
if (reloc->import) {
mn = rz_bin_demangle(r->bin->cur, lang, reloc->import->name, addr, keep_lib);
relname = strdup(reloc->import->name);
} else if (reloc->symbol) {
mn = rz_bin_demangle(r->bin->cur, lang, reloc->symbol->name, addr, keep_lib);
relname = strdup(reloc->symbol->name);
}

// check if name is available
if (relname && *relname) {
pj_ks(pj, "name", relname);
}
pj_ks(pj, "demname", mn ? mn : "");
pj_ks(pj, "type", bin_reloc_type_name(reloc));
pj_kn(pj, "vaddr", reloc->vaddr);
pj_kn(pj, "paddr", reloc->paddr);
if (reloc->symbol) {
pj_kn(pj, "sym_va", reloc->symbol->vaddr);
}
pj_kb(pj, "is_ifunc", reloc->is_ifunc);
// end reloc item
pj_end(pj);

free(mn);
if (relname) {
free(relname);
}
} else if (IS_MODE_NORMAL(mode)) {
char *name = reloc->import
? strdup(reloc->import->name)
: reloc->symbol
? strdup(reloc->symbol->name)
: NULL;
if (bin_demangle) {
char *mn = rz_bin_demangle(r->bin->cur, NULL, name, addr, keep_lib);
if (mn && *mn) {
free(name);
name = mn;
}
}
char *reloc_name = construct_reloc_name(reloc, name);
RzStrBuf *buf = rz_strbuf_new(reloc_name ? reloc_name : "");
free(reloc_name);
RZ_FREE(name);
if (reloc->addend) {
if ((reloc->import || reloc->symbol) && !rz_strbuf_is_empty(buf) && reloc->addend > 0) {
rz_strbuf_append(buf, " +");
}
if (reloc->addend < 0) {
rz_strbuf_appendf(buf, " - 0x%08" PFMT64x, -reloc->addend);
} else {
rz_strbuf_appendf(buf, " 0x%08" PFMT64x, reloc->addend);
}
}
if (reloc->is_ifunc) {
rz_strbuf_append(buf, " (ifunc)");
}
char *res = rz_strbuf_drain(buf);
rz_table_add_rowf(table, "XXss", addr, reloc->paddr,
bin_reloc_type_name(reloc), res);
free(res);
}
i++;
}
relocs_count = print_relocs_for_object(r, bf, o, va, mode, pj, table);
}

if (IS_MODE_JSON(mode)) {
Expand All @@ -1846,16 +1859,16 @@ static int bin_relocs(RzCore *r, PJ *pj, int mode, int va) {
char *s = rz_table_tostring(table);
rz_cons_printf("\n%s\n", s);
free(s);
rz_cons_printf("\n%i relocations\n", i);
rz_cons_printf("\n%i relocations\n", relocs_count >= 0 ? relocs_count : 0);
}

rz_table_free(table);

RZ_TIME_PROFILE_END;
if (IS_MODE_JSON(mode) && relocs == NULL) {
return true;
if (IS_MODE_JSON(mode)) {
return true; // ignore relocs_count here
}
return relocs != NULL;
return relocs_count >= 0;
}

#define MYDB 1
Expand Down

0 comments on commit 68f5ed0

Please sign in to comment.