kwk updated this revision to Diff 218297.
kwk marked 3 inline comments as done.
kwk added a comment.
- Moved .symtab add/replace to OBjectFileELF::CreateSections
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66791/new/
https://reviews.llvm.org/D66791
Files:
lldb/include/lldb/Host/LZMA.h
lldb/packages/Python/lldbsuite/test/decorators.py
lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/Makefile
lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/TestMiniDebugInfo.py
lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/main.c
lldb/packages/Python/lldbsuite/test/make/Makefile.rules
lldb/source/API/SBDebugger.cpp
lldb/source/Host/CMakeLists.txt
lldb/source/Host/common/LZMA.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
lldb/test/CMakeLists.txt
llvm/CMakeLists.txt
Index: llvm/CMakeLists.txt
===================================================================
--- llvm/CMakeLists.txt
+++ llvm/CMakeLists.txt
@@ -50,6 +50,8 @@
VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}
LANGUAGES C CXX ASM)
+include(CMakeDependentOption)
+
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type selected, default to Debug")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type (default Debug)" FORCE)
@@ -345,6 +347,18 @@
option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON)
+find_package(LibLZMA)
+cmake_dependent_option(LLVM_ENABLE_LZMA "Support LZMA compression" ON "LIBLZMA_FOUND" OFF)
+set(LLVM_LIBLZMA_LIBRARIES)
+if (LLVM_ENABLE_LZMA)
+ if (LIBLZMA_FOUND)
+ add_definitions(-DLLVM_ENABLE_LZMA)
+ include_directories(${LIBLZMA_INCLUDE_DIRS})
+ else()
+ message(FATAL_ERROR "LZMA devel package is required when LLVM_ENABLE_LZMA is On.")
+ endif()
+endif()
+
set(LLVM_Z3_INSTALL_DIR "" CACHE STRING "Install directory of the Z3 solver.")
find_package(Z3 4.7.1)
Index: lldb/test/CMakeLists.txt
===================================================================
--- lldb/test/CMakeLists.txt
+++ lldb/test/CMakeLists.txt
@@ -116,6 +116,10 @@
endif()
endif()
+if (LLVM_ENABLE_LZMA)
+ add_dependencies(lldb-test-deps llvm-nm llvm-strip)
+endif()
+
set(LLDB_DOTEST_ARGS ${LLDB_TEST_COMMON_ARGS};${LLDB_TEST_USER_ARGS})
set_property(GLOBAL PROPERTY LLDB_DOTEST_ARGS_PROPERTY ${LLDB_DOTEST_ARGS})
Index: lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
===================================================================
--- lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -67,6 +67,10 @@
if (!obj_file)
return nullptr;
+ std::unique_ptr<SymbolVendorELF> symbol_vendor(
+ new SymbolVendorELF(module_sp));
+ SectionList *module_section_list = module_sp->GetSectionList();
+
lldb_private::UUID uuid = obj_file->GetUUID();
if (!uuid)
return nullptr;
@@ -111,11 +115,9 @@
// have stripped the code sections, etc.
dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
- SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
-
// Get the module unified section list and add our debug sections to
// that.
- SectionList *module_section_list = module_sp->GetSectionList();
+ module_section_list = module_sp->GetSectionList();
SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
static const SectionType g_sections[] = {
@@ -141,7 +143,8 @@
}
symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
- return symbol_vendor;
+
+ return symbol_vendor.release();
}
// PluginInterface protocol
Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
===================================================================
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -154,6 +154,14 @@
void RelocateSection(lldb_private::Section *section) override;
+ /// Takes the .gnu_debugdata and returns the decompressed object file that is
+ /// stored within that section.
+ ///
+ /// \returns either the decompressed object file stored within the
+ /// .gnu_debugdata section or \c nullptr if an error occured or if there's no
+ /// section with that name.
+ std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile();
+
protected:
std::vector<LoadableData>
@@ -383,6 +391,8 @@
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
+
+ std::shared_ptr<ObjectFileELF> m_gnuDebugDataObjectFile;
};
#endif // liblldb_ObjectFileELF_h_
Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/LZMA.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
@@ -1842,6 +1843,83 @@
// unified section list.
if (GetType() != eTypeDebugInfo)
unified_section_list = *m_sections_up;
+
+ // If there's a .gnu_debugdata section, we'll try to read the .symtab that's
+ // embedded in there and replace the one in the original object file (if any).
+ // If there's none in the orignal object file, we add it to it.
+ SectionList *module_section_list = GetModule()->GetSectionList();
+ if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) {
+ if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
+ if (SectionSP symtab_section_sp =
+ gdd_objfile_section_list->FindSectionByType(
+ eSectionTypeELFSymbolTable, true)) {
+ SectionSP module_section_sp = module_section_list->FindSectionByType(
+ eSectionTypeELFSymbolTable, true);
+ if (module_section_sp)
+ module_section_list->ReplaceSection(module_section_sp->GetID(),
+ symtab_section_sp);
+ else
+ module_section_list->AddSection(symtab_section_sp);
+ }
+ }
+ }
+}
+
+std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
+ if (m_gnuDebugDataObjectFile != nullptr)
+ return m_gnuDebugDataObjectFile;
+
+ SectionSP section =
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"));
+ if (!section)
+ return nullptr;
+
+ if (!lldb_private::lzma::isAvailable()) {
+ GetModule()->ReportWarning(
+ "No LZMA support found for reading .gnu_debugdata section");
+ return nullptr;
+ }
+
+ // Determine size of uncompressed data
+ DataExtractor data;
+ section->GetSectionData(data);
+ uint64_t uncompressedSize = 0;
+ auto err = lldb_private::lzma::getUncompressedSize(data.GetDataStart(), data.GetByteSize(), uncompressedSize);
+ if (err) {
+ GetModule()->ReportWarning(
+ "Failed to get size of uncompressed LZMA buffer from section %s: %s",
+ section->GetName().AsCString(), Status(std::move(err)).AsCString());
+ return nullptr;
+ }
+
+ // Uncompress into large enough buffer
+ std::vector<uint8_t> uncompressedData(uncompressedSize);
+ err =
+ lldb_private::lzma::uncompress(data.GetDataStart(), data.GetByteSize(),
+ uncompressedData.data(), uncompressedSize);
+ if (err) {
+ GetModule()->ReportWarning(
+ "An error occured while decompression the section %s: %s",
+ section->GetName().AsCString(), Status(std::move(err)).AsCString());
+ return nullptr;
+ }
+
+ // Construct ObjectFileELF object from decompressed buffer
+ DataBufferSP gdd_data_buf(
+ new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
+ auto fspec = GetFileSpec().CopyByAppendingPathComponent(
+ llvm::StringRef("gnu_debugdata"));
+ m_gnuDebugDataObjectFile.reset(new ObjectFileELF(
+ GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
+
+ // This line is essential; otherwise a breakpoint can be set but not hit.
+ m_gnuDebugDataObjectFile->SetType(ObjectFile::eTypeDebugInfo);
+
+ ArchSpec spec = m_gnuDebugDataObjectFile->GetArchitecture();
+ if (spec && m_gnuDebugDataObjectFile->SetModulesArchitecture(spec))
+ return m_gnuDebugDataObjectFile;
+
+ return nullptr;
}
// Find the arm/aarch64 mapping symbol character in the given symbol name.
@@ -2649,19 +2727,25 @@
// while the reverse is not necessarily true.
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. If both, .symtab
+ // and .dynsym exist, we load both. And if only .dymsym exists, we load it
+ // alone.
+ auto 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
Index: lldb/source/Host/common/LZMA.cpp
===================================================================
--- /dev/null
+++ lldb/source/Host/common/LZMA.cpp
@@ -0,0 +1,156 @@
+//===--- Compression.cpp - Compression implementation ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+#ifdef LLVM_ENABLE_LZMA
+#include <lzma.h>
+#endif // LLVM_ENABLE_LZMA
+
+namespace lldb_private {
+
+namespace lzma {
+
+#ifndef LLVM_ENABLE_LZMA
+bool isAvailable() { return false; }
+llvm::Error getUncompressedSize(const uint8_t *compressedBuffer,
+ uint64_t compressedBufferSize,
+ uint64_t &uncompressedSize) {
+ llvm_unreachable("lzma::getUncompressedSize is unavailable");
+}
+
+llvm::Error uncompress(const uint8_t *compressedBuffer,
+ uint64_t compressedBufferSize, uint8_t *uncompressedData,
+ uint64_t uncompressedSize) {
+ llvm_unreachable("lzma::uncompress is unavailable");
+}
+
+#else // LLVM_ENABLE_LZMA
+
+bool isAvailable() { return true; }
+
+static llvm::StringRef convertLZMACodeToString(lzma_ret Code) {
+ switch (Code) {
+ case LZMA_STREAM_END:
+ return "lzma error: LZMA_STREAM_END";
+ case LZMA_NO_CHECK:
+ return "lzma error: LZMA_NO_CHECK";
+ case LZMA_UNSUPPORTED_CHECK:
+ return "lzma error: LZMA_UNSUPPORTED_CHECK";
+ case LZMA_GET_CHECK:
+ return "lzma error: LZMA_GET_CHECK";
+ case LZMA_MEM_ERROR:
+ return "lzma error: LZMA_MEM_ERROR";
+ case LZMA_MEMLIMIT_ERROR:
+ return "lzma error: LZMA_MEMLIMIT_ERROR";
+ case LZMA_FORMAT_ERROR:
+ return "lzma error: LZMA_FORMAT_ERROR";
+ case LZMA_OPTIONS_ERROR:
+ return "lzma error: LZMA_OPTIONS_ERROR";
+ case LZMA_DATA_ERROR:
+ return "lzma error: LZMA_DATA_ERROR";
+ case LZMA_BUF_ERROR:
+ return "lzma error: LZMA_BUF_ERROR";
+ case LZMA_PROG_ERROR:
+ return "lzma error: LZMA_PROG_ERROR";
+ default:
+ llvm_unreachable("unknown or unexpected lzma status code");
+ }
+}
+
+llvm::Error getUncompressedSize(const uint8_t *compressedBuffer,
+ uint64_t compressedBufferSize,
+ uint64_t &uncompressedSize) {
+ if (!compressedBuffer || compressedBufferSize == 0) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "address (%p) or size (%lu) of xz-compressed blob cannot be 0",
+ compressedBuffer, compressedBufferSize);
+ }
+
+ auto opts = lzma_stream_flags{};
+ if (compressedBufferSize < LZMA_STREAM_HEADER_SIZE) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "size of xz-compressed blob ({0} bytes) is smaller than the "
+ "LZMA_STREAM_HEADER_SIZE ({1} bytes)",
+ compressedBufferSize, LZMA_STREAM_HEADER_SIZE);
+ }
+
+ // Decode xz footer.
+ auto xzerr = lzma_stream_footer_decode(
+ &opts, compressedBuffer + compressedBufferSize - LZMA_STREAM_HEADER_SIZE);
+ if (xzerr != LZMA_OK) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "lzma_stream_footer_decode()={%s}",
+ convertLZMACodeToString(xzerr).data());
+ }
+ if (compressedBufferSize < (opts.backward_size + LZMA_STREAM_HEADER_SIZE)) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "xz-compressed buffer size ({%lu} bytes) too small (required at "
+ "least {%lu} bytes) ",
+ compressedBufferSize, (opts.backward_size + LZMA_STREAM_HEADER_SIZE));
+ }
+
+ // Decode xz index.
+ lzma_index *xzindex;
+ uint64_t memlimit(UINT64_MAX);
+ size_t inpos = 0;
+ xzerr =
+ lzma_index_buffer_decode(&xzindex, &memlimit, nullptr,
+ compressedBuffer + compressedBufferSize -
+ LZMA_STREAM_HEADER_SIZE - opts.backward_size,
+ &inpos, compressedBufferSize);
+ if (xzerr != LZMA_OK) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "lzma_index_buffer_decode()={%s}",
+ convertLZMACodeToString(xzerr).data());
+ }
+
+ // Get size of uncompressed file to construct an in-memory buffer of the
+ // same size on the calling end (if needed).
+ uncompressedSize = lzma_index_uncompressed_size(xzindex);
+
+ // Deallocate xz index as it is no longer needed.
+ lzma_index_end(xzindex, nullptr);
+
+ return llvm::Error::success();
+}
+
+llvm::Error uncompress(const uint8_t *compressedBuffer,
+ uint64_t compressedBufferSize, uint8_t *uncompressedData,
+ uint64_t uncompressedSize) {
+ if (!compressedBuffer || compressedBufferSize == 0) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "address (%p) or size (%lu) of xz-compressed blob cannot be 0",
+ compressedBuffer, compressedBufferSize);
+ }
+
+ // Decompress xz buffer to buffer.
+ uint64_t memlimit(UINT64_MAX);
+ size_t inpos = 0;
+ inpos = 0;
+ size_t outpos = 0;
+ auto xzerr = lzma_stream_buffer_decode(
+ &memlimit, 0, nullptr, compressedBuffer, &inpos, compressedBufferSize,
+ uncompressedData, &outpos, uncompressedSize);
+ if (xzerr != LZMA_OK) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "lzma_stream_buffer_decode()={%s}",
+ convertLZMACodeToString(xzerr).data());
+ }
+
+ return llvm::Error::success();
+}
+#endif // LLVM_ENABLE_LZMA
+
+} // end of namespace lzma
+} // namespace lldb_private
Index: lldb/source/Host/CMakeLists.txt
===================================================================
--- lldb/source/Host/CMakeLists.txt
+++ lldb/source/Host/CMakeLists.txt
@@ -29,6 +29,7 @@
common/HostProcess.cpp
common/HostThread.cpp
common/LockFileBase.cpp
+ common/LZMA.cpp
common/MainLoop.cpp
common/MonitoringProcessLauncher.cpp
common/NativeProcessProtocol.cpp
@@ -157,6 +158,9 @@
if (NOT LLDB_DISABLE_LIBEDIT)
list(APPEND EXTRA_LIBS ${libedit_LIBRARIES})
endif()
+if (LLVM_ENABLE_LZMA)
+ list(APPEND EXTRA_LIBS ${LIBLZMA_LIBRARIES})
+endif()
if (NOT LLDB_DISABLE_LIBEDIT)
list(APPEND LLDB_LIBEDIT_LIBS ${libedit_LIBRARIES})
Index: lldb/source/API/SBDebugger.cpp
===================================================================
--- lldb/source/API/SBDebugger.cpp
+++ lldb/source/API/SBDebugger.cpp
@@ -40,6 +40,7 @@
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Host/XML.h"
+#include "lldb/Host/LZMA.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionArgParser.h"
@@ -624,6 +625,9 @@
AddBoolConfigEntry(
*config_up, "xml", XMLDocument::XMLEnabled(),
"A boolean value that indicates if XML support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "lzma", lldb_private::lzma::isAvailable(),
+ "A boolean value that indicates if LZMA support is enabled in LLDB");
AddLLVMTargets(*config_up);
SBStructuredData data;
Index: lldb/packages/Python/lldbsuite/test/make/Makefile.rules
===================================================================
--- lldb/packages/Python/lldbsuite/test/make/Makefile.rules
+++ lldb/packages/Python/lldbsuite/test/make/Makefile.rules
@@ -388,6 +388,8 @@
endif
OBJCOPY ?= $(call replace_cc_with,objcopy)
+ LLVMNM ?= $(call replace_cc_with,llvm-nm)
+ LLVMSTRIP ?= $(call replace_cc_with,llvm-strip)
ARCHIVER ?= $(call replace_cc_with,ar)
override AR = $(ARCHIVER)
endif
Index: lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/main.c
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/main.c
@@ -0,0 +1,6 @@
+int multiplyByThree(int num) { return num * 3; }
+
+int main(int argc, char *argv[]) {
+ (void)argv;
+ return multiplyByThree(argc);
+}
Index: lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/TestMiniDebugInfo.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/TestMiniDebugInfo.py
@@ -0,0 +1,37 @@
+""" Testing debugging of a binary with "mini debuginfo" in .gnu_debugdata section. """
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestMinidebugInfo(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ TestBase.setUp(self)
+
+ @no_debug_info_test # Prevent the genaration of the dwarf version of this test
+ @add_test_categories(["dwo"])
+ @skipUnlessPlatform(["linux"])
+ @skipIfLzmaSupportMissing
+ def test_mini_debug_info(self):
+ """Test that we can set and hit a breakpoint on a symbol from .gnu_debugdata."""
+
+ self.build()
+ exe = self.getBuildArtifact("binary")
+
+ self.target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ main_bp = self.target.BreakpointCreateByName("multiplyByThree", "binary")
+ self.assertTrue(main_bp, VALID_BREAKPOINT)
+
+ self.process = self.target.LaunchSimple(
+ None, None, self.get_process_working_directory())
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ self.assertTrue(self.process.GetState() == lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
Index: lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/linux/minidebuginfo/Makefile
@@ -0,0 +1,55 @@
+LEVEL = ../../make
+C_SOURCES := main.c
+
+all: clean binary
+
+.PHONY: binary
+binary: a.out
+ $(RM) -r $@
+ cp a.out binary
+
+ # The following section is adapted from GDB's official documentation:
+ # http://sourceware.org/gdb/current/onlinedocs/gdb/MiniDebugInfo.html#MiniDebugInfo
+
+ # Extract the dynamic symbols from the main binary, there is no need
+ # to also have these in the normal symbol table.
+ $(LLVMNM) -D binary --format=posix --defined-only \
+ | awk '{ print $$1 }' | sort > dynsyms
+
+ # Extract all the text (i.e. function) symbols from the debuginfo.
+ # (Note that we actually also accept "D" symbols, for the benefit
+ # of platforms like PowerPC64 that use function descriptors.)
+ $(LLVMNM) binary --format=posix --defined-only \
+ | awk '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' \
+ | sort > funcsyms
+
+ # Keep all the function symbols not already in the dynamic symbol
+ # table.
+ comm -13 dynsyms funcsyms > keep_symbols
+
+ # Separate full debug info into debug binary.
+ $(OBJCOPY) --only-keep-debug binary debug
+
+ # Copy the full debuginfo, keeping only a minimal set of symbols and
+ # removing some unnecessary sections.
+ $(OBJCOPY) -S --remove-section .gdb_index --remove-section .comment \
+ --keep-symbols=keep_symbols debug mini_debuginfo
+
+ # Drop the full debug info from the original binary.
+ $(LLVMSTRIP) --strip-all -R .comment binary
+
+ # Inject the compressed data into the .gnu_debugdata section of the
+ # original binary.
+ xz --keep mini_debuginfo
+ $(OBJCOPY) --add-section .gnu_debugdata=mini_debuginfo.xz binary
+
+clean::
+ $(RM) -r mini_debuginfo \
+ mini_debuginfo.xz \
+ binary \
+ debug \
+ keep_symbols \
+ funcsyms \
+ dynsyms
+
+include $(LEVEL)/Makefile.rules
Index: lldb/packages/Python/lldbsuite/test/decorators.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/decorators.py
+++ lldb/packages/Python/lldbsuite/test/decorators.py
@@ -791,6 +791,14 @@
have_xml = xml.GetValueForKey("value").GetBooleanValue(fail_value)
return unittest2.skipIf(not have_xml, "requires xml support")(func)
+def skipIfLzmaSupportMissing(func):
+ config = lldb.SBDebugger.GetBuildConfiguration()
+ lzma = config.GetValueForKey("lzma")
+
+ fail_value = True # More likely to notice if something goes wrong
+ have_lzma = lzma.GetValueForKey("value").GetBooleanValue(fail_value)
+ return unittest2.skipIf(not have_lzma, "requires lzma support")(func)
+
def skipIfLLVMTargetMissing(target):
config = lldb.SBDebugger.GetBuildConfiguration()
targets = config.GetValueForKey("targets").GetValueForKey("value")
Index: lldb/include/lldb/Host/LZMA.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Host/LZMA.h
@@ -0,0 +1,36 @@
+//===-- LZMA.h --------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_LZMA_h_
+#define liblldb_Host_LZMA_h_
+
+#include <vector>
+
+namespace llvm {
+class Error;
+} // End of namespace llvm
+
+namespace lldb_private {
+
+namespace lzma {
+
+bool isAvailable();
+
+llvm::Error getUncompressedSize(const uint8_t *compressedBuffer,
+ uint64_t compressedBufferSize,
+ uint64_t &uncompressedSize);
+
+llvm::Error uncompress(const uint8_t *compressedBuffer,
+ uint64_t compressedBufferSize, uint8_t *uncompressedData,
+ uint64_t uncompressedSize);
+
+} // End of namespace lzma
+
+} // End of namespace lldb_private
+
+#endif // liblldb_Host_LZMA_h_
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits