Skip to content

Commit cd6ced0

Browse files
jbachorikclaude
andcommitted
Set clang frame layout as default for macOS aarch64
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e279f4f commit cd6ced0

4 files changed

Lines changed: 23 additions & 10 deletions

File tree

ddprof-lib/src/main/cpp/dwarf.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,19 @@ struct FrameDesc {
8383
static FrameDesc default_clang_frame;
8484
static FrameDesc no_dwarf_frame;
8585

86+
// Platform default frame layout for native code when no DWARF info is available.
87+
// On macOS aarch64 all native libraries are built with Apple clang, which uses
88+
// a different frame layout (FP/LR at [fp-16]/[fp-8]) than GCC (FP/LR at [fp]/[fp+8]).
89+
// On Linux aarch64 both compilers coexist, so the per-library default is detected
90+
// from DWARF via DwarfParser::detectedDefaultFrame() in ElfParser::parseDwarfInfo().
91+
static const FrameDesc& default_native_frame() {
92+
#if defined(__APPLE__) && defined(__aarch64__)
93+
return default_clang_frame;
94+
#else
95+
return default_frame;
96+
#endif
97+
}
98+
8699
static int comparator(const void* p1, const void* p2) {
87100
FrameDesc* fd1 = (FrameDesc*)p1;
88101
FrameDesc* fd2 = (FrameDesc*)p2;

ddprof-lib/src/main/cpp/stackWalker.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,7 @@ int StackWalker::walkDwarf(void* ucontext, const void** callchain, int max_depth
158158

159159
uintptr_t prev_sp = sp;
160160
CodeCache* cc = profiler->findLibraryByAddress(pc);
161-
#if defined(__APPLE__) && defined(__aarch64__)
162-
FrameDesc f = cc != NULL ? cc->findFrameDesc(pc) : FrameDesc::default_clang_frame;
163-
#else
164-
FrameDesc f = cc != NULL ? cc->findFrameDesc(pc) : FrameDesc::default_frame;
165-
#endif
161+
FrameDesc f = cc != NULL ? cc->findFrameDesc(pc) : FrameDesc::default_native_frame();
166162

167163
u8 cfa_reg = (u8)f.cfa;
168164
int cfa_off = f.cfa >> 8;
@@ -698,11 +694,7 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
698694
dwarf_unwind:
699695
uintptr_t prev_sp = sp;
700696
CodeCache* cc = profiler->findLibraryByAddress(pc);
701-
#if defined(__APPLE__) && defined(__aarch64__)
702-
FrameDesc f = cc != NULL ? cc->findFrameDesc(pc) : FrameDesc::default_clang_frame;
703-
#else
704-
FrameDesc f = cc != NULL ? cc->findFrameDesc(pc) : FrameDesc::default_frame;
705-
#endif
697+
FrameDesc f = cc != NULL ? cc->findFrameDesc(pc) : FrameDesc::default_native_frame();
706698

707699
u8 cfa_reg = (u8)f.cfa;
708700
int cfa_off = f.cfa >> 8;

ddprof-lib/src/main/cpp/symbols_linux.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,9 @@ void ElfParser::parseDwarfInfo() {
604604
ElfProgramHeader* eh_frame_hdr = findProgramHeader(PT_GNU_EH_FRAME);
605605
if (eh_frame_hdr != NULL) {
606606
if (eh_frame_hdr->p_vaddr != 0) {
607+
// Parse per-PC frame descriptions and detect per-library default frame layout.
608+
// On aarch64 this distinguishes GCC (LINKED_FRAME_SIZE=0) from clang
609+
// (LINKED_FRAME_CLANG_SIZE=16) conventions for each shared library.
607610
DwarfParser dwarf(_cc->name(), _base, at(eh_frame_hdr));
608611
_cc->setDwarfTable(dwarf.table(), dwarf.count(), dwarf.detectedDefaultFrame());
609612
} else if (strcmp(_cc->name(), "[vdso]") == 0) {

ddprof-lib/src/main/cpp/symbols_macos.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <mach-o/loader.h>
1313
#include <mach-o/nlist.h>
1414
#include "symbols.h"
15+
#include "dwarf.h"
1516
#include "log.h"
1617

1718
UnloadProtection::UnloadProtection(const CodeCache *cc) {
@@ -212,6 +213,10 @@ void Symbols::parseLibraries(CodeCacheArray* array, bool kernel_symbols) {
212213
if (!parser.parse()) {
213214
Log::warn("Could not parse symbols from %s", path);
214215
}
216+
// Mach-O has no eh_frame_hdr index, so we can't parse per-PC DWARF entries.
217+
// Set the platform default frame layout so findFrameDesc() returns the
218+
// correct fallback for aarch64 (clang frame convention).
219+
cc->setDwarfTable(NULL, 0, FrameDesc::default_native_frame());
215220
cc->sort();
216221
if (!array->add(cc)) {
217222
delete cc;

0 commit comments

Comments
 (0)