61 "invalid integer write size: %zu",
Size);
67 std::vector<uint8_t> FillData(
Size, 0);
68 OS.
write(
reinterpret_cast<char *
>(FillData.data()),
Size);
73 bool IsLittleEndian) {
90 OS.
write(Str.data(), Str.size());
99 "Index should be less than the size of DebugAbbrev array");
100 auto It = AbbrevTableContents.find(
Index);
101 if (It != AbbrevTableContents.cend())
104 std::string AbbrevTableBuffer;
109 AbbrevCode = AbbrevDecl.Code ? (
uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
113 for (
const auto &Attr : AbbrevDecl.Attributes) {
116 if (Attr.Form == dwarf::DW_FORM_implicit_const)
127 AbbrevTableContents.insert({
Index, AbbrevTableBuffer});
129 return AbbrevTableContents[
Index];
146 AddrSize = *Range.AddrSize;
159 const uint64_t PaddedHeaderLength =
alignTo(HeaderLength, AddrSize * 2);
164 Length += PaddedHeaderLength - HeaderLength;
165 Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
175 for (
const auto &Descriptor : Range.Descriptors) {
179 "unable to write debug_aranges address: %s",
191 const size_t RangesOffset =
OS.
tell();
194 const size_t CurrOffset =
OS.
tell() - RangesOffset;
195 if (DebugRanges.Offset && (
uint64_t)*DebugRanges.Offset < CurrOffset)
197 "'Offset' for 'debug_ranges' with index " +
199 " must be greater than or equal to the "
200 "number of bytes written already (0x" +
202 if (DebugRanges.Offset)
206 if (DebugRanges.AddrSize)
207 AddrSize = *DebugRanges.AddrSize;
210 for (
const auto &
Entry : DebugRanges.Entries) {
215 "unable to write debug_ranges address offset: %s",
228 bool IsLittleEndian,
bool IsGNUPubSec =
false) {
233 for (
const auto &Entry : Sect.
Entries) {
237 OS.
write(Entry.Name.data(), Entry.Name.size());
273 if (AbbrCode == 0 || Entry.Values.empty())
274 return OS.
tell() - EntryBegin;
278 if (!AbbrevTableInfoOrErr)
281 " for compilation unit with index " +
285 DI.
DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
287 if (AbbrCode > AbbrevDecls.
size())
290 "abbrev code must be less than or equal to the number of "
291 "entries in abbreviation table");
293 auto FormVal = Entry.Values.begin();
295 for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.
Attributes.end();
296 ++FormVal, ++AbbrForm) {
302 case dwarf::DW_FORM_addr:
305 FormVal->Value, Params.
AddrSize,
OS, IsLittleEndian))
306 return std::move(Err);
308 case dwarf::DW_FORM_ref_addr:
313 return std::move(Err);
315 case dwarf::DW_FORM_exprloc:
316 case dwarf::DW_FORM_block:
318 OS.
write((
const char *)FormVal->BlockData.data(),
319 FormVal->BlockData.size());
321 case dwarf::DW_FORM_block1: {
322 writeInteger((uint8_t)FormVal->BlockData.size(),
OS, IsLittleEndian);
323 OS.
write((
const char *)FormVal->BlockData.data(),
324 FormVal->BlockData.size());
327 case dwarf::DW_FORM_block2: {
329 OS.
write((
const char *)FormVal->BlockData.data(),
330 FormVal->BlockData.size());
333 case dwarf::DW_FORM_block4: {
335 OS.
write((
const char *)FormVal->BlockData.data(),
336 FormVal->BlockData.size());
339 case dwarf::DW_FORM_strx:
340 case dwarf::DW_FORM_addrx:
341 case dwarf::DW_FORM_rnglistx:
342 case dwarf::DW_FORM_loclistx:
343 case dwarf::DW_FORM_udata:
344 case dwarf::DW_FORM_ref_udata:
345 case dwarf::DW_FORM_GNU_addr_index:
346 case dwarf::DW_FORM_GNU_str_index:
349 case dwarf::DW_FORM_data1:
350 case dwarf::DW_FORM_ref1:
351 case dwarf::DW_FORM_flag:
352 case dwarf::DW_FORM_strx1:
353 case dwarf::DW_FORM_addrx1:
356 case dwarf::DW_FORM_data2:
357 case dwarf::DW_FORM_ref2:
358 case dwarf::DW_FORM_strx2:
359 case dwarf::DW_FORM_addrx2:
362 case dwarf::DW_FORM_data4:
363 case dwarf::DW_FORM_ref4:
364 case dwarf::DW_FORM_ref_sup4:
365 case dwarf::DW_FORM_strx4:
366 case dwarf::DW_FORM_addrx4:
369 case dwarf::DW_FORM_data8:
370 case dwarf::DW_FORM_ref8:
371 case dwarf::DW_FORM_ref_sup8:
372 case dwarf::DW_FORM_ref_sig8:
375 case dwarf::DW_FORM_sdata:
378 case dwarf::DW_FORM_string:
379 OS.
write(FormVal->CStr.data(), FormVal->CStr.size());
382 case dwarf::DW_FORM_indirect:
388 case dwarf::DW_FORM_strp:
389 case dwarf::DW_FORM_sec_offset:
390 case dwarf::DW_FORM_GNU_ref_alt:
391 case dwarf::DW_FORM_GNU_strp_alt:
392 case dwarf::DW_FORM_line_strp:
393 case dwarf::DW_FORM_strp_sup:
404 return OS.
tell() - EntryBegin;
424 std::string EntryBuffer;
434 return EntryLength.takeError();
451 AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
469 OS.
write(EntryBuffer.data(), EntryBuffer.size());
476 OS.
write(File.Name.data(), File.Name.size());
484 uint8_t AddrSize,
bool IsLittleEndian,
491 std::string OpBuffer;
494 switch (
Op.SubOpcode) {
495 case dwarf::DW_LNE_set_address:
499 case dwarf::DW_LNE_define_file:
502 case dwarf::DW_LNE_set_discriminator:
505 case dwarf::DW_LNE_end_sequence:
508 for (
auto OpByte :
Op.UnknownOpcodeData)
509 writeInteger((uint8_t)OpByte, OpBufferOS, IsLittleEndian);
511 uint64_t ExtLen =
Op.ExtLen.value_or(OpBuffer.size());
513 OS.
write(OpBuffer.data(), OpBuffer.size());
517 uint8_t OpcodeBase, uint8_t AddrSize,
520 if (
Op.Opcode == 0) {
522 }
else if (
Op.Opcode < OpcodeBase) {
524 case dwarf::DW_LNS_copy:
525 case dwarf::DW_LNS_negate_stmt:
526 case dwarf::DW_LNS_set_basic_block:
527 case dwarf::DW_LNS_const_add_pc:
528 case dwarf::DW_LNS_set_prologue_end:
529 case dwarf::DW_LNS_set_epilogue_begin:
532 case dwarf::DW_LNS_advance_pc:
533 case dwarf::DW_LNS_set_file:
534 case dwarf::DW_LNS_set_column:
535 case dwarf::DW_LNS_set_isa:
539 case dwarf::DW_LNS_advance_line:
543 case dwarf::DW_LNS_fixed_advance_pc:
548 for (
auto OpData :
Op.StandardOpcodeData) {
555static std::vector<uint8_t>
559 std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
563 StandardOpcodeLengths.resize(9);
564 }
else if (OpcodeBase) {
565 StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
567 return StandardOpcodeLengths;
585 std::vector<uint8_t> StandardOpcodeLengths =
590 : StandardOpcodeLengths.size() + 1;
592 for (uint8_t OpcodeLength : StandardOpcodeLengths)
597 BufferOS.
write(
'\0');
599 BufferOS.
write(
'\0');
603 BufferOS.
write(
'\0');
625 OS.
write(Buffer.data(), Buffer.size());
658 "unable to write debug_addr segment: %s",
664 "unable to write debug_addr address: %s",
697 if (Values.
size() != ExpectedOperands)
700 "invalid number (%zu) of operands for the operator: %s, %" PRIu64
702 Values.
size(), EncodingString.
str().c_str(), ExpectedOperands);
709 bool IsLittleEndian) {
712 "unable to write address for the operator %s: %s",
713 EncodingName.
str().c_str(),
722 uint8_t AddrSize,
bool IsLittleEndian) {
723 auto CheckOperands = [&](
uint64_t ExpectedOperands) ->
Error {
731 case dwarf::DW_OP_consts:
732 if (
Error Err = CheckOperands(1))
733 return std::move(Err);
736 case dwarf::DW_OP_stack_value:
737 if (
Error Err = CheckOperands(0))
738 return std::move(Err);
743 "DWARF expression: " +
747 " is not supported");
749 return OS.
tell() - ExpressionBegin;
755 bool IsLittleEndian) {
761 auto CheckOperands = [&](
uint64_t ExpectedOperands) ->
Error {
770 switch (Entry.Operator) {
771 case dwarf::DW_RLE_end_of_list:
772 if (
Error Err = CheckOperands(0))
773 return std::move(Err);
775 case dwarf::DW_RLE_base_addressx:
776 if (
Error Err = CheckOperands(1))
777 return std::move(Err);
780 case dwarf::DW_RLE_startx_endx:
781 case dwarf::DW_RLE_startx_length:
782 case dwarf::DW_RLE_offset_pair:
783 if (
Error Err = CheckOperands(2))
784 return std::move(Err);
788 case dwarf::DW_RLE_base_address:
789 if (
Error Err = CheckOperands(1))
790 return std::move(Err);
791 if (
Error Err = WriteAddress(Entry.Values[0]))
792 return std::move(Err);
794 case dwarf::DW_RLE_start_end:
795 if (
Error Err = CheckOperands(2))
796 return std::move(Err);
797 if (
Error Err = WriteAddress(Entry.Values[0]))
798 return std::move(Err);
799 cantFail(WriteAddress(Entry.Values[1]));
801 case dwarf::DW_RLE_start_length:
802 if (
Error Err = CheckOperands(2))
803 return std::move(Err);
804 if (
Error Err = WriteAddress(Entry.Values[0]))
805 return std::move(Err);
810 return OS.
tell() - BeginOffset;
816 bool IsLittleEndian) {
822 auto CheckOperands = [&](
uint64_t ExpectedOperands) ->
Error {
831 auto WriteDWARFOperations = [&]() ->
Error {
832 std::string OpBuffer;
839 DescriptionsLength += *OpSize;
841 return OpSize.takeError();
844 if (Entry.DescriptionsLength)
845 DescriptionsLength = *Entry.DescriptionsLength;
847 DescriptionsLength = OpBuffer.size();
850 OS.
write(OpBuffer.data(), OpBuffer.size());
855 switch (Entry.Operator) {
856 case dwarf::DW_LLE_end_of_list:
857 if (
Error Err = CheckOperands(0))
858 return std::move(Err);
860 case dwarf::DW_LLE_base_addressx:
861 if (
Error Err = CheckOperands(1))
862 return std::move(Err);
865 case dwarf::DW_LLE_startx_endx:
866 case dwarf::DW_LLE_startx_length:
867 case dwarf::DW_LLE_offset_pair:
868 if (
Error Err = CheckOperands(2))
869 return std::move(Err);
872 if (
Error Err = WriteDWARFOperations())
873 return std::move(Err);
875 case dwarf::DW_LLE_default_location:
876 if (
Error Err = CheckOperands(0))
877 return std::move(Err);
878 if (
Error Err = WriteDWARFOperations())
879 return std::move(Err);
881 case dwarf::DW_LLE_base_address:
882 if (
Error Err = CheckOperands(1))
883 return std::move(Err);
884 if (
Error Err = WriteAddress(Entry.Values[0]))
885 return std::move(Err);
887 case dwarf::DW_LLE_start_end:
888 if (
Error Err = CheckOperands(2))
889 return std::move(Err);
890 if (
Error Err = WriteAddress(Entry.Values[0]))
891 return std::move(Err);
892 cantFail(WriteAddress(Entry.Values[1]));
893 if (
Error Err = WriteDWARFOperations())
894 return std::move(Err);
896 case dwarf::DW_LLE_start_length:
897 if (
Error Err = CheckOperands(2))
898 return std::move(Err);
899 if (
Error Err = WriteAddress(Entry.Values[0]))
900 return std::move(Err);
902 if (
Error Err = WriteDWARFOperations())
903 return std::move(Err);
907 return OS.
tell() - BeginOffset;
910template <
typename EntryType>
913 bool IsLittleEndian,
bool Is64BitAddrSize) {
921 AddrSize = *Table.AddrSize;
923 AddrSize = Is64BitAddrSize ? 8 : 4;
929 std::string ListBuffer;
935 std::vector<uint64_t> Offsets;
938 Offsets.push_back(ListBufferOS.
tell());
942 }
else if (
List.Entries) {
943 for (
const EntryType &Entry : *
List.Entries) {
958 if (Table.OffsetEntryCount)
959 OffsetEntryCount = *Table.OffsetEntryCount;
961 OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
985 Table.Offsets->size()),
987 else if (OffsetEntryCount != 0)
988 EmitOffsets(Offsets, OffsetsSize);
990 OS.
write(ListBuffer.data(), ListBuffer.size());
998 return writeDWARFLists<DWARFYAML::RnglistEntry>(
1004 return writeDWARFLists<DWARFYAML::LoclistEntry>(
1029 SecName +
" is not supported");
1037 StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
1043 if (
Error Err = EmitFunc(DebugInfoStream, DI))
1045 DebugInfoStream.
flush();
1054 bool Is64BitAddrSize) {
1055 auto CollectDiagnostic = [](
const SMDiagnostic &Diag,
void *DiagContext) {
1060 yaml::Input YIn(YAMLString,
nullptr, CollectDiagnostic,
1079 return std::move(Err);
1080 return std::move(DebugSections);
This file defines the StringMap class.
static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, raw_ostream &OS, bool IsLittleEndian)
static Error emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec, StringMap< std::unique_ptr< MemoryBuffer > > &OutputBuffers)
static void ZeroFillBytes(raw_ostream &OS, size_t Size)
static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File)
static Error writeDWARFLists(raw_ostream &OS, ArrayRef< DWARFYAML::ListTable< EntryType > > Tables, bool IsLittleEndian, bool Is64BitAddrSize)
static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t OpcodeBase, uint8_t AddrSize, raw_ostream &OS, bool IsLittleEndian)
static Error writeVariableSizedInteger(uint64_t Integer, size_t Size, raw_ostream &OS, bool IsLittleEndian)
static Expected< uint64_t > writeListEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry, uint8_t AddrSize, bool IsLittleEndian)
static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian)
static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t AddrSize, bool IsLittleEndian, raw_ostream &OS)
static Error checkOperandCount(StringRef EncodingString, ArrayRef< yaml::Hex64 > Values, uint64_t ExpectedOperands)
static Expected< uint64_t > writeDWARFExpression(raw_ostream &OS, const DWARFYAML::DWARFOperation &Operation, uint8_t AddrSize, bool IsLittleEndian)
static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, bool IsLittleEndian, bool IsGNUPubSec=false)
static Expected< uint64_t > writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex, uint64_t AbbrevTableID, const dwarf::FormParams &Params, const DWARFYAML::Entry &Entry, raw_ostream &OS, bool IsLittleEndian)
static void writeInitialLength(const dwarf::DwarfFormat Format, const uint64_t Length, raw_ostream &OS, bool IsLittleEndian)
static std::vector< uint8_t > getStandardOpcodeLengths(uint16_t Version, std::optional< uint8_t > OpcodeBase)
static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS, uint64_t Addr, uint8_t AddrSize, bool IsLittleEndian)
Common declarations for yaml2obj.
This file declares classes for handling the YAML representation of DWARF Debug Info.
This file contains constants used for implementing Dwarf debug support.
PowerPC Reduce CR logical Operation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
This class represents an Operation in the Expression.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
StringRef getMessage() const
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(const uint64_t &Val)
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an std::string.
StringRef RangeListEncodingString(unsigned Encoding)
StringRef LocListEncodingString(unsigned Encoding)
StringRef OperationEncodingString(unsigned Encoding)
Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI)
Error emitDebugInfo(raw_ostream &OS, const Data &DI)
Error emitDebugRanges(raw_ostream &OS, const Data &DI)
Error emitDebugAranges(raw_ostream &OS, const Data &DI)
Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI)
Error emitDebugAbbrev(raw_ostream &OS, const Data &DI)
Error emitDebugRnglists(raw_ostream &OS, const Data &DI)
Error emitDebugLoclists(raw_ostream &OS, const Data &DI)
std::function< Error(raw_ostream &, const Data &)> getDWARFEmitterByName(StringRef SecName)
Expected< StringMap< std::unique_ptr< MemoryBuffer > > > emitDebugSections(StringRef YAMLString, bool IsLittleEndian=sys::IsLittleEndianHost, bool Is64BitAddrSize=true)
Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI)
Error emitDebugStr(raw_ostream &OS, const Data &DI)
Error emitDebugPubnames(raw_ostream &OS, const Data &DI)
Error emitDebugAddr(raw_ostream &OS, const Data &DI)
Error emitDebugPubtypes(raw_ostream &OS, const Data &DI)
Error emitDebugLine(raw_ostream &OS, const Data &DI)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
static const bool IsLittleEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
void consumeError(Error Err)
Consume a Error without doing anything.
std::vector< AttributeAbbrev > Attributes
std::optional< yaml::Hex64 > Length
std::optional< yaml::Hex8 > AddrSize
dwarf::DwarfFormat Format
yaml::Hex8 SegSelectorSize
std::vector< SegAddrPair > SegAddrPairs
std::vector< LineTable > DebugLines
std::optional< std::vector< AddrTableEntry > > DebugAddr
std::optional< std::vector< Ranges > > DebugRanges
std::optional< std::vector< ListTable< LoclistEntry > > > DebugLoclists
std::vector< AbbrevTable > DebugAbbrev
Expected< AbbrevTableInfo > getAbbrevTableInfoByID(uint64_t ID) const
std::optional< PubSection > GNUPubNames
std::optional< std::vector< ARange > > DebugAranges
StringRef getAbbrevTableContentByIndex(uint64_t Index) const
std::vector< Unit > CompileUnits
std::optional< PubSection > GNUPubTypes
SetVector< StringRef > getNonEmptySectionNames() const
std::optional< std::vector< StringOffsetsTable > > DebugStrOffsets
std::optional< std::vector< StringRef > > DebugStrings
std::optional< std::vector< ListTable< RnglistEntry > > > DebugRnglists
std::optional< PubSection > PubNames
std::optional< PubSection > PubTypes
std::optional< uint64_t > Length
std::optional< uint8_t > OpcodeBase
std::vector< LineTableOpcode > Opcodes
std::optional< uint64_t > PrologueLength
dwarf::DwarfFormat Format
std::vector< File > Files
std::vector< StringRef > IncludeDirs
std::optional< std::vector< uint8_t > > StandardOpcodeLengths
dwarf::DwarfFormat Format
std::vector< PubEntry > Entries
std::optional< yaml::Hex64 > Length
std::vector< yaml::Hex64 > Offsets
dwarf::DwarfFormat Format
std::optional< uint64_t > AbbrevTableID
dwarf::DwarfFormat Format
std::optional< yaml::Hex64 > Length
std::optional< uint8_t > AddrSize
llvm::dwarf::UnitType Type
std::vector< Entry > Entries
std::optional< yaml::Hex64 > AbbrOffset