aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeonard Grey <lgrey@chromium.org>2023-03-13 18:14:34 -0400
committerLeonard Grey <lgrey@chromium.org>2023-03-27 19:07:21 +0000
commitc179ddaa58e0ec3093f98de555ad5791e9cb432a (patch)
tree061f49686724c693ca74861510a2d2fd452ae2c8
parent9cc38fec8bbf4efc58f077c975e7f2b422a74ee3 (diff)
downloadgoogle-breakpad-c179ddaa58e0ec3093f98de555ad5791e9cb432a.tar.gz
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>
-rw-r--r--src/common/mac/arch_utilities.cc18
-rw-r--r--src/common/mac/dump_syms.cc75
2 files changed, 26 insertions, 67 deletions
diff --git a/src/common/mac/arch_utilities.cc b/src/common/mac/arch_utilities.cc
index cdc1dfa5..febf8a22 100644
--- a/src/common/mac/arch_utilities.cc
+++ b/src/common/mac/arch_utilities.cc
@@ -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__
diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc
index 6396e97a..04ccae25 100644
--- a/src/common/mac/dump_syms.cc
+++ b/src/common/mac/dump_syms.cc
@@ -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;
- }
- 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];
+SuperFatArch* DumpSymbols::FindBestMatchForArchitecture(
+ 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;
+ }
+ // Otherwise, hold on to this as the closest match since at least the CPU
+ // type matches.
+ if (!closest_match) {
+ closest_match = &object_file;
+ }
}
- 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() {