[Lldb-commits] [lldb] b9867df - [lldb] Fix CTF parsing of large structs

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Sat Jul 29 19:37:13 PDT 2023


Author: Jonas Devlieghere
Date: 2023-07-29T19:37:08-07:00
New Revision: b9867df64a312b2fe248d536d943733b8817ed4f

URL: https://github.com/llvm/llvm-project/commit/b9867df64a312b2fe248d536d943733b8817ed4f
DIFF: https://github.com/llvm/llvm-project/commit/b9867df64a312b2fe248d536d943733b8817ed4f.diff

LOG: [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

Added: 
    

Modified: 
    lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h
    lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
    lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
    lldb/test/API/macosx/ctf/Makefile
    lldb/test/API/macosx/ctf/TestCTF.py
    lldb/test/API/macosx/ctf/test.c

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h b/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h
index b2cf5cf3191b64..99a74dbe674aea 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h
+++ b/lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h
@@ -131,14 +131,12 @@ struct CTFFunction : public CTFType {
 struct CTFRecord : public CTFType {
 public:
   struct Field {
-    Field(llvm::StringRef name, uint32_t type, uint16_t offset,
-          uint16_t padding)
-        : name(name), type(type), offset(offset), padding(padding) {}
+    Field(llvm::StringRef name, uint32_t type, uint64_t offset)
+        : name(name), type(type), offset(offset) {}
 
     llvm::StringRef name;
     uint32_t type;
-    uint16_t offset;
-    uint16_t padding;
+    uint64_t offset;
   };
 
   CTFRecord(Kind kind, lldb::user_id_t uid, llvm::StringRef name,

diff  --git a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
index f737db3ed4e4b2..1c4de94e06d7b8 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
+++ b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
@@ -642,9 +642,16 @@ SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
     for (uint32_t i = 0; i < variable_length; ++i) {
       const uint32_t field_name = m_data.GetU32(&offset);
       const uint32_t type = m_data.GetU32(&offset);
-      const uint16_t field_offset = m_data.GetU16(&offset);
-      const uint16_t padding = m_data.GetU16(&offset);
-      fields.emplace_back(ReadString(field_name), type, field_offset, padding);
+      uint64_t field_offset = 0;
+      if (size < g_ctf_field_threshold) {
+        field_offset = m_data.GetU16(&offset);
+        m_data.GetU16(&offset); // Padding
+      } else {
+        const uint32_t offset_hi = m_data.GetU32(&offset);
+        const uint32_t offset_lo = m_data.GetU32(&offset);
+        field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
+      }
+      fields.emplace_back(ReadString(field_name), type, field_offset);
     }
     return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
                                        name, variable_length, size, fields);
@@ -850,7 +857,6 @@ size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
     if (Symbol *symbol =
             symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
                                        Symtab::eVisibilityAny, symbol_idx)) {
-
       Variable::RangeList ranges;
       ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
 

diff  --git a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
index f5a78e5b59a908..170a6d8700516a 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
+++ b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
@@ -254,6 +254,7 @@ class SymbolFileCTF : public lldb_private::SymbolFileCommon {
 
   static constexpr uint16_t g_ctf_magic = 0xcff1;
   static constexpr uint8_t g_ctf_version = 4;
+  static constexpr uint16_t g_ctf_field_threshold = 0x2000;
 };
 } // namespace lldb_private
 

diff  --git a/lldb/test/API/macosx/ctf/Makefile b/lldb/test/API/macosx/ctf/Makefile
index efe1043cc584ab..afe6ab1b5db06b 100644
--- a/lldb/test/API/macosx/ctf/Makefile
+++ b/lldb/test/API/macosx/ctf/Makefile
@@ -28,3 +28,4 @@ a.ctf: a.out.dSYM
 		-R __DWARF,__apple_objc \
 		a.ctf a.ctf
 	rm -rf a.out.dSYM
+	rm -rf test.o

diff  --git a/lldb/test/API/macosx/ctf/TestCTF.py b/lldb/test/API/macosx/ctf/TestCTF.py
index 9f8583bccb7a5b..470d35f74d1d92 100644
--- a/lldb/test/API/macosx/ctf/TestCTF.py
+++ b/lldb/test/API/macosx/ctf/TestCTF.py
@@ -37,6 +37,9 @@ def do_test(self):
 
         symbol_file = self.getBuildArtifact("a.ctf")
 
+        if self.TraceOn():
+            self.runCmd("log enable -v lldb symbol")
+
         self.runCmd("target symbols add {}".format(symbol_file))
         self.expect(
             "target variable foo",
@@ -53,7 +56,6 @@ def do_test(self):
                 "f = 0x0000000000000000",
             ],
         )
-
         self.expect("target variable foo.n.i", substrs=["(MyInt) foo.n.i = 1"])
         self.expect(
             "target variable foo.n.s", substrs=["(const char *) foo.n.s", '"foo"']

diff  --git a/lldb/test/API/macosx/ctf/test.c b/lldb/test/API/macosx/ctf/test.c
index 30be60320c47ff..71433e941c5b45 100644
--- a/lldb/test/API/macosx/ctf/test.c
+++ b/lldb/test/API/macosx/ctf/test.c
@@ -31,8 +31,14 @@ typedef struct MyStruct {
   void (*f)(int);
 } MyStructT;
 
+struct LargeStruct {
+  char buffer[9000];
+  int b;
+};
+
 MyStructT foo;
 struct ForwardDecl *forward;
+struct LargeStruct bar;
 
 void populate(MyInt i) {
   foo.n.i = i;
@@ -45,6 +51,7 @@ void populate(MyInt i) {
   foo.n.e = eOne;
   foo.f = NULL;
   forward = NULL;
+  bar.b = i;
 }
 
 int main(int argc, char** argv) {


        


More information about the lldb-commits mailing list