[lldb] Handle STT_TLS symbol type in ELF parser#178975
[lldb] Handle STT_TLS symbol type in ELF parser#178975DavidSpickett merged 1 commit intollvm:mainfrom
Conversation
|
@llvm/pr-subscribers-lldb Author: puneeth_aditya_5656 (mugiwaraluffy56) ChangesAdd handling for This treats TLS symbols as data symbols ( Fixes #178953 Full diff: https://github.com/llvm/llvm-project/pull/178975.diff 1 Files Affected:
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 90afd5b2dc93a..0ec135324ea37 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2241,6 +2241,12 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
// function will be resolved if it is referenced.
symbol_type = eSymbolTypeResolver;
break;
+
+ case STT_TLS:
+ // The symbol is associated with a thread-local data object, such as
+ // a thread-local variable.
+ symbol_type = eSymbolTypeData;
+ break;
}
}
|
|
@JDevlieghere , can you review this |
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
f81a937 to
58f59e1
Compare
|
You need to fix the conflicts with the main branch before the CI can run again (it applies your changes to main to simulate the post-merge situation). This needs a targeted test case. The ideal for this is to put it in lldb/test/Shell/ObjectFile/ELF and generate the input from a YAML file. LLVM has tools obj2yaml and yaml2obj for this purpose, or you could modify one of the existing yaml files. If you need to check more than that style of test can, a simple C program can be used. I expect such a test will fail on AArch64 (#83466 / #71666) and probably ARM. We can sort that out with post merge fixes if so. There is a test for TLS global variables - lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py. This does run on x86 Linux judging by the skip annotations. errno is a "global" so you could check access in that test. |
|
Thanks for taking a look at this! :D
I don't know the details but I'd like to note that, as I said, this symbol is available even on a stripped glibc, i.e. with no dwarf |
58f59e1 to
431b0cf
Compare
Now I think about it, I'm not sure why it's being so picky, it isn't normally. Oh well, since there aren't any outstanding comments on this, feel free to force push updates.
This makes me worry that this PR is an improvement but not a full fix for the issue as reported. I'd still be happy to accept this PR but we should check before we claim to have fixed the issue. @mugiwaraluffy56 can you reproduce the issue and see what happens? Other than that, this looks nice, the YAML test in particular is very neat. I'm just holding off approving until we know its exact effects. |
d83823d to
32d52cd
Compare
Add handling for STT_TLS (thread-local storage) symbols in the ELF symbol parsing code. Previously, TLS symbols like errno from glibc were not recognized because STT_TLS was not handled in the symbol type switch statement. This treats TLS symbols as data symbols (eSymbolTypeData), similar to STT_OBJECT. Fixes llvm#178953
32d52cd to
15f9842
Compare
|
Parsing ➜ ./build/bin/lldb ./build/lldb-test-build.noindex/lang/cpp/thread_local/TestThreadLocal.test_thread_local_dwo/a.out
(lldb) target create "./build/lldb-test-build.noindex/lang/cpp/thread_local/TestThreadLocal.test_thread_local_dwo/a.out"
Current executable set to '/usr/src/llvm/tls/build/lldb-test-build.noindex/lang/cpp/thread_local/TestThreadLocal.test_thread_local_dwo/a.out' (x86_64).
(lldb) b main.cpp:10
Breakpoint 1: where = a.out`main + 76 at main.cpp:10:3, address = 0x00000000002016ec
(lldb) r
Process 24792 launched: '/usr/src/llvm/tls/build/lldb-test-build.noindex/lang/cpp/thread_local/TestThreadLocal.test_thread_local_dwo/a.out' (x86_64)
Process 24792 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x00000000002016ec a.out`main(argc=1, argv=0x0000000820795330) at main.cpp:10:3
7 thread_local int *tl_local_ptr = nullptr;
8 tl_local_ptr = &tl_local_int;
9 tl_local_int++;
-> 10 return 0; // Set breakpoint here
^
11 }
(lldb) expr tl_local_int + 1
error: Couldn't materialize: couldn't get the value of variable tl_local_int: no TLS data currently exists for this thread
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression] |
This PR only fixes STT_TLS symbol parsing (recognizing the symbol type in the ELF table). The runtime TLS variable evaluation you're showing is a separate issue in the Process plugin .My PR doesn't address that. The yaml test confirms parsing works correctly. |
mchoo7
left a comment
There was a problem hiding this comment.
I'll fix FreeBSD issue on my side. At least for FreeBSD, LGTM.
DavidSpickett
left a comment
There was a problem hiding this comment.
This PR LGTM on the condition that
Fixes #178953
Is either proven to be true, or you remove that claim from the PR description, and the original issue reporter can test it on their own time.
I suggest the latter.
Nothing wrong with either path, just being a pedant about process :)
Done. |
Add handling for `STT_TLS` (thread-local storage) symbols in the ELF symbol parsing code. Previously, TLS symbols like `errno` from glibc were not recognized because `STT_TLS` was not handled in the symbol type switch statement. This treats TLS symbols as data symbols (`eSymbolTypeData`), similar to `STT_OBJECT`. The actual TLS address resolution is already implemented in `DynamicLoaderPOSIXDYLD::GetThreadLocalData()` which uses the DWARF `DW_OP_form_tls_address` opcode to calculate thread-local addresses.
Add handling for
STT_TLS(thread-local storage) symbols in the ELF symbol parsing code. Previously, TLS symbols likeerrnofrom glibc were not recognized becauseSTT_TLSwas not handled in the symbol type switch statement.This treats TLS symbols as data symbols (
eSymbolTypeData), similar toSTT_OBJECT. The actual TLS address resolution is already implemented inDynamicLoaderPOSIXDYLD::GetThreadLocalData()which uses the DWARFDW_OP_form_tls_addressopcode to calculate thread-local addresses.