9#include "lldb/Host/Config.h"
10#include "llvm/ADT/StringRef.h"
11#include "llvm/Support/Error.h"
23llvm::Expected<uint64_t>
25 llvm_unreachable(
"lzma::getUncompressedSize is unavailable");
28llvm::Error
uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
30 llvm_unreachable(
"lzma::uncompress is unavailable");
37static const char *convertLZMACodeToString(lzma_ret Code) {
40 return "lzma error: LZMA_STREAM_END";
42 return "lzma error: LZMA_NO_CHECK";
43 case LZMA_UNSUPPORTED_CHECK:
44 return "lzma error: LZMA_UNSUPPORTED_CHECK";
46 return "lzma error: LZMA_GET_CHECK";
48 return "lzma error: LZMA_MEM_ERROR";
49 case LZMA_MEMLIMIT_ERROR:
50 return "lzma error: LZMA_MEMLIMIT_ERROR";
51 case LZMA_FORMAT_ERROR:
52 return "lzma error: LZMA_FORMAT_ERROR";
53 case LZMA_OPTIONS_ERROR:
54 return "lzma error: LZMA_OPTIONS_ERROR";
56 return "lzma error: LZMA_DATA_ERROR";
58 return "lzma error: LZMA_BUF_ERROR";
60 return "lzma error: LZMA_PROG_ERROR";
62 llvm_unreachable(
"unknown or unexpected lzma status code");
66llvm::Expected<uint64_t>
68 lzma_stream_flags opts{};
69 if (InputBuffer.size() < LZMA_STREAM_HEADER_SIZE) {
70 return llvm::createStringError(
71 llvm::inconvertibleErrorCode(),
72 "size of xz-compressed blob (%lu bytes) is smaller than the "
73 "LZMA_STREAM_HEADER_SIZE (%lu bytes)",
74 InputBuffer.size(), LZMA_STREAM_HEADER_SIZE);
78 lzma_ret xzerr = lzma_stream_footer_decode(
79 &opts, InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE).data());
80 if (xzerr != LZMA_OK) {
81 return llvm::createStringError(llvm::inconvertibleErrorCode(),
82 "lzma_stream_footer_decode()=%s",
83 convertLZMACodeToString(xzerr));
85 if (InputBuffer.size() < (opts.backward_size + LZMA_STREAM_HEADER_SIZE)) {
86 return llvm::createStringError(
87 llvm::inconvertibleErrorCode(),
88 "xz-compressed buffer size (%lu bytes) too small (required at "
90 InputBuffer.size(), (opts.backward_size + LZMA_STREAM_HEADER_SIZE));
97 xzerr = lzma_index_buffer_decode(
98 &xzindex, &memlimit,
nullptr,
99 InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE + opts.backward_size)
101 &inpos, InputBuffer.size());
102 if (xzerr != LZMA_OK) {
103 return llvm::createStringError(llvm::inconvertibleErrorCode(),
104 "lzma_index_buffer_decode()=%s",
105 convertLZMACodeToString(xzerr));
110 uint64_t uncompressedSize = lzma_index_uncompressed_size(xzindex);
113 lzma_index_end(xzindex,
nullptr);
115 return uncompressedSize;
118llvm::Error
uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
122 if (
auto err = uncompressedSize.takeError())
125 Uncompressed.resize(*uncompressedSize);
131 lzma_ret ret = lzma_stream_buffer_decode(
132 &memlimit, 0,
nullptr, InputBuffer.data(), &inpos, InputBuffer.size(),
133 Uncompressed.data(), &outpos, Uncompressed.size());
134 if (ret != LZMA_OK) {
135 return llvm::createStringError(llvm::inconvertibleErrorCode(),
136 "lzma_stream_buffer_decode()=%s",
137 convertLZMACodeToString(ret));
140 return llvm::Error::success();
llvm::Expected< uint64_t > getUncompressedSize(llvm::ArrayRef< uint8_t > InputBuffer)
llvm::Error uncompress(llvm::ArrayRef< uint8_t > InputBuffer, llvm::SmallVectorImpl< uint8_t > &Uncompressed)
A class that represents a running process on the host machine.