LLVM  14.0.0git
DWARFEmitter.cpp
Go to the documentation of this file.
1 //===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// The DWARF component of yaml2obj. Provided as library code for tests.
11 ///
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/Support/Errc.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/Host.h"
24 #include "llvm/Support/LEB128.h"
27 #include "llvm/Support/SourceMgr.h"
31 #include <algorithm>
32 #include <cassert>
33 #include <cstddef>
34 #include <cstdint>
35 #include <memory>
36 #include <string>
37 #include <vector>
38 
39 using namespace llvm;
40 
41 template <typename T>
42 static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
43  if (IsLittleEndian != sys::IsLittleEndianHost)
45  OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
46 }
47 
49  raw_ostream &OS, bool IsLittleEndian) {
50  if (8 == Size)
51  writeInteger((uint64_t)Integer, OS, IsLittleEndian);
52  else if (4 == Size)
53  writeInteger((uint32_t)Integer, OS, IsLittleEndian);
54  else if (2 == Size)
55  writeInteger((uint16_t)Integer, OS, IsLittleEndian);
56  else if (1 == Size)
57  writeInteger((uint8_t)Integer, OS, IsLittleEndian);
58  else
60  "invalid integer write size: %zu", Size);
61 
62  return Error::success();
63 }
64 
65 static void ZeroFillBytes(raw_ostream &OS, size_t Size) {
66  std::vector<uint8_t> FillData(Size, 0);
67  OS.write(reinterpret_cast<char *>(FillData.data()), Size);
68 }
69 
70 static void writeInitialLength(const dwarf::DwarfFormat Format,
71  const uint64_t Length, raw_ostream &OS,
72  bool IsLittleEndian) {
73  bool IsDWARF64 = Format == dwarf::DWARF64;
74  if (IsDWARF64)
76  IsLittleEndian));
77  cantFail(
78  writeVariableSizedInteger(Length, IsDWARF64 ? 8 : 4, OS, IsLittleEndian));
79 }
80 
82  raw_ostream &OS, bool IsLittleEndian) {
84  OS, IsLittleEndian));
85 }
86 
88  for (StringRef Str : *DI.DebugStrings) {
89  OS.write(Str.data(), Str.size());
90  OS.write('\0');
91  }
92 
93  return Error::success();
94 }
95 
97  assert(Index < DebugAbbrev.size() &&
98  "Index should be less than the size of DebugAbbrev array");
99  auto It = AbbrevTableContents.find(Index);
100  if (It != AbbrevTableContents.cend())
101  return It->second;
102 
103  std::string AbbrevTableBuffer;
104  raw_string_ostream OS(AbbrevTableBuffer);
105 
106  uint64_t AbbrevCode = 0;
107  for (const DWARFYAML::Abbrev &AbbrevDecl : DebugAbbrev[Index].Table) {
108  AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
109  encodeULEB128(AbbrevCode, OS);
110  encodeULEB128(AbbrevDecl.Tag, OS);
111  OS.write(AbbrevDecl.Children);
112  for (const auto &Attr : AbbrevDecl.Attributes) {
113  encodeULEB128(Attr.Attribute, OS);
114  encodeULEB128(Attr.Form, OS);
115  if (Attr.Form == dwarf::DW_FORM_implicit_const)
116  encodeSLEB128(Attr.Value, OS);
117  }
118  encodeULEB128(0, OS);
119  encodeULEB128(0, OS);
120  }
121 
122  // The abbreviations for a given compilation unit end with an entry
123  // consisting of a 0 byte for the abbreviation code.
124  OS.write_zeros(1);
125 
126  AbbrevTableContents.insert({Index, AbbrevTableBuffer});
127 
128  return AbbrevTableContents[Index];
129 }
130 
132  for (uint64_t I = 0; I < DI.DebugAbbrev.size(); ++I) {
133  StringRef AbbrevTableContent = DI.getAbbrevTableContentByIndex(I);
134  OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
135  }
136 
137  return Error::success();
138 }
139 
141  assert(DI.DebugAranges && "unexpected emitDebugAranges() call");
142  for (const auto &Range : *DI.DebugAranges) {
143  uint8_t AddrSize;
144  if (Range.AddrSize)
145  AddrSize = *Range.AddrSize;
146  else
147  AddrSize = DI.Is64BitAddrSize ? 8 : 4;
148 
149  uint64_t Length = 4; // sizeof(version) 2 + sizeof(address_size) 1 +
150  // sizeof(segment_selector_size) 1
151  Length +=
152  Range.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_info_offset)
153 
154  const uint64_t HeaderLength =
155  Length + (Range.Format == dwarf::DWARF64
156  ? 12
157  : 4); // sizeof(unit_header) = 12 (DWARF64) or 4 (DWARF32)
158  const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2);
159 
160  if (Range.Length) {
161  Length = *Range.Length;
162  } else {
163  Length += PaddedHeaderLength - HeaderLength;
164  Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
165  }
166 
167  writeInitialLength(Range.Format, Length, OS, DI.IsLittleEndian);
168  writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
169  writeDWARFOffset(Range.CuOffset, Range.Format, OS, DI.IsLittleEndian);
170  writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
171  writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
172  ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength);
173 
174  for (const auto &Descriptor : Range.Descriptors) {
175  if (Error Err = writeVariableSizedInteger(Descriptor.Address, AddrSize,
176  OS, DI.IsLittleEndian))
178  "unable to write debug_aranges address: %s",
179  toString(std::move(Err)).c_str());
180  cantFail(writeVariableSizedInteger(Descriptor.Length, AddrSize, OS,
181  DI.IsLittleEndian));
182  }
183  ZeroFillBytes(OS, AddrSize * 2);
184  }
185 
186  return Error::success();
187 }
188 
190  const size_t RangesOffset = OS.tell();
191  uint64_t EntryIndex = 0;
192  for (const auto &DebugRanges : *DI.DebugRanges) {
193  const size_t CurrOffset = OS.tell() - RangesOffset;
194  if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset)
196  "'Offset' for 'debug_ranges' with index " +
197  Twine(EntryIndex) +
198  " must be greater than or equal to the "
199  "number of bytes written already (0x" +
200  Twine::utohexstr(CurrOffset) + ")");
201  if (DebugRanges.Offset)
202  ZeroFillBytes(OS, *DebugRanges.Offset - CurrOffset);
203 
204  uint8_t AddrSize;
205  if (DebugRanges.AddrSize)
206  AddrSize = *DebugRanges.AddrSize;
207  else
208  AddrSize = DI.Is64BitAddrSize ? 8 : 4;
209  for (const auto &Entry : DebugRanges.Entries) {
210  if (Error Err = writeVariableSizedInteger(Entry.LowOffset, AddrSize, OS,
211  DI.IsLittleEndian))
212  return createStringError(
214  "unable to write debug_ranges address offset: %s",
215  toString(std::move(Err)).c_str());
216  cantFail(writeVariableSizedInteger(Entry.HighOffset, AddrSize, OS,
217  DI.IsLittleEndian));
218  }
219  ZeroFillBytes(OS, AddrSize * 2);
220  ++EntryIndex;
221  }
222 
223  return Error::success();
224 }
225 
227  bool IsLittleEndian, bool IsGNUPubSec = false) {
228  writeInitialLength(Sect.Format, Sect.Length, OS, IsLittleEndian);
229  writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
230  writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
231  writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
232  for (const auto &Entry : Sect.Entries) {
233  writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
234  if (IsGNUPubSec)
235  writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
236  OS.write(Entry.Name.data(), Entry.Name.size());
237  OS.write('\0');
238  }
239  return Error::success();
240 }
241 
243  assert(DI.PubNames && "unexpected emitDebugPubnames() call");
244  return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian);
245 }
246 
248  assert(DI.PubTypes && "unexpected emitDebugPubtypes() call");
249  return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian);
250 }
251 
253  assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call");
254  return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian,
255  /*IsGNUStyle=*/true);
256 }
257 
259  assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call");
260  return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian,
261  /*IsGNUStyle=*/true);
262 }
263 
265  uint64_t AbbrevTableID,
266  const dwarf::FormParams &Params,
267  const DWARFYAML::Entry &Entry,
268  raw_ostream &OS, bool IsLittleEndian) {
269  uint64_t EntryBegin = OS.tell();
270  encodeULEB128(Entry.AbbrCode, OS);
271  uint32_t AbbrCode = Entry.AbbrCode;
272  if (AbbrCode == 0 || Entry.Values.empty())
273  return OS.tell() - EntryBegin;
274 
275  Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
276  DI.getAbbrevTableInfoByID(AbbrevTableID);
277  if (!AbbrevTableInfoOrErr)
279  toString(AbbrevTableInfoOrErr.takeError()) +
280  " for compilation unit with index " +
281  utostr(CUIndex));
282 
283  ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
284  DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
285 
286  if (AbbrCode > AbbrevDecls.size())
287  return createStringError(
289  "abbrev code must be less than or equal to the number of "
290  "entries in abbreviation table");
291  const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1];
292  auto FormVal = Entry.Values.begin();
293  auto AbbrForm = Abbrev.Attributes.begin();
294  for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
295  ++FormVal, ++AbbrForm) {
296  dwarf::Form Form = AbbrForm->Form;
297  bool Indirect;
298  do {
299  Indirect = false;
300  switch (Form) {
301  case dwarf::DW_FORM_addr:
302  // TODO: Test this error.
304  FormVal->Value, Params.AddrSize, OS, IsLittleEndian))
305  return std::move(Err);
306  break;
307  case dwarf::DW_FORM_ref_addr:
308  // TODO: Test this error.
309  if (Error Err = writeVariableSizedInteger(FormVal->Value,
310  Params.getRefAddrByteSize(),
311  OS, IsLittleEndian))
312  return std::move(Err);
313  break;
314  case dwarf::DW_FORM_exprloc:
315  case dwarf::DW_FORM_block:
316  encodeULEB128(FormVal->BlockData.size(), OS);
317  OS.write((const char *)FormVal->BlockData.data(),
318  FormVal->BlockData.size());
319  break;
320  case dwarf::DW_FORM_block1: {
321  writeInteger((uint8_t)FormVal->BlockData.size(), OS, IsLittleEndian);
322  OS.write((const char *)FormVal->BlockData.data(),
323  FormVal->BlockData.size());
324  break;
325  }
326  case dwarf::DW_FORM_block2: {
327  writeInteger((uint16_t)FormVal->BlockData.size(), OS, IsLittleEndian);
328  OS.write((const char *)FormVal->BlockData.data(),
329  FormVal->BlockData.size());
330  break;
331  }
332  case dwarf::DW_FORM_block4: {
333  writeInteger((uint32_t)FormVal->BlockData.size(), OS, IsLittleEndian);
334  OS.write((const char *)FormVal->BlockData.data(),
335  FormVal->BlockData.size());
336  break;
337  }
338  case dwarf::DW_FORM_strx:
339  case dwarf::DW_FORM_addrx:
340  case dwarf::DW_FORM_rnglistx:
341  case dwarf::DW_FORM_loclistx:
342  case dwarf::DW_FORM_udata:
343  case dwarf::DW_FORM_ref_udata:
344  case dwarf::DW_FORM_GNU_addr_index:
345  case dwarf::DW_FORM_GNU_str_index:
346  encodeULEB128(FormVal->Value, OS);
347  break;
348  case dwarf::DW_FORM_data1:
349  case dwarf::DW_FORM_ref1:
350  case dwarf::DW_FORM_flag:
351  case dwarf::DW_FORM_strx1:
352  case dwarf::DW_FORM_addrx1:
353  writeInteger((uint8_t)FormVal->Value, OS, IsLittleEndian);
354  break;
355  case dwarf::DW_FORM_data2:
356  case dwarf::DW_FORM_ref2:
357  case dwarf::DW_FORM_strx2:
358  case dwarf::DW_FORM_addrx2:
359  writeInteger((uint16_t)FormVal->Value, OS, IsLittleEndian);
360  break;
361  case dwarf::DW_FORM_data4:
362  case dwarf::DW_FORM_ref4:
363  case dwarf::DW_FORM_ref_sup4:
364  case dwarf::DW_FORM_strx4:
365  case dwarf::DW_FORM_addrx4:
366  writeInteger((uint32_t)FormVal->Value, OS, IsLittleEndian);
367  break;
368  case dwarf::DW_FORM_data8:
369  case dwarf::DW_FORM_ref8:
370  case dwarf::DW_FORM_ref_sup8:
371  case dwarf::DW_FORM_ref_sig8:
372  writeInteger((uint64_t)FormVal->Value, OS, IsLittleEndian);
373  break;
374  case dwarf::DW_FORM_sdata:
375  encodeSLEB128(FormVal->Value, OS);
376  break;
377  case dwarf::DW_FORM_string:
378  OS.write(FormVal->CStr.data(), FormVal->CStr.size());
379  OS.write('\0');
380  break;
381  case dwarf::DW_FORM_indirect:
382  encodeULEB128(FormVal->Value, OS);
383  Indirect = true;
384  Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
385  ++FormVal;
386  break;
387  case dwarf::DW_FORM_strp:
388  case dwarf::DW_FORM_sec_offset:
389  case dwarf::DW_FORM_GNU_ref_alt:
390  case dwarf::DW_FORM_GNU_strp_alt:
391  case dwarf::DW_FORM_line_strp:
392  case dwarf::DW_FORM_strp_sup:
393  cantFail(writeVariableSizedInteger(FormVal->Value,
394  Params.getDwarfOffsetByteSize(), OS,
395  IsLittleEndian));
396  break;
397  default:
398  break;
399  }
400  } while (Indirect);
401  }
402 
403  return OS.tell() - EntryBegin;
404 }
405 
407  for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) {
408  const DWARFYAML::Unit &Unit = DI.CompileUnits[I];
409  uint8_t AddrSize;
410  if (Unit.AddrSize)
411  AddrSize = *Unit.AddrSize;
412  else
413  AddrSize = DI.Is64BitAddrSize ? 8 : 4;
414  dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format};
415  uint64_t Length = 3; // sizeof(version) + sizeof(address_size)
416  Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type)
417  Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset)
418 
419  // Since the length of the current compilation unit is undetermined yet, we
420  // firstly write the content of the compilation unit to a buffer to
421  // calculate it and then serialize the buffer content to the actual output
422  // stream.
423  std::string EntryBuffer;
424  raw_string_ostream EntryBufferOS(EntryBuffer);
425 
426  uint64_t AbbrevTableID = Unit.AbbrevTableID.getValueOr(I);
427  for (const DWARFYAML::Entry &Entry : Unit.Entries) {
428  if (Expected<uint64_t> EntryLength =
429  writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS,
430  DI.IsLittleEndian))
431  Length += *EntryLength;
432  else
433  return EntryLength.takeError();
434  }
435 
436  // If the length is specified in the YAML description, we use it instead of
437  // the actual length.
438  if (Unit.Length)
439  Length = *Unit.Length;
440 
441  writeInitialLength(Unit.Format, Length, OS, DI.IsLittleEndian);
443 
444  uint64_t AbbrevTableOffset = 0;
445  if (Unit.AbbrOffset) {
446  AbbrevTableOffset = *Unit.AbbrOffset;
447  } else {
448  if (Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
449  DI.getAbbrevTableInfoByID(AbbrevTableID)) {
450  AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
451  } else {
452  // The current compilation unit may not have DIEs and it will not be
453  // able to find the associated abbrev table. We consume the error and
454  // assign 0 to the debug_abbrev_offset in such circumstances.
455  consumeError(AbbrevTableInfoOrErr.takeError());
456  }
457  }
458 
459  if (Unit.Version >= 5) {
460  writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
461  writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
462  writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
463  } else {
464  writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
465  writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
466  }
467 
468  OS.write(EntryBuffer.data(), EntryBuffer.size());
469  }
470 
471  return Error::success();
472 }
473 
474 static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
475  OS.write(File.Name.data(), File.Name.size());
476  OS.write('\0');
477  encodeULEB128(File.DirIdx, OS);
478  encodeULEB128(File.ModTime, OS);
479  encodeULEB128(File.Length, OS);
480 }
481 
483  uint8_t AddrSize, bool IsLittleEndian,
484  raw_ostream &OS) {
485  // The first byte of extended opcodes is a zero byte. The next bytes are an
486  // ULEB128 integer giving the number of bytes in the instruction itself (does
487  // not include the first zero byte or the size). We serialize the instruction
488  // itself into the OpBuffer and then write the size of the buffer and the
489  // buffer to the real output stream.
490  std::string OpBuffer;
491  raw_string_ostream OpBufferOS(OpBuffer);
492  writeInteger((uint8_t)Op.SubOpcode, OpBufferOS, IsLittleEndian);
493  switch (Op.SubOpcode) {
494  case dwarf::DW_LNE_set_address:
495  cantFail(writeVariableSizedInteger(Op.Data, AddrSize, OpBufferOS,
496  IsLittleEndian));
497  break;
498  case dwarf::DW_LNE_define_file:
499  emitFileEntry(OpBufferOS, Op.FileEntry);
500  break;
501  case dwarf::DW_LNE_set_discriminator:
502  encodeULEB128(Op.Data, OpBufferOS);
503  break;
504  case dwarf::DW_LNE_end_sequence:
505  break;
506  default:
507  for (auto OpByte : Op.UnknownOpcodeData)
508  writeInteger((uint8_t)OpByte, OpBufferOS, IsLittleEndian);
509  }
510  uint64_t ExtLen = Op.ExtLen.getValueOr(OpBuffer.size());
511  encodeULEB128(ExtLen, OS);
512  OS.write(OpBuffer.data(), OpBuffer.size());
513 }
514 
516  uint8_t OpcodeBase, uint8_t AddrSize,
517  raw_ostream &OS, bool IsLittleEndian) {
518  writeInteger((uint8_t)Op.Opcode, OS, IsLittleEndian);
519  if (Op.Opcode == 0) {
520  writeExtendedOpcode(Op, AddrSize, IsLittleEndian, OS);
521  } else if (Op.Opcode < OpcodeBase) {
522  switch (Op.Opcode) {
523  case dwarf::DW_LNS_copy:
524  case dwarf::DW_LNS_negate_stmt:
525  case dwarf::DW_LNS_set_basic_block:
526  case dwarf::DW_LNS_const_add_pc:
527  case dwarf::DW_LNS_set_prologue_end:
528  case dwarf::DW_LNS_set_epilogue_begin:
529  break;
530 
531  case dwarf::DW_LNS_advance_pc:
532  case dwarf::DW_LNS_set_file:
533  case dwarf::DW_LNS_set_column:
534  case dwarf::DW_LNS_set_isa:
535  encodeULEB128(Op.Data, OS);
536  break;
537 
538  case dwarf::DW_LNS_advance_line:
539  encodeSLEB128(Op.SData, OS);
540  break;
541 
542  case dwarf::DW_LNS_fixed_advance_pc:
543  writeInteger((uint16_t)Op.Data, OS, IsLittleEndian);
544  break;
545 
546  default:
547  for (auto OpData : Op.StandardOpcodeData) {
548  encodeULEB128(OpData, OS);
549  }
550  }
551  }
552 }
553 
554 static std::vector<uint8_t>
556  // If the opcode_base field isn't specified, we returns the
557  // standard_opcode_lengths array according to the version by default.
558  std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
559  0, 0, 1, 0, 0, 1};
560  if (Version == 2) {
561  // DWARF v2 uses the same first 9 standard opcodes as v3-5.
562  StandardOpcodeLengths.resize(9);
563  } else if (OpcodeBase) {
564  StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
565  }
566  return StandardOpcodeLengths;
567 }
568 
570  for (const DWARFYAML::LineTable &LineTable : DI.DebugLines) {
571  // Buffer holds the bytes following the header_length (or prologue_length in
572  // DWARFv2) field to the end of the line number program itself.
573  std::string Buffer;
574  raw_string_ostream BufferOS(Buffer);
575 
577  // TODO: Add support for emitting DWARFv5 line table.
578  if (LineTable.Version >= 4)
583 
584  std::vector<uint8_t> StandardOpcodeLengths =
587  uint8_t OpcodeBase = LineTable.OpcodeBase
589  : StandardOpcodeLengths.size() + 1;
590  writeInteger(OpcodeBase, BufferOS, DI.IsLittleEndian);
591  for (uint8_t OpcodeLength : StandardOpcodeLengths)
592  writeInteger(OpcodeLength, BufferOS, DI.IsLittleEndian);
593 
594  for (StringRef IncludeDir : LineTable.IncludeDirs) {
595  BufferOS.write(IncludeDir.data(), IncludeDir.size());
596  BufferOS.write('\0');
597  }
598  BufferOS.write('\0');
599 
600  for (const DWARFYAML::File &File : LineTable.Files)
601  emitFileEntry(BufferOS, File);
602  BufferOS.write('\0');
603 
604  uint64_t HeaderLength =
606 
608  writeLineTableOpcode(Op, OpcodeBase, DI.Is64BitAddrSize ? 8 : 4, BufferOS,
609  DI.IsLittleEndian);
610 
611  uint64_t Length;
612  if (LineTable.Length) {
613  Length = *LineTable.Length;
614  } else {
615  Length = 2; // sizeof(version)
616  Length +=
617  (LineTable.Format == dwarf::DWARF64 ? 8 : 4); // sizeof(header_length)
618  Length += Buffer.size();
619  }
620 
623  writeDWARFOffset(HeaderLength, LineTable.Format, OS, DI.IsLittleEndian);
624  OS.write(Buffer.data(), Buffer.size());
625  }
626 
627  return Error::success();
628 }
629 
631  for (const AddrTableEntry &TableEntry : *DI.DebugAddr) {
632  uint8_t AddrSize;
633  if (TableEntry.AddrSize)
634  AddrSize = *TableEntry.AddrSize;
635  else
636  AddrSize = DI.Is64BitAddrSize ? 8 : 4;
637 
638  uint64_t Length;
639  if (TableEntry.Length)
640  Length = (uint64_t)*TableEntry.Length;
641  else
642  // 2 (version) + 1 (address_size) + 1 (segment_selector_size) = 4
643  Length = 4 + (AddrSize + TableEntry.SegSelectorSize) *
644  TableEntry.SegAddrPairs.size();
645 
646  writeInitialLength(TableEntry.Format, Length, OS, DI.IsLittleEndian);
647  writeInteger((uint16_t)TableEntry.Version, OS, DI.IsLittleEndian);
648  writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
649  writeInteger((uint8_t)TableEntry.SegSelectorSize, OS, DI.IsLittleEndian);
650 
651  for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) {
652  if (TableEntry.SegSelectorSize != yaml::Hex8{0})
653  if (Error Err = writeVariableSizedInteger(Pair.Segment,
654  TableEntry.SegSelectorSize,
655  OS, DI.IsLittleEndian))
657  "unable to write debug_addr segment: %s",
658  toString(std::move(Err)).c_str());
659  if (AddrSize != 0)
660  if (Error Err = writeVariableSizedInteger(Pair.Address, AddrSize, OS,
661  DI.IsLittleEndian))
663  "unable to write debug_addr address: %s",
664  toString(std::move(Err)).c_str());
665  }
666  }
667 
668  return Error::success();
669 }
670 
672  assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call");
673  for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) {
674  uint64_t Length;
675  if (Table.Length)
676  Length = *Table.Length;
677  else
678  // sizeof(version) + sizeof(padding) = 4
679  Length =
680  4 + Table.Offsets.size() * (Table.Format == dwarf::DWARF64 ? 8 : 4);
681 
682  writeInitialLength(Table.Format, Length, OS, DI.IsLittleEndian);
685 
686  for (uint64_t Offset : Table.Offsets)
688  }
689 
690  return Error::success();
691 }
692 
693 static Error checkOperandCount(StringRef EncodingString,
694  ArrayRef<yaml::Hex64> Values,
695  uint64_t ExpectedOperands) {
696  if (Values.size() != ExpectedOperands)
697  return createStringError(
699  "invalid number (%zu) of operands for the operator: %s, %" PRIu64
700  " expected",
701  Values.size(), EncodingString.str().c_str(), ExpectedOperands);
702 
703  return Error::success();
704 }
705 
707  uint64_t Addr, uint8_t AddrSize,
708  bool IsLittleEndian) {
709  if (Error Err = writeVariableSizedInteger(Addr, AddrSize, OS, IsLittleEndian))
711  "unable to write address for the operator %s: %s",
712  EncodingName.str().c_str(),
713  toString(std::move(Err)).c_str());
714 
715  return Error::success();
716 }
717 
718 static Expected<uint64_t>
721  uint8_t AddrSize, bool IsLittleEndian) {
722  auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
724  Operation.Values, ExpectedOperands);
725  };
726 
727  uint64_t ExpressionBegin = OS.tell();
728  writeInteger((uint8_t)Operation.Operator, OS, IsLittleEndian);
729  switch (Operation.Operator) {
730  case dwarf::DW_OP_consts:
731  if (Error Err = CheckOperands(1))
732  return std::move(Err);
733  encodeSLEB128(Operation.Values[0], OS);
734  break;
735  case dwarf::DW_OP_stack_value:
736  if (Error Err = CheckOperands(0))
737  return std::move(Err);
738  break;
739  default:
740  StringRef EncodingStr = dwarf::OperationEncodingString(Operation.Operator);
742  "DWARF expression: " +
743  (EncodingStr.empty()
744  ? "0x" + utohexstr(Operation.Operator)
745  : EncodingStr) +
746  " is not supported");
747  }
748  return OS.tell() - ExpressionBegin;
749 }
750 
752  const DWARFYAML::RnglistEntry &Entry,
753  uint8_t AddrSize,
754  bool IsLittleEndian) {
755  uint64_t BeginOffset = OS.tell();
756  writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
757 
758  StringRef EncodingName = dwarf::RangeListEncodingString(Entry.Operator);
759 
760  auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
761  return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
762  };
763 
764  auto WriteAddress = [&](uint64_t Addr) -> Error {
765  return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
766  IsLittleEndian);
767  };
768 
769  switch (Entry.Operator) {
770  case dwarf::DW_RLE_end_of_list:
771  if (Error Err = CheckOperands(0))
772  return std::move(Err);
773  break;
774  case dwarf::DW_RLE_base_addressx:
775  if (Error Err = CheckOperands(1))
776  return std::move(Err);
777  encodeULEB128(Entry.Values[0], OS);
778  break;
779  case dwarf::DW_RLE_startx_endx:
780  case dwarf::DW_RLE_startx_length:
781  case dwarf::DW_RLE_offset_pair:
782  if (Error Err = CheckOperands(2))
783  return std::move(Err);
784  encodeULEB128(Entry.Values[0], OS);
785  encodeULEB128(Entry.Values[1], OS);
786  break;
787  case dwarf::DW_RLE_base_address:
788  if (Error Err = CheckOperands(1))
789  return std::move(Err);
790  if (Error Err = WriteAddress(Entry.Values[0]))
791  return std::move(Err);
792  break;
793  case dwarf::DW_RLE_start_end:
794  if (Error Err = CheckOperands(2))
795  return std::move(Err);
796  if (Error Err = WriteAddress(Entry.Values[0]))
797  return std::move(Err);
798  cantFail(WriteAddress(Entry.Values[1]));
799  break;
800  case dwarf::DW_RLE_start_length:
801  if (Error Err = CheckOperands(2))
802  return std::move(Err);
803  if (Error Err = WriteAddress(Entry.Values[0]))
804  return std::move(Err);
805  encodeULEB128(Entry.Values[1], OS);
806  break;
807  }
808 
809  return OS.tell() - BeginOffset;
810 }
811 
813  const DWARFYAML::LoclistEntry &Entry,
814  uint8_t AddrSize,
815  bool IsLittleEndian) {
816  uint64_t BeginOffset = OS.tell();
817  writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
818 
819  StringRef EncodingName = dwarf::LocListEncodingString(Entry.Operator);
820 
821  auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
822  return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
823  };
824 
825  auto WriteAddress = [&](uint64_t Addr) -> Error {
826  return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
827  IsLittleEndian);
828  };
829 
830  auto WriteDWARFOperations = [&]() -> Error {
831  std::string OpBuffer;
832  raw_string_ostream OpBufferOS(OpBuffer);
833  uint64_t DescriptionsLength = 0;
834 
835  for (const DWARFYAML::DWARFOperation &Op : Entry.Descriptions) {
836  if (Expected<uint64_t> OpSize =
837  writeDWARFExpression(OpBufferOS, Op, AddrSize, IsLittleEndian))
838  DescriptionsLength += *OpSize;
839  else
840  return OpSize.takeError();
841  }
842 
843  if (Entry.DescriptionsLength)
844  DescriptionsLength = *Entry.DescriptionsLength;
845  else
846  DescriptionsLength = OpBuffer.size();
847 
848  encodeULEB128(DescriptionsLength, OS);
849  OS.write(OpBuffer.data(), OpBuffer.size());
850 
851  return Error::success();
852  };
853 
854  switch (Entry.Operator) {
855  case dwarf::DW_LLE_end_of_list:
856  if (Error Err = CheckOperands(0))
857  return std::move(Err);
858  break;
859  case dwarf::DW_LLE_base_addressx:
860  if (Error Err = CheckOperands(1))
861  return std::move(Err);
862  encodeULEB128(Entry.Values[0], OS);
863  break;
864  case dwarf::DW_LLE_startx_endx:
865  case dwarf::DW_LLE_startx_length:
866  case dwarf::DW_LLE_offset_pair:
867  if (Error Err = CheckOperands(2))
868  return std::move(Err);
869  encodeULEB128(Entry.Values[0], OS);
870  encodeULEB128(Entry.Values[1], OS);
871  if (Error Err = WriteDWARFOperations())
872  return std::move(Err);
873  break;
874  case dwarf::DW_LLE_default_location:
875  if (Error Err = CheckOperands(0))
876  return std::move(Err);
877  if (Error Err = WriteDWARFOperations())
878  return std::move(Err);
879  break;
880  case dwarf::DW_LLE_base_address:
881  if (Error Err = CheckOperands(1))
882  return std::move(Err);
883  if (Error Err = WriteAddress(Entry.Values[0]))
884  return std::move(Err);
885  break;
886  case dwarf::DW_LLE_start_end:
887  if (Error Err = CheckOperands(2))
888  return std::move(Err);
889  if (Error Err = WriteAddress(Entry.Values[0]))
890  return std::move(Err);
891  cantFail(WriteAddress(Entry.Values[1]));
892  if (Error Err = WriteDWARFOperations())
893  return std::move(Err);
894  break;
895  case dwarf::DW_LLE_start_length:
896  if (Error Err = CheckOperands(2))
897  return std::move(Err);
898  if (Error Err = WriteAddress(Entry.Values[0]))
899  return std::move(Err);
900  encodeULEB128(Entry.Values[1], OS);
901  if (Error Err = WriteDWARFOperations())
902  return std::move(Err);
903  break;
904  }
905 
906  return OS.tell() - BeginOffset;
907 }
908 
909 template <typename EntryType>
912  bool IsLittleEndian, bool Is64BitAddrSize) {
913  for (const DWARFYAML::ListTable<EntryType> &Table : Tables) {
914  // sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) +
915  // sizeof(offset_entry_count) = 8
916  uint64_t Length = 8;
917 
918  uint8_t AddrSize;
919  if (Table.AddrSize)
920  AddrSize = *Table.AddrSize;
921  else
922  AddrSize = Is64BitAddrSize ? 8 : 4;
923 
924  // Since the length of the current range/location lists entry is
925  // undetermined yet, we firstly write the content of the range/location
926  // lists to a buffer to calculate the length and then serialize the buffer
927  // content to the actual output stream.
928  std::string ListBuffer;
929  raw_string_ostream ListBufferOS(ListBuffer);
930 
931  // Offsets holds offsets for each range/location list. The i-th element is
932  // the offset from the beginning of the first range/location list to the
933  // location of the i-th range list.
934  std::vector<uint64_t> Offsets;
935 
936  for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
937  Offsets.push_back(ListBufferOS.tell());
938  if (List.Content) {
939  List.Content->writeAsBinary(ListBufferOS, UINT64_MAX);
940  Length += List.Content->binary_size();
941  } else if (List.Entries) {
942  for (const EntryType &Entry : *List.Entries) {
943  Expected<uint64_t> EntrySize =
944  writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
945  if (!EntrySize)
946  return EntrySize.takeError();
947  Length += *EntrySize;
948  }
949  }
950  }
951 
952  // If the offset_entry_count field isn't specified, yaml2obj will infer it
953  // from the 'Offsets' field in the YAML description. If the 'Offsets' field
954  // isn't specified either, yaml2obj will infer it from the auto-generated
955  // offsets.
956  uint32_t OffsetEntryCount;
957  if (Table.OffsetEntryCount)
958  OffsetEntryCount = *Table.OffsetEntryCount;
959  else
960  OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
961  uint64_t OffsetsSize =
962  OffsetEntryCount * (Table.Format == dwarf::DWARF64 ? 8 : 4);
963  Length += OffsetsSize;
964 
965  // If the length is specified in the YAML description, we use it instead of
966  // the actual length.
967  if (Table.Length)
968  Length = *Table.Length;
969 
970  writeInitialLength(Table.Format, Length, OS, IsLittleEndian);
971  writeInteger((uint16_t)Table.Version, OS, IsLittleEndian);
972  writeInteger((uint8_t)AddrSize, OS, IsLittleEndian);
973  writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian);
974  writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian);
975 
976  auto EmitOffsets = [&](ArrayRef<uint64_t> Offsets, uint64_t OffsetsSize) {
977  for (uint64_t Offset : Offsets)
978  writeDWARFOffset(OffsetsSize + Offset, Table.Format, OS,
979  IsLittleEndian);
980  };
981 
982  if (Table.Offsets)
983  EmitOffsets(ArrayRef<uint64_t>((const uint64_t *)Table.Offsets->data(),
984  Table.Offsets->size()),
985  0);
986  else if (OffsetEntryCount != 0)
987  EmitOffsets(Offsets, OffsetsSize);
988 
989  OS.write(ListBuffer.data(), ListBuffer.size());
990  }
991 
992  return Error::success();
993 }
994 
996  assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
997  return writeDWARFLists<DWARFYAML::RnglistEntry>(
999 }
1000 
1002  assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call");
1003  return writeDWARFLists<DWARFYAML::LoclistEntry>(
1004  OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize);
1005 }
1006 
1009  auto EmitFunc =
1010  StringSwitch<
1011  std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName)
1012  .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev)
1013  .Case("debug_addr", DWARFYAML::emitDebugAddr)
1014  .Case("debug_aranges", DWARFYAML::emitDebugAranges)
1015  .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames)
1016  .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes)
1017  .Case("debug_info", DWARFYAML::emitDebugInfo)
1018  .Case("debug_line", DWARFYAML::emitDebugLine)
1019  .Case("debug_loclists", DWARFYAML::emitDebugLoclists)
1020  .Case("debug_pubnames", DWARFYAML::emitDebugPubnames)
1021  .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes)
1022  .Case("debug_ranges", DWARFYAML::emitDebugRanges)
1023  .Case("debug_rnglists", DWARFYAML::emitDebugRnglists)
1024  .Case("debug_str", DWARFYAML::emitDebugStr)
1025  .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets)
1026  .Default([&](raw_ostream &, const DWARFYAML::Data &) {
1028  SecName + " is not supported");
1029  });
1030 
1031  return EmitFunc;
1032 }
1033 
1034 static Error
1036  StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
1037  std::string Data;
1038  raw_string_ostream DebugInfoStream(Data);
1039 
1040  auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec);
1041 
1042  if (Error Err = EmitFunc(DebugInfoStream, DI))
1043  return Err;
1044  DebugInfoStream.flush();
1045  if (!Data.empty())
1046  OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data);
1047 
1048  return Error::success();
1049 }
1050 
1052 DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian,
1053  bool Is64BitAddrSize) {
1054  auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
1055  *static_cast<SMDiagnostic *>(DiagContext) = Diag;
1056  };
1057 
1058  SMDiagnostic GeneratedDiag;
1059  yaml::Input YIn(YAMLString, /*Ctxt=*/nullptr, CollectDiagnostic,
1060  &GeneratedDiag);
1061 
1062  DWARFYAML::Data DI;
1063  DI.IsLittleEndian = IsLittleEndian;
1064  DI.Is64BitAddrSize = Is64BitAddrSize;
1065 
1066  YIn >> DI;
1067  if (YIn.error())
1068  return createStringError(YIn.error(), GeneratedDiag.getMessage());
1069 
1071  Error Err = Error::success();
1072 
1073  for (StringRef SecName : DI.getNonEmptySectionNames())
1074  Err = joinErrors(std::move(Err),
1075  emitDebugSectionImpl(DI, SecName, DebugSections));
1076 
1077  if (Err)
1078  return std::move(Err);
1079  return std::move(DebugSections);
1080 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MemoryBuffer.h
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:148
llvm::DWARFYAML::DWARFOperation
Definition: DWARFYAML.h:177
llvm::raw_ostream::tell
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:135
llvm::errc::invalid_argument
@ invalid_argument
llvm::DWARFYAML::LineTable::Version
uint16_t Version
Definition: DWARFYAML.h:141
MathExtras.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
writeVariableSizedInteger
static Error writeVariableSizedInteger(uint64_t Integer, size_t Size, raw_ostream &OS, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:48
llvm::DWARFYAML::LineTable::LineRange
uint8_t LineRange
Definition: DWARFYAML.h:147
llvm::SMDiagnostic::getMessage
StringRef getMessage() const
Definition: SourceMgr.h:281
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::DWARFYAML::AddrTableEntry::SegSelectorSize
yaml::Hex8 SegSelectorSize
Definition: DWARFYAML.h:165
llvm::sys::swapByteOrder
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:158
llvm::DWARFYAML::Data::DebugRnglists
Optional< std::vector< ListTable< RnglistEntry > > > DebugRnglists
Definition: DWARFYAML.h:228
llvm::DWARFYAML::PubSection::Format
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:84
T
llvm::raw_ostream::write_zeros
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
Definition: raw_ostream.cpp:502
StringRef.h
llvm::DWARFYAML::StringOffsetsTable
Definition: DWARFYAML.h:169
llvm::DWARFYAML::LineTable::DefaultIsStmt
uint8_t DefaultIsStmt
Definition: DWARFYAML.h:145
llvm::DWARFYAML::LineTable::LineBase
uint8_t LineBase
Definition: DWARFYAML.h:146
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:625
llvm::DWARFYAML::AddrTableEntry::AddrSize
Optional< yaml::Hex8 > AddrSize
Definition: DWARFYAML.h:164
llvm::toString
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:1020
Host.h
llvm::dwarf::Form
Form
Definition: Dwarf.h:131
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::DWARFYAML::Data::DebugLoclists
Optional< std::vector< ListTable< LoclistEntry > > > DebugLoclists
Definition: DWARFYAML.h:229
llvm::DWARFYAML::Data::IsLittleEndian
bool IsLittleEndian
Definition: DWARFYAML.h:211
llvm::DWARFYAML::PubSection::Length
yaml::Hex64 Length
Definition: DWARFYAML.h:85
Error.h
SwapByteOrder.h
llvm::dwarf::DW_LENGTH_DWARF64
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition: Dwarf.h:56
Errc.h
llvm::DWARFYAML::LineTable::OpcodeBase
Optional< uint8_t > OpcodeBase
Definition: DWARFYAML.h:148
llvm::DWARFYAML::StringOffsetsTable::Offsets
std::vector< yaml::Hex64 > Offsets
Definition: DWARFYAML.h:174
llvm::DWARFYAML::StringOffsetsTable::Version
yaml::Hex16 Version
Definition: DWARFYAML.h:172
llvm::dwarf::FormParams::AddrSize
uint8_t AddrSize
Definition: Dwarf.h:650
llvm::dwarf::RangeListEncodingString
StringRef RangeListEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:514
llvm::DWARFYAML::Data::DebugLines
std::vector< LineTable > DebugLines
Definition: DWARFYAML.h:227
llvm::DWARFYAML::LineTable::PrologueLength
Optional< uint64_t > PrologueLength
Definition: DWARFYAML.h:142
llvm::DWARFYAML::LineTableOpcode
Definition: DWARFYAML.h:127
llvm::Optional< uint8_t >
llvm::DWARFYAML::LineTable::IncludeDirs
std::vector< StringRef > IncludeDirs
Definition: DWARFYAML.h:150
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::DWARFYAML::RnglistEntry
Definition: DWARFYAML.h:182
llvm::DWARFYAML::emitDebugAranges
Error emitDebugAranges(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:140
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1035
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::DWARFYAML::emitDebugAbbrev
Error emitDebugAbbrev(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:131
llvm::DWARFYAML::Data
Definition: DWARFYAML.h:210
llvm::DWARFYAML::Data::DebugAddr
Optional< std::vector< AddrTableEntry > > DebugAddr
Definition: DWARFYAML.h:218
llvm::DWARFYAML::AddrTableEntry::Format
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:161
llvm::DWARFYAML::emitDebugAddr
Error emitDebugAddr(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:630
llvm::DWARFYAML::Data::DebugRanges
Optional< std::vector< Ranges > > DebugRanges
Definition: DWARFYAML.h:217
writeDWARFLists
static Error writeDWARFLists(raw_ostream &OS, ArrayRef< DWARFYAML::ListTable< EntryType >> Tables, bool IsLittleEndian, bool Is64BitAddrSize)
Definition: DWARFEmitter.cpp:910
llvm::DWARFYAML::Data::PubTypes
Optional< PubSection > PubTypes
Definition: DWARFYAML.h:220
llvm::DWARFYAML::SegAddrPair::Address
yaml::Hex64 Address
Definition: DWARFYAML.h:157
llvm::encodeSLEB128
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
Operation
PowerPC Reduce CR logical Operation
Definition: PPCReduceCRLogicals.cpp:734
llvm::DWARFYAML::Data::DebugAbbrev
std::vector< AbbrevTable > DebugAbbrev
Definition: DWARFYAML.h:213
llvm::DWARFYAML::StringOffsetsTable::Padding
yaml::Hex16 Padding
Definition: DWARFYAML.h:173
writeListEntry
static Expected< uint64_t > writeListEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry, uint8_t AddrSize, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:751
llvm::DWARFYAML::PubSection::Version
uint16_t Version
Definition: DWARFYAML.h:86
llvm::SMDiagnostic
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:251
llvm::DWARFYAML::Data::PubNames
Optional< PubSection > PubNames
Definition: DWARFYAML.h:219
UINT64_MAX
#define UINT64_MAX
Definition: DataTypes.h:77
Integer
So we should use XX3Form_Rcr to implement instrinsic Convert DP outs ins xscvdpsp No builtin are required Round &Convert QP DP(dword[1] is set to zero) No builtin are required Round to Quad Precision Integer
Definition: README_P9.txt:366
llvm::raw_ostream::write
raw_ostream & write(unsigned char C)
Definition: raw_ostream.cpp:220
llvm::DWARFYAML::emitDebugPubtypes
Error emitDebugPubtypes(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:247
llvm::DWARFYAML::Abbrev::Attributes
std::vector< AttributeAbbrev > Attributes
Definition: DWARFYAML.h:40
llvm::DWARFYAML::emitDebugStrOffsets
Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:671
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::DWARFYAML::emitDebugInfo
Error emitDebugInfo(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:406
llvm::raw_ostream::flush
void flush()
Definition: raw_ostream.h:186
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:991
llvm::DWARFYAML::Abbrev
Definition: DWARFYAML.h:36
StringMap.h
llvm::DWARFYAML::Data::GNUPubTypes
Optional< PubSection > GNUPubTypes
Definition: DWARFYAML.h:223
ZeroFillBytes
static void ZeroFillBytes(raw_ostream &OS, size_t Size)
Definition: DWARFEmitter.cpp:65
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:92
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:245
writeExtendedOpcode
static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t AddrSize, bool IsLittleEndian, raw_ostream &OS)
Definition: DWARFEmitter.cpp:482
SourceMgr.h
llvm::DWARFYAML::Data::GNUPubNames
Optional< PubSection > GNUPubNames
Definition: DWARFYAML.h:222
llvm::DWARFYAML::LineTable::MinInstLength
uint8_t MinInstLength
Definition: DWARFYAML.h:143
llvm::DWARFYAML::File
Definition: DWARFYAML.h:120
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:108
DWARFYAML.h
llvm::DWARFYAML::ListEntries
Definition: DWARFYAML.h:194
writeInitialLength
static void writeInitialLength(const dwarf::DwarfFormat Format, const uint64_t Length, raw_ostream &OS, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:70
llvm::DWARFYAML::PubSection::Entries
std::vector< PubEntry > Entries
Definition: DWARFYAML.h:89
llvm::Optional::getValueOr
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION
Definition: Optional.h:297
getStandardOpcodeLengths
static std::vector< uint8_t > getStandardOpcodeLengths(uint16_t Version, Optional< uint8_t > OpcodeBase)
Definition: DWARFEmitter.cpp:555
llvm::DWARFYAML::LineTable::Format
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:139
llvm::DWARFYAML::StringOffsetsTable::Length
Optional< yaml::Hex64 > Length
Definition: DWARFYAML.h:171
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:408
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::DWARFYAML::getDWARFEmitterByName
std::function< Error(raw_ostream &, const Data &)> getDWARFEmitterByName(StringRef SecName)
Definition: DWARFEmitter.h:48
LEB128.h
writeDIE
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)
Definition: DWARFEmitter.cpp:264
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:428
ArrayRef.h
llvm::dwarf::FormParams
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:648
llvm::DWARFYAML::SegAddrPair
Definition: DWARFYAML.h:155
llvm::DWARFYAML::LineTable::StandardOpcodeLengths
Optional< std::vector< uint8_t > > StandardOpcodeLengths
Definition: DWARFYAML.h:149
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DWARFYAML::PubSection
Definition: DWARFYAML.h:83
llvm::DWARFYAML::Unit
Definition: DWARFYAML.h:109
llvm::DWARFYAML::Unit::AddrSize
Optional< uint8_t > AddrSize
Definition: DWARFYAML.h:113
llvm::DWARFYAML::LoclistEntry
Definition: DWARFYAML.h:187
llvm::DWARFYAML::LineTable::Opcodes
std::vector< LineTableOpcode > Opcodes
Definition: DWARFYAML.h:152
llvm::DWARFYAML::Unit::Format
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:110
llvm::dwarf::FormParams::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:663
emitDebugSectionImpl
static Error emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec, StringMap< std::unique_ptr< MemoryBuffer >> &OutputBuffers)
Definition: DWARFEmitter.cpp:1035
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::DWARFYAML::StringOffsetsTable::Format
dwarf::DwarfFormat Format
Definition: DWARFYAML.h:170
llvm::DWARFYAML::AddrTableEntry::Length
Optional< yaml::Hex64 > Length
Definition: DWARFYAML.h:162
llvm::DWARFYAML::LineTable::MaxOpsPerInst
uint8_t MaxOpsPerInst
Definition: DWARFYAML.h:144
llvm::DWARFYAML::Unit::Type
llvm::dwarf::UnitType Type
Definition: DWARFYAML.h:114
llvm::DWARFYAML::PubSection::UnitOffset
uint32_t UnitOffset
Definition: DWARFYAML.h:87
YAMLTraits.h
llvm::DWARFYAML::Data::getAbbrevTableContentByIndex
StringRef getAbbrevTableContentByIndex(uint64_t Index) const
Definition: DWARFEmitter.cpp:96
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
emitFileEntry
static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File)
Definition: DWARFEmitter.cpp:474
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
Dwarf.h
llvm::DWARFYAML::AddrTableEntry
Definition: DWARFYAML.h:160
llvm::DWARFYAML::Data::CompileUnits
std::vector< Unit > CompileUnits
Definition: DWARFYAML.h:225
llvm::errc::not_supported
@ not_supported
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:737
uint32_t
writeDWARFExpression
static Expected< uint64_t > writeDWARFExpression(raw_ostream &OS, const DWARFYAML::DWARFOperation &Operation, uint8_t AddrSize, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:719
writeDWARFOffset
static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, raw_ostream &OS, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:81
llvm::DWARFYAML::emitDebugLine
Error emitDebugLine(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:569
llvm::DWARFYAML::Entry
Definition: DWARFYAML.h:98
llvm::DWARFYAML::emitDebugLoclists
Error emitDebugLoclists(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:1001
DWARFEmitter.h
emitPubSection
static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, bool IsLittleEndian, bool IsGNUPubSec=false)
Definition: DWARFEmitter.cpp:226
llvm::DWARFYAML::emitDebugRnglists
Error emitDebugRnglists(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:995
llvm::DWARFYAML::Unit::Length
Optional< yaml::Hex64 > Length
Definition: DWARFYAML.h:111
llvm::DWARFYAML::emitDebugPubnames
Error emitDebugPubnames(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:242
llvm::DWARFYAML::Data::DebugStrOffsets
Optional< std::vector< StringOffsetsTable > > DebugStrOffsets
Definition: DWARFYAML.h:215
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::DWARFYAML::ListTable
Definition: DWARFYAML.h:199
llvm::DWARFYAML::LineTable
Definition: DWARFYAML.h:138
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1231
writeLineTableOpcode
static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op, uint8_t OpcodeBase, uint8_t AddrSize, raw_ostream &OS, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:515
uint16_t
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::DWARFYAML::Unit::Entries
std::vector< Entry > Entries
Definition: DWARFYAML.h:117
llvm::c_str
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Definition: WindowsSupport.h:193
llvm::DWARFYAML::emitDebugSections
Expected< StringMap< std::unique_ptr< MemoryBuffer > > > emitDebugSections(StringRef YAMLString, bool IsLittleEndian=sys::IsLittleEndianHost, bool Is64BitAddrSize=true)
Definition: DWARFEmitter.cpp:1052
llvm::DWARFYAML::emitDebugGNUPubnames
Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:252
StringSwitch.h
llvm::DWARFYAML::Data::Is64BitAddrSize
bool Is64BitAddrSize
Definition: DWARFYAML.h:212
writeListEntryAddress
static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS, uint64_t Addr, uint8_t AddrSize, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:706
llvm::DWARFYAML::AddrTableEntry::SegAddrPairs
std::vector< SegAddrPair > SegAddrPairs
Definition: DWARFYAML.h:166
llvm::DWARFYAML::LineTable::Length
Optional< uint64_t > Length
Definition: DWARFYAML.h:140
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:589
llvm::DWARFYAML::emitDebugRanges
Error emitDebugRanges(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:189
llvm::DWARFYAML::Data::getAbbrevTableInfoByID
Expected< AbbrevTableInfo > getAbbrevTableInfoByID(uint64_t ID) const
Definition: DWARFYAML.cpp:59
llvm::DWARFYAML::Unit::AbbrOffset
Optional< yaml::Hex64 > AbbrOffset
Definition: DWARFYAML.h:116
llvm::sys::IsLittleEndianHost
static const bool IsLittleEndianHost
Definition: SwapByteOrder.h:101
List
const NodeList & List
Definition: RDFGraph.cpp:201
llvm::DWARFYAML::LineTable::Files
std::vector< File > Files
Definition: DWARFYAML.h:151
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::DWARFYAML::emitDebugStr
Error emitDebugStr(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:87
llvm::DWARFYAML::Data::DebugAranges
Optional< std::vector< ARange > > DebugAranges
Definition: DWARFYAML.h:216
llvm::encodeULEB128
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:149
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
llvm::dwarf::DWARF64
@ DWARF64
Definition: Dwarf.h:92
raw_ostream.h
llvm::SI::KernelInputOffsets::Offsets
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1262
llvm::DWARFYAML::SegAddrPair::Segment
yaml::Hex64 Segment
Definition: DWARFYAML.h:156
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::MemoryBuffer::getMemBufferCopy
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.
Definition: MemoryBuffer.cpp:136
checkOperandCount
static Error checkOperandCount(StringRef EncodingString, ArrayRef< yaml::Hex64 > Values, uint64_t ExpectedOperands)
Definition: DWARFEmitter.cpp:693
llvm::DWARFYAML::Data::DebugStrings
Optional< std::vector< StringRef > > DebugStrings
Definition: DWARFYAML.h:214
llvm::DWARFYAML::PubSection::UnitSize
uint32_t UnitSize
Definition: DWARFYAML.h:88
File
Instrumentation for Order File
Definition: InstrOrderFile.cpp:205
writeInteger
static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian)
Definition: DWARFEmitter.cpp:42
llvm::dwarf::OperationEncodingString
StringRef OperationEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:138
llvm::dwarf::LocListEncodingString
StringRef LocListEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:525
llvm::DWARFYAML::Unit::AbbrevTableID
Optional< uint64_t > AbbrevTableID
Definition: DWARFYAML.h:115
llvm::DWARFYAML::AddrTableEntry::Version
yaml::Hex16 Version
Definition: DWARFYAML.h:163
llvm::dwarf::FormParams::getRefAddrByteSize
uint8_t getRefAddrByteSize() const
The definition of the size of form DW_FORM_ref_addr depends on the version.
Definition: Dwarf.h:656
llvm::DWARFYAML::emitDebugGNUPubtypes
Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI)
Definition: DWARFEmitter.cpp:258
llvm::DWARFYAML::Unit::Version
uint16_t Version
Definition: DWARFYAML.h:112