1
1
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:
Rui Ueyama 2022-04-07 14:19:47 +08:00
parent a151f4180f
commit ba6347996b

View File

@ -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);