2014-03-08 06:43:09 +08:00
|
|
|
//===-- llvm/CodeGen/ByteStreamer.h - ByteStreamer class --------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2014-03-08 06:43:09 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains a class that can take bytes that would normally be
|
|
|
|
// streamed via the AsmPrinter.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-14 00:26:38 +08:00
|
|
|
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
|
|
|
|
#define LLVM_LIB_CODEGEN_ASMPRINTER_BYTESTREAMER_H
|
2014-03-08 06:43:09 +08:00
|
|
|
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "DIEHash.h"
|
2014-03-08 06:43:09 +08:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
|
|
|
#include "llvm/MC/MCStreamer.h"
|
2015-03-03 06:02:33 +08:00
|
|
|
#include "llvm/Support/LEB128.h"
|
|
|
|
#include <string>
|
2014-03-08 06:43:09 +08:00
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
class ByteStreamer {
|
2015-08-04 04:12:58 +08:00
|
|
|
protected:
|
|
|
|
~ByteStreamer() = default;
|
|
|
|
ByteStreamer(const ByteStreamer&) = default;
|
|
|
|
ByteStreamer() = default;
|
2014-03-08 06:53:36 +08:00
|
|
|
|
2015-08-04 04:12:58 +08:00
|
|
|
public:
|
2014-03-08 06:43:09 +08:00
|
|
|
// For now we're just handling the calls we need for dwarf emission/hashing.
|
|
|
|
virtual void EmitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
|
2020-02-14 05:26:21 +08:00
|
|
|
virtual void emitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
|
|
|
|
virtual void emitULEB128(uint64_t DWord, const Twine &Comment = "",
|
|
|
|
unsigned PadTo = 0) = 0;
|
2014-03-08 06:43:09 +08:00
|
|
|
};
|
|
|
|
|
2015-08-04 04:12:58 +08:00
|
|
|
class APByteStreamer final : public ByteStreamer {
|
2014-03-08 06:43:09 +08:00
|
|
|
private:
|
|
|
|
AsmPrinter &AP;
|
|
|
|
|
|
|
|
public:
|
|
|
|
APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}
|
2014-03-08 14:31:39 +08:00
|
|
|
void EmitInt8(uint8_t Byte, const Twine &Comment) override {
|
2015-04-25 03:11:51 +08:00
|
|
|
AP.OutStreamer->AddComment(Comment);
|
2018-03-30 07:32:54 +08:00
|
|
|
AP.emitInt8(Byte);
|
2014-03-08 06:43:09 +08:00
|
|
|
}
|
2020-02-14 05:26:21 +08:00
|
|
|
void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
|
2015-04-25 03:11:51 +08:00
|
|
|
AP.OutStreamer->AddComment(Comment);
|
2020-02-14 05:26:21 +08:00
|
|
|
AP.emitSLEB128(DWord);
|
2014-03-08 06:43:09 +08:00
|
|
|
}
|
2020-02-14 05:26:21 +08:00
|
|
|
void emitULEB128(uint64_t DWord, const Twine &Comment,
|
|
|
|
unsigned PadTo) override {
|
2015-04-25 03:11:51 +08:00
|
|
|
AP.OutStreamer->AddComment(Comment);
|
2020-02-14 05:26:21 +08:00
|
|
|
AP.emitULEB128(DWord, nullptr, PadTo);
|
2014-03-08 06:43:09 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-08-04 04:12:58 +08:00
|
|
|
class HashingByteStreamer final : public ByteStreamer {
|
2014-03-08 06:43:09 +08:00
|
|
|
private:
|
|
|
|
DIEHash &Hash;
|
|
|
|
public:
|
|
|
|
HashingByteStreamer(DIEHash &H) : Hash(H) {}
|
2014-03-08 14:31:39 +08:00
|
|
|
void EmitInt8(uint8_t Byte, const Twine &Comment) override {
|
2014-03-08 06:43:09 +08:00
|
|
|
Hash.update(Byte);
|
|
|
|
}
|
2020-02-14 05:26:21 +08:00
|
|
|
void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
|
2014-03-08 06:43:09 +08:00
|
|
|
Hash.addSLEB128(DWord);
|
|
|
|
}
|
2020-02-14 05:26:21 +08:00
|
|
|
void emitULEB128(uint64_t DWord, const Twine &Comment,
|
|
|
|
unsigned PadTo) override {
|
2014-03-08 06:43:09 +08:00
|
|
|
Hash.addULEB128(DWord);
|
|
|
|
}
|
|
|
|
};
|
2015-03-03 06:02:33 +08:00
|
|
|
|
2015-08-04 04:12:58 +08:00
|
|
|
class BufferByteStreamer final : public ByteStreamer {
|
2015-03-03 06:02:33 +08:00
|
|
|
private:
|
|
|
|
SmallVectorImpl<char> &Buffer;
|
2019-10-15 17:21:09 +08:00
|
|
|
std::vector<std::string> &Comments;
|
2015-03-03 06:02:33 +08:00
|
|
|
|
[DebugInfo] Add interface for pre-calculating the size of emitted DWARF
Summary:
DWARF's DW_OP_entry_value operation has two operands; the first is a
ULEB128 operand that specifies the size of the second operand, which is
a DWARF block. This means that we need to be able to pre-calculate and
emit the size of DWARF expressions before emitting them. There is
currently no interface for doing this in DwarfExpression, so this patch
introduces that.
When implementing this I initially thought about running through
DwarfExpression's emission two times; first with a temporary buffer to
emit the expression, in order to being able to calculate the size of
that emitted data. However, DwarfExpression is a quite complex state
machine, so I decided against that, as it seemed like the two runs could
get out of sync, resulting in incorrect size operands. Therefore I have
implemented this in a way that we only have to run DwarfExpression once.
The idea is to emit DWARF to a temporary buffer, for which it is
possible to query the size. The data in the temporary buffer can then be
emitted to DwarfExpression's main output.
In the case of DIEDwarfExpression, a temporary DIE is used. The values
are all allocated using the same BumpPtrAllocator as for all other DIEs,
and the values are then transferred to the real value list. In the case
of DebugLocDwarfExpression, the temporary buffer is implemented using a
BufferByteStreamer which emits to a buffer in the DwarfExpression
object.
Reviewers: aprantl, vsk, NikolaPrica, djtodoro
Reviewed By: aprantl
Subscribers: hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67768
llvm-svn: 374879
2019-10-15 19:14:35 +08:00
|
|
|
public:
|
2018-05-01 23:54:18 +08:00
|
|
|
/// Only verbose textual output needs comments. This will be set to
|
2015-05-21 06:51:27 +08:00
|
|
|
/// true for that case, and false otherwise. If false, comments passed in to
|
|
|
|
/// the emit methods will be ignored.
|
[DebugInfo] Add interface for pre-calculating the size of emitted DWARF
Summary:
DWARF's DW_OP_entry_value operation has two operands; the first is a
ULEB128 operand that specifies the size of the second operand, which is
a DWARF block. This means that we need to be able to pre-calculate and
emit the size of DWARF expressions before emitting them. There is
currently no interface for doing this in DwarfExpression, so this patch
introduces that.
When implementing this I initially thought about running through
DwarfExpression's emission two times; first with a temporary buffer to
emit the expression, in order to being able to calculate the size of
that emitted data. However, DwarfExpression is a quite complex state
machine, so I decided against that, as it seemed like the two runs could
get out of sync, resulting in incorrect size operands. Therefore I have
implemented this in a way that we only have to run DwarfExpression once.
The idea is to emit DWARF to a temporary buffer, for which it is
possible to query the size. The data in the temporary buffer can then be
emitted to DwarfExpression's main output.
In the case of DIEDwarfExpression, a temporary DIE is used. The values
are all allocated using the same BumpPtrAllocator as for all other DIEs,
and the values are then transferred to the real value list. In the case
of DebugLocDwarfExpression, the temporary buffer is implemented using a
BufferByteStreamer which emits to a buffer in the DwarfExpression
object.
Reviewers: aprantl, vsk, NikolaPrica, djtodoro
Reviewed By: aprantl
Subscribers: hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67768
llvm-svn: 374879
2019-10-15 19:14:35 +08:00
|
|
|
const bool GenerateComments;
|
2015-05-21 06:51:27 +08:00
|
|
|
|
2015-03-03 06:02:33 +08:00
|
|
|
BufferByteStreamer(SmallVectorImpl<char> &Buffer,
|
[DebugInfo] Add interface for pre-calculating the size of emitted DWARF
Summary:
DWARF's DW_OP_entry_value operation has two operands; the first is a
ULEB128 operand that specifies the size of the second operand, which is
a DWARF block. This means that we need to be able to pre-calculate and
emit the size of DWARF expressions before emitting them. There is
currently no interface for doing this in DwarfExpression, so this patch
introduces that.
When implementing this I initially thought about running through
DwarfExpression's emission two times; first with a temporary buffer to
emit the expression, in order to being able to calculate the size of
that emitted data. However, DwarfExpression is a quite complex state
machine, so I decided against that, as it seemed like the two runs could
get out of sync, resulting in incorrect size operands. Therefore I have
implemented this in a way that we only have to run DwarfExpression once.
The idea is to emit DWARF to a temporary buffer, for which it is
possible to query the size. The data in the temporary buffer can then be
emitted to DwarfExpression's main output.
In the case of DIEDwarfExpression, a temporary DIE is used. The values
are all allocated using the same BumpPtrAllocator as for all other DIEs,
and the values are then transferred to the real value list. In the case
of DebugLocDwarfExpression, the temporary buffer is implemented using a
BufferByteStreamer which emits to a buffer in the DwarfExpression
object.
Reviewers: aprantl, vsk, NikolaPrica, djtodoro
Reviewed By: aprantl
Subscribers: hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67768
llvm-svn: 374879
2019-10-15 19:14:35 +08:00
|
|
|
std::vector<std::string> &Comments, bool GenerateComments)
|
|
|
|
: Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {
|
|
|
|
}
|
2015-03-03 06:02:33 +08:00
|
|
|
void EmitInt8(uint8_t Byte, const Twine &Comment) override {
|
|
|
|
Buffer.push_back(Byte);
|
2015-05-21 06:51:27 +08:00
|
|
|
if (GenerateComments)
|
|
|
|
Comments.push_back(Comment.str());
|
2015-03-03 06:02:33 +08:00
|
|
|
}
|
2020-02-14 05:26:21 +08:00
|
|
|
void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
|
2015-03-03 06:02:33 +08:00
|
|
|
raw_svector_ostream OSE(Buffer);
|
[DebugInfo] Align comments in debug_loc section
Summary:
This commit updates the BufferByteStreamer, used by DebugLocStream
to buffer bytes/comments to put in the debug_loc section, to
make sure that the Buffer and Comments vectors are synced.
Previously, when an SLEB128 or ULEB128 was emitted together with
a comment, the vectors could be out-of-sync if the LEB encoding
added several entries to the Buffer vectors, while we only added
a single entry to the Comments vector.
The goal with this is to get the comments in the debug_loc
section in the .s file correctly aligned.
Example (using ARM as target):
Instead of
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @ DW_OP_piece
.byte 147 @ 8
.byte 8 @ sub-register DW_OP_regx
.byte 144 @ 257
.byte 129 @ DW_OP_piece
.byte 2 @ 8
.byte 147 @
.byte 8 @
we now get
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
.byte 144 @ sub-register DW_OP_regx
.byte 129 @ 257
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
Reviewers: JDevlieghere, rnk, aprantl
Reviewed By: aprantl
Subscribers: davide, Ka-Ka, uabelho, aemerson, javed.absar, kristof.beyls, llvm-commits, JDevlieghere
Differential Revision: https://reviews.llvm.org/D41763
llvm-svn: 321907
2018-01-06 06:20:30 +08:00
|
|
|
unsigned Length = encodeSLEB128(DWord, OSE);
|
|
|
|
if (GenerateComments) {
|
2015-05-21 06:51:27 +08:00
|
|
|
Comments.push_back(Comment.str());
|
[DebugInfo] Align comments in debug_loc section
Summary:
This commit updates the BufferByteStreamer, used by DebugLocStream
to buffer bytes/comments to put in the debug_loc section, to
make sure that the Buffer and Comments vectors are synced.
Previously, when an SLEB128 or ULEB128 was emitted together with
a comment, the vectors could be out-of-sync if the LEB encoding
added several entries to the Buffer vectors, while we only added
a single entry to the Comments vector.
The goal with this is to get the comments in the debug_loc
section in the .s file correctly aligned.
Example (using ARM as target):
Instead of
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @ DW_OP_piece
.byte 147 @ 8
.byte 8 @ sub-register DW_OP_regx
.byte 144 @ 257
.byte 129 @ DW_OP_piece
.byte 2 @ 8
.byte 147 @
.byte 8 @
we now get
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
.byte 144 @ sub-register DW_OP_regx
.byte 129 @ 257
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
Reviewers: JDevlieghere, rnk, aprantl
Reviewed By: aprantl
Subscribers: davide, Ka-Ka, uabelho, aemerson, javed.absar, kristof.beyls, llvm-commits, JDevlieghere
Differential Revision: https://reviews.llvm.org/D41763
llvm-svn: 321907
2018-01-06 06:20:30 +08:00
|
|
|
// Add some empty comments to keep the Buffer and Comments vectors aligned
|
|
|
|
// with each other.
|
|
|
|
for (size_t i = 1; i < Length; ++i)
|
|
|
|
Comments.push_back("");
|
|
|
|
|
|
|
|
}
|
2015-03-03 06:02:33 +08:00
|
|
|
}
|
2020-02-14 05:26:21 +08:00
|
|
|
void emitULEB128(uint64_t DWord, const Twine &Comment,
|
|
|
|
unsigned PadTo) override {
|
2015-03-03 06:02:33 +08:00
|
|
|
raw_svector_ostream OSE(Buffer);
|
2019-03-19 21:16:28 +08:00
|
|
|
unsigned Length = encodeULEB128(DWord, OSE, PadTo);
|
[DebugInfo] Align comments in debug_loc section
Summary:
This commit updates the BufferByteStreamer, used by DebugLocStream
to buffer bytes/comments to put in the debug_loc section, to
make sure that the Buffer and Comments vectors are synced.
Previously, when an SLEB128 or ULEB128 was emitted together with
a comment, the vectors could be out-of-sync if the LEB encoding
added several entries to the Buffer vectors, while we only added
a single entry to the Comments vector.
The goal with this is to get the comments in the debug_loc
section in the .s file correctly aligned.
Example (using ARM as target):
Instead of
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @ DW_OP_piece
.byte 147 @ 8
.byte 8 @ sub-register DW_OP_regx
.byte 144 @ 257
.byte 129 @ DW_OP_piece
.byte 2 @ 8
.byte 147 @
.byte 8 @
we now get
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
.byte 144 @ sub-register DW_OP_regx
.byte 129 @ 257
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
Reviewers: JDevlieghere, rnk, aprantl
Reviewed By: aprantl
Subscribers: davide, Ka-Ka, uabelho, aemerson, javed.absar, kristof.beyls, llvm-commits, JDevlieghere
Differential Revision: https://reviews.llvm.org/D41763
llvm-svn: 321907
2018-01-06 06:20:30 +08:00
|
|
|
if (GenerateComments) {
|
2015-05-21 06:51:27 +08:00
|
|
|
Comments.push_back(Comment.str());
|
[DebugInfo] Align comments in debug_loc section
Summary:
This commit updates the BufferByteStreamer, used by DebugLocStream
to buffer bytes/comments to put in the debug_loc section, to
make sure that the Buffer and Comments vectors are synced.
Previously, when an SLEB128 or ULEB128 was emitted together with
a comment, the vectors could be out-of-sync if the LEB encoding
added several entries to the Buffer vectors, while we only added
a single entry to the Comments vector.
The goal with this is to get the comments in the debug_loc
section in the .s file correctly aligned.
Example (using ARM as target):
Instead of
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @ DW_OP_piece
.byte 147 @ 8
.byte 8 @ sub-register DW_OP_regx
.byte 144 @ 257
.byte 129 @ DW_OP_piece
.byte 2 @ 8
.byte 147 @
.byte 8 @
we now get
.byte 144 @ sub-register DW_OP_regx
.byte 128 @ 256
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
.byte 144 @ sub-register DW_OP_regx
.byte 129 @ 257
.byte 2 @
.byte 147 @ DW_OP_piece
.byte 8 @ 8
Reviewers: JDevlieghere, rnk, aprantl
Reviewed By: aprantl
Subscribers: davide, Ka-Ka, uabelho, aemerson, javed.absar, kristof.beyls, llvm-commits, JDevlieghere
Differential Revision: https://reviews.llvm.org/D41763
llvm-svn: 321907
2018-01-06 06:20:30 +08:00
|
|
|
// Add some empty comments to keep the Buffer and Comments vectors aligned
|
|
|
|
// with each other.
|
|
|
|
for (size_t i = 1; i < Length; ++i)
|
|
|
|
Comments.push_back("");
|
|
|
|
|
|
|
|
}
|
2015-03-03 06:02:33 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-06-23 17:49:53 +08:00
|
|
|
}
|
2014-03-08 06:43:09 +08:00
|
|
|
|
|
|
|
#endif
|