mirror of
https://github.com/rui314/mold.git
synced 2024-11-10 19:26:38 +03:00
[ELF] Implement a workaround for libbacktrace
This commit enables mold to work with libbacktrace before 2022-04-06. https://github.com/rui314/mold/issues/402
This commit is contained in:
parent
a151f4180f
commit
ba6347996b
24
compress.cc
24
compress.cc
@ -54,9 +54,33 @@ static std::vector<u8> do_compress(std::string_view input) {
|
|||||||
// on the compression size. +16 for Z_SYNC_FLUSH.
|
// on the compression size. +16 for Z_SYNC_FLUSH.
|
||||||
std::vector<u8> buf(deflateBound(&strm, strm.avail_in) + 16);
|
std::vector<u8> buf(deflateBound(&strm, strm.avail_in) + 16);
|
||||||
|
|
||||||
|
// Compress data. It writes all compressed bytes except the last
|
||||||
|
// partial byte, so up to 7 bits can be held to be written to the
|
||||||
|
// buffer.
|
||||||
strm.avail_out = buf.size();
|
strm.avail_out = buf.size();
|
||||||
strm.next_out = buf.data();
|
strm.next_out = buf.data();
|
||||||
|
CHECK(deflate(&strm, Z_BLOCK));
|
||||||
|
|
||||||
|
// This is a workaround for libbacktrace before 2022-04-06.
|
||||||
|
//
|
||||||
|
// Zlib is a bit stream, and what Z_SYNC_FLUSH does is to write a
|
||||||
|
// three bit value indicating the start of an uncompressed data
|
||||||
|
// block followed by four byte data 00 00 ff ff which indicates that
|
||||||
|
// the length of the block is zero. libbacktrace uses its own zlib
|
||||||
|
// inflate routine, and it had a bug that if that particular three
|
||||||
|
// bit value happens to end at a byte boundary, it accidentally
|
||||||
|
// skipped the next byte.
|
||||||
|
//
|
||||||
|
// In order to avoid triggering that bug, we should avoid calling
|
||||||
|
// deflate() with Z_SYNC_FLUSH if the current bit position is 5.
|
||||||
|
// If it's 5, we insert an empty block consisting of 10 bits so
|
||||||
|
// that the bit position is 7 in the next byte.
|
||||||
|
//
|
||||||
|
// https://github.com/ianlancetaylor/libbacktrace/pull/87
|
||||||
|
int nbits;
|
||||||
|
deflatePending(&strm, Z_NULL, &nbits);
|
||||||
|
if (nbits == 5)
|
||||||
|
CHECK(deflatePrime(&strm, 10, 2));
|
||||||
CHECK(deflate(&strm, Z_SYNC_FLUSH));
|
CHECK(deflate(&strm, Z_SYNC_FLUSH));
|
||||||
|
|
||||||
assert(strm.avail_out > 0);
|
assert(strm.avail_out > 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user