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

This commit is contained in:
potato 2026-08-23 01:05:45 +05:30 committed by GitHub
parent b4e48fb498
commit b281ec86b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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) {