This revision was automatically updated to reflect the committed changes.
JDevlieghere marked an inline comment as done.
Closed by commit rG0e285a13eb7f: [lldb] Support compressed CTF (authored by
JDevlieghere).
Herald added a project: LLDB.
Changed prior to commit:
https://reviews.llvm.org/D155221?vs=540103&id=540194#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D155221/new/
https://reviews.llvm.org/D155221
Files:
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
Index: lldb/test/API/macosx/ctf/TestCTF.py
===================================================================
--- lldb/test/API/macosx/ctf/TestCTF.py
+++ lldb/test/API/macosx/ctf/TestCTF.py
@@ -18,12 +18,18 @@
return "llvm-objcopy not found in environment"
return None
- @skipTestIfFn(no_ctf_convert)
- @skipTestIfFn(no_objcopy)
- @skipUnlessDarwin
def test(self):
self.build()
+ self.do_test()
+
+ def test_compressed(self):
+ self.build(dictionary={"COMPRESS_CTF": "YES"})
+ self.do_test()
+ @skipTestIfFn(no_ctf_convert)
+ @skipTestIfFn(no_objcopy)
+ @skipUnlessDarwin
+ def do_test(self):
lldbutil.run_to_name_breakpoint(self, "printf")
symbol_file = self.getBuildArtifact("a.ctf")
Index: lldb/test/API/macosx/ctf/Makefile
===================================================================
--- lldb/test/API/macosx/ctf/Makefile
+++ lldb/test/API/macosx/ctf/Makefile
@@ -1,21 +1,30 @@
C_SOURCES := test.c
MAKE_DSYM := YES
+ifeq "$(COMPRESS_CTF)" "YES"
+ COMPRESS := -c
+else
+ COMPRESS :=
+endif
+
all: a.out a.ctf
include Makefile.rules
a.ctf: a.out.dSYM
- ctfconvert -l a -o a.ctf a.out.dSYM/Contents/Resources/DWARF/a.out
- $(OBJCOPY) \
- -R __DWARF,__debug_line \
- -R __DWARF,__debug_aranges \
- -R __DWARF,__debug_info \
- -R __DWARF,__debug_abbrev \
- -R __DWARF,__debug_str \
- -R __DWARF,__apple_names \
- -R __DWARF,__apple_namespac \
- -R __DWARF,__apple_types \
- -R __DWARF,__apple_objc \
- a.ctf a.ctf
- rm -rf a.out.dSYM
+ ctfconvert $(COMPRESS) \
+ -l a \
+ -o a.ctf \
+ a.out.dSYM/Contents/Resources/DWARF/a.out
+ $(OBJCOPY) \
+ -R __DWARF,__debug_line \
+ -R __DWARF,__debug_aranges \
+ -R __DWARF,__debug_info \
+ -R __DWARF,__debug_abbrev \
+ -R __DWARF,__debug_str \
+ -R __DWARF,__apple_names \
+ -R __DWARF,__apple_namespac \
+ -R __DWARF,__apple_types \
+ -R __DWARF,__apple_objc \
+ a.ctf a.ctf
+ rm -rf a.out.dSYM
Index: lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
+++ lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
@@ -155,6 +155,13 @@
};
private:
+ enum Flags : uint32_t {
+ eFlagCompress = (1u << 0),
+ eFlagNewFuncInfo = (1u << 1),
+ eFlagIdxSorted = (1u << 2),
+ eFlagDynStr = (1u << 3),
+ };
+
enum IntEncoding : uint32_t {
eSigned = 0x1,
eChar = 0x2,
@@ -270,6 +277,13 @@
uint32_t fields, uint32_t struct_size);
DataExtractor m_data;
+
+ /// The start offset of the CTF body into m_data. If the body is uncompressed,
+ /// m_data contains the header and the body and the body starts after the
+ /// header. If the body is compressed, m_data only contains the body and the
+ /// offset is zero.
+ lldb::offset_t m_body_offset = 0;
+
TypeSystemClang *m_ast;
lldb::CompUnitSP m_comp_unit_sp;
Index: lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
+++ lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamBuffer.h"
+#include "lldb/Host/Config.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -35,6 +36,10 @@
#include <memory>
#include <optional>
+#if LLVM_ENABLE_ZLIB
+#include <zlib.h>
+#endif
+
using namespace llvm;
using namespace lldb;
using namespace lldb_private;
@@ -129,24 +134,79 @@
LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}",
ctf_header.preamble.version, ctf_header.preamble.flags);
- const lldb::offset_t header_offset = offset;
+ m_body_offset = offset;
+
+ if (ctf_header.preamble.flags & eFlagCompress) {
+ // The body has been compressed with zlib deflate. Header offsets point into
+ // the decompressed data.
+#if LLVM_ENABLE_ZLIB
+ const std::size_t decompressed_size = ctf_header.stroff + ctf_header.strlen;
+ DataBufferSP decompressed_data =
+ std::make_shared<DataBufferHeap>(decompressed_size, 0x0);
+
+ z_stream zstr;
+ memset(&zstr, 0, sizeof(zstr));
+ zstr.next_in = (Bytef *)const_cast<uint8_t *>(m_data.GetDataStart() +
+ sizeof(ctf_header_t));
+ zstr.avail_in = m_data.BytesLeft(offset);
+ zstr.next_out =
+ (Bytef *)const_cast<uint8_t *>(decompressed_data->GetBytes());
+ zstr.avail_out = decompressed_size;
+
+ int rc = inflateInit(&zstr);
+ if (rc != Z_OK) {
+ LLDB_LOG(log, "CTF parsing failed: inflate initialization error: {0}",
+ zError(rc));
+ return false;
+ }
+
+ rc = inflate(&zstr, Z_FINISH);
+ if (rc != Z_STREAM_END) {
+ LLDB_LOG(log, "CTF parsing failed: inflate error: {0}", zError(rc));
+ return false;
+ }
+
+ rc = inflateEnd(&zstr);
+ if (rc != Z_OK) {
+ LLDB_LOG(log, "CTF parsing failed: inflate end error: {0}", zError(rc));
+ return false;
+ }
+
+ if (zstr.total_out != decompressed_size) {
+ LLDB_LOG(log,
+ "CTF parsing failed: decompressed size ({0}) doesn't match "
+ "expected size ([1})",
+ zstr.total_out, decompressed_size);
+ return false;
+ }
+
+ m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(),
+ m_data.GetAddressByteSize());
+ m_body_offset = 0;
+#else
+ LLDB_LOG(
+ log,
+ "CTF parsing failed: data is compressed but no zlib inflate support");
+ return false;
+#endif
+ }
// Validate the header.
- if (!m_data.ValidOffset(header_offset + ctf_header.lbloff)) {
+ if (!m_data.ValidOffset(m_body_offset + ctf_header.lbloff)) {
LLDB_LOG(log,
"CTF parsing failed: invalid label section offset in header: {0}",
ctf_header.lbloff);
return false;
}
- if (!m_data.ValidOffset(header_offset + ctf_header.objtoff)) {
+ if (!m_data.ValidOffset(m_body_offset + ctf_header.objtoff)) {
LLDB_LOG(log,
"CTF parsing failed: invalid object section offset in header: {0}",
ctf_header.objtoff);
return false;
}
- if (!m_data.ValidOffset(header_offset + ctf_header.funcoff)) {
+ if (!m_data.ValidOffset(m_body_offset + ctf_header.funcoff)) {
LLDB_LOG(
log,
"CTF parsing failed: invalid function section offset in header: {0}",
@@ -154,14 +214,14 @@
return false;
}
- if (!m_data.ValidOffset(header_offset + ctf_header.typeoff)) {
+ if (!m_data.ValidOffset(m_body_offset + ctf_header.typeoff)) {
LLDB_LOG(log,
"CTF parsing failed: invalid type section offset in header: {0}",
ctf_header.typeoff);
return false;
}
- if (!m_data.ValidOffset(header_offset + ctf_header.stroff)) {
+ if (!m_data.ValidOffset(m_body_offset + ctf_header.stroff)) {
LLDB_LOG(log,
"CTF parsing failed: invalid string section offset in header: {0}",
ctf_header.stroff);
@@ -169,7 +229,7 @@
}
const lldb::offset_t str_end_offset =
- header_offset + ctf_header.stroff + ctf_header.strlen;
+ m_body_offset + ctf_header.stroff + ctf_header.strlen;
if (!m_data.ValidOffset(str_end_offset - 1)) {
LLDB_LOG(log,
"CTF parsing failed: invalid string section length in header: {0}",
@@ -177,7 +237,7 @@
return false;
}
- if (header_offset + ctf_header.stroff + ctf_header.parlabel >
+ if (m_body_offset + ctf_header.stroff + ctf_header.parlabel >
str_end_offset) {
LLDB_LOG(log,
"CTF parsing failed: invalid parent label offset: {0} exceeds end "
@@ -186,7 +246,7 @@
return false;
}
- if (header_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) {
+ if (m_body_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) {
LLDB_LOG(log,
"CTF parsing failed: invalid parent name offset: {0} exceeds end "
"of string section ({1})",
@@ -222,7 +282,7 @@
}
llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const {
- lldb::offset_t offset = sizeof(ctf_header_t) + m_header->stroff + str_offset;
+ lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset;
if (!m_data.ValidOffset(offset))
return "(invalid)";
const char *str = m_data.GetCStr(&offset);
@@ -539,9 +599,8 @@
Log *log = GetLog(LLDBLog::Symbols);
LLDB_LOG(log, "Parsing CTF types");
- lldb::offset_t type_offset = sizeof(ctf_header_t) + m_header->typeoff;
- const lldb::offset_t type_offset_end =
- sizeof(ctf_header_t) + m_header->stroff;
+ lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
+ const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
lldb::user_id_t type_uid = 1;
while (type_offset < type_offset_end) {
@@ -597,9 +656,8 @@
Log *log = GetLog(LLDBLog::Symbols);
LLDB_LOG(log, "Parsing CTF functions");
- lldb::offset_t function_offset = sizeof(ctf_header_t) + m_header->funcoff;
- const lldb::offset_t function_offset_end =
- sizeof(ctf_header_t) + m_header->typeoff;
+ lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
+ const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
uint32_t symbol_idx = 0;
Declaration decl;
@@ -713,9 +771,8 @@
Log *log = GetLog(LLDBLog::Symbols);
LLDB_LOG(log, "Parsing CTF objects");
- lldb::offset_t object_offset = sizeof(ctf_header_t) + m_header->objtoff;
- const lldb::offset_t object_offset_end =
- sizeof(ctf_header_t) + m_header->funcoff;
+ lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
+ const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
uint32_t symbol_idx = 0;
Declaration decl;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits