@@ -212,12 +212,33 @@ get_native_custom_labels(PerCPURecord *record, NativeCustomLabelsProcInfo *proc)
212212 return false;
213213 }
214214
215- u64 offset = tsd_base + proc -> tls_offset ;
216- DEBUG_PRINT ("cl: native custom labels data at 0x%llx" , offset );
215+ int err ;
216+ #if defined(__aarch64__ )
217+ // ELF Handling For Thread-Local Storage, p.5.
218+ // The thread register points to a "TCB" (Thread Control Block)
219+ // whose first element is a pointer to a "DTV" (Dynamic Thread Vector)...
220+ u64 dtv_addr ;
221+ if ((err = bpf_probe_read_user (& dtv_addr , sizeof (void * ), (void * )(tsd_base )))) {
222+ increment_metric (metricID_UnwindNativeCustomLabelsErrReadData );
223+ DEBUG_PRINT ("Failed to read TLS DTV addr: %d" , err );
224+ return false;
225+ }
226+ // ... and at offsite 16 in the DTV, there is a pointer to the TLS block.
227+ u64 addr ;
228+ if ((err = bpf_probe_read_user (& addr , sizeof (void * ), (void * )(dtv_addr + 16 )))) {
229+ increment_metric (metricID_UnwindNativeCustomLabelsErrReadData );
230+ DEBUG_PRINT ("Failed to read main TLS block addr: %d" , err );
231+ return false;
232+ }
233+ addr += proc -> tls_offset ;
234+ #else
235+ u64 addr = tsd_base + proc -> tls_offset ;
236+ #endif
237+
238+ DEBUG_PRINT ("cl: native custom labels data at 0x%llx" , addr );
217239
218240 NativeCustomLabelsSet * p_current_set ;
219- int err ;
220- if ((err = bpf_probe_read_user (& p_current_set , sizeof (void * ), (void * )(offset )))) {
241+ if ((err = bpf_probe_read_user (& p_current_set , sizeof (void * ), (void * )(addr )))) {
221242 increment_metric (metricID_UnwindNativeCustomLabelsErrReadData );
222243 DEBUG_PRINT ("Failed to read custom labels current set pointer: %d" , err );
223244 return false;
0 commit comments