mirror of
https://github.com/yuzu-emu/breakpad
synced 2024-11-22 16:43:46 +00:00
Mac: don't call NXFindBestFatArch
`NXFindBestFatArch` is deprecated in macOS 13. We use this when an architecture is passed in via the `-a` flag. Unfortunately, neither of the potential replacements can help with this use case: - `macho_for_each_slice` as suggested in a reply to FB11955188 just enumerates slices, without the logic for inexact matches (for example, x86_64h -> x86_64 or arm64e -> arm64). - `macho_best_slice` as recommended by the deprecation notice only supports finding a suitable slice to run on the local machine. We could adapt the logic in `NXFindBestFatArch` but it gets quite complex for some architectures. Instead, this change adapts the `NXFindBestFatArch` polyfill used in `dump_syms_mac` for Linux, which returns an exact match if possible, and the first slice that matches the requested CPU type otherwise. I think this is probably Good Enough for most cases; if not, we can try porting the x86_64 and ARM logic and falling back to this for the rest. Change-Id: I3b269dab7246eced768cecd994e915debd95721a Bug: chromium:14206541420654 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4335477 Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
9cc38fec8b
commit
c179ddaa58
2 changed files with 26 additions and 67 deletions
|
@ -210,22 +210,4 @@ const NXArchInfo *NXGetArchInfoFromCpuType(cpu_type_t cputype,
|
||||||
}
|
}
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fat_arch *NXFindBestFatArch(cpu_type_t cputype,
|
|
||||||
cpu_subtype_t cpusubtype,
|
|
||||||
struct fat_arch *fat_archs,
|
|
||||||
uint32_t nfat_archs) {
|
|
||||||
struct fat_arch *candidate = NULL;
|
|
||||||
for (uint32_t f = 0; f < nfat_archs; ++f) {
|
|
||||||
if (fat_archs[f].cputype == cputype) {
|
|
||||||
if (fat_archs[f].cpusubtype == cpusubtype) {
|
|
||||||
return &fat_archs[f];
|
|
||||||
}
|
|
||||||
if (!candidate) {
|
|
||||||
candidate = &fat_archs[f];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
#endif // !__APPLE__
|
#endif // !__APPLE__
|
||||||
|
|
|
@ -232,60 +232,37 @@ bool DumpSymbols::SetArchitecture(const ArchInfo& info) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SuperFatArch* DumpSymbols::FindBestMatchForArchitecture(
|
SuperFatArch* DumpSymbols::FindBestMatchForArchitecture(
|
||||||
cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
|
cpu_type_t cpu_type,
|
||||||
// Check if all the object files can be converted to struct fat_arch.
|
cpu_subtype_t cpu_subtype) {
|
||||||
bool can_convert_to_fat_arch = true;
|
SuperFatArch* closest_match = nullptr;
|
||||||
vector<struct fat_arch> fat_arch_vector;
|
for (auto& object_file : object_files_) {
|
||||||
for (vector<SuperFatArch>::const_iterator it = object_files_.begin();
|
if (static_cast<cpu_type_t>(object_file.cputype) == cpu_type) {
|
||||||
it != object_files_.end();
|
// If there's an exact match, return it directly.
|
||||||
++it) {
|
if ((static_cast<cpu_subtype_t>(object_file.cpusubtype) &
|
||||||
struct fat_arch arch;
|
~CPU_SUBTYPE_MASK) == (cpu_subtype & ~CPU_SUBTYPE_MASK)) {
|
||||||
bool success = it->ConvertToFatArch(&arch);
|
return &object_file;
|
||||||
if (!success) {
|
}
|
||||||
can_convert_to_fat_arch = false;
|
// Otherwise, hold on to this as the closest match since at least the CPU
|
||||||
break;
|
// type matches.
|
||||||
|
if (!closest_match) {
|
||||||
|
closest_match = &object_file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fat_arch_vector.push_back(arch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all the object files can be converted to struct fat_arch, use
|
|
||||||
// NXFindBestFatArch.
|
|
||||||
if (can_convert_to_fat_arch) {
|
|
||||||
const struct fat_arch* best_match
|
|
||||||
= NXFindBestFatArch(cpu_type, cpu_subtype, &fat_arch_vector[0],
|
|
||||||
static_cast<uint32_t>(fat_arch_vector.size()));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < fat_arch_vector.size(); ++i) {
|
|
||||||
if (best_match == &fat_arch_vector[i])
|
|
||||||
return &object_files_[i];
|
|
||||||
}
|
|
||||||
assert(best_match == NULL);
|
|
||||||
// Fall through since NXFindBestFatArch can't find arm slices on x86_64
|
|
||||||
// macOS 13. See FB11955188.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for an exact match with cpu_type and cpu_subtype.
|
|
||||||
for (vector<SuperFatArch>::iterator it = object_files_.begin();
|
|
||||||
it != object_files_.end();
|
|
||||||
++it) {
|
|
||||||
if (static_cast<cpu_type_t>(it->cputype) == cpu_type &&
|
|
||||||
(static_cast<cpu_subtype_t>(it->cpusubtype) & ~CPU_SUBTYPE_MASK) ==
|
|
||||||
(cpu_subtype & ~CPU_SUBTYPE_MASK))
|
|
||||||
return &*it;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No exact match found.
|
// No exact match found.
|
||||||
// TODO(erikchen): If it becomes necessary, we can copy the implementation of
|
fprintf(stderr,
|
||||||
// NXFindBestFatArch, located at
|
"Failed to find an exact match for an object file with cpu "
|
||||||
// http://web.mit.edu/darwin/src/modules/cctools/libmacho/arch.c.
|
"type: %d and cpu subtype: %d.\n",
|
||||||
fprintf(stderr, "Failed to find an exact match for an object file with cpu "
|
cpu_type, cpu_subtype);
|
||||||
"type: %d and cpu subtype: %d.\n", cpu_type, cpu_subtype);
|
if (closest_match) {
|
||||||
if (!can_convert_to_fat_arch) {
|
fprintf(stderr, "Using %s as the closest match.\n",
|
||||||
fprintf(stderr, "Furthermore, at least one object file is larger "
|
GetNameFromCPUType(closest_match->cputype,
|
||||||
"than 2**32.\n");
|
closest_match->cpusubtype));
|
||||||
|
return closest_match;
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DumpSymbols::Identifier() {
|
string DumpSymbols::Identifier() {
|
||||||
|
|
Loading…
Reference in a new issue