diff --git a/interpreter/customlabels/customlabels.go b/interpreter/customlabels/customlabels.go index 7f9404450..757a372e5 100644 --- a/interpreter/customlabels/customlabels.go +++ b/interpreter/customlabels/customlabels.go @@ -80,7 +80,7 @@ func Loader(_ interpreter.EbpfHandler, info *interpreter.LoaderInfo) (interprete return nil, err } if ef.Machine == elf.EM_AARCH64 { - tlsAddr = libpf.Address(tlsSym.Address + 16) + tlsAddr = libpf.Address(tlsSym.Address) } else if ef.Machine == elf.EM_X86_64 { // Symbol addresses are relative to the start of the // thread-local storage image, but the thread pointer points to the _end_ diff --git a/support/ebpf/interpreter_dispatcher.ebpf.c b/support/ebpf/interpreter_dispatcher.ebpf.c index 829263d0b..f205005c0 100644 --- a/support/ebpf/interpreter_dispatcher.ebpf.c +++ b/support/ebpf/interpreter_dispatcher.ebpf.c @@ -212,12 +212,33 @@ get_native_custom_labels(PerCPURecord *record, NativeCustomLabelsProcInfo *proc) return false; } - u64 offset = tsd_base + proc->tls_offset; - DEBUG_PRINT("cl: native custom labels data at 0x%llx", offset); + int err; +#if defined(__aarch64__) + // ELF Handling For Thread-Local Storage, p.5. + // The thread register points to a "TCB" (Thread Control Block) + // whose first element is a pointer to a "DTV" (Dynamic Thread Vector)... + u64 dtv_addr; + if ((err = bpf_probe_read_user(&dtv_addr, sizeof(void *), (void *)(tsd_base)))) { + increment_metric(metricID_UnwindNativeCustomLabelsErrReadData); + DEBUG_PRINT("Failed to read TLS DTV addr: %d", err); + return false; + } + // ... and at offsite 16 in the DTV, there is a pointer to the TLS block. + u64 addr; + if ((err = bpf_probe_read_user(&addr, sizeof(void *), (void *)(dtv_addr + 16)))) { + increment_metric(metricID_UnwindNativeCustomLabelsErrReadData); + DEBUG_PRINT("Failed to read main TLS block addr: %d", err); + return false; + } + addr += proc->tls_offset; +#else + u64 addr = tsd_base + proc->tls_offset; +#endif + + DEBUG_PRINT("cl: native custom labels data at 0x%llx", addr); NativeCustomLabelsSet *p_current_set; - int err; - if ((err = bpf_probe_read_user(&p_current_set, sizeof(void *), (void *)(offset)))) { + if ((err = bpf_probe_read_user(&p_current_set, sizeof(void *), (void *)(addr)))) { increment_metric(metricID_UnwindNativeCustomLabelsErrReadData); DEBUG_PRINT("Failed to read custom labels current set pointer: %d", err); return false; diff --git a/support/ebpf/tracer.ebpf.debug.arm64 b/support/ebpf/tracer.ebpf.debug.arm64 index 2b8a9f9b1..a06dffad2 100644 Binary files a/support/ebpf/tracer.ebpf.debug.arm64 and b/support/ebpf/tracer.ebpf.debug.arm64 differ diff --git a/support/ebpf/tracer.ebpf.release.arm64 b/support/ebpf/tracer.ebpf.release.arm64 index 6d2962166..f85932597 100644 Binary files a/support/ebpf/tracer.ebpf.release.arm64 and b/support/ebpf/tracer.ebpf.release.arm64 differ