[llvm-bugs] [Bug 37212] New: LLD can create incorrect debug PC ranges for functions in Comdat groups.
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Apr 23 09:19:20 PDT 2018
https://bugs.llvm.org/show_bug.cgi?id=37212
Bug ID: 37212
Summary: LLD can create incorrect debug PC ranges for functions
in Comdat groups.
Product: lld
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: ELF
Assignee: unassignedbugs at nondot.org
Reporter: peter.smith at linaro.org
CC: llvm-bugs at lists.llvm.org
clang and gcc produce technically incorrect ELF when representing the debug
information for comdat groups. Both gold and bfd have special case code that
accounts for this whereas LLD does not. For a better C++ debug illusion we
should consider implementing the same compensating code as it may be some time
before there is a sufficiently correct debug output from the compilers.
The problem is best observed via an example:
// File t.h
template <class T>
class Foo {
public:
Foo(T x, T y) : x_(x), y_(y) {}
T add() const { return x_ + y_; }
private:
T x_;
T y_;
};
// File t.cpp, instantiates Foo::Foo() and Foo::add() in comdat groups.
#include "t.h"
int f1(int a, int b, int c, int d) {
Foo<int> f1(a, b);
Foo<int> f2(c, d);
return f1.add() + f2.add();
}
// File t2.cpp, instantiates Foo::Foo() and Foo::add() in comdat groups.
#include "t.h"
int f2(int a, int b, int c, int d) {
Foo<int> f1(a, b);
Foo<int> f2(c, d);
return f1.add() + f2.add();
}
// main.cpp
extern int f1(int a, int b, int c, int d);
extern int f2(int a, int b, int c, int d);
int main(void) {
return f1(1,2,3,4) + f2(5,6,7,8);
}
clang -g t.cpp t2.cpp main.cpp -o main.exe
With bfd as the linker:
llvm-dwarfdump main.exe | grep DW_AT_low_pc
DW_AT_low_pc (0x0000000000000000)
DW_AT_low_pc (0x00000000004004c0)
DW_AT_low_pc (0x0000000000400520)
DW_AT_low_pc (0x0000000000400540)
DW_AT_low_pc (0x0000000000000000)
DW_AT_low_pc (0x0000000000400560)
DW_AT_low_pc (0x0000000000400520)
DW_AT_low_pc (0x0000000000400540)
DW_AT_low_pc (0x00000000004005c0)
DW_AT_low_pc (0x00000000004005c0)
With lld as the linker:
DW_AT_low_pc (0x0000000000000000)
DW_AT_low_pc (0x0000000000201100)
DW_AT_low_pc (0x0000000000201160)
DW_AT_low_pc (0x0000000000201180)
DW_AT_low_pc (0x0000000000000000)
DW_AT_low_pc (0x00000000002011a0)
DW_AT_low_pc (0x0000000000000000)
DW_AT_low_pc (0x0000000000000000)
DW_AT_low_pc (0x0000000000201200)
DW_AT_low_pc (0x0000000000201200)
Note that there are two more DW_AT_low_pc (0x0000000000000000) in the lld
output. These are references from the .debug_info, in the object where the
Foo::Foo() and Foo::add() groups were discarded, to a local symbol within the
group.
Section (11) .rela.debug_info {
...
0x10C R_X86_64_64 .text._ZN3FooIiEC2Eii 0x0
0x150 R_X86_64_64 .text._ZNK3FooIiE3addEv 0x0
...
These references to local symbols defined within a group from outside the group
are not permitted by ELF. LLD has special case code to allow them, but gold and
bfd go further and redirect the relocation from the objects with discarded
groups to the object with the selected group. The special case code can be
found by searching for PRETEND in bfd and CB_PRETEND in gold.
What bfd and gold are doing is most definitely a hack, but it probably works
well enough to give a better debug illusion than resolving to 0. We may want to
follow suit and implement it.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180423/d329c2b5/attachment-0001.html>
More information about the llvm-bugs
mailing list