summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
diff options
context:
space:
mode:
authorNilanjana Basu <nilanjana.basu87@gmail.com>2019-07-03 00:26:23 +0000
committerNilanjana Basu <nilanjana.basu87@gmail.com>2019-07-03 00:26:23 +0000
commit2082bf28ebea76cc187b508f801122866420d9ff (patch)
tree856ccf456733d3c5de5c4e468200767230af3896 /llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
parentda1dfecd32f405d00b2432acd9fdd24526e5614f (diff)
downloadbcm5719-llvm-2082bf28ebea76cc187b508f801122866420d9ff.tar.gz
bcm5719-llvm-2082bf28ebea76cc187b508f801122866420d9ff.zip
Changing CodeView debug info type record representation in assembly files to make it more human-readable & editable
llvm-svn: 364982
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp')
-rw-r--r--llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp126
1 files changed, 109 insertions, 17 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index 92c795ab8fa..2b69a1e0768 100644
--- a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -20,6 +20,7 @@ Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
Limit.MaxLength = MaxLength;
Limit.BeginOffset = getCurrentOffset();
Limits.push_back(Limit);
+ resetStreamedLen();
return Error::success();
}
@@ -34,10 +35,29 @@ Error CodeViewRecordIO::endRecord() {
// we don't know how big the record is until we're finished writing it, so
// even though we don't commit the extraneous data, we still can't guarantee
// we're at the end of the allocated data.
+
+ if (isStreaming()) {
+ // For streaming mode, add padding to align with 4 byte boundaries for each
+ // record
+ uint32_t Align = getStreamedLen() % 4;
+ if (Align == 0)
+ return Error::success();
+
+ int PaddingBytes = 4 - Align;
+ while (PaddingBytes > 0) {
+ char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
+ StringRef BytesSR = StringRef(&Pad, sizeof(Pad));
+ Streamer->EmitBytes(BytesSR);
+ --PaddingBytes;
+ }
+ }
return Error::success();
}
uint32_t CodeViewRecordIO::maxFieldLength() const {
+ if (isStreaming())
+ return 0;
+
assert(!Limits.empty() && "Not in a record!");
// The max length of the next field is the minimum of all lengths that would
@@ -78,7 +98,10 @@ Error CodeViewRecordIO::skipPadding() {
}
Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) {
- if (isWriting()) {
+ if (isStreaming()) {
+ Streamer->EmitBinaryData(toStringRef(Bytes));
+ incrStreamedLen(Bytes.size());
+ } else if (isWriting()) {
if (auto EC = Writer->writeBytes(Bytes))
return EC;
} else {
@@ -99,21 +122,28 @@ Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) {
}
Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
- if (isWriting()) {
+ if (isStreaming()) {
+ Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
+ incrStreamedLen(sizeof(TypeInd.getIndex()));
+ } else if (isWriting()) {
if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
return EC;
- return Error::success();
+ } else {
+ uint32_t I;
+ if (auto EC = Reader->readInteger(I))
+ return EC;
+ TypeInd.setIndex(I);
}
-
- uint32_t I;
- if (auto EC = Reader->readInteger(I))
- return EC;
- TypeInd.setIndex(I);
return Error::success();
}
Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) {
- if (isWriting()) {
+ if (isStreaming()) {
+ if (Value >= 0)
+ emitEncodedUnsignedInteger(static_cast<uint64_t>(Value));
+ else
+ emitEncodedSignedInteger(Value);
+ } else if (isWriting()) {
if (Value >= 0) {
if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
return EC;
@@ -132,7 +162,9 @@ Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) {
}
Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
- if (isWriting()) {
+ if (isStreaming())
+ emitEncodedUnsignedInteger(Value);
+ else if (isWriting()) {
if (auto EC = writeEncodedUnsignedInteger(Value))
return EC;
} else {
@@ -145,17 +177,26 @@ Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
}
Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) {
- if (isWriting()) {
+ if (isStreaming()) {
+ if (Value.isSigned())
+ emitEncodedSignedInteger(Value.getSExtValue());
+ else
+ emitEncodedUnsignedInteger(Value.getZExtValue());
+ } else if (isWriting()) {
if (Value.isSigned())
return writeEncodedSignedInteger(Value.getSExtValue());
return writeEncodedUnsignedInteger(Value.getZExtValue());
- }
-
- return consume(*Reader, Value);
+ } else
+ return consume(*Reader, Value);
+ return Error::success();
}
Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
- if (isWriting()) {
+ if (isStreaming()) {
+ auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1);
+ Streamer->EmitBytes(NullTerminatedString);
+ incrStreamedLen(NullTerminatedString.size());
+ } else if (isWriting()) {
// Truncate if we attempt to write too much.
StringRef S = Value.take_front(maxFieldLength() - 1);
if (auto EC = Writer->writeCString(S))
@@ -169,6 +210,15 @@ Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
Error CodeViewRecordIO::mapGuid(GUID &Guid) {
constexpr uint32_t GuidSize = 16;
+
+ if (isStreaming()) {
+ StringRef GuidSR =
+ StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize);
+ Streamer->EmitBytes(GuidSR);
+ incrStreamedLen(GuidSize);
+ return Error::success();
+ }
+
if (maxFieldLength() < GuidSize)
return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
@@ -185,12 +235,14 @@ Error CodeViewRecordIO::mapGuid(GUID &Guid) {
}
Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) {
- if (isWriting()) {
+
+ if (!isReading()) {
for (auto V : Value) {
if (auto EC = mapStringZ(V))
return EC;
}
- if (auto EC = Writer->writeInteger<uint8_t>(0))
+ uint8_t FinalZero = 0;
+ if (auto EC = mapInteger(FinalZero))
return EC;
} else {
StringRef S;
@@ -205,6 +257,46 @@ Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) {
return Error::success();
}
+void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value) {
+ assert(Value < 0 && "Encoded integer is not signed!");
+ if (Value >= std::numeric_limits<int8_t>::min()) {
+ Streamer->EmitIntValue(LF_CHAR, 2);
+ Streamer->EmitIntValue(Value, 1);
+ incrStreamedLen(3);
+ } else if (Value >= std::numeric_limits<int16_t>::min()) {
+ Streamer->EmitIntValue(LF_SHORT, 2);
+ Streamer->EmitIntValue(Value, 2);
+ incrStreamedLen(4);
+ } else if (Value >= std::numeric_limits<int32_t>::min()) {
+ Streamer->EmitIntValue(LF_LONG, 2);
+ Streamer->EmitIntValue(Value, 4);
+ incrStreamedLen(6);
+ } else {
+ Streamer->EmitIntValue(LF_QUADWORD, 2);
+ Streamer->EmitIntValue(Value, 4);
+ incrStreamedLen(6);
+ }
+}
+
+void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value) {
+ if (Value < LF_NUMERIC) {
+ Streamer->EmitIntValue(Value, 2);
+ incrStreamedLen(2);
+ } else if (Value <= std::numeric_limits<uint16_t>::max()) {
+ Streamer->EmitIntValue(LF_USHORT, 2);
+ Streamer->EmitIntValue(Value, 2);
+ incrStreamedLen(4);
+ } else if (Value <= std::numeric_limits<uint32_t>::max()) {
+ Streamer->EmitIntValue(LF_ULONG, 2);
+ Streamer->EmitIntValue(Value, 4);
+ incrStreamedLen(6);
+ } else {
+ Streamer->EmitIntValue(LF_UQUADWORD, 2);
+ Streamer->EmitIntValue(Value, 8);
+ incrStreamedLen(6);
+ }
+}
+
Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
assert(Value < 0 && "Encoded integer is not signed!");
if (Value >= std::numeric_limits<int8_t>::min()) {
OpenPOWER on IntegriCloud