LLVM  15.0.0git
XCOFFEmitter.cpp
Go to the documentation of this file.
1 //===- yaml2xcoff - Convert YAML to a xcoff object file -------------------===//
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 xcoff component of yaml2obj.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/Support/LEB128.h"
24 
25 using namespace llvm;
26 
27 namespace {
28 
29 constexpr unsigned DefaultSectionAlign = 4;
30 constexpr int16_t MaxSectionIndex = INT16_MAX;
31 constexpr uint32_t MaxRawDataSize = UINT32_MAX;
32 
33 class XCOFFWriter {
34 public:
35  XCOFFWriter(XCOFFYAML::Object &Obj, raw_ostream &OS, yaml::ErrorHandler EH)
36  : Obj(Obj), W(OS, support::big), ErrHandler(EH),
37  StrTblBuilder(StringTableBuilder::XCOFF) {
38  Is64Bit = Obj.Header.Magic == (llvm::yaml::Hex16)XCOFF::XCOFF64;
39  }
40  bool writeXCOFF();
41 
42 private:
43  bool nameShouldBeInStringTable(StringRef SymbolName);
44  bool initFileHeader(uint64_t CurrentOffset);
45  void initAuxFileHeader();
46  bool initSectionHeader(uint64_t &CurrentOffset);
47  bool initRelocations(uint64_t &CurrentOffset);
48  bool initStringTable();
49  bool assignAddressesAndIndices();
50 
51  void writeFileHeader();
52  void writeAuxFileHeader();
53  void writeSectionHeader();
54  bool writeSectionData();
55  bool writeRelocations();
56  bool writeSymbols();
57  void writeStringTable();
58 
59  void writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym);
60  void writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym);
61  void writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym);
62  void writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
63  void writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym);
64  void writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
65  void writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym);
66  void writeAuxSymbol(const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
67 
68  XCOFFYAML::Object &Obj;
69  bool Is64Bit = false;
71  yaml::ErrorHandler ErrHandler;
72  StringTableBuilder StrTblBuilder;
73  uint64_t StartOffset;
74  // Map the section name to its corrresponding section index.
75  DenseMap<StringRef, int16_t> SectionIndexMap = {
76  {StringRef("N_DEBUG"), XCOFF::N_DEBUG},
77  {StringRef("N_ABS"), XCOFF::N_ABS},
78  {StringRef("N_UNDEF"), XCOFF::N_UNDEF}};
79  XCOFFYAML::FileHeader InitFileHdr = Obj.Header;
80  XCOFFYAML::AuxiliaryHeader InitAuxFileHdr;
81  std::vector<XCOFFYAML::Section> InitSections = Obj.Sections;
82 };
83 
84 static void writeName(StringRef StrName, support::endian::Writer W) {
85  char Name[XCOFF::NameSize];
86  memset(Name, 0, XCOFF::NameSize);
87  char SrcName[] = "";
88  memcpy(Name, StrName.size() ? StrName.data() : SrcName, StrName.size());
90  W.write(NameRef);
91 }
92 
93 bool XCOFFWriter::nameShouldBeInStringTable(StringRef SymbolName) {
94  // For XCOFF64: The symbol name is always in the string table.
95  return (SymbolName.size() > XCOFF::NameSize) || Is64Bit;
96 }
97 
98 bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
99  for (XCOFFYAML::Section &InitSection : InitSections) {
100  if (!InitSection.Relocations.empty()) {
101  InitSection.NumberOfRelocations = InitSection.Relocations.size();
102  InitSection.FileOffsetToRelocations = CurrentOffset;
105  CurrentOffset += InitSection.NumberOfRelocations * RelSize;
106  if (CurrentOffset > MaxRawDataSize) {
107  ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
108  "exceeded when writing relocation data");
109  return false;
110  }
111  }
112  }
113  return true;
114 }
115 
116 bool XCOFFWriter::initSectionHeader(uint64_t &CurrentOffset) {
117  uint64_t CurrentSecAddr = 0;
118  for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
119  if (CurrentOffset > MaxRawDataSize) {
120  ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
121  "exceeded when writing section data");
122  return false;
123  }
124 
125  // Assign indices for sections.
126  if (InitSections[I].SectionName.size() &&
127  !SectionIndexMap[InitSections[I].SectionName]) {
128  // The section index starts from 1.
129  SectionIndexMap[InitSections[I].SectionName] = I + 1;
130  if ((I + 1) > MaxSectionIndex) {
131  ErrHandler("exceeded the maximum permitted section index of " +
132  Twine(MaxSectionIndex));
133  return false;
134  }
135  }
136 
137  // Calculate the physical/virtual address. This field should contain 0 for
138  // all sections except the text, data and bss sections.
139  if (InitSections[I].Flags != XCOFF::STYP_TEXT &&
140  InitSections[I].Flags != XCOFF::STYP_DATA &&
141  InitSections[I].Flags != XCOFF::STYP_BSS)
142  InitSections[I].Address = 0;
143  else
144  InitSections[I].Address = CurrentSecAddr;
145 
146  // Calculate the FileOffsetToData and data size for sections.
147  if (InitSections[I].SectionData.binary_size()) {
148  InitSections[I].FileOffsetToData = CurrentOffset;
149  CurrentOffset += InitSections[I].SectionData.binary_size();
150  // Ensure the offset is aligned to DefaultSectionAlign.
151  CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
152  InitSections[I].Size = CurrentOffset - InitSections[I].FileOffsetToData;
153  CurrentSecAddr += InitSections[I].Size;
154  }
155  }
156  return initRelocations(CurrentOffset);
157 }
158 
159 bool XCOFFWriter::initStringTable() {
160  if (Obj.StrTbl.RawContent) {
161  size_t RawSize = Obj.StrTbl.RawContent->binary_size();
162  if (Obj.StrTbl.Strings || Obj.StrTbl.Length) {
163  ErrHandler(
164  "can't specify Strings or Length when RawContent is specified");
165  return false;
166  }
167  if (Obj.StrTbl.ContentSize && *Obj.StrTbl.ContentSize < RawSize) {
168  ErrHandler("specified ContentSize (" + Twine(*Obj.StrTbl.ContentSize) +
169  ") is less than the RawContent data size (" + Twine(RawSize) +
170  ")");
171  return false;
172  }
173  return true;
174  }
175  if (Obj.StrTbl.ContentSize && *Obj.StrTbl.ContentSize <= 3) {
176  ErrHandler("ContentSize shouldn't be less than 4 without RawContent");
177  return false;
178  }
179 
180  // Build the string table.
181  StrTblBuilder.clear();
182 
183  if (Obj.StrTbl.Strings) {
184  // All specified strings should be added to the string table.
185  for (StringRef StringEnt : *Obj.StrTbl.Strings)
186  StrTblBuilder.add(StringEnt);
187 
188  size_t StrTblIdx = 0;
189  size_t NumOfStrings = Obj.StrTbl.Strings->size();
190  for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
191  if (nameShouldBeInStringTable(YamlSym.SymbolName)) {
192  if (StrTblIdx < NumOfStrings) {
193  // Overwrite the symbol name with the specified string.
194  YamlSym.SymbolName = (*Obj.StrTbl.Strings)[StrTblIdx];
195  ++StrTblIdx;
196  } else
197  // Names that are not overwritten are still stored in the string
198  // table.
199  StrTblBuilder.add(YamlSym.SymbolName);
200  }
201  }
202  } else {
203  for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
204  if (nameShouldBeInStringTable(YamlSym.SymbolName))
205  StrTblBuilder.add(YamlSym.SymbolName);
206  }
207  }
208 
209  // Check if the file name in the File Auxiliary Entry should be added to the
210  // string table.
211  for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
212  for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
213  YamlSym.AuxEntries) {
214  if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get()))
215  if (nameShouldBeInStringTable(AS->FileNameOrString.getValueOr("")))
216  StrTblBuilder.add(AS->FileNameOrString.getValueOr(""));
217  }
218  }
219 
220  StrTblBuilder.finalize();
221 
222  size_t StrTblSize = StrTblBuilder.getSize();
223  if (Obj.StrTbl.ContentSize && *Obj.StrTbl.ContentSize < StrTblSize) {
224  ErrHandler("specified ContentSize (" + Twine(*Obj.StrTbl.ContentSize) +
225  ") is less than the size of the data that would otherwise be "
226  "written (" +
227  Twine(StrTblSize) + ")");
228  return false;
229  }
230 
231  return true;
232 }
233 
234 bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
235  // The default format of the object file is XCOFF32.
236  InitFileHdr.Magic = XCOFF::XCOFF32;
237  InitFileHdr.NumberOfSections = Obj.Sections.size();
238  InitFileHdr.NumberOfSymTableEntries = Obj.Symbols.size();
239 
240  for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
241  uint32_t AuxCount = YamlSym.AuxEntries.size();
242  if (YamlSym.NumberOfAuxEntries && *YamlSym.NumberOfAuxEntries < AuxCount) {
243  ErrHandler("specified NumberOfAuxEntries " +
244  Twine(static_cast<uint32_t>(*YamlSym.NumberOfAuxEntries)) +
245  " is less than the actual number "
246  "of auxiliary entries " +
247  Twine(AuxCount));
248  return false;
249  }
250  YamlSym.NumberOfAuxEntries =
251  YamlSym.NumberOfAuxEntries.getValueOr(AuxCount);
252  // Add the number of auxiliary symbols to the total number.
253  InitFileHdr.NumberOfSymTableEntries += *YamlSym.NumberOfAuxEntries;
254  }
255 
256  // Calculate SymbolTableOffset for the file header.
257  if (InitFileHdr.NumberOfSymTableEntries) {
258  InitFileHdr.SymbolTableOffset = CurrentOffset;
259  CurrentOffset +=
260  InitFileHdr.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;
261  if (CurrentOffset > MaxRawDataSize) {
262  ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
263  "exceeded when writing symbols");
264  return false;
265  }
266  }
267  // TODO: Calculate FileOffsetToLineNumbers when line number supported.
268  return true;
269 }
270 
271 void XCOFFWriter::initAuxFileHeader() {
272  InitAuxFileHdr = *Obj.AuxHeader;
273  // In general, an object file might contain multiple sections of a given type,
274  // but in a loadable module, there must be exactly one .text, .data, .bss, and
275  // .loader section. A loadable object might also have one .tdata section and
276  // one .tbss section.
277  // Set these section-related values if not set explicitly. We assume that the
278  // input YAML matches the format of the loadable object, but if multiple input
279  // sections still have the same type, the first section with that type
280  // prevails.
281  for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
282  switch (InitSections[I].Flags) {
283  case XCOFF::STYP_TEXT:
284  if (!InitAuxFileHdr.TextSize)
285  InitAuxFileHdr.TextSize = InitSections[I].Size;
286  if (!InitAuxFileHdr.TextStartAddr)
287  InitAuxFileHdr.TextStartAddr = InitSections[I].Address;
288  if (!InitAuxFileHdr.SecNumOfText)
289  InitAuxFileHdr.SecNumOfText = I + 1;
290  break;
291  case XCOFF::STYP_DATA:
292  if (!InitAuxFileHdr.InitDataSize)
293  InitAuxFileHdr.InitDataSize = InitSections[I].Size;
294  if (!InitAuxFileHdr.DataStartAddr)
295  InitAuxFileHdr.DataStartAddr = InitSections[I].Address;
296  if (!InitAuxFileHdr.SecNumOfData)
297  InitAuxFileHdr.SecNumOfData = I + 1;
298  break;
299  case XCOFF::STYP_BSS:
300  if (!InitAuxFileHdr.BssDataSize)
301  InitAuxFileHdr.BssDataSize = InitSections[I].Size;
302  if (!InitAuxFileHdr.SecNumOfBSS)
303  InitAuxFileHdr.SecNumOfBSS = I + 1;
304  break;
305  case XCOFF::STYP_TDATA:
306  if (!InitAuxFileHdr.SecNumOfTData)
307  InitAuxFileHdr.SecNumOfTData = I + 1;
308  break;
309  case XCOFF::STYP_TBSS:
310  if (!InitAuxFileHdr.SecNumOfTBSS)
311  InitAuxFileHdr.SecNumOfTBSS = I + 1;
312  break;
313  case XCOFF::STYP_LOADER:
314  if (!InitAuxFileHdr.SecNumOfLoader)
315  InitAuxFileHdr.SecNumOfLoader = I + 1;
316  break;
317  default:
318  break;
319  }
320  }
321 }
322 
323 bool XCOFFWriter::assignAddressesAndIndices() {
324  uint64_t FileHdrSize =
326  uint64_t AuxFileHdrSize = 0;
327  if (Obj.AuxHeader)
328  AuxFileHdrSize = Obj.Header.AuxHeaderSize
329  ? Obj.Header.AuxHeaderSize
330  : (Is64Bit ? XCOFF::AuxFileHeaderSize64
332  uint64_t SecHdrSize =
334  uint64_t CurrentOffset =
335  FileHdrSize + AuxFileHdrSize + InitSections.size() * SecHdrSize;
336 
337  // Calculate section header info.
338  if (!initSectionHeader(CurrentOffset))
339  return false;
340  InitFileHdr.AuxHeaderSize = AuxFileHdrSize;
341 
342  // Calculate file header info.
343  if (!initFileHeader(CurrentOffset))
344  return false;
345 
346  // Initialize the auxiliary file header.
347  if (Obj.AuxHeader)
348  initAuxFileHeader();
349 
350  // Initialize the string table.
351  return initStringTable();
352 }
353 
354 void XCOFFWriter::writeFileHeader() {
355  W.write<uint16_t>(Obj.Header.Magic ? Obj.Header.Magic : InitFileHdr.Magic);
356  W.write<uint16_t>(Obj.Header.NumberOfSections ? Obj.Header.NumberOfSections
357  : InitFileHdr.NumberOfSections);
358  W.write<int32_t>(Obj.Header.TimeStamp);
359  if (Is64Bit) {
360  W.write<uint64_t>(Obj.Header.SymbolTableOffset
361  ? Obj.Header.SymbolTableOffset
362  : InitFileHdr.SymbolTableOffset);
363  W.write<uint16_t>(InitFileHdr.AuxHeaderSize);
364  W.write<uint16_t>(Obj.Header.Flags);
365  W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
366  ? Obj.Header.NumberOfSymTableEntries
367  : InitFileHdr.NumberOfSymTableEntries);
368  } else {
369  W.write<uint32_t>(Obj.Header.SymbolTableOffset
370  ? Obj.Header.SymbolTableOffset
371  : InitFileHdr.SymbolTableOffset);
372  W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
373  ? Obj.Header.NumberOfSymTableEntries
374  : InitFileHdr.NumberOfSymTableEntries);
375  W.write<uint16_t>(InitFileHdr.AuxHeaderSize);
376  W.write<uint16_t>(Obj.Header.Flags);
377  }
378 }
379 
380 void XCOFFWriter::writeAuxFileHeader() {
381  W.write<uint16_t>(InitAuxFileHdr.Magic.getValueOr(yaml::Hex16(1)));
382  W.write<uint16_t>(InitAuxFileHdr.Version.getValueOr(yaml::Hex16(1)));
383  if (Is64Bit) {
384  W.OS.write_zeros(4); // Reserved for debugger.
385  W.write<uint64_t>(InitAuxFileHdr.TextStartAddr.getValueOr(yaml::Hex64(0)));
386  W.write<uint64_t>(InitAuxFileHdr.DataStartAddr.getValueOr(yaml::Hex64(0)));
387  W.write<uint64_t>(InitAuxFileHdr.TOCAnchorAddr.getValueOr(yaml::Hex64(0)));
388  } else {
389  W.write<uint32_t>(InitAuxFileHdr.TextSize.getValueOr(yaml::Hex64(0)));
390  W.write<uint32_t>(InitAuxFileHdr.InitDataSize.getValueOr(yaml::Hex64(0)));
391  W.write<uint32_t>(InitAuxFileHdr.BssDataSize.getValueOr(yaml::Hex64(0)));
392  W.write<uint32_t>(InitAuxFileHdr.EntryPointAddr.getValueOr(yaml::Hex64(0)));
393  W.write<uint32_t>(InitAuxFileHdr.TextStartAddr.getValueOr(yaml::Hex64(0)));
394  W.write<uint32_t>(InitAuxFileHdr.DataStartAddr.getValueOr(yaml::Hex64(0)));
395  W.write<uint32_t>(InitAuxFileHdr.TOCAnchorAddr.getValueOr(yaml::Hex64(0)));
396  }
397  W.write<uint16_t>(InitAuxFileHdr.SecNumOfEntryPoint.getValueOr(0));
398  W.write<uint16_t>(InitAuxFileHdr.SecNumOfText.getValueOr(0));
399  W.write<uint16_t>(InitAuxFileHdr.SecNumOfData.getValueOr(0));
400  W.write<uint16_t>(InitAuxFileHdr.SecNumOfTOC.getValueOr(0));
401  W.write<uint16_t>(InitAuxFileHdr.SecNumOfLoader.getValueOr(0));
402  W.write<uint16_t>(InitAuxFileHdr.SecNumOfBSS.getValueOr(0));
403  W.write<uint16_t>(InitAuxFileHdr.MaxAlignOfText.getValueOr(yaml::Hex16(0)));
404  W.write<uint16_t>(InitAuxFileHdr.MaxAlignOfData.getValueOr(yaml::Hex16(0)));
405  W.write<uint16_t>(InitAuxFileHdr.ModuleType.getValueOr(yaml::Hex16(0)));
406  W.write<uint8_t>(InitAuxFileHdr.CpuFlag.getValueOr(yaml::Hex8(0)));
407  W.write<uint8_t>(0); // Reserved for CPU type.
408  if (Is64Bit) {
409  W.write<uint8_t>(InitAuxFileHdr.TextPageSize.getValueOr(yaml::Hex8(0)));
410  W.write<uint8_t>(InitAuxFileHdr.DataPageSize.getValueOr(yaml::Hex8(0)));
411  W.write<uint8_t>(InitAuxFileHdr.StackPageSize.getValueOr(yaml::Hex8(0)));
412  W.write<uint8_t>(
413  InitAuxFileHdr.FlagAndTDataAlignment.getValueOr(yaml::Hex8(0x80)));
414  W.write<uint64_t>(InitAuxFileHdr.TextSize.getValueOr(yaml::Hex64(0)));
415  W.write<uint64_t>(InitAuxFileHdr.InitDataSize.getValueOr(yaml::Hex64(0)));
416  W.write<uint64_t>(InitAuxFileHdr.BssDataSize.getValueOr(yaml::Hex64(0)));
417  W.write<uint64_t>(InitAuxFileHdr.EntryPointAddr.getValueOr(yaml::Hex64(0)));
418  W.write<uint64_t>(InitAuxFileHdr.MaxStackSize.getValueOr(yaml::Hex64(0)));
419  W.write<uint64_t>(InitAuxFileHdr.MaxDataSize.getValueOr(yaml::Hex64(0)));
420  } else {
421  W.write<uint32_t>(InitAuxFileHdr.MaxStackSize.getValueOr(yaml::Hex64(0)));
422  W.write<uint32_t>(InitAuxFileHdr.MaxDataSize.getValueOr(yaml::Hex64(0)));
423  W.OS.write_zeros(4); // Reserved for debugger.
424  W.write<uint8_t>(InitAuxFileHdr.TextPageSize.getValueOr(yaml::Hex8(0)));
425  W.write<uint8_t>(InitAuxFileHdr.DataPageSize.getValueOr(yaml::Hex8(0)));
426  W.write<uint8_t>(InitAuxFileHdr.StackPageSize.getValueOr(yaml::Hex8(0)));
427  W.write<uint8_t>(
428  InitAuxFileHdr.FlagAndTDataAlignment.getValueOr(yaml::Hex8(0)));
429  }
430  W.write<uint16_t>(InitAuxFileHdr.SecNumOfTData.getValueOr(0));
431  W.write<uint16_t>(InitAuxFileHdr.SecNumOfTBSS.getValueOr(0));
432  if (Is64Bit) {
433  W.write<uint16_t>(InitAuxFileHdr.Flag.getValueOr(yaml::Hex16(XCOFF::SHR_SYMTAB)));
434  if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize64)
435  W.OS.write_zeros(InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize64);
436  } else if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize32) {
437  W.OS.write_zeros(InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize32);
438  }
439 }
440 
441 void XCOFFWriter::writeSectionHeader() {
442  for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
443  XCOFFYAML::Section YamlSec = Obj.Sections[I];
444  XCOFFYAML::Section DerivedSec = InitSections[I];
445  writeName(YamlSec.SectionName, W);
446  // Virtual address is the same as physical address.
447  uint64_t SectionAddress =
448  YamlSec.Address ? YamlSec.Address : DerivedSec.Address;
449  if (Is64Bit) {
450  W.write<uint64_t>(SectionAddress); // Physical address
451  W.write<uint64_t>(SectionAddress); // Virtual address
452  W.write<uint64_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
453  W.write<uint64_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
454  : DerivedSec.FileOffsetToData);
455  W.write<uint64_t>(YamlSec.FileOffsetToRelocations
456  ? YamlSec.FileOffsetToRelocations
457  : DerivedSec.FileOffsetToRelocations);
458  W.write<uint64_t>(YamlSec.FileOffsetToLineNumbers);
459  W.write<uint32_t>(YamlSec.NumberOfRelocations
460  ? YamlSec.NumberOfRelocations
461  : DerivedSec.NumberOfRelocations);
462  W.write<uint32_t>(YamlSec.NumberOfLineNumbers);
463  W.write<int32_t>(YamlSec.Flags);
464  W.OS.write_zeros(4);
465  } else {
466  W.write<uint32_t>(SectionAddress); // Physical address
467  W.write<uint32_t>(SectionAddress); // Virtual address
468  W.write<uint32_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
469  W.write<uint32_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
470  : DerivedSec.FileOffsetToData);
471  W.write<uint32_t>(YamlSec.FileOffsetToRelocations
472  ? YamlSec.FileOffsetToRelocations
473  : DerivedSec.FileOffsetToRelocations);
474  W.write<uint32_t>(YamlSec.FileOffsetToLineNumbers);
475  W.write<uint16_t>(YamlSec.NumberOfRelocations
476  ? YamlSec.NumberOfRelocations
477  : DerivedSec.NumberOfRelocations);
478  W.write<uint16_t>(YamlSec.NumberOfLineNumbers);
479  W.write<int32_t>(YamlSec.Flags);
480  }
481  }
482 }
483 
484 bool XCOFFWriter::writeSectionData() {
485  for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
486  XCOFFYAML::Section YamlSec = Obj.Sections[I];
487  if (YamlSec.SectionData.binary_size()) {
488  // Fill the padding size with zeros.
489  int64_t PaddingSize =
490  InitSections[I].FileOffsetToData - (W.OS.tell() - StartOffset);
491  if (PaddingSize < 0) {
492  ErrHandler("redundant data was written before section data");
493  return false;
494  }
495  W.OS.write_zeros(PaddingSize);
496  YamlSec.SectionData.writeAsBinary(W.OS);
497  }
498  }
499  return true;
500 }
501 
502 bool XCOFFWriter::writeRelocations() {
503  for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
504  XCOFFYAML::Section YamlSec = Obj.Sections[I];
505  if (!YamlSec.Relocations.empty()) {
506  int64_t PaddingSize =
507  InitSections[I].FileOffsetToRelocations - (W.OS.tell() - StartOffset);
508  if (PaddingSize < 0) {
509  ErrHandler("redundant data was written before relocations");
510  return false;
511  }
512  W.OS.write_zeros(PaddingSize);
513  for (const XCOFFYAML::Relocation &YamlRel : YamlSec.Relocations) {
514  if (Is64Bit)
515  W.write<uint64_t>(YamlRel.VirtualAddress);
516  else
517  W.write<uint32_t>(YamlRel.VirtualAddress);
518  W.write<uint32_t>(YamlRel.SymbolIndex);
519  W.write<uint8_t>(YamlRel.Info);
520  W.write<uint8_t>(YamlRel.Type);
521  }
522  }
523  }
524  return true;
525 }
526 
527 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
528  if (Is64Bit) {
529  W.write<uint32_t>(AuxSym.SectionOrLengthLo.getValueOr(0));
530  W.write<uint32_t>(AuxSym.ParameterHashIndex.getValueOr(0));
531  W.write<uint16_t>(AuxSym.TypeChkSectNum.getValueOr(0));
532  W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.getValueOr(0));
533  W.write<uint8_t>(AuxSym.StorageMappingClass.getValueOr(XCOFF::XMC_PR));
534  W.write<uint32_t>(AuxSym.SectionOrLengthHi.getValueOr(0));
535  W.write<uint8_t>(0);
536  W.write<uint8_t>(XCOFF::AUX_CSECT);
537  } else {
538  W.write<uint32_t>(AuxSym.SectionOrLength.getValueOr(0));
539  W.write<uint32_t>(AuxSym.ParameterHashIndex.getValueOr(0));
540  W.write<uint16_t>(AuxSym.TypeChkSectNum.getValueOr(0));
541  W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.getValueOr(0));
542  W.write<uint8_t>(AuxSym.StorageMappingClass.getValueOr(XCOFF::XMC_PR));
543  W.write<uint32_t>(AuxSym.StabInfoIndex.getValueOr(0));
544  W.write<uint16_t>(AuxSym.StabSectNum.getValueOr(0));
545  }
546 }
547 
548 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
549  assert(Is64Bit && "can't write the exception auxiliary symbol for XCOFF32");
550  W.write<uint64_t>(AuxSym.OffsetToExceptionTbl.getValueOr(0));
551  W.write<uint32_t>(AuxSym.SizeOfFunction.getValueOr(0));
552  W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.getValueOr(0));
553  W.write<uint8_t>(0);
554  W.write<uint8_t>(XCOFF::AUX_EXCEPT);
555 }
556 
557 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
558  if (Is64Bit) {
559  W.write<uint64_t>(AuxSym.PtrToLineNum.getValueOr(0));
560  W.write<uint32_t>(AuxSym.SizeOfFunction.getValueOr(0));
561  W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.getValueOr(0));
562  W.write<uint8_t>(0);
563  W.write<uint8_t>(XCOFF::AUX_FCN);
564  } else {
565  W.write<uint32_t>(AuxSym.OffsetToExceptionTbl.getValueOr(0));
566  W.write<uint32_t>(AuxSym.SizeOfFunction.getValueOr(0));
567  W.write<uint32_t>(AuxSym.PtrToLineNum.getValueOr(0));
568  W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.getValueOr(0));
569  W.OS.write_zeros(2);
570  }
571 }
572 
573 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
574  StringRef FileName = AuxSym.FileNameOrString.getValueOr("");
575  if (nameShouldBeInStringTable(FileName)) {
576  W.write<int32_t>(0);
577  W.write<uint32_t>(StrTblBuilder.getOffset(FileName));
578  } else {
579  writeName(FileName, W);
580  }
581  W.OS.write_zeros(XCOFF::FileNamePadSize);
582  W.write<uint8_t>(AuxSym.FileStringType.getValueOr(XCOFF::XFT_FN));
583  if (Is64Bit) {
584  W.OS.write_zeros(2);
585  W.write<uint8_t>(XCOFF::AUX_FILE);
586  } else {
587  W.OS.write_zeros(3);
588  }
589 }
590 
591 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
592  if (Is64Bit) {
593  W.write<uint32_t>(AuxSym.LineNum.getValueOr(0));
594  W.OS.write_zeros(13);
595  W.write<uint8_t>(XCOFF::AUX_SYM);
596  } else {
597  W.OS.write_zeros(2);
598  W.write<uint16_t>(AuxSym.LineNumHi.getValueOr(0));
599  W.write<uint16_t>(AuxSym.LineNumLo.getValueOr(0));
600  W.OS.write_zeros(12);
601  }
602 }
603 
604 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
605  if (Is64Bit) {
606  W.write<uint64_t>(AuxSym.LengthOfSectionPortion.getValueOr(0));
607  W.write<uint64_t>(AuxSym.NumberOfRelocEnt.getValueOr(0));
608  W.write<uint8_t>(0);
609  W.write<uint8_t>(XCOFF::AUX_SECT);
610  } else {
611  W.write<uint32_t>(AuxSym.LengthOfSectionPortion.getValueOr(0));
612  W.OS.write_zeros(4);
613  W.write<uint32_t>(AuxSym.NumberOfRelocEnt.getValueOr(0));
614  W.OS.write_zeros(6);
615  }
616 }
617 
618 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) {
619  assert(!Is64Bit && "can't write the stat auxiliary symbol for XCOFF64");
620  W.write<uint32_t>(AuxSym.SectionLength.getValueOr(0));
621  W.write<uint16_t>(AuxSym.NumberOfRelocEnt.getValueOr(0));
622  W.write<uint16_t>(AuxSym.NumberOfLineNum.getValueOr(0));
623  W.OS.write_zeros(10);
624 }
625 
626 void XCOFFWriter::writeAuxSymbol(
627  const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) {
628  if (auto AS = dyn_cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get()))
629  writeAuxSymbol(*AS);
630  else if (auto AS = dyn_cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get()))
631  writeAuxSymbol(*AS);
632  else if (auto AS = dyn_cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get()))
633  writeAuxSymbol(*AS);
634  else if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get()))
635  writeAuxSymbol(*AS);
636  else if (auto AS = dyn_cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get()))
637  writeAuxSymbol(*AS);
638  else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get()))
639  writeAuxSymbol(*AS);
640  else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForStat>(AuxSym.get()))
641  writeAuxSymbol(*AS);
642  else
643  llvm_unreachable("unknown auxiliary symbol type");
644 }
645 
646 bool XCOFFWriter::writeSymbols() {
647  int64_t PaddingSize =
648  (uint64_t)InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);
649  if (PaddingSize < 0) {
650  ErrHandler("redundant data was written before symbols");
651  return false;
652  }
653  W.OS.write_zeros(PaddingSize);
654  for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
655  if (Is64Bit) {
656  W.write<uint64_t>(YamlSym.Value);
657  W.write<uint32_t>(StrTblBuilder.getOffset(YamlSym.SymbolName));
658  } else {
659  if (nameShouldBeInStringTable(YamlSym.SymbolName)) {
660  // For XCOFF32: A value of 0 indicates that the symbol name is in the
661  // string table.
662  W.write<int32_t>(0);
663  W.write<uint32_t>(StrTblBuilder.getOffset(YamlSym.SymbolName));
664  } else {
665  writeName(YamlSym.SymbolName, W);
666  }
667  W.write<uint32_t>(YamlSym.Value);
668  }
669  if (YamlSym.SectionName) {
670  if (!SectionIndexMap.count(*YamlSym.SectionName)) {
671  ErrHandler("the SectionName " + *YamlSym.SectionName +
672  " specified in the symbol does not exist");
673  return false;
674  }
675  if (YamlSym.SectionIndex &&
676  SectionIndexMap[*YamlSym.SectionName] != *YamlSym.SectionIndex) {
677  ErrHandler("the SectionName " + *YamlSym.SectionName +
678  " and the SectionIndex (" + Twine(*YamlSym.SectionIndex) +
679  ") refer to different sections");
680  return false;
681  }
682  W.write<int16_t>(SectionIndexMap[*YamlSym.SectionName]);
683  } else {
684  W.write<int16_t>(YamlSym.SectionIndex ? *YamlSym.SectionIndex : 0);
685  }
686  W.write<uint16_t>(YamlSym.Type);
687  W.write<uint8_t>(YamlSym.StorageClass);
688 
689  uint8_t NumOfAuxSym = YamlSym.NumberOfAuxEntries.getValueOr(0);
690  W.write<uint8_t>(NumOfAuxSym);
691 
692  if (!NumOfAuxSym && !YamlSym.AuxEntries.size())
693  continue;
694 
695  // Now write auxiliary entries.
696  if (!YamlSym.AuxEntries.size()) {
697  W.OS.write_zeros(XCOFF::SymbolTableEntrySize * NumOfAuxSym);
698  } else {
699  for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
700  YamlSym.AuxEntries) {
701  writeAuxSymbol(AuxSym);
702  }
703  // Pad with zeros.
704  if (NumOfAuxSym > YamlSym.AuxEntries.size())
705  W.OS.write_zeros(XCOFF::SymbolTableEntrySize *
706  (NumOfAuxSym - YamlSym.AuxEntries.size()));
707  }
708  }
709  return true;
710 }
711 
713  if (Obj.StrTbl.RawContent) {
714  Obj.StrTbl.RawContent->writeAsBinary(W.OS);
715  if (Obj.StrTbl.ContentSize) {
716  assert(*Obj.StrTbl.ContentSize >= Obj.StrTbl.RawContent->binary_size() &&
717  "Specified ContentSize is less than the RawContent size.");
718  W.OS.write_zeros(*Obj.StrTbl.ContentSize -
719  Obj.StrTbl.RawContent->binary_size());
720  }
721  return;
722  }
723 
724  size_t StrTblBuilderSize = StrTblBuilder.getSize();
725  // If neither Length nor ContentSize is specified, write the StrTblBuilder
726  // directly, which contains the auto-generated Length value.
727  if (!Obj.StrTbl.Length && !Obj.StrTbl.ContentSize) {
728  if (StrTblBuilderSize <= 4)
729  return;
730  StrTblBuilder.write(W.OS);
731  return;
732  }
733 
734  // Serialize the string table's content to a temporary buffer.
735  std::unique_ptr<WritableMemoryBuffer> Buf =
736  WritableMemoryBuffer::getNewMemBuffer(StrTblBuilderSize);
737  uint8_t *Ptr = reinterpret_cast<uint8_t *>(Buf->getBufferStart());
738  StrTblBuilder.write(Ptr);
739  // Replace the first 4 bytes, which contain the auto-generated Length value,
740  // with the specified value.
741  memset(Ptr, 0, 4);
742  support::endian::write32be(Ptr, Obj.StrTbl.Length ? *Obj.StrTbl.Length
743  : *Obj.StrTbl.ContentSize);
744  // Copy the buffer content to the actual output stream.
745  W.OS.write(Buf->getBufferStart(), Buf->getBufferSize());
746  // Add zeros as padding after strings.
747  if (Obj.StrTbl.ContentSize) {
748  assert(*Obj.StrTbl.ContentSize >= StrTblBuilderSize &&
749  "Specified ContentSize is less than the StringTableBuilder size.");
750  W.OS.write_zeros(*Obj.StrTbl.ContentSize - StrTblBuilderSize);
751  }
752 }
753 
754 bool XCOFFWriter::writeXCOFF() {
755  if (!assignAddressesAndIndices())
756  return false;
757  StartOffset = W.OS.tell();
758  writeFileHeader();
759  if (Obj.AuxHeader)
760  writeAuxFileHeader();
761  if (!Obj.Sections.empty()) {
762  writeSectionHeader();
763  if (!writeSectionData())
764  return false;
765  if (!writeRelocations())
766  return false;
767  }
768  if (!Obj.Symbols.empty() && !writeSymbols())
769  return false;
771  return true;
772 }
773 
774 } // end anonymous namespace
775 
776 namespace llvm {
777 namespace yaml {
778 
780  XCOFFWriter Writer(Doc, Out, EH);
781  return Writer.writeXCOFF();
782 }
783 
784 } // namespace yaml
785 } // namespace llvm
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::XCOFFYAML::Symbol::SectionIndex
Optional< uint16_t > SectionIndex
Definition: XCOFFYAML.h:193
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
ObjectYAML.h
llvm::XCOFFYAML::FileHeader
Definition: XCOFFYAML.h:22
llvm::XCOFFYAML::Section::FileOffsetToRelocations
llvm::yaml::Hex64 FileOffsetToRelocations
Definition: XCOFFYAML.h:76
llvm::XCOFF::SectionHeaderSize64
constexpr size_t SectionHeaderSize64
Definition: XCOFF.h:35
llvm::support::endian::write32be
void write32be(void *P, uint32_t V)
Definition: Endian.h:419
llvm::XCOFF::RelocationSerializationSize64
constexpr size_t RelocationSerializationSize64
Definition: XCOFF.h:38
llvm::XCOFF::STYP_BSS
@ STYP_BSS
Definition: XCOFF.h:123
llvm::XCOFFYAML::AuxiliaryHeader
Definition: XCOFFYAML.h:32
llvm::yaml::yaml2xcoff
bool yaml2xcoff(XCOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH)
Definition: XCOFFEmitter.cpp:779
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:241
llvm::XCOFFYAML::Object::Sections
std::vector< Section > Sections
Definition: XCOFFYAML.h:211
llvm::XCOFF::SectionHeaderSize32
constexpr size_t SectionHeaderSize32
Definition: XCOFF.h:34
llvm::XCOFFYAML::SectAuxEntForStat::SectionLength
Optional< uint32_t > SectionLength
Definition: XCOFFYAML.h:179
llvm::XCOFF::XMC_PR
@ XMC_PR
Program Code.
Definition: XCOFF.h:89
llvm::XCOFFYAML::FileHeader::Magic
llvm::yaml::Hex16 Magic
Definition: XCOFFYAML.h:23
DenseMap.h
llvm::XCOFFYAML::Section::FileOffsetToData
llvm::yaml::Hex64 FileOffsetToData
Definition: XCOFFYAML.h:75
llvm::XCOFFYAML::ExcpetionAuxEnt
Definition: XCOFFYAML.h:144
initRelocations
static Error initRelocations(RelocationSection *Relocs, T RelRange)
Definition: ELFObject.cpp:1626
llvm::XCOFFYAML::SectAuxEntForDWARF::NumberOfRelocEnt
Optional< uint32_t > NumberOfRelocEnt
Definition: XCOFFYAML.h:170
llvm::XCOFFYAML::Symbol::SectionName
Optional< StringRef > SectionName
Definition: XCOFFYAML.h:192
llvm::XCOFFYAML::CsectAuxEnt::ParameterHashIndex
Optional< uint32_t > ParameterHashIndex
Definition: XCOFFYAML.h:121
llvm::XCOFF::STYP_LOADER
@ STYP_LOADER
Definition: XCOFF.h:128
llvm::XCOFFYAML::FunctionAuxEnt::SymIdxOfNextBeyond
Optional< int32_t > SymIdxOfNextBeyond
Definition: XCOFFYAML.h:136
llvm::XCOFFYAML::FunctionAuxEnt::SizeOfFunction
Optional< uint32_t > SizeOfFunction
Definition: XCOFFYAML.h:135
llvm::support::endian::Writer
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:52
llvm::XCOFFYAML::Relocation
Definition: XCOFFYAML.h:64
llvm::XCOFFYAML::FileAuxEnt::FileNameOrString
Optional< StringRef > FileNameOrString
Definition: XCOFFYAML.h:103
llvm::XCOFFYAML::ExcpetionAuxEnt::OffsetToExceptionTbl
Optional< uint64_t > OffsetToExceptionTbl
Definition: XCOFFYAML.h:145
llvm::XCOFFYAML::BlockAuxEnt::LineNumHi
Optional< uint16_t > LineNumHi
Definition: XCOFFYAML.h:157
XCOFF.h
StringTableBuilder.h
llvm::XCOFF::XCOFF32
@ XCOFF32
Definition: XCOFF.h:44
llvm::XCOFF::N_ABS
@ N_ABS
Definition: XCOFF.h:42
llvm::XCOFFYAML::CsectAuxEnt::SectionOrLength
Optional< uint32_t > SectionOrLength
Definition: XCOFFYAML.h:114
llvm::XCOFFYAML::FunctionAuxEnt::PtrToLineNum
Optional< uint64_t > PtrToLineNum
Definition: XCOFFYAML.h:134
llvm::XCOFFYAML::ExcpetionAuxEnt::SizeOfFunction
Optional< uint32_t > SizeOfFunction
Definition: XCOFFYAML.h:146
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::XCOFF::AUX_SECT
@ AUX_SECT
Identifies a SECT auxiliary entry.
Definition: XCOFF.h:331
llvm::XCOFF::AUX_EXCEPT
@ AUX_EXCEPT
Identifies an exception auxiliary entry.
Definition: XCOFF.h:326
llvm::XCOFF::XCOFF64
@ XCOFF64
Definition: XCOFF.h:44
llvm::Optional::getValueOr
constexpr T getValueOr(U &&value) const &
Definition: Optional.h:289
llvm::XCOFFYAML::ExcpetionAuxEnt::SymIdxOfNextBeyond
Optional< int32_t > SymIdxOfNextBeyond
Definition: XCOFFYAML.h:147
llvm::XCOFFYAML::CsectAuxEnt::StabSectNum
Optional< uint16_t > StabSectNum
Definition: XCOFFYAML.h:116
XCOFFObjectFile.h
llvm::XCOFFYAML::CsectAuxEnt
Definition: XCOFFYAML.h:112
llvm::XCOFF::SHR_SYMTAB
@ SHR_SYMTAB
At exec time, create shared symbol table for program (main program only).
Definition: XCOFF.h:48
llvm::XCOFF::SymbolTableEntrySize
constexpr size_t SymbolTableEntrySize
Definition: XCOFF.h:36
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::object::writeStringTable
static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string > Strings)
Definition: COFFImportFile.cpp:70
llvm::WritableMemoryBuffer::getNewMemBuffer
static std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
Definition: MemoryBuffer.cpp:310
llvm::XCOFF::AUX_FILE
@ AUX_FILE
Identifies a file auxiliary entry.
Definition: XCOFF.h:329
llvm::XCOFFYAML::FileAuxEnt
Definition: XCOFFYAML.h:102
llvm::XCOFFYAML::Symbol::SymbolName
StringRef SymbolName
Definition: XCOFFYAML.h:190
llvm::XCOFFYAML::Section::Flags
uint32_t Flags
Definition: XCOFFYAML.h:80
llvm::XCOFF::N_DEBUG
@ N_DEBUG
Definition: XCOFF.h:42
llvm::XCOFFYAML::Relocation::VirtualAddress
llvm::yaml::Hex64 VirtualAddress
Definition: XCOFFYAML.h:65
llvm::XCOFFYAML::BlockAuxEnt::LineNum
Optional< uint32_t > LineNum
Definition: XCOFFYAML.h:160
llvm::XCOFFYAML::SectAuxEntForStat::NumberOfLineNum
Optional< uint16_t > NumberOfLineNum
Definition: XCOFFYAML.h:181
llvm::XCOFF::NameSize
constexpr size_t NameSize
Definition: XCOFF.h:29
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
llvm::XCOFFYAML::Symbol::NumberOfAuxEntries
Optional< uint8_t > NumberOfAuxEntries
Definition: XCOFFYAML.h:196
llvm::XCOFFYAML::Symbol::Type
llvm::yaml::Hex16 Type
Definition: XCOFFYAML.h:194
llvm::XCOFF::STYP_TDATA
@ STYP_TDATA
Definition: XCOFF.h:126
llvm::XCOFFYAML::CsectAuxEnt::SectionOrLengthLo
Optional< uint32_t > SectionOrLengthLo
Definition: XCOFFYAML.h:118
llvm::XCOFF::XFT_FN
@ XFT_FN
Specifies the source-file name.
Definition: XCOFF.h:308
uint64_t
llvm::XCOFFYAML::SectAuxEntForDWARF::LengthOfSectionPortion
Optional< uint32_t > LengthOfSectionPortion
Definition: XCOFFYAML.h:169
llvm::XCOFFYAML::FileAuxEnt::FileStringType
Optional< XCOFF::CFileStringType > FileStringType
Definition: XCOFFYAML.h:104
llvm::yaml::BinaryRef::writeAsBinary
void writeAsBinary(raw_ostream &OS, uint64_t N=UINT64_MAX) const
Write the contents (regardless of whether it is binary or a hex string) as binary to the given raw_os...
Definition: YAML.cpp:39
LEB128.h
llvm::DenseMap
Definition: DenseMap.h:716
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::XCOFFYAML::Section::NumberOfRelocations
llvm::yaml::Hex16 NumberOfRelocations
Definition: XCOFFYAML.h:78
llvm::XCOFFYAML::Symbol::AuxEntries
std::vector< std::unique_ptr< AuxSymbolEnt > > AuxEntries
Definition: XCOFFYAML.h:197
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::XCOFFYAML::CsectAuxEnt::SectionOrLengthHi
Optional< uint32_t > SectionOrLengthHi
Definition: XCOFFYAML.h:119
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::XCOFFYAML::SectAuxEntForStat::NumberOfRelocEnt
Optional< uint16_t > NumberOfRelocEnt
Definition: XCOFFYAML.h:180
llvm::XCOFF::FileNamePadSize
constexpr size_t FileNamePadSize
Definition: XCOFF.h:28
llvm::XCOFFYAML::Object
Definition: XCOFFYAML.h:208
llvm::XCOFFYAML::Symbol::Value
llvm::yaml::Hex64 Value
Definition: XCOFFYAML.h:191
llvm::XCOFFYAML::Relocation::Type
llvm::yaml::Hex8 Type
Definition: XCOFFYAML.h:68
llvm::XCOFFYAML::BlockAuxEnt
Definition: XCOFFYAML.h:155
llvm::XCOFFYAML::Section
Definition: XCOFFYAML.h:71
llvm::XCOFFYAML::FunctionAuxEnt
Definition: XCOFFYAML.h:132
yaml2obj.h
llvm::XCOFFYAML::Relocation::Info
llvm::yaml::Hex8 Info
Definition: XCOFFYAML.h:67
llvm::ArrayRef< char >
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::XCOFFYAML::BlockAuxEnt::LineNumLo
Optional< uint16_t > LineNumLo
Definition: XCOFFYAML.h:158
llvm::XCOFF::AUX_SYM
@ AUX_SYM
Identifies a symbol auxiliary entry.
Definition: XCOFF.h:328
uint32_t
llvm::XCOFF::FileHeaderSize64
constexpr size_t FileHeaderSize64
Definition: XCOFF.h:31
llvm::XCOFF::FileHeaderSize32
constexpr size_t FileHeaderSize32
Definition: XCOFF.h:30
llvm::XCOFF::N_UNDEF
@ N_UNDEF
Definition: XCOFF.h:42
llvm::XCOFFYAML::CsectAuxEnt::StabInfoIndex
Optional< uint32_t > StabInfoIndex
Definition: XCOFFYAML.h:115
llvm::XCOFFYAML::Object::Header
FileHeader Header
Definition: XCOFFYAML.h:209
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
EndianStream.h
llvm::XCOFFYAML::Section::Size
llvm::yaml::Hex64 Size
Definition: XCOFFYAML.h:74
uint16_t
llvm::SectionName
Definition: DWARFSection.h:21
llvm::XCOFFYAML::Section::FileOffsetToLineNumbers
llvm::yaml::Hex64 FileOffsetToLineNumbers
Definition: XCOFFYAML.h:77
llvm::XCOFF::AUX_CSECT
@ AUX_CSECT
Identifies a csect auxiliary entry.
Definition: XCOFF.h:330
llvm::StringTableBuilder
Utility for building string tables with deduplicated suffixes.
Definition: StringTableBuilder.h:23
llvm::XCOFFYAML::SectAuxEntForDWARF
Definition: XCOFFYAML.h:168
llvm::XCOFF::AUX_FCN
@ AUX_FCN
Identifies a function auxiliary entry.
Definition: XCOFF.h:327
llvm::XCOFFYAML::Section::NumberOfLineNumbers
llvm::yaml::Hex16 NumberOfLineNumbers
Definition: XCOFFYAML.h:79
llvm::XCOFFYAML::CsectAuxEnt::StorageMappingClass
Optional< XCOFF::StorageMappingClass > StorageMappingClass
Definition: XCOFFYAML.h:124
llvm::XCOFF::STYP_DATA
@ STYP_DATA
Definition: XCOFF.h:122
llvm::XCOFF::AuxFileHeaderSize32
constexpr size_t AuxFileHeaderSize32
Definition: XCOFF.h:32
llvm::XCOFFYAML::Section::Address
llvm::yaml::Hex64 Address
Definition: XCOFFYAML.h:73
llvm::XCOFF::STYP_TEXT
@ STYP_TEXT
Definition: XCOFF.h:121
llvm::yaml::BinaryRef::binary_size
ArrayRef< uint8_t >::size_type binary_size() const
The number of bytes that are represented by this BinaryRef.
Definition: YAML.h:80
llvm::XCOFFYAML::FunctionAuxEnt::OffsetToExceptionTbl
Optional< uint32_t > OffsetToExceptionTbl
Definition: XCOFFYAML.h:133
support
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
Definition: README.txt:10
llvm::XCOFFYAML::Section::SectionData
yaml::BinaryRef SectionData
Definition: XCOFFYAML.h:81
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::XCOFFYAML::Relocation::SymbolIndex
llvm::yaml::Hex64 SymbolIndex
Definition: XCOFFYAML.h:66
llvm::XCOFFYAML::Section::Relocations
std::vector< Relocation > Relocations
Definition: XCOFFYAML.h:82
llvm::XCOFF::RelocationSerializationSize32
constexpr size_t RelocationSerializationSize32
Definition: XCOFF.h:37
llvm::XCOFF::STYP_TBSS
@ STYP_TBSS
Definition: XCOFF.h:127
llvm::XCOFFYAML::Symbol::StorageClass
XCOFF::StorageClass StorageClass
Definition: XCOFFYAML.h:195
raw_ostream.h
llvm::XCOFFYAML::CsectAuxEnt::SymbolAlignmentAndType
Optional< uint8_t > SymbolAlignmentAndType
Definition: XCOFFYAML.h:123
llvm::XCOFFYAML::CsectAuxEnt::TypeChkSectNum
Optional< uint16_t > TypeChkSectNum
Definition: XCOFFYAML.h:122
llvm::XCOFFYAML::SectAuxEntForStat
Definition: XCOFFYAML.h:178
llvm::XCOFFYAML::Symbol
Definition: XCOFFYAML.h:189
llvm::XCOFFYAML::Section::SectionName
StringRef SectionName
Definition: XCOFFYAML.h:72
llvm::support::big
@ big
Definition: Endian.h:27
llvm::XCOFF::AuxFileHeaderSize64
constexpr size_t AuxFileHeaderSize64
Definition: XCOFF.h:33