mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-12-22 18:56:31 +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
|
@ -210,22 +210,4 @@ const NXArchInfo *NXGetArchInfoFromCpuType(cpu_type_t cputype,
|
|||
}
|
||||
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__
|
||||
|
|
|
@ -232,60 +232,37 @@ bool DumpSymbols::SetArchitecture(const ArchInfo& info) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
SuperFatArch* DumpSymbols::FindBestMatchForArchitecture(
|
||||
cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
|
||||
// Check if all the object files can be converted to struct fat_arch.
|
||||
bool can_convert_to_fat_arch = true;
|
||||
vector<struct fat_arch> fat_arch_vector;
|
||||
for (vector<SuperFatArch>::const_iterator it = object_files_.begin();
|
||||
it != object_files_.end();
|
||||
++it) {
|
||||
struct fat_arch arch;
|
||||
bool success = it->ConvertToFatArch(&arch);
|
||||
if (!success) {
|
||||
can_convert_to_fat_arch = false;
|
||||
break;
|
||||
cpu_type_t cpu_type,
|
||||
cpu_subtype_t cpu_subtype) {
|
||||
SuperFatArch* closest_match = nullptr;
|
||||
for (auto& object_file : object_files_) {
|
||||
if (static_cast<cpu_type_t>(object_file.cputype) == cpu_type) {
|
||||
// If there's an exact match, return it directly.
|
||||
if ((static_cast<cpu_subtype_t>(object_file.cpusubtype) &
|
||||
~CPU_SUBTYPE_MASK) == (cpu_subtype & ~CPU_SUBTYPE_MASK)) {
|
||||
return &object_file;
|
||||
}
|
||||
fat_arch_vector.push_back(arch);
|
||||
// Otherwise, hold on to this as the closest match since at least the CPU
|
||||
// type matches.
|
||||
if (!closest_match) {
|
||||
closest_match = &object_file;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// TODO(erikchen): If it becomes necessary, we can copy the implementation of
|
||||
// NXFindBestFatArch, located at
|
||||
// http://web.mit.edu/darwin/src/modules/cctools/libmacho/arch.c.
|
||||
fprintf(stderr, "Failed to find an exact match for an object file with cpu "
|
||||
"type: %d and cpu subtype: %d.\n", cpu_type, cpu_subtype);
|
||||
if (!can_convert_to_fat_arch) {
|
||||
fprintf(stderr, "Furthermore, at least one object file is larger "
|
||||
"than 2**32.\n");
|
||||
fprintf(stderr,
|
||||
"Failed to find an exact match for an object file with cpu "
|
||||
"type: %d and cpu subtype: %d.\n",
|
||||
cpu_type, cpu_subtype);
|
||||
if (closest_match) {
|
||||
fprintf(stderr, "Using %s as the closest match.\n",
|
||||
GetNameFromCPUType(closest_match->cputype,
|
||||
closest_match->cpusubtype));
|
||||
return closest_match;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
string DumpSymbols::Identifier() {
|
||||
|
|
Loading…
Reference in a new issue