annotate lldb/source/Host/common/LZMA.cpp @ 173:0572611fdcc8 llvm10 llvm12

reorgnization done
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 11:55:54 +0900
parents 1d019706d866
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===-- LZMA.cpp ----------------------------------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "lldb/Host/Config.h"
anatofuz
parents:
diff changeset
10 #include "llvm/ADT/StringRef.h"
anatofuz
parents:
diff changeset
11 #include "llvm/Support/Error.h"
anatofuz
parents:
diff changeset
12
anatofuz
parents:
diff changeset
13 #if LLDB_ENABLE_LZMA
anatofuz
parents:
diff changeset
14 #include <lzma.h>
anatofuz
parents:
diff changeset
15 #endif // LLDB_ENABLE_LZMA
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 namespace lldb_private {
anatofuz
parents:
diff changeset
18
anatofuz
parents:
diff changeset
19 namespace lzma {
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 #if !LLDB_ENABLE_LZMA
anatofuz
parents:
diff changeset
22 bool isAvailable() { return false; }
anatofuz
parents:
diff changeset
23 llvm::Expected<uint64_t>
anatofuz
parents:
diff changeset
24 getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) {
anatofuz
parents:
diff changeset
25 llvm_unreachable("lzma::getUncompressedSize is unavailable");
anatofuz
parents:
diff changeset
26 }
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
anatofuz
parents:
diff changeset
29 llvm::SmallVectorImpl<uint8_t> &Uncompressed) {
anatofuz
parents:
diff changeset
30 llvm_unreachable("lzma::uncompress is unavailable");
anatofuz
parents:
diff changeset
31 }
anatofuz
parents:
diff changeset
32
anatofuz
parents:
diff changeset
33 #else // LLDB_ENABLE_LZMA
anatofuz
parents:
diff changeset
34
anatofuz
parents:
diff changeset
35 bool isAvailable() { return true; }
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 static const char *convertLZMACodeToString(lzma_ret Code) {
anatofuz
parents:
diff changeset
38 switch (Code) {
anatofuz
parents:
diff changeset
39 case LZMA_STREAM_END:
anatofuz
parents:
diff changeset
40 return "lzma error: LZMA_STREAM_END";
anatofuz
parents:
diff changeset
41 case LZMA_NO_CHECK:
anatofuz
parents:
diff changeset
42 return "lzma error: LZMA_NO_CHECK";
anatofuz
parents:
diff changeset
43 case LZMA_UNSUPPORTED_CHECK:
anatofuz
parents:
diff changeset
44 return "lzma error: LZMA_UNSUPPORTED_CHECK";
anatofuz
parents:
diff changeset
45 case LZMA_GET_CHECK:
anatofuz
parents:
diff changeset
46 return "lzma error: LZMA_GET_CHECK";
anatofuz
parents:
diff changeset
47 case LZMA_MEM_ERROR:
anatofuz
parents:
diff changeset
48 return "lzma error: LZMA_MEM_ERROR";
anatofuz
parents:
diff changeset
49 case LZMA_MEMLIMIT_ERROR:
anatofuz
parents:
diff changeset
50 return "lzma error: LZMA_MEMLIMIT_ERROR";
anatofuz
parents:
diff changeset
51 case LZMA_FORMAT_ERROR:
anatofuz
parents:
diff changeset
52 return "lzma error: LZMA_FORMAT_ERROR";
anatofuz
parents:
diff changeset
53 case LZMA_OPTIONS_ERROR:
anatofuz
parents:
diff changeset
54 return "lzma error: LZMA_OPTIONS_ERROR";
anatofuz
parents:
diff changeset
55 case LZMA_DATA_ERROR:
anatofuz
parents:
diff changeset
56 return "lzma error: LZMA_DATA_ERROR";
anatofuz
parents:
diff changeset
57 case LZMA_BUF_ERROR:
anatofuz
parents:
diff changeset
58 return "lzma error: LZMA_BUF_ERROR";
anatofuz
parents:
diff changeset
59 case LZMA_PROG_ERROR:
anatofuz
parents:
diff changeset
60 return "lzma error: LZMA_PROG_ERROR";
anatofuz
parents:
diff changeset
61 default:
anatofuz
parents:
diff changeset
62 llvm_unreachable("unknown or unexpected lzma status code");
anatofuz
parents:
diff changeset
63 }
anatofuz
parents:
diff changeset
64 }
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 llvm::Expected<uint64_t>
anatofuz
parents:
diff changeset
67 getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) {
anatofuz
parents:
diff changeset
68 lzma_stream_flags opts{};
anatofuz
parents:
diff changeset
69 if (InputBuffer.size() < LZMA_STREAM_HEADER_SIZE) {
anatofuz
parents:
diff changeset
70 return llvm::createStringError(
anatofuz
parents:
diff changeset
71 llvm::inconvertibleErrorCode(),
anatofuz
parents:
diff changeset
72 "size of xz-compressed blob (%lu bytes) is smaller than the "
anatofuz
parents:
diff changeset
73 "LZMA_STREAM_HEADER_SIZE (%lu bytes)",
anatofuz
parents:
diff changeset
74 InputBuffer.size(), LZMA_STREAM_HEADER_SIZE);
anatofuz
parents:
diff changeset
75 }
anatofuz
parents:
diff changeset
76
anatofuz
parents:
diff changeset
77 // Decode xz footer.
anatofuz
parents:
diff changeset
78 lzma_ret xzerr = lzma_stream_footer_decode(
anatofuz
parents:
diff changeset
79 &opts, InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE).data());
anatofuz
parents:
diff changeset
80 if (xzerr != LZMA_OK) {
anatofuz
parents:
diff changeset
81 return llvm::createStringError(llvm::inconvertibleErrorCode(),
anatofuz
parents:
diff changeset
82 "lzma_stream_footer_decode()=%s",
anatofuz
parents:
diff changeset
83 convertLZMACodeToString(xzerr));
anatofuz
parents:
diff changeset
84 }
anatofuz
parents:
diff changeset
85 if (InputBuffer.size() < (opts.backward_size + LZMA_STREAM_HEADER_SIZE)) {
anatofuz
parents:
diff changeset
86 return llvm::createStringError(
anatofuz
parents:
diff changeset
87 llvm::inconvertibleErrorCode(),
anatofuz
parents:
diff changeset
88 "xz-compressed buffer size (%lu bytes) too small (required at "
anatofuz
parents:
diff changeset
89 "least %lu bytes) ",
anatofuz
parents:
diff changeset
90 InputBuffer.size(), (opts.backward_size + LZMA_STREAM_HEADER_SIZE));
anatofuz
parents:
diff changeset
91 }
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 // Decode xz index.
anatofuz
parents:
diff changeset
94 lzma_index *xzindex;
anatofuz
parents:
diff changeset
95 uint64_t memlimit(UINT64_MAX);
anatofuz
parents:
diff changeset
96 size_t inpos = 0;
anatofuz
parents:
diff changeset
97 xzerr = lzma_index_buffer_decode(
anatofuz
parents:
diff changeset
98 &xzindex, &memlimit, nullptr,
anatofuz
parents:
diff changeset
99 InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE + opts.backward_size)
anatofuz
parents:
diff changeset
100 .data(),
anatofuz
parents:
diff changeset
101 &inpos, InputBuffer.size());
anatofuz
parents:
diff changeset
102 if (xzerr != LZMA_OK) {
anatofuz
parents:
diff changeset
103 return llvm::createStringError(llvm::inconvertibleErrorCode(),
anatofuz
parents:
diff changeset
104 "lzma_index_buffer_decode()=%s",
anatofuz
parents:
diff changeset
105 convertLZMACodeToString(xzerr));
anatofuz
parents:
diff changeset
106 }
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 // Get size of uncompressed file to construct an in-memory buffer of the
anatofuz
parents:
diff changeset
109 // same size on the calling end (if needed).
anatofuz
parents:
diff changeset
110 uint64_t uncompressedSize = lzma_index_uncompressed_size(xzindex);
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 // Deallocate xz index as it is no longer needed.
anatofuz
parents:
diff changeset
113 lzma_index_end(xzindex, nullptr);
anatofuz
parents:
diff changeset
114
anatofuz
parents:
diff changeset
115 return uncompressedSize;
anatofuz
parents:
diff changeset
116 }
anatofuz
parents:
diff changeset
117
anatofuz
parents:
diff changeset
118 llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
anatofuz
parents:
diff changeset
119 llvm::SmallVectorImpl<uint8_t> &Uncompressed) {
anatofuz
parents:
diff changeset
120 llvm::Expected<uint64_t> uncompressedSize = getUncompressedSize(InputBuffer);
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 if (auto err = uncompressedSize.takeError())
anatofuz
parents:
diff changeset
123 return err;
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 Uncompressed.resize(*uncompressedSize);
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 // Decompress xz buffer to buffer.
anatofuz
parents:
diff changeset
128 uint64_t memlimit = UINT64_MAX;
anatofuz
parents:
diff changeset
129 size_t inpos = 0;
anatofuz
parents:
diff changeset
130 size_t outpos = 0;
anatofuz
parents:
diff changeset
131 lzma_ret ret = lzma_stream_buffer_decode(
anatofuz
parents:
diff changeset
132 &memlimit, 0, nullptr, InputBuffer.data(), &inpos, InputBuffer.size(),
anatofuz
parents:
diff changeset
133 Uncompressed.data(), &outpos, Uncompressed.size());
anatofuz
parents:
diff changeset
134 if (ret != LZMA_OK) {
anatofuz
parents:
diff changeset
135 return llvm::createStringError(llvm::inconvertibleErrorCode(),
anatofuz
parents:
diff changeset
136 "lzma_stream_buffer_decode()=%s",
anatofuz
parents:
diff changeset
137 convertLZMACodeToString(ret));
anatofuz
parents:
diff changeset
138 }
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 return llvm::Error::success();
anatofuz
parents:
diff changeset
141 }
anatofuz
parents:
diff changeset
142
anatofuz
parents:
diff changeset
143 #endif // LLDB_ENABLE_LZMA
anatofuz
parents:
diff changeset
144
anatofuz
parents:
diff changeset
145 } // end of namespace lzma
anatofuz
parents:
diff changeset
146 } // namespace lldb_private