[Lldb-commits] [lldb] r371599 - [LLDB][ELF] Load both, .symtab and .dynsym sections
Konrad Kleine via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 11 03:00:32 PDT 2019
Author: kwk
Date: Wed Sep 11 03:00:30 2019
New Revision: 371599
URL: http://llvm.org/viewvc/llvm-project?rev=371599&view=rev
Log:
[LLDB][ELF] Load both, .symtab and .dynsym sections
Summary:
This change ensures that the .dynsym section will be parsed even when there's already is a .symtab.
It is motivated because of minidebuginfo (https://sourceware.org/gdb/current/onlinedocs/gdb/MiniDebugInfo.html#MiniDebugInfo).
There it says:
Keep all the function symbols not already in the dynamic symbol table.
That means the .symtab embedded inside the .gnu_debugdata does NOT contain the symbols from .dynsym. But in order to put a breakpoint on all symbols we need to load both. I hope this makes sense.
My other patch D66791 implements support for minidebuginfo, that's why I need this change.
Reviewers: labath, espindola, alexshap
Subscribers: JDevlieghere, emaste, arichardson, MaskRay, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D67390
Added:
lldb/trunk/lit/Modules/ELF/Inputs/load-from-dynsym-alone.c
lldb/trunk/lit/Modules/ELF/Inputs/load-symtab-and-dynsym.c
lldb/trunk/lit/Modules/ELF/load-from-dynsym-alone.test
lldb/trunk/lit/Modules/ELF/load-symtab-and-dynsym.test
Modified:
lldb/trunk/lit/helper/toolchain.py
lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Added: lldb/trunk/lit/Modules/ELF/Inputs/load-from-dynsym-alone.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/ELF/Inputs/load-from-dynsym-alone.c?rev=371599&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/ELF/Inputs/load-from-dynsym-alone.c (added)
+++ lldb/trunk/lit/Modules/ELF/Inputs/load-from-dynsym-alone.c Wed Sep 11 03:00:30 2019
@@ -0,0 +1,7 @@
+// This function will be embedded within the .dynsym section of the main binary.
+int functionInDynsym(int num) { return num * 3; }
+
+int main(int argc, char *argv[]) {
+ int y = functionInDynsym(argc);
+ return y;
+}
Added: lldb/trunk/lit/Modules/ELF/Inputs/load-symtab-and-dynsym.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/ELF/Inputs/load-symtab-and-dynsym.c?rev=371599&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/ELF/Inputs/load-symtab-and-dynsym.c (added)
+++ lldb/trunk/lit/Modules/ELF/Inputs/load-symtab-and-dynsym.c Wed Sep 11 03:00:30 2019
@@ -0,0 +1,12 @@
+// This function will be embedded within the .symtab section of the
+// .gnu_debugdata section.
+int functionInSymtab(int num) { return num * 4; }
+
+// This function will be embedded within the .dynsym section of the main binary.
+int functionInDynsym(int num) { return num * 3; }
+
+int main(int argc, char *argv[]) {
+ int x = functionInSymtab(argc);
+ int y = functionInDynsym(x);
+ return y;
+}
Added: lldb/trunk/lit/Modules/ELF/load-from-dynsym-alone.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/ELF/load-from-dynsym-alone.test?rev=371599&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/ELF/load-from-dynsym-alone.test (added)
+++ lldb/trunk/lit/Modules/ELF/load-from-dynsym-alone.test Wed Sep 11 03:00:30 2019
@@ -0,0 +1,33 @@
+# REQUIRES: system-linux
+
+# This test ensures that we will load .dynsym even if there's no .symtab section.
+# We do this by compiling a small C program with a function and we direct the
+# linker where to put the symbols so that in the end the layout is as follows:
+#
+# Symbol table '.dynsym' contains 4 entries:
+# Num: Value Size Type Bind Vis Ndx Name
+# 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main at GLIBC_2.2.5
+# 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
+# 3: 0000000000401110 13 FUNC GLOBAL DEFAULT 10 functionInDynsym
+
+# We want to keep the symbol "functionInDynsym" in the .dynamic section and not
+# have it put the default .symtab section.
+# RUN: echo "{functionInDynsym;};" > %T/dynmic-symbols.txt
+# RUN: %clang -Wl,--dynamic-list=%T/dynmic-symbols.txt -g -o %t.binary %p/Inputs/load-from-dynsym-alone.c
+
+# Remove not needed symbols
+# RUN: echo "functionInDynsym" > %t.keep_symbols
+# RUN: llvm-objcopy --strip-all --remove-section .gdb_index --remove-section .comment --keep-symbols=%t.keep_symbols %t.binary
+
+# Remove functionInDynsym symbol from .symtab (will leave symbol in .dynsym intact)
+# RUN: llvm-strip --strip-symbol=functionInDynsym %t.binary
+
+# RUN: %lldb -b -o 'b functionInDynsym' -o 'run' -o 'continue' %t.binary | FileCheck %s
+
+# CHECK: (lldb) b functionInDynsym
+# CHECK-NEXT: Breakpoint 1: where = {{.*}}.binary`functionInDynsym, address = 0x{{.*}}
+
+# CHECK: (lldb) run
+# CHECK-NEXT: Process {{.*}} stopped
+# CHECK-NEXT: * thread #1, name = 'load-from-dynsy', stop reason = breakpoint 1.1
Added: lldb/trunk/lit/Modules/ELF/load-symtab-and-dynsym.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/ELF/load-symtab-and-dynsym.test?rev=371599&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/ELF/load-symtab-and-dynsym.test (added)
+++ lldb/trunk/lit/Modules/ELF/load-symtab-and-dynsym.test Wed Sep 11 03:00:30 2019
@@ -0,0 +1,48 @@
+# REQUIRES: system-linux
+
+# This test ensures that we will load .dynsym even if there's a .symtab section.
+# We do this by compiling a small C program with two functions and we direct the
+# linker where to put the symbols so that in the end the layout is as follows:
+#
+# Symbol table '.dynsym' contains 4 entries:
+# Num: Value Size Type Bind Vis Ndx Name
+# 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main at GLIBC_2.2.5
+# 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
+# 3: 0000000000401120 13 FUNC GLOBAL DEFAULT 10 functionInDynsym
+#
+# Symbol table '.symtab' contains 2 entries:
+# Num: Value Size Type Bind Vis Ndx Name
+# 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# 1: 0000000000401110 15 FUNC GLOBAL DEFAULT 10 functionInSymtab
+
+# We want to keep the symbol "functionInDynsym" in the .dynamic section and not
+# have it put the default .symtab section.
+# RUN: echo "{functionInDynsym;};" > %T/dynmic-symbols.txt
+# RUN: %clang -Wl,--dynamic-list=%T/dynmic-symbols.txt -g -o %t.binary %p/Inputs/load-symtab-and-dynsym.c
+
+# Remove not needed symbols
+# RUN: echo "functionInSymtab" > %t.keep_symbols
+# RUN: echo "functionInDynsym" >> %t.keep_symbols
+# RUN: llvm-objcopy --strip-all --remove-section .gdb_index --remove-section .comment --keep-symbols=%t.keep_symbols %t.binary
+
+# Remove functionInDynsym symbol from .symtab (will leave symbol in .dynsym intact)
+# RUN: llvm-strip --strip-symbol=functionInDynsym %t.binary
+
+# RUN: %lldb -b -o 'b functionInSymtab' -o 'b functionInDynsym' -o 'run' -o 'continue' %t.binary | FileCheck %s
+
+# CHECK: (lldb) b functionInSymtab
+# CHECK-NEXT: Breakpoint 1: where = {{.*}}.binary`functionInSymtab, address = 0x{{.*}}
+
+# CHECK: (lldb) b functionInDynsym
+# CHECK-NEXT: Breakpoint 2: where = {{.*}}.binary`functionInDynsym, address = 0x{{.*}}
+
+# CHECK: (lldb) run
+# CHECK-NEXT: Process {{.*}} stopped
+# CHECK-NEXT: * thread #1, name = 'load-symtab-and', stop reason = breakpoint 1.1
+
+# CHECK: (lldb) continue
+# CHECK-NEXT: Process {{.*}} resuming
+# CHECK-NEXT: Process {{.*}} stopped
+# CHECK-NEXT: * thread #1, name = 'load-symtab-and', stop reason = breakpoint 2.1
+
Modified: lldb/trunk/lit/helper/toolchain.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/helper/toolchain.py?rev=371599&r1=371598&r2=371599&view=diff
==============================================================================
--- lldb/trunk/lit/helper/toolchain.py (original)
+++ lldb/trunk/lit/helper/toolchain.py Wed Sep 11 03:00:30 2019
@@ -126,6 +126,6 @@ def use_support_substitutions(config):
support_tools = ['yaml2obj', 'obj2yaml', 'llvm-pdbutil',
'llvm-mc', 'llvm-readobj', 'llvm-objdump',
- 'llvm-objcopy', 'lli']
+ 'llvm-objcopy', 'lli', 'llvm-strip']
additional_tool_dirs += [config.lldb_tools_dir, config.llvm_tools_dir]
llvm_config.add_tool_substitutions(support_tools, additional_tool_dirs)
Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=371599&r1=371598&r2=371599&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Wed Sep 11 03:00:30 2019
@@ -2647,21 +2647,31 @@ Symtab *ObjectFileELF::GetSymtab() {
// smaller version of the symtab that only contains global symbols. The
// information found in the dynsym is therefore also found in the symtab,
// while the reverse is not necessarily true.
+ // One exception to the above rule is when we have minidebuginfo embedded
+ // into a compressed .gnu_debugdata section. This section contains a .symtab
+ // from which all symbols already contained in the .dynsym are stripped.
Section *symtab =
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
- if (!symtab) {
- // The symtab section is non-allocable and can be stripped, so if it
- // doesn't exist then use the dynsym section which should always be
- // there.
- symtab =
- section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
- .get();
- }
if (symtab) {
m_symtab_up.reset(new Symtab(symtab->GetObjectFile()));
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
}
+ // The symtab section is non-allocable and can be stripped, while the dynsym
+ // section which should always be always be there. If both exist we load
+ // both to support the minidebuginfo case. Otherwise we just load the dynsym
+ // section.
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ if (dynsym) {
+ if (!m_symtab_up) {
+ auto sec = symtab ? symtab : dynsym;
+ m_symtab_up.reset(new Symtab(sec->GetObjectFile()));
+ }
+ symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
+ }
+
// DT_JMPREL
// If present, this entry's d_ptr member holds the address of
// relocation
More information about the lldb-commits
mailing list