mirror of
https://github.com/radareorg/radare2
synced 2026-08-22 20:23:32 -04:00
Sideload macho dsym matching arch slice and uuid ##bin
Some checks failed
build / freebsd (push) Failing after 3s
CI / mipsbe (push) Failing after 2s
CI / linux-acr-gperf (push) Has been cancelled
Code scanning - action / CodeQL-Build (push) Has been cancelled
tcc / ubuntu-tcc-test (push) Has been cancelled
build / tarball (push) Has been cancelled
build / linux-deps (push) Has been cancelled
build / linux-wasi (push) Has been cancelled
build / filc (push) Has been cancelled
build / linux-static (push) Has been cancelled
build / linux-acr-rpm-64 (push) Has been cancelled
build / linux-acr-deb (push) Has been cancelled
build / macos-acr (push) Has been cancelled
build / android-meson (x86_64) (push) Has been cancelled
build / ios (cydia32) (push) Has been cancelled
build / ios (true, cydia) (push) Has been cancelled
build / android-acr (16, arm) (push) Has been cancelled
build / android-acr (aarch64) (push) Has been cancelled
build / android-sdk (push) Has been cancelled
build / w32-meson (push) Has been cancelled
build / w64-static (push) Has been cancelled
build / w64-meson (push) Has been cancelled
build / msys2-w64-meson (push) Has been cancelled
build / msys2-w64-arm-meson (push) Has been cancelled
build / w64-arm-meson (push) Has been cancelled
build / macos-xcframework (push) Has been cancelled
CI / linux-acr-oldlibsbug (push) Has been cancelled
CI / linux-nocs (push) Has been cancelled
CI / linux-sys-capstone-resymlink (push) Has been cancelled
CI / linux-test (push) Has been cancelled
CI / linux-static-meson (push) Has been cancelled
CI / macos-test (push) Has been cancelled
CI / linux-rpath (push) Has been cancelled
CI / macos-rpath (push) Has been cancelled
CI / linux-meson-spaces (push) Has been cancelled
CI / linux-tinyasan-fuzz (push) Has been cancelled
CI / linux-asan-fuzz (push) Has been cancelled
CI / w64-make (push) Has been cancelled
CI / w32-mingw (push) Has been cancelled
CI / w64-mingw (push) Has been cancelled
tcc / ubuntu-tcc-nodbg (push) Has been cancelled
tcc / r2pm-tcc (push) Has been cancelled
tcc / ubuntu-tcc-syslibs (push) Has been cancelled
tcc / ubuntu-tcc-leaks (push) Has been cancelled
build / linux-wasi-api (push) Has been cancelled
build / linux-wasi-browser (push) Has been cancelled
build / check_abi_compatibility (push) Has been cancelled
build / check_release (push) Has been cancelled
build / release (push) Has been cancelled
Some checks failed
build / freebsd (push) Failing after 3s
CI / mipsbe (push) Failing after 2s
CI / linux-acr-gperf (push) Has been cancelled
Code scanning - action / CodeQL-Build (push) Has been cancelled
tcc / ubuntu-tcc-test (push) Has been cancelled
build / tarball (push) Has been cancelled
build / linux-deps (push) Has been cancelled
build / linux-wasi (push) Has been cancelled
build / filc (push) Has been cancelled
build / linux-static (push) Has been cancelled
build / linux-acr-rpm-64 (push) Has been cancelled
build / linux-acr-deb (push) Has been cancelled
build / macos-acr (push) Has been cancelled
build / android-meson (x86_64) (push) Has been cancelled
build / ios (cydia32) (push) Has been cancelled
build / ios (true, cydia) (push) Has been cancelled
build / android-acr (16, arm) (push) Has been cancelled
build / android-acr (aarch64) (push) Has been cancelled
build / android-sdk (push) Has been cancelled
build / w32-meson (push) Has been cancelled
build / w64-static (push) Has been cancelled
build / w64-meson (push) Has been cancelled
build / msys2-w64-meson (push) Has been cancelled
build / msys2-w64-arm-meson (push) Has been cancelled
build / w64-arm-meson (push) Has been cancelled
build / macos-xcframework (push) Has been cancelled
CI / linux-acr-oldlibsbug (push) Has been cancelled
CI / linux-nocs (push) Has been cancelled
CI / linux-sys-capstone-resymlink (push) Has been cancelled
CI / linux-test (push) Has been cancelled
CI / linux-static-meson (push) Has been cancelled
CI / macos-test (push) Has been cancelled
CI / linux-rpath (push) Has been cancelled
CI / macos-rpath (push) Has been cancelled
CI / linux-meson-spaces (push) Has been cancelled
CI / linux-tinyasan-fuzz (push) Has been cancelled
CI / linux-asan-fuzz (push) Has been cancelled
CI / w64-make (push) Has been cancelled
CI / w32-mingw (push) Has been cancelled
CI / w64-mingw (push) Has been cancelled
tcc / ubuntu-tcc-nodbg (push) Has been cancelled
tcc / r2pm-tcc (push) Has been cancelled
tcc / ubuntu-tcc-syslibs (push) Has been cancelled
tcc / ubuntu-tcc-leaks (push) Has been cancelled
build / linux-wasi-api (push) Has been cancelled
build / linux-wasi-browser (push) Has been cancelled
build / check_abi_compatibility (push) Has been cancelled
build / check_release (push) Has been cancelled
build / release (push) Has been cancelled
This commit is contained in:
parent
b4e48fb498
commit
b281ec86b4
1 changed files with 166 additions and 20 deletions
|
|
@ -757,6 +757,168 @@ static bool mustreopen(RCore *core, RIODesc *desc, const char *fn) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static char *mach0_dsym_path(const char *binary_path) {
|
||||
R_RETURN_VAL_IF_FAIL (binary_path, NULL);
|
||||
const char *basename = r_file_basename (binary_path);
|
||||
return r_str_newf ("%s.dSYM/Contents/Resources/DWARF/%s", binary_path, basename);
|
||||
}
|
||||
|
||||
static const char *mach0_uuid(RBinFile *bf) {
|
||||
RBinPlugin *plugin = r_bin_file_cur_plugin (bf);
|
||||
if (!plugin || !plugin->meta.name) {
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp (plugin->meta.name, "mach0") && strcmp (plugin->meta.name, "mach064")) {
|
||||
return NULL;
|
||||
}
|
||||
const char *uuid = bf->sdb_info? sdb_const_get (bf->sdb_info, "uuid.0", 0): NULL;
|
||||
return uuid && strlen (uuid) == 32? uuid: NULL;
|
||||
}
|
||||
|
||||
static bool mach0_identity_matches(RBinFile *main_bf, RBinFile *dsym_bf) {
|
||||
RBinPlugin *main_plugin = r_bin_file_cur_plugin (main_bf);
|
||||
RBinPlugin *dsym_plugin = r_bin_file_cur_plugin (dsym_bf);
|
||||
if (!main_plugin || !dsym_plugin || !main_plugin->meta.name || !dsym_plugin->meta.name) {
|
||||
return false;
|
||||
}
|
||||
if (strcmp (main_plugin->meta.name, dsym_plugin->meta.name)) {
|
||||
return false;
|
||||
}
|
||||
RBinInfo *main_info = main_bf->bo? main_bf->bo->info: NULL;
|
||||
RBinInfo *dsym_info = dsym_bf->bo? dsym_bf->bo->info: NULL;
|
||||
if (!main_info || !dsym_info || R_STR_ISEMPTY (main_info->arch) || R_STR_ISEMPTY (dsym_info->arch) ||
|
||||
main_info->bits < 1 || main_info->bits != dsym_info->bits || strcmp (main_info->arch, dsym_info->arch)) {
|
||||
return false;
|
||||
}
|
||||
if (R_STR_ISEMPTY (main_info->machine) || R_STR_ISEMPTY (dsym_info->machine) ||
|
||||
strcmp (main_info->machine, dsym_info->machine)) {
|
||||
return false;
|
||||
}
|
||||
const char *main_uuid = mach0_uuid (main_bf);
|
||||
const char *dsym_uuid = mach0_uuid (dsym_bf);
|
||||
return main_uuid && dsym_uuid && !strcmp (main_uuid, dsym_uuid);
|
||||
}
|
||||
|
||||
static void mach0_dsym_restore_main(RBin *bin, RBinFile *main_bf) {
|
||||
r_bin_file_set_cur_binfile (bin, main_bf);
|
||||
if (bin->sdb && main_bf->sdb) {
|
||||
sdb_ns_set (bin->sdb, "cur", main_bf->sdb);
|
||||
}
|
||||
}
|
||||
|
||||
static void mach0_dsym_delete_fd_binfiles(RBin *bin, RBinFile *main_bf, RBinFile *keep_bf, int fd) {
|
||||
RBinFile *bf;
|
||||
RListIter *iter;
|
||||
RListIter *tmp;
|
||||
r_list_foreach_safe (bin->binfiles, iter, tmp, bf) {
|
||||
if (!bf || bf == main_bf || bf == keep_bf || bf->fd != fd) {
|
||||
continue;
|
||||
}
|
||||
if (bin->sdb && bf->sdb) {
|
||||
r_strf_var (fdns, 32, "fd.%d", fd);
|
||||
sdb_ns_unset (bin->sdb, fdns, bf->sdb);
|
||||
}
|
||||
r_bin_file_delete (bin, bf->id);
|
||||
}
|
||||
mach0_dsym_restore_main (bin, main_bf);
|
||||
}
|
||||
|
||||
static void mach0_dsym_umount_fd(RCore *core, int fd) {
|
||||
RFSRoot *root;
|
||||
while ((root = r_fs_root_by_fd (core->fs, fd))) {
|
||||
char *path = strdup (root->path);
|
||||
if (!path) {
|
||||
break;
|
||||
}
|
||||
bool unmounted = r_fs_umount (core->fs, path);
|
||||
free (path);
|
||||
if (!unmounted) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static RBinFile *mach0_load_matching_slice(RBin *bin, RBinFile *main_bf, RBinFile *dsym_bf) {
|
||||
if (dsym_bf->bo) {
|
||||
return mach0_identity_matches (main_bf, dsym_bf)? dsym_bf: NULL;
|
||||
}
|
||||
if (!dsym_bf->xtr_data) {
|
||||
return NULL;
|
||||
}
|
||||
RBinXtrData *xtr_data;
|
||||
RListIter *iter;
|
||||
r_list_foreach (dsym_bf->xtr_data, iter, xtr_data) {
|
||||
if (!xtr_data || !xtr_data->buf) {
|
||||
continue;
|
||||
}
|
||||
RBinFileOptions opt;
|
||||
r_bin_file_options_init (&opt, dsym_bf->fd, xtr_data->baddr, xtr_data->laddr, bin->options.rawstr);
|
||||
opt.filename = dsym_bf->file;
|
||||
if (!r_bin_open_buf (bin, xtr_data->buf, &opt)) {
|
||||
mach0_dsym_delete_fd_binfiles (bin, main_bf, dsym_bf, dsym_bf->fd);
|
||||
continue;
|
||||
}
|
||||
RBinFile *slice_bf = r_bin_cur (bin);
|
||||
if (slice_bf && slice_bf != main_bf && slice_bf != dsym_bf && mach0_identity_matches (main_bf, slice_bf)) {
|
||||
return slice_bf;
|
||||
}
|
||||
mach0_dsym_delete_fd_binfiles (bin, main_bf, dsym_bf, dsym_bf->fd);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool load_mach0_dsym_file(RCore *core, RBinFile *main_bf, const char *dsym_path) {
|
||||
RIODesc *dsym_desc = r_io_open_nomap (core->io, dsym_path, R_PERM_R, 0644);
|
||||
if (!dsym_desc) {
|
||||
return false;
|
||||
}
|
||||
const int dsym_fd = dsym_desc->fd;
|
||||
if (!r_io_use_fd (core->io, dsym_fd)) {
|
||||
r_io_fd_close (core->io, dsym_fd);
|
||||
return false;
|
||||
}
|
||||
RBinFileOptions opt;
|
||||
r_bin_file_options_init (&opt, dsym_fd, r_bin_file_get_baddr (main_bf), 0, core->bin->options.rawstr);
|
||||
bool old_skip_symbols = core->bin->options.skip_symbols;
|
||||
core->bin->options.skip_symbols = true;
|
||||
bool opened = r_bin_open_io (core->bin, &opt);
|
||||
|
||||
RBinFile *dsym_bf = r_bin_file_find_by_fd (core->bin, dsym_fd);
|
||||
RBinFile *loaded_bf = opened && dsym_bf && dsym_bf != main_bf?
|
||||
mach0_load_matching_slice (core->bin, main_bf, dsym_bf): NULL;
|
||||
core->bin->options.skip_symbols = old_skip_symbols;
|
||||
bool merged = loaded_bf != NULL;
|
||||
if (merged) {
|
||||
(void)r_core_bin_info (core, R_CORE_BIN_ACC_ADDRLINE, NULL, R_MODE_SET, true, NULL, NULL);
|
||||
r_bin_file_merge (main_bf, loaded_bf);
|
||||
}
|
||||
mach0_dsym_delete_fd_binfiles (core->bin, main_bf, NULL, dsym_fd);
|
||||
mach0_dsym_umount_fd (core, dsym_fd);
|
||||
r_io_fd_close (core->io, dsym_fd);
|
||||
r_io_use_fd (core->io, main_bf->fd);
|
||||
return merged;
|
||||
}
|
||||
|
||||
static void load_mach0_dsym(RCore *core, RBinFile *main_bf) {
|
||||
if (!main_bf || !mach0_uuid (main_bf)) {
|
||||
return;
|
||||
}
|
||||
const char *opened_path = r_io_fd_get_name (core->io, main_bf->fd);
|
||||
if (R_STR_ISEMPTY (opened_path)) {
|
||||
return;
|
||||
}
|
||||
char *alias_dsym = mach0_dsym_path (opened_path);
|
||||
bool loaded = alias_dsym && load_mach0_dsym_file (core, main_bf, alias_dsym);
|
||||
char *canonical_path = loaded? NULL: r_file_abspath (opened_path);
|
||||
char *canonical_dsym = canonical_path? mach0_dsym_path (canonical_path): NULL;
|
||||
if (!loaded && canonical_dsym && (!alias_dsym || strcmp (canonical_dsym, alias_dsym))) {
|
||||
load_mach0_dsym_file (core, main_bf, canonical_dsym);
|
||||
}
|
||||
free (canonical_dsym);
|
||||
free (canonical_path);
|
||||
free (alias_dsym);
|
||||
}
|
||||
|
||||
R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
|
||||
R_RETURN_VAL_IF_FAIL (r && r->io, false);
|
||||
R_CRITICAL_ENTER (r);
|
||||
|
|
@ -812,6 +974,7 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
|
|||
}
|
||||
desc = r->io->desc;
|
||||
RBinFile *binfile = r_bin_cur (r->bin);
|
||||
const int binfile_fd = binfile? binfile->fd: -1;
|
||||
RBinPlugin *bp = R_UNWRAP5 (r, bin, cur, bo, plugin);
|
||||
if (bp) {
|
||||
char msg[2];
|
||||
|
|
@ -1000,26 +1163,9 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
|
|||
goto beach;
|
||||
}
|
||||
beach:
|
||||
{
|
||||
const char *dbginfo_uri = filenameuri_safe? filenameuri_safe: filenameuri;
|
||||
if (has_cmd_load && !filenameuri_safe) {
|
||||
dbginfo_uri = NULL;
|
||||
}
|
||||
if (r_config_get_b (r->config, "bin.dbginfo") && R_STR_ISNOTEMPTY (dbginfo_uri)) {
|
||||
// TODO only for macho
|
||||
// load companion dwarf files
|
||||
const char *basename = r_file_basename (dbginfo_uri);
|
||||
char *macdwarf = r_str_newf ("%s.dSYM/Contents/Resources/DWARF/%s", dbginfo_uri, basename);
|
||||
if (r_file_exists (macdwarf)) {
|
||||
// Skip symbols for dSYM since they duplicate main binary
|
||||
bool old_skipsyms = r->bin->options.skip_symbols;
|
||||
r->bin->options.skip_symbols = true;
|
||||
r_core_callf (r, "o %s", macdwarf);
|
||||
r->bin->options.skip_symbols = old_skipsyms;
|
||||
r_core_call (r, "obm-");
|
||||
}
|
||||
free (macdwarf);
|
||||
}
|
||||
if (r_config_get_b (r->config, "bin.dbginfo") && (!has_cmd_load || filenameuri_safe)) {
|
||||
RBinFile *main_bf = binfile_fd >= 0? r_bin_file_find_by_fd (r->bin, binfile_fd): NULL;
|
||||
load_mach0_dsym (r, main_bf);
|
||||
}
|
||||
free (filenameuri_safe);
|
||||
if (mustclose) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue