Skip to content

Commit b9867df

Browse files
committed
[lldb] Fix CTF parsing of large structs
Fix parsing of large structs. If the size of a struct exceeds a certain threshold, the offset is encoded using two 32-bit integers instead of one. Differential revision: https://reviews.llvm.org/D156490
1 parent abae53f commit b9867df

File tree

6 files changed

+25
-10
lines changed

6 files changed

+25
-10
lines changed

lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,12 @@ struct CTFFunction : public CTFType {
131131
struct CTFRecord : public CTFType {
132132
public:
133133
struct Field {
134-
Field(llvm::StringRef name, uint32_t type, uint16_t offset,
135-
uint16_t padding)
136-
: name(name), type(type), offset(offset), padding(padding) {}
134+
Field(llvm::StringRef name, uint32_t type, uint64_t offset)
135+
: name(name), type(type), offset(offset) {}
137136

138137
llvm::StringRef name;
139138
uint32_t type;
140-
uint16_t offset;
141-
uint16_t padding;
139+
uint64_t offset;
142140
};
143141

144142
CTFRecord(Kind kind, lldb::user_id_t uid, llvm::StringRef name,

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -642,9 +642,16 @@ SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
642642
for (uint32_t i = 0; i < variable_length; ++i) {
643643
const uint32_t field_name = m_data.GetU32(&offset);
644644
const uint32_t type = m_data.GetU32(&offset);
645-
const uint16_t field_offset = m_data.GetU16(&offset);
646-
const uint16_t padding = m_data.GetU16(&offset);
647-
fields.emplace_back(ReadString(field_name), type, field_offset, padding);
645+
uint64_t field_offset = 0;
646+
if (size < g_ctf_field_threshold) {
647+
field_offset = m_data.GetU16(&offset);
648+
m_data.GetU16(&offset); // Padding
649+
} else {
650+
const uint32_t offset_hi = m_data.GetU32(&offset);
651+
const uint32_t offset_lo = m_data.GetU32(&offset);
652+
field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
653+
}
654+
fields.emplace_back(ReadString(field_name), type, field_offset);
648655
}
649656
return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
650657
name, variable_length, size, fields);
@@ -850,7 +857,6 @@ size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
850857
if (Symbol *symbol =
851858
symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
852859
Symtab::eVisibilityAny, symbol_idx)) {
853-
854860
Variable::RangeList ranges;
855861
ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
856862

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ class SymbolFileCTF : public lldb_private::SymbolFileCommon {
254254

255255
static constexpr uint16_t g_ctf_magic = 0xcff1;
256256
static constexpr uint8_t g_ctf_version = 4;
257+
static constexpr uint16_t g_ctf_field_threshold = 0x2000;
257258
};
258259
} // namespace lldb_private
259260

lldb/test/API/macosx/ctf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ a.ctf: a.out.dSYM
2828
-R __DWARF,__apple_objc \
2929
a.ctf a.ctf
3030
rm -rf a.out.dSYM
31+
rm -rf test.o

lldb/test/API/macosx/ctf/TestCTF.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ def do_test(self):
3737

3838
symbol_file = self.getBuildArtifact("a.ctf")
3939

40+
if self.TraceOn():
41+
self.runCmd("log enable -v lldb symbol")
42+
4043
self.runCmd("target symbols add {}".format(symbol_file))
4144
self.expect(
4245
"target variable foo",
@@ -53,7 +56,6 @@ def do_test(self):
5356
"f = 0x0000000000000000",
5457
],
5558
)
56-
5759
self.expect("target variable foo.n.i", substrs=["(MyInt) foo.n.i = 1"])
5860
self.expect(
5961
"target variable foo.n.s", substrs=["(const char *) foo.n.s", '"foo"']

lldb/test/API/macosx/ctf/test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,14 @@ typedef struct MyStruct {
3131
void (*f)(int);
3232
} MyStructT;
3333

34+
struct LargeStruct {
35+
char buffer[9000];
36+
int b;
37+
};
38+
3439
MyStructT foo;
3540
struct ForwardDecl *forward;
41+
struct LargeStruct bar;
3642

3743
void populate(MyInt i) {
3844
foo.n.i = i;
@@ -45,6 +51,7 @@ void populate(MyInt i) {
4551
foo.n.e = eOne;
4652
foo.f = NULL;
4753
forward = NULL;
54+
bar.b = i;
4855
}
4956

5057
int main(int argc, char** argv) {

0 commit comments

Comments
 (0)