LLVM  16.0.0git
XCOFFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===//
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 // This file implements XCOFF object file writer information.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/MC/MCAsmBackend.h"
15 #include "llvm/MC/MCAsmLayout.h"
16 #include "llvm/MC/MCAssembler.h"
17 #include "llvm/MC/MCFixup.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSectionXCOFF.h"
21 #include "llvm/MC/MCSymbolXCOFF.h"
22 #include "llvm/MC/MCValue.h"
25 #include "llvm/Support/Casting.h"
29 
30 #include <deque>
31 #include <map>
32 
33 using namespace llvm;
34 
35 // An XCOFF object file has a limited set of predefined sections. The most
36 // important ones for us (right now) are:
37 // .text --> contains program code and read-only data.
38 // .data --> contains initialized data, function descriptors, and the TOC.
39 // .bss --> contains uninitialized data.
40 // Each of these sections is composed of 'Control Sections'. A Control Section
41 // is more commonly referred to as a csect. A csect is an indivisible unit of
42 // code or data, and acts as a container for symbols. A csect is mapped
43 // into a section based on its storage-mapping class, with the exception of
44 // XMC_RW which gets mapped to either .data or .bss based on whether it's
45 // explicitly initialized or not.
46 //
47 // We don't represent the sections in the MC layer as there is nothing
48 // interesting about them at at that level: they carry information that is
49 // only relevant to the ObjectWriter, so we materialize them in this class.
50 namespace {
51 
52 constexpr unsigned DefaultSectionAlign = 4;
53 constexpr int16_t MaxSectionIndex = INT16_MAX;
54 
55 // Packs the csect's alignment and type into a byte.
56 uint8_t getEncodedType(const MCSectionXCOFF *);
57 
58 struct XCOFFRelocation {
59  uint32_t SymbolTableIndex;
60  uint32_t FixupOffsetInCsect;
61  uint8_t SignAndSize;
62  uint8_t Type;
63 };
64 
65 // Wrapper around an MCSymbolXCOFF.
66 struct Symbol {
67  const MCSymbolXCOFF *const MCSym;
68  uint32_t SymbolTableIndex;
69 
70  XCOFF::VisibilityType getVisibilityType() const {
71  return MCSym->getVisibilityType();
72  }
73 
74  XCOFF::StorageClass getStorageClass() const {
75  return MCSym->getStorageClass();
76  }
77  StringRef getSymbolTableName() const { return MCSym->getSymbolTableName(); }
78  Symbol(const MCSymbolXCOFF *MCSym) : MCSym(MCSym), SymbolTableIndex(-1) {}
79 };
80 
81 // Wrapper for an MCSectionXCOFF.
82 // It can be a Csect or debug section or DWARF section and so on.
83 struct XCOFFSection {
84  const MCSectionXCOFF *const MCSec;
85  uint32_t SymbolTableIndex;
87  uint64_t Size;
88 
91  StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); }
92  XCOFF::VisibilityType getVisibilityType() const {
93  return MCSec->getVisibilityType();
94  }
95  XCOFFSection(const MCSectionXCOFF *MCSec)
96  : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}
97 };
98 
99 // Type to be used for a container representing a set of csects with
100 // (approximately) the same storage mapping class. For example all the csects
101 // with a storage mapping class of `xmc_pr` will get placed into the same
102 // container.
103 using CsectGroup = std::deque<XCOFFSection>;
104 using CsectGroups = std::deque<CsectGroup *>;
105 
106 // The basic section entry defination. This Section represents a section entry
107 // in XCOFF section header table.
108 struct SectionEntry {
109  char Name[XCOFF::NameSize];
110  // The physical/virtual address of the section. For an object file
111  // these values are equivalent.
113  uint64_t Size;
114  uint64_t FileOffsetToData;
115  uint64_t FileOffsetToRelocations;
116  uint32_t RelocationCount;
117  int32_t Flags;
118 
119  int16_t Index;
120 
121  // XCOFF has special section numbers for symbols:
122  // -2 Specifies N_DEBUG, a special symbolic debugging symbol.
123  // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not
124  // relocatable.
125  // 0 Specifies N_UNDEF, an undefined external symbol.
126  // Therefore, we choose -3 (N_DEBUG - 1) to represent a section index that
127  // hasn't been initialized.
128  static constexpr int16_t UninitializedIndex =
130 
131  SectionEntry(StringRef N, int32_t Flags)
132  : Name(), Address(0), Size(0), FileOffsetToData(0),
133  FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
134  Index(UninitializedIndex) {
135  assert(N.size() <= XCOFF::NameSize && "section name too long");
136  memcpy(Name, N.data(), N.size());
137  }
138 
139  virtual void reset() {
140  Address = 0;
141  Size = 0;
142  FileOffsetToData = 0;
143  FileOffsetToRelocations = 0;
144  RelocationCount = 0;
145  Index = UninitializedIndex;
146  }
147 
148  virtual ~SectionEntry() = default;
149 };
150 
151 // Represents the data related to a section excluding the csects that make up
152 // the raw data of the section. The csects are stored separately as not all
153 // sections contain csects, and some sections contain csects which are better
154 // stored separately, e.g. the .data section containing read-write, descriptor,
155 // TOCBase and TOC-entry csects.
156 struct CsectSectionEntry : public SectionEntry {
157  // Virtual sections do not need storage allocated in the object file.
158  const bool IsVirtual;
159 
160  // This is a section containing csect groups.
161  CsectGroups Groups;
162 
163  CsectSectionEntry(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
164  CsectGroups Groups)
165  : SectionEntry(N, Flags), IsVirtual(IsVirtual), Groups(Groups) {
166  assert(N.size() <= XCOFF::NameSize && "section name too long");
167  memcpy(Name, N.data(), N.size());
168  }
169 
170  void reset() override {
171  SectionEntry::reset();
172  // Clear any csects we have stored.
173  for (auto *Group : Groups)
174  Group->clear();
175  }
176 
177  virtual ~CsectSectionEntry() = default;
178 };
179 
180 struct DwarfSectionEntry : public SectionEntry {
181  // For DWARF section entry.
182  std::unique_ptr<XCOFFSection> DwarfSect;
183 
184  // For DWARF section, we must use real size in the section header. MemorySize
185  // is for the size the DWARF section occupies including paddings.
186  uint32_t MemorySize;
187 
188  DwarfSectionEntry(StringRef N, int32_t Flags,
189  std::unique_ptr<XCOFFSection> Sect)
190  : SectionEntry(N, Flags | XCOFF::STYP_DWARF), DwarfSect(std::move(Sect)),
191  MemorySize(0) {
192  assert(DwarfSect->MCSec->isDwarfSect() &&
193  "This should be a DWARF section!");
194  assert(N.size() <= XCOFF::NameSize && "section name too long");
195  memcpy(Name, N.data(), N.size());
196  }
197 
198  DwarfSectionEntry(DwarfSectionEntry &&s) = default;
199 
200  virtual ~DwarfSectionEntry() = default;
201 };
202 
203 struct ExceptionTableEntry {
204  const MCSymbol *Trap;
205  uint64_t TrapAddress;
206  unsigned Lang;
207  unsigned Reason;
208 
209  ExceptionTableEntry(const MCSymbol *Trap, unsigned Lang, unsigned Reason) :
210  Trap(Trap), Lang(Lang), Reason(Reason) {}
211 };
212 
213 struct ExceptionInfo {
214  const MCSymbol *FunctionSymbol;
215  unsigned FunctionSize;
216  std::vector<ExceptionTableEntry> Entries;
217 };
218 
219 struct ExceptionSectionEntry : public SectionEntry {
220  std::map<const StringRef, ExceptionInfo> ExceptionTable;
221  bool isDebugEnabled = false;
222 
223  ExceptionSectionEntry(StringRef N, int32_t Flags) :
224  SectionEntry(N, Flags | XCOFF::STYP_EXCEPT) {
225  assert(N.size() <= XCOFF::NameSize && "Section too long.");
226  memcpy(Name, N.data(), N.size());
227  }
228 
229  virtual ~ExceptionSectionEntry() = default;
230 };
231 
232 class XCOFFObjectWriter : public MCObjectWriter {
233 
234  uint32_t SymbolTableEntryCount = 0;
235  uint64_t SymbolTableOffset = 0;
236  uint16_t SectionCount = 0;
237  uint64_t RelocationEntryOffset = 0;
238  std::vector<std::pair<std::string, size_t>> FileNames;
239  bool HasVisibility = false;
240 
242  std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
243  StringTableBuilder Strings;
244 
245  const uint64_t MaxRawDataSize =
246  TargetObjectWriter->is64Bit() ? UINT64_MAX : UINT32_MAX;
247 
248  // Maps the MCSection representation to its corresponding XCOFFSection
249  // wrapper. Needed for finding the XCOFFSection to insert an MCSymbol into
250  // from its containing MCSectionXCOFF.
252 
253  // Maps the MCSymbol representation to its corrresponding symbol table index.
254  // Needed for relocation.
256 
257  // CsectGroups. These store the csects which make up different parts of
258  // the sections. Should have one for each set of csects that get mapped into
259  // the same section and get handled in a 'similar' way.
260  CsectGroup UndefinedCsects;
261  CsectGroup ProgramCodeCsects;
262  CsectGroup ReadOnlyCsects;
263  CsectGroup DataCsects;
264  CsectGroup FuncDSCsects;
265  CsectGroup TOCCsects;
266  CsectGroup BSSCsects;
267  CsectGroup TDataCsects;
268  CsectGroup TBSSCsects;
269 
270  // The Predefined sections.
271  CsectSectionEntry Text;
272  CsectSectionEntry Data;
273  CsectSectionEntry BSS;
274  CsectSectionEntry TData;
275  CsectSectionEntry TBSS;
276 
277  // All the XCOFF sections, in the order they will appear in the section header
278  // table.
279  std::array<CsectSectionEntry *const, 5> Sections{
280  {&Text, &Data, &BSS, &TData, &TBSS}};
281 
282  std::vector<DwarfSectionEntry> DwarfSections;
283 
284  ExceptionSectionEntry ExceptionSection;
285 
286  CsectGroup &getCsectGroup(const MCSectionXCOFF *MCSec);
287 
288  void reset() override;
289 
290  void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override;
291 
292  void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *,
293  const MCFixup &, MCValue, uint64_t &) override;
294 
295  uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override;
296 
297  bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
298  bool nameShouldBeInStringTable(const StringRef &);
299  void writeSymbolName(const StringRef &);
300 
301  void writeSymbolEntryForCsectMemberLabel(const Symbol &SymbolRef,
302  const XCOFFSection &CSectionRef,
303  int16_t SectionIndex,
304  uint64_t SymbolOffset);
305  void writeSymbolEntryForControlSection(const XCOFFSection &CSectionRef,
306  int16_t SectionIndex,
308  void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef,
309  int16_t SectionIndex);
310  void writeFileHeader();
311  void writeAuxFileHeader();
312  void writeSectionHeaderTable();
313  void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
314  void writeSectionForControlSectionEntry(const MCAssembler &Asm,
315  const MCAsmLayout &Layout,
316  const CsectSectionEntry &CsectEntry,
317  uint64_t &CurrentAddressLocation);
318  void writeSectionForDwarfSectionEntry(const MCAssembler &Asm,
319  const MCAsmLayout &Layout,
320  const DwarfSectionEntry &DwarfEntry,
321  uint64_t &CurrentAddressLocation);
322  void writeSectionForExceptionSectionEntry(const MCAssembler &Asm,
323  const MCAsmLayout &Layout,
324  ExceptionSectionEntry &ExceptionEntry,
325  uint64_t &CurrentAddressLocation);
326  void writeSymbolTable(const MCAsmLayout &Layout);
327  void writeSymbolAuxDwarfEntry(uint64_t LengthOfSectionPortion,
328  uint64_t NumberOfRelocEnt = 0);
329  void writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
330  uint8_t SymbolAlignmentAndType,
331  uint8_t StorageMappingClass);
332  void writeSymbolAuxFunctionEntry(uint32_t EntryOffset,
333  uint32_t FunctionSize,
334  uint64_t LineNumberPointer,
335  uint32_t EndIndex);
336  void writeSymbolAuxExceptionEntry(uint64_t EntryOffset,
337  uint32_t FunctionSize, uint32_t EndIndex);
338  void writeSymbolEntry(StringRef SymbolName, uint64_t Value,
339  int16_t SectionNumber, uint16_t SymbolType,
340  uint8_t StorageClass, uint8_t NumberOfAuxEntries = 1);
341  void writeRelocations();
342  void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &Section);
343 
344  // Called after all the csects and symbols have been processed by
345  // `executePostLayoutBinding`, this function handles building up the majority
346  // of the structures in the object file representation. Namely:
347  // *) Calculates physical/virtual addresses, raw-pointer offsets, and section
348  // sizes.
349  // *) Assigns symbol table indices.
350  // *) Builds up the section header table by adding any non-empty sections to
351  // `Sections`.
352  void assignAddressesAndIndices(const MCAsmLayout &);
353  void finalizeSectionInfo();
354  void addExceptionEntry(const MCSymbol *Symbol, const MCSymbol *Trap,
355  unsigned LanguageCode, unsigned ReasonCode,
356  unsigned FunctionSize, bool hasDebug) override;
357  bool hasExceptionSection() {
358  return !ExceptionSection.ExceptionTable.empty();
359  }
360  unsigned getExceptionSectionSize();
361  unsigned getExceptionOffset(const MCSymbol *Symbol);
362 
363  size_t auxiliaryHeaderSize() const {
364  // 64-bit object files have no auxiliary header.
365  return HasVisibility && !is64Bit() ? XCOFF::AuxFileHeaderSizeShort : 0;
366  }
367 
368 public:
369  XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
370  raw_pwrite_stream &OS);
371 
372  void writeWord(uint64_t Word) {
373  is64Bit() ? W.write<uint64_t>(Word) : W.write<uint32_t>(Word);
374  }
375 };
376 
377 XCOFFObjectWriter::XCOFFObjectWriter(
378  std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
379  : W(OS, support::big), TargetObjectWriter(std::move(MOTW)),
380  Strings(StringTableBuilder::XCOFF),
381  Text(".text", XCOFF::STYP_TEXT, /* IsVirtual */ false,
382  CsectGroups{&ProgramCodeCsects, &ReadOnlyCsects}),
383  Data(".data", XCOFF::STYP_DATA, /* IsVirtual */ false,
384  CsectGroups{&DataCsects, &FuncDSCsects, &TOCCsects}),
385  BSS(".bss", XCOFF::STYP_BSS, /* IsVirtual */ true,
386  CsectGroups{&BSSCsects}),
387  TData(".tdata", XCOFF::STYP_TDATA, /* IsVirtual */ false,
388  CsectGroups{&TDataCsects}),
389  TBSS(".tbss", XCOFF::STYP_TBSS, /* IsVirtual */ true,
390  CsectGroups{&TBSSCsects}),
391  ExceptionSection(".except", XCOFF::STYP_EXCEPT) {}
392 
393 void XCOFFObjectWriter::reset() {
394  // Clear the mappings we created.
395  SymbolIndexMap.clear();
396  SectionMap.clear();
397 
398  UndefinedCsects.clear();
399  // Reset any sections we have written to, and empty the section header table.
400  for (auto *Sec : Sections)
401  Sec->reset();
402  for (auto &DwarfSec : DwarfSections)
403  DwarfSec.reset();
404  ExceptionSection.reset();
405 
406  // Reset states in XCOFFObjectWriter.
407  SymbolTableEntryCount = 0;
408  SymbolTableOffset = 0;
409  SectionCount = 0;
410  RelocationEntryOffset = 0;
411  Strings.clear();
412 
413  MCObjectWriter::reset();
414 }
415 
416 CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
417  switch (MCSec->getMappingClass()) {
418  case XCOFF::XMC_PR:
419  assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
420  "Only an initialized csect can contain program code.");
421  return ProgramCodeCsects;
422  case XCOFF::XMC_RO:
423  assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
424  "Only an initialized csect can contain read only data.");
425  return ReadOnlyCsects;
426  case XCOFF::XMC_RW:
427  if (XCOFF::XTY_CM == MCSec->getCSectType())
428  return BSSCsects;
429 
430  if (XCOFF::XTY_SD == MCSec->getCSectType())
431  return DataCsects;
432 
433  report_fatal_error("Unhandled mapping of read-write csect to section.");
434  case XCOFF::XMC_DS:
435  return FuncDSCsects;
436  case XCOFF::XMC_BS:
437  assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
438  "Mapping invalid csect. CSECT with bss storage class must be "
439  "common type.");
440  return BSSCsects;
441  case XCOFF::XMC_TL:
442  assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
443  "Mapping invalid csect. CSECT with tdata storage class must be "
444  "an initialized csect.");
445  return TDataCsects;
446  case XCOFF::XMC_UL:
447  assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
448  "Mapping invalid csect. CSECT with tbss storage class must be "
449  "an uninitialized csect.");
450  return TBSSCsects;
451  case XCOFF::XMC_TC0:
452  assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
453  "Only an initialized csect can contain TOC-base.");
454  assert(TOCCsects.empty() &&
455  "We should have only one TOC-base, and it should be the first csect "
456  "in this CsectGroup.");
457  return TOCCsects;
458  case XCOFF::XMC_TC:
459  case XCOFF::XMC_TE:
460  assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
461  "Only an initialized csect can contain TC entry.");
462  assert(!TOCCsects.empty() &&
463  "We should at least have a TOC-base in this CsectGroup.");
464  return TOCCsects;
465  case XCOFF::XMC_TD:
466  report_fatal_error("toc-data not yet supported when writing object files.");
467  default:
468  report_fatal_error("Unhandled mapping of csect to section.");
469  }
470 }
471 
472 static MCSectionXCOFF *getContainingCsect(const MCSymbolXCOFF *XSym) {
473  if (XSym->isDefined())
474  return cast<MCSectionXCOFF>(XSym->getFragment()->getParent());
475  return XSym->getRepresentedCsect();
476 }
477 
478 void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
479  const MCAsmLayout &Layout) {
480  for (const auto &S : Asm) {
481  const auto *MCSec = cast<const MCSectionXCOFF>(&S);
482  assert(SectionMap.find(MCSec) == SectionMap.end() &&
483  "Cannot add a section twice.");
484 
485  // If the name does not fit in the storage provided in the symbol table
486  // entry, add it to the string table.
487  if (nameShouldBeInStringTable(MCSec->getSymbolTableName()))
488  Strings.add(MCSec->getSymbolTableName());
489  if (MCSec->isCsect()) {
490  // A new control section. Its CsectSectionEntry should already be staticly
491  // generated as Text/Data/BSS/TDATA/TBSS. Add this section to the group of
492  // the CsectSectionEntry.
493  assert(XCOFF::XTY_ER != MCSec->getCSectType() &&
494  "An undefined csect should not get registered.");
495  CsectGroup &Group = getCsectGroup(MCSec);
496  Group.emplace_back(MCSec);
497  SectionMap[MCSec] = &Group.back();
498  } else if (MCSec->isDwarfSect()) {
499  // A new DwarfSectionEntry.
500  std::unique_ptr<XCOFFSection> DwarfSec =
501  std::make_unique<XCOFFSection>(MCSec);
502  SectionMap[MCSec] = DwarfSec.get();
503 
504  DwarfSectionEntry SecEntry(MCSec->getName(),
505  *MCSec->getDwarfSubtypeFlags(),
506  std::move(DwarfSec));
507  DwarfSections.push_back(std::move(SecEntry));
508  } else
509  llvm_unreachable("unsupport section type!");
510  }
511 
512  for (const MCSymbol &S : Asm.symbols()) {
513  // Nothing to do for temporary symbols.
514  if (S.isTemporary())
515  continue;
516 
517  const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(&S);
518  const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym);
519 
521  HasVisibility = true;
522 
523  if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) {
524  // Handle undefined symbol.
525  UndefinedCsects.emplace_back(ContainingCsect);
526  SectionMap[ContainingCsect] = &UndefinedCsects.back();
527  if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName()))
528  Strings.add(ContainingCsect->getSymbolTableName());
529  continue;
530  }
531 
532  // If the symbol is the csect itself, we don't need to put the symbol
533  // into csect's Syms.
534  if (XSym == ContainingCsect->getQualNameSymbol())
535  continue;
536 
537  // Only put a label into the symbol table when it is an external label.
538  if (!XSym->isExternal())
539  continue;
540 
541  assert(SectionMap.find(ContainingCsect) != SectionMap.end() &&
542  "Expected containing csect to exist in map");
543  XCOFFSection *Csect = SectionMap[ContainingCsect];
544  // Lookup the containing csect and add the symbol to it.
545  assert(Csect->MCSec->isCsect() && "only csect is supported now!");
546  Csect->Syms.emplace_back(XSym);
547 
548  // If the name does not fit in the storage provided in the symbol table
549  // entry, add it to the string table.
550  if (nameShouldBeInStringTable(XSym->getSymbolTableName()))
551  Strings.add(XSym->getSymbolTableName());
552  }
553 
554  FileNames = Asm.getFileNames();
555  // Emit ".file" as the source file name when there is no file name.
556  if (FileNames.empty())
557  FileNames.emplace_back(".file", 0);
558  for (const std::pair<std::string, size_t> &F : FileNames) {
559  if (nameShouldBeInStringTable(F.first))
560  Strings.add(F.first);
561  }
562 
563  Strings.finalize();
564  assignAddressesAndIndices(Layout);
565 }
566 
567 void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
568  const MCAsmLayout &Layout,
569  const MCFragment *Fragment,
570  const MCFixup &Fixup, MCValue Target,
571  uint64_t &FixedValue) {
572  auto getIndex = [this](const MCSymbol *Sym,
573  const MCSectionXCOFF *ContainingCsect) {
574  // If we could not find the symbol directly in SymbolIndexMap, this symbol
575  // could either be a temporary symbol or an undefined symbol. In this case,
576  // we would need to have the relocation reference its csect instead.
577  return SymbolIndexMap.find(Sym) != SymbolIndexMap.end()
578  ? SymbolIndexMap[Sym]
579  : SymbolIndexMap[ContainingCsect->getQualNameSymbol()];
580  };
581 
582  auto getVirtualAddress =
583  [this, &Layout](const MCSymbol *Sym,
584  const MCSectionXCOFF *ContainingSect) -> uint64_t {
585  // A DWARF section.
586  if (ContainingSect->isDwarfSect())
587  return Layout.getSymbolOffset(*Sym);
588 
589  // A csect.
590  if (!Sym->isDefined())
591  return SectionMap[ContainingSect]->Address;
592 
593  // A label.
594  assert(Sym->isDefined() && "not a valid object that has address!");
595  return SectionMap[ContainingSect]->Address + Layout.getSymbolOffset(*Sym);
596  };
597 
598  const MCSymbol *const SymA = &Target.getSymA()->getSymbol();
599 
600  MCAsmBackend &Backend = Asm.getBackend();
601  bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
602  MCFixupKindInfo::FKF_IsPCRel;
603 
604  uint8_t Type;
605  uint8_t SignAndSize;
606  std::tie(Type, SignAndSize) =
607  TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);
608 
609  const MCSectionXCOFF *SymASec = getContainingCsect(cast<MCSymbolXCOFF>(SymA));
610 
611  if (SymASec->isCsect() && SymASec->getMappingClass() == XCOFF::XMC_TD)
612  report_fatal_error("toc-data not yet supported when writing object files.");
613 
614  assert(SectionMap.find(SymASec) != SectionMap.end() &&
615  "Expected containing csect to exist in map.");
616 
617  const uint32_t Index = getIndex(SymA, SymASec);
620  // The FixedValue should be symbol's virtual address in this object file
621  // plus any constant value that we might get.
622  FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
624  // The FixedValue should always be zero since the region handle is only
625  // known at load time.
626  FixedValue = 0;
627  else if (Type == XCOFF::RelocationType::R_TOC ||
629  // The FixedValue should be the TOC entry offset from the TOC-base plus any
630  // constant offset value.
631  const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
632  TOCCsects.front().Address +
633  Target.getConstant();
634  if (Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
635  report_fatal_error("TOCEntryOffset overflows in small code model mode");
636 
637  FixedValue = TOCEntryOffset;
638  }
639 
640  assert((Fixup.getOffset() <=
641  MaxRawDataSize - Layout.getFragmentOffset(Fragment)) &&
642  "Fragment offset + fixup offset is overflowed.");
643  uint32_t FixupOffsetInCsect =
644  Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
645 
646  XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type};
647  MCSectionXCOFF *RelocationSec = cast<MCSectionXCOFF>(Fragment->getParent());
648  assert(SectionMap.find(RelocationSec) != SectionMap.end() &&
649  "Expected containing csect to exist in map.");
650  SectionMap[RelocationSec]->Relocations.push_back(Reloc);
651 
652  if (!Target.getSymB())
653  return;
654 
655  const MCSymbol *const SymB = &Target.getSymB()->getSymbol();
656  if (SymA == SymB)
657  report_fatal_error("relocation for opposite term is not yet supported");
658 
659  const MCSectionXCOFF *SymBSec = getContainingCsect(cast<MCSymbolXCOFF>(SymB));
660  assert(SectionMap.find(SymBSec) != SectionMap.end() &&
661  "Expected containing csect to exist in map.");
662  if (SymASec == SymBSec)
664  "relocation for paired relocatable term is not yet supported");
665 
667  "SymA must be R_POS here if it's not opposite term or paired "
668  "relocatable term.");
669  const uint32_t IndexB = getIndex(SymB, SymBSec);
670  // SymB must be R_NEG here, given the general form of Target(MCValue) is
671  // "SymbolA - SymbolB + imm64".
672  const uint8_t TypeB = XCOFF::RelocationType::R_NEG;
673  XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};
674  SectionMap[RelocationSec]->Relocations.push_back(RelocB);
675  // We already folded "SymbolA + imm64" above when Type is R_POS for SymbolA,
676  // now we just need to fold "- SymbolB" here.
677  FixedValue -= getVirtualAddress(SymB, SymBSec);
678 }
679 
680 void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
681  const MCAsmLayout &Layout) {
682  uint64_t CurrentAddressLocation = 0;
683  for (const auto *Section : Sections)
684  writeSectionForControlSectionEntry(Asm, Layout, *Section,
685  CurrentAddressLocation);
686  for (const auto &DwarfSection : DwarfSections)
687  writeSectionForDwarfSectionEntry(Asm, Layout, DwarfSection,
688  CurrentAddressLocation);
689  writeSectionForExceptionSectionEntry(Asm, Layout, ExceptionSection,
690  CurrentAddressLocation);
691 }
692 
693 uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm,
694  const MCAsmLayout &Layout) {
695  // We always emit a timestamp of 0 for reproducibility, so ensure incremental
696  // linking is not enabled, in case, like with Windows COFF, such a timestamp
697  // is incompatible with incremental linking of XCOFF.
698  if (Asm.isIncrementalLinkerCompatible())
699  report_fatal_error("Incremental linking not supported for XCOFF.");
700 
701  finalizeSectionInfo();
702  uint64_t StartOffset = W.OS.tell();
703 
704  writeFileHeader();
705  writeAuxFileHeader();
706  writeSectionHeaderTable();
707  writeSections(Asm, Layout);
708  writeRelocations();
709  writeSymbolTable(Layout);
710  // Write the string table.
711  Strings.write(W.OS);
712 
713  return W.OS.tell() - StartOffset;
714 }
715 
716 bool XCOFFObjectWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {
717  return SymbolName.size() > XCOFF::NameSize || is64Bit();
718 }
719 
720 void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
721  // Magic, Offset or SymbolName.
722  if (nameShouldBeInStringTable(SymbolName)) {
723  W.write<int32_t>(0);
724  W.write<uint32_t>(Strings.getOffset(SymbolName));
725  } else {
726  char Name[XCOFF::NameSize + 1];
727  std::strncpy(Name, SymbolName.data(), XCOFF::NameSize);
729  W.write(NameRef);
730  }
731 }
732 
733 void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
734  int16_t SectionNumber,
736  uint8_t StorageClass,
737  uint8_t NumberOfAuxEntries) {
738  if (is64Bit()) {
739  W.write<uint64_t>(Value);
740  W.write<uint32_t>(Strings.getOffset(SymbolName));
741  } else {
742  writeSymbolName(SymbolName);
743  W.write<uint32_t>(Value);
744  }
745  W.write<int16_t>(SectionNumber);
746  W.write<uint16_t>(SymbolType);
747  W.write<uint8_t>(StorageClass);
748  W.write<uint8_t>(NumberOfAuxEntries);
749 }
750 
751 void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
752  uint8_t SymbolAlignmentAndType,
753  uint8_t StorageMappingClass) {
754  W.write<uint32_t>(is64Bit() ? Lo_32(SectionOrLength) : SectionOrLength);
755  W.write<uint32_t>(0); // ParameterHashIndex
756  W.write<uint16_t>(0); // TypeChkSectNum
757  W.write<uint8_t>(SymbolAlignmentAndType);
758  W.write<uint8_t>(StorageMappingClass);
759  if (is64Bit()) {
760  W.write<uint32_t>(Hi_32(SectionOrLength));
761  W.OS.write_zeros(1); // Reserved
762  W.write<uint8_t>(XCOFF::AUX_CSECT);
763  } else {
764  W.write<uint32_t>(0); // StabInfoIndex
765  W.write<uint16_t>(0); // StabSectNum
766  }
767 }
768 
769 void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
770  uint64_t LengthOfSectionPortion, uint64_t NumberOfRelocEnt) {
771  writeWord(LengthOfSectionPortion);
772  if (!is64Bit())
773  W.OS.write_zeros(4); // Reserved
774  writeWord(NumberOfRelocEnt);
775  if (is64Bit()) {
776  W.OS.write_zeros(1); // Reserved
777  W.write<uint8_t>(XCOFF::AUX_SECT);
778  } else {
779  W.OS.write_zeros(6); // Reserved
780  }
781 }
782 
783 void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
784  const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
785  int16_t SectionIndex, uint64_t SymbolOffset) {
786  assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&
787  "Symbol address overflowed.");
788 
789  auto Entry = ExceptionSection.ExceptionTable.find(SymbolRef.MCSym->getName());
790  if (Entry != ExceptionSection.ExceptionTable.end()) {
791  writeSymbolEntry(SymbolRef.getSymbolTableName(),
792  CSectionRef.Address + SymbolOffset, SectionIndex,
793  // In the old version of the 32-bit XCOFF interpretation,
794  // symbols may require bit 10 (0x0020) to be set if the
795  // symbol is a function, otherwise the bit should be 0.
796  is64Bit() ? SymbolRef.getVisibilityType()
797  : SymbolRef.getVisibilityType() | 0x0020,
798  SymbolRef.getStorageClass(),
799  (is64Bit() && ExceptionSection.isDebugEnabled) ? 3 : 2);
800  if (is64Bit() && ExceptionSection.isDebugEnabled) {
801  // On 64 bit with debugging enabled, we have a csect, exception, and
802  // function auxilliary entries, so we must increment symbol index by 4.
803  writeSymbolAuxExceptionEntry(
804  ExceptionSection.FileOffsetToData +
805  getExceptionOffset(Entry->second.FunctionSymbol),
806  Entry->second.FunctionSize,
807  SymbolIndexMap[Entry->second.FunctionSymbol] + 4);
808  }
809  // For exception section entries, csect and function auxilliary entries
810  // must exist. On 64-bit there is also an exception auxilliary entry.
811  writeSymbolAuxFunctionEntry(
812  ExceptionSection.FileOffsetToData +
813  getExceptionOffset(Entry->second.FunctionSymbol),
814  Entry->second.FunctionSize, 0,
815  (is64Bit() && ExceptionSection.isDebugEnabled)
816  ? SymbolIndexMap[Entry->second.FunctionSymbol] + 4
817  : SymbolIndexMap[Entry->second.FunctionSymbol] + 3);
818  } else {
819  writeSymbolEntry(SymbolRef.getSymbolTableName(),
820  CSectionRef.Address + SymbolOffset, SectionIndex,
821  SymbolRef.getVisibilityType(),
822  SymbolRef.getStorageClass());
823  }
824  writeSymbolAuxCsectEntry(CSectionRef.SymbolTableIndex, XCOFF::XTY_LD,
825  CSectionRef.MCSec->getMappingClass());
826 }
827 
828 void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
829  const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {
830  assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!");
831 
832  writeSymbolEntry(DwarfSectionRef.getSymbolTableName(), /*Value=*/0,
833  SectionIndex, /*SymbolType=*/0, XCOFF::C_DWARF);
834 
835  writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);
836 }
837 
838 void XCOFFObjectWriter::writeSymbolEntryForControlSection(
839  const XCOFFSection &CSectionRef, int16_t SectionIndex,
841  writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,
842  SectionIndex, CSectionRef.getVisibilityType(), StorageClass);
843 
844  writeSymbolAuxCsectEntry(CSectionRef.Size, getEncodedType(CSectionRef.MCSec),
845  CSectionRef.MCSec->getMappingClass());
846 }
847 
848 void XCOFFObjectWriter::writeSymbolAuxFunctionEntry(uint32_t EntryOffset,
849  uint32_t FunctionSize,
850  uint64_t LineNumberPointer,
851  uint32_t EndIndex) {
852  if (is64Bit())
853  writeWord(LineNumberPointer);
854  else
855  W.write<uint32_t>(EntryOffset);
856  W.write<uint32_t>(FunctionSize);
857  if (!is64Bit())
858  writeWord(LineNumberPointer);
859  W.write<uint32_t>(EndIndex);
860  if (is64Bit()) {
861  W.OS.write_zeros(1);
862  W.write<uint8_t>(XCOFF::AUX_FCN);
863  } else {
864  W.OS.write_zeros(2);
865  }
866 }
867 
868 void XCOFFObjectWriter::writeSymbolAuxExceptionEntry(uint64_t EntryOffset,
869  uint32_t FunctionSize,
870  uint32_t EndIndex) {
871  assert(is64Bit() && "Exception auxilliary entries are 64-bit only.");
872  W.write<uint64_t>(EntryOffset);
873  W.write<uint32_t>(FunctionSize);
874  W.write<uint32_t>(EndIndex);
875  W.OS.write_zeros(1); // Pad (unused)
876  W.write<uint8_t>(XCOFF::AUX_EXCEPT);
877 }
878 
879 void XCOFFObjectWriter::writeFileHeader() {
881  W.write<uint16_t>(SectionCount);
882  W.write<int32_t>(0); // TimeStamp
883  writeWord(SymbolTableOffset);
884  if (is64Bit()) {
885  W.write<uint16_t>(auxiliaryHeaderSize());
886  W.write<uint16_t>(0); // Flags
887  W.write<int32_t>(SymbolTableEntryCount);
888  } else {
889  W.write<int32_t>(SymbolTableEntryCount);
890  W.write<uint16_t>(auxiliaryHeaderSize());
891  W.write<uint16_t>(0); // Flags
892  }
893 }
894 
895 void XCOFFObjectWriter::writeAuxFileHeader() {
896  if (!auxiliaryHeaderSize())
897  return;
898  W.write<uint16_t>(0); // Magic
899  W.write<uint16_t>(
900  XCOFF::NEW_XCOFF_INTERPRET); // Version. The new interpretation of the
901  // n_type field in the symbol table entry is
902  // used in XCOFF32.
903  W.write<uint32_t>(Sections[0]->Size); // TextSize
904  W.write<uint32_t>(Sections[1]->Size); // InitDataSize
905  W.write<uint32_t>(Sections[2]->Size); // BssDataSize
906  W.write<uint32_t>(0); // EntryPointAddr
907  W.write<uint32_t>(Sections[0]->Address); // TextStartAddr
908  W.write<uint32_t>(Sections[1]->Address); // DataStartAddr
909 }
910 
911 void XCOFFObjectWriter::writeSectionHeaderTable() {
912  auto writeSectionHeader = [&](const SectionEntry *Sec, bool IsDwarf) {
913  // Nothing to write for this Section.
914  if (Sec->Index == SectionEntry::UninitializedIndex)
915  return false;
916 
917  // Write Name.
918  ArrayRef<char> NameRef(Sec->Name, XCOFF::NameSize);
919  W.write(NameRef);
920 
921  // Write the Physical Address and Virtual Address. In an object file these
922  // are the same.
923  // We use 0 for DWARF sections' Physical and Virtual Addresses.
924  writeWord(IsDwarf ? 0 : Sec->Address);
925  writeWord(IsDwarf ? 0 : Sec->Address);
926 
927  writeWord(Sec->Size);
928  writeWord(Sec->FileOffsetToData);
929  writeWord(Sec->FileOffsetToRelocations);
930  writeWord(0); // FileOffsetToLineNumberInfo. Not supported yet.
931 
932  if (is64Bit()) {
933  W.write<uint32_t>(Sec->RelocationCount);
934  W.write<uint32_t>(0); // NumberOfLineNumbers. Not supported yet.
935  W.write<int32_t>(Sec->Flags);
936  W.OS.write_zeros(4);
937  } else {
938  W.write<uint16_t>(Sec->RelocationCount);
939  W.write<uint16_t>(0); // NumberOfLineNumbers. Not supported yet.
940  W.write<int32_t>(Sec->Flags);
941  }
942 
943  return true;
944  };
945 
946  for (const auto *CsectSec : Sections)
947  writeSectionHeader(CsectSec, /* IsDwarf */ false);
948  for (const auto &DwarfSec : DwarfSections)
949  writeSectionHeader(&DwarfSec, /* IsDwarf */ true);
950  if (hasExceptionSection())
951  writeSectionHeader(&ExceptionSection, false);
952 }
953 
954 void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
955  const XCOFFSection &Section) {
956  if (Section.MCSec->isCsect())
957  writeWord(Section.Address + Reloc.FixupOffsetInCsect);
958  else {
959  // DWARF sections' address is set to 0.
960  assert(Section.MCSec->isDwarfSect() && "unsupport section type!");
961  writeWord(Reloc.FixupOffsetInCsect);
962  }
963  W.write<uint32_t>(Reloc.SymbolTableIndex);
964  W.write<uint8_t>(Reloc.SignAndSize);
965  W.write<uint8_t>(Reloc.Type);
966 }
967 
968 void XCOFFObjectWriter::writeRelocations() {
969  for (const auto *Section : Sections) {
970  if (Section->Index == SectionEntry::UninitializedIndex)
971  // Nothing to write for this Section.
972  continue;
973 
974  for (const auto *Group : Section->Groups) {
975  if (Group->empty())
976  continue;
977 
978  for (const auto &Csect : *Group) {
979  for (const auto Reloc : Csect.Relocations)
980  writeRelocation(Reloc, Csect);
981  }
982  }
983  }
984 
985  for (const auto &DwarfSection : DwarfSections)
986  for (const auto &Reloc : DwarfSection.DwarfSect->Relocations)
987  writeRelocation(Reloc, *DwarfSection.DwarfSect);
988 }
989 
991  // Write C_FILE symbols.
992  // The n_name of a C_FILE symbol is the source file's name when no auxiliary
993  // entries are present.
994  for (const std::pair<std::string, size_t> &F : FileNames) {
995  writeSymbolEntry(F.first, /*Value=*/0, XCOFF::ReservedSectionNum::N_DEBUG,
996  /*SymbolType=*/0, XCOFF::C_FILE,
997  /*NumberOfAuxEntries=*/0);
998  }
999 
1000  for (const auto &Csect : UndefinedCsects) {
1001  writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF,
1002  Csect.MCSec->getStorageClass());
1003  }
1004 
1005  for (const auto *Section : Sections) {
1006  if (Section->Index == SectionEntry::UninitializedIndex)
1007  // Nothing to write for this Section.
1008  continue;
1009 
1010  for (const auto *Group : Section->Groups) {
1011  if (Group->empty())
1012  continue;
1013 
1014  const int16_t SectionIndex = Section->Index;
1015  for (const auto &Csect : *Group) {
1016  // Write out the control section first and then each symbol in it.
1017  writeSymbolEntryForControlSection(Csect, SectionIndex,
1018  Csect.MCSec->getStorageClass());
1019 
1020  for (const auto &Sym : Csect.Syms)
1021  writeSymbolEntryForCsectMemberLabel(
1022  Sym, Csect, SectionIndex, Layout.getSymbolOffset(*(Sym.MCSym)));
1023  }
1024  }
1025  }
1026 
1027  for (const auto &DwarfSection : DwarfSections)
1028  writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect,
1029  DwarfSection.Index);
1030 }
1031 
1032 void XCOFFObjectWriter::finalizeSectionInfo() {
1033  for (auto *Section : Sections) {
1034  if (Section->Index == SectionEntry::UninitializedIndex)
1035  // Nothing to record for this Section.
1036  continue;
1037 
1038  for (const auto *Group : Section->Groups) {
1039  if (Group->empty())
1040  continue;
1041 
1042  for (auto &Csect : *Group) {
1043  const size_t CsectRelocCount = Csect.Relocations.size();
1044  // An XCOFF64 file may not contain an overflow section header.
1045  if (!is64Bit() && (CsectRelocCount >= XCOFF::RelocOverflow ||
1046  Section->RelocationCount >=
1047  XCOFF::RelocOverflow - CsectRelocCount))
1049  "relocation entries overflowed; overflow section is "
1050  "not implemented yet");
1051 
1052  Section->RelocationCount += CsectRelocCount;
1053  }
1054  }
1055  }
1056 
1057  for (auto &DwarfSection : DwarfSections)
1058  DwarfSection.RelocationCount = DwarfSection.DwarfSect->Relocations.size();
1059 
1060  // Calculate the file offset to the relocation entries.
1061  uint64_t RawPointer = RelocationEntryOffset;
1062  auto calcOffsetToRelocations = [&](SectionEntry *Sec, bool IsDwarf) {
1063  if (!IsDwarf && Sec->Index == SectionEntry::UninitializedIndex)
1064  return false;
1065 
1066  if (!Sec->RelocationCount)
1067  return false;
1068 
1069  Sec->FileOffsetToRelocations = RawPointer;
1070  const uint64_t RelocationSizeInSec =
1071  Sec->RelocationCount * (is64Bit()
1074  RawPointer += RelocationSizeInSec;
1075  if (RawPointer > MaxRawDataSize)
1076  report_fatal_error("Relocation data overflowed this object file.");
1077 
1078  return true;
1079  };
1080 
1081  for (auto *Sec : Sections)
1082  calcOffsetToRelocations(Sec, /* IsDwarf */ false);
1083 
1084  for (auto &DwarfSec : DwarfSections)
1085  calcOffsetToRelocations(&DwarfSec, /* IsDwarf */ true);
1086 
1087  // TODO Error check that the number of symbol table entries fits in 32-bits
1088  // signed ...
1089  if (SymbolTableEntryCount)
1090  SymbolTableOffset = RawPointer;
1091 }
1092 
1093 void XCOFFObjectWriter::addExceptionEntry(const MCSymbol *Symbol,
1094  const MCSymbol *Trap,
1095  unsigned LanguageCode,
1096  unsigned ReasonCode,
1097  unsigned FunctionSize,
1098  bool hasDebug) {
1099  // If a module had debug info, debugging is enabled and XCOFF emits the
1100  // exception auxilliary entry.
1101  if (hasDebug)
1102  ExceptionSection.isDebugEnabled = true;
1103  auto Entry = ExceptionSection.ExceptionTable.find(Symbol->getName());
1104  if (Entry != ExceptionSection.ExceptionTable.end()) {
1105  Entry->second.Entries.push_back(
1106  ExceptionTableEntry(Trap, LanguageCode, ReasonCode));
1107  return;
1108  }
1109  ExceptionInfo NewEntry;
1110  NewEntry.FunctionSymbol = Symbol;
1111  NewEntry.FunctionSize = FunctionSize;
1112  NewEntry.Entries.push_back(
1113  ExceptionTableEntry(Trap, LanguageCode, ReasonCode));
1114  ExceptionSection.ExceptionTable.insert(
1115  std::pair<const StringRef, ExceptionInfo>(Symbol->getName(), NewEntry));
1116 }
1117 
1118 unsigned XCOFFObjectWriter::getExceptionSectionSize() {
1119  unsigned EntryNum=0;
1120 
1121  for (auto it = ExceptionSection.ExceptionTable.begin();
1122  it != ExceptionSection.ExceptionTable.end(); ++it)
1123  // The size() gets +1 to account for the initial entry containing the
1124  // symbol table index.
1125  EntryNum += it->second.Entries.size() + 1;
1126 
1127  return EntryNum * (is64Bit() ? XCOFF::ExceptionSectionEntrySize64 :
1129 }
1130 
1131 unsigned XCOFFObjectWriter::getExceptionOffset(const MCSymbol *Symbol) {
1132  unsigned EntryNum = 0;
1133  for (auto it = ExceptionSection.ExceptionTable.begin();
1134  it != ExceptionSection.ExceptionTable.end(); ++it) {
1135  if (Symbol == it->second.FunctionSymbol)
1136  break;
1137  EntryNum += it->second.Entries.size() + 1;
1138  }
1139  return EntryNum * (is64Bit() ? XCOFF::ExceptionSectionEntrySize64 :
1141 }
1142 
1143 void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
1144  // The symbol table starts with all the C_FILE symbols.
1145  uint32_t SymbolTableIndex = FileNames.size();
1146 
1147  // Calculate indices for undefined symbols.
1148  for (auto &Csect : UndefinedCsects) {
1149  Csect.Size = 0;
1150  Csect.Address = 0;
1151  Csect.SymbolTableIndex = SymbolTableIndex;
1152  SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1153  // 1 main and 1 auxiliary symbol table entry for each contained symbol.
1154  SymbolTableIndex += 2;
1155  }
1156 
1157  // The address corrresponds to the address of sections and symbols in the
1158  // object file. We place the shared address 0 immediately after the
1159  // section header table.
1160  uint64_t Address = 0;
1161  // Section indices are 1-based in XCOFF.
1162  int32_t SectionIndex = 1;
1163  bool HasTDataSection = false;
1164  uint32_t PaddingsBeforeDwarf = 0;
1165 
1166  for (auto *Section : Sections) {
1167  const bool IsEmpty =
1168  llvm::all_of(Section->Groups,
1169  [](const CsectGroup *Group) { return Group->empty(); });
1170  if (IsEmpty)
1171  continue;
1172 
1173  if (SectionIndex > MaxSectionIndex)
1174  report_fatal_error("Section index overflow!");
1175  Section->Index = SectionIndex++;
1176  SectionCount++;
1177 
1178  bool SectionAddressSet = false;
1179  // Reset the starting address to 0 for TData section.
1180  if (Section->Flags == XCOFF::STYP_TDATA) {
1181  Address = 0;
1182  HasTDataSection = true;
1183  }
1184  // Reset the starting address to 0 for TBSS section if the object file does
1185  // not contain TData Section.
1186  if ((Section->Flags == XCOFF::STYP_TBSS) && !HasTDataSection)
1187  Address = 0;
1188 
1189  for (auto *Group : Section->Groups) {
1190  if (Group->empty())
1191  continue;
1192 
1193  for (auto &Csect : *Group) {
1194  const MCSectionXCOFF *MCSec = Csect.MCSec;
1195  Csect.Address = alignTo(Address, MCSec->getAlign());
1196  Csect.Size = Layout.getSectionAddressSize(MCSec);
1197  Address = Csect.Address + Csect.Size;
1198  Csect.SymbolTableIndex = SymbolTableIndex;
1199  SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1200  // 1 main and 1 auxiliary symbol table entry for the csect.
1201  SymbolTableIndex += 2;
1202 
1203  for (auto &Sym : Csect.Syms) {
1204  bool hasExceptEntry = false;
1205  auto Entry =
1206  ExceptionSection.ExceptionTable.find(Sym.MCSym->getName());
1207  if(Entry != ExceptionSection.ExceptionTable.end()) {
1208  hasExceptEntry = true;
1209  for (auto &TrapEntry : Entry->second.Entries) {
1210  TrapEntry.TrapAddress = Layout.getSymbolOffset(*(Sym.MCSym)) +
1211  TrapEntry.Trap->getOffset();
1212  }
1213  }
1214  Sym.SymbolTableIndex = SymbolTableIndex;
1215  SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex;
1216  // 1 main and 1 auxiliary symbol table entry for each contained
1217  // symbol. For symbols with exception section entries, a function
1218  // auxilliary entry is needed, and on 64-bit XCOFF with debugging
1219  // enabled, an additional exception auxilliary entry is needed.
1220  SymbolTableIndex += 2;
1221  if (hasExceptionSection() && hasExceptEntry) {
1222  if (is64Bit() && ExceptionSection.isDebugEnabled)
1223  SymbolTableIndex += 2;
1224  else
1225  SymbolTableIndex += 1;
1226  }
1227  }
1228  }
1229 
1230  if (!SectionAddressSet) {
1231  Section->Address = Group->front().Address;
1232  SectionAddressSet = true;
1233  }
1234  }
1235 
1236  // Make sure the address of the next section aligned to
1237  // DefaultSectionAlign.
1238  Address = alignTo(Address, DefaultSectionAlign);
1239  Section->Size = Address - Section->Address;
1240  }
1241 
1242  // Start to generate DWARF sections. Sections other than DWARF section use
1243  // DefaultSectionAlign as the default alignment, while DWARF sections have
1244  // their own alignments. If these two alignments are not the same, we need
1245  // some paddings here and record the paddings bytes for FileOffsetToData
1246  // calculation.
1247  if (!DwarfSections.empty())
1248  PaddingsBeforeDwarf =
1249  alignTo(Address,
1250  (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) -
1251  Address;
1252 
1253  DwarfSectionEntry *LastDwarfSection = nullptr;
1254 
1255  for (auto &DwarfSection : DwarfSections) {
1256  assert((SectionIndex <= MaxSectionIndex) && "Section index overflow!");
1257 
1258  XCOFFSection &DwarfSect = *DwarfSection.DwarfSect;
1259  const MCSectionXCOFF *MCSec = DwarfSect.MCSec;
1260 
1261  // Section index.
1262  DwarfSection.Index = SectionIndex++;
1263  SectionCount++;
1264 
1265  // Symbol index.
1266  DwarfSect.SymbolTableIndex = SymbolTableIndex;
1267  SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex;
1268  // 1 main and 1 auxiliary symbol table entry for the csect.
1269  SymbolTableIndex += 2;
1270 
1271  // Section address. Make it align to section alignment.
1272  // We use address 0 for DWARF sections' Physical and Virtual Addresses.
1273  // This address is used to tell where is the section in the final object.
1274  // See writeSectionForDwarfSectionEntry().
1275  DwarfSection.Address = DwarfSect.Address =
1276  alignTo(Address, MCSec->getAlign());
1277 
1278  // Section size.
1279  // For DWARF section, we must use the real size which may be not aligned.
1280  DwarfSection.Size = DwarfSect.Size = Layout.getSectionAddressSize(MCSec);
1281 
1282  Address = DwarfSection.Address + DwarfSection.Size;
1283 
1284  if (LastDwarfSection)
1285  LastDwarfSection->MemorySize =
1286  DwarfSection.Address - LastDwarfSection->Address;
1287  LastDwarfSection = &DwarfSection;
1288  }
1289  if (LastDwarfSection) {
1290  // Make the final DWARF section address align to the default section
1291  // alignment for follow contents.
1292  Address = alignTo(LastDwarfSection->Address + LastDwarfSection->Size,
1293  DefaultSectionAlign);
1294  LastDwarfSection->MemorySize = Address - LastDwarfSection->Address;
1295  }
1296  if (hasExceptionSection()) {
1297  ExceptionSection.Index = SectionIndex++;
1298  SectionCount++;
1299  ExceptionSection.Address = 0;
1300  ExceptionSection.Size = getExceptionSectionSize();
1301  Address += ExceptionSection.Size;
1302  Address = alignTo(Address, DefaultSectionAlign);
1303  }
1304  SymbolTableEntryCount = SymbolTableIndex;
1305 
1306  // Calculate the RawPointer value for each section.
1307  uint64_t RawPointer =
1309  SectionCount * XCOFF::SectionHeaderSize64)
1311  SectionCount * XCOFF::SectionHeaderSize32)) +
1312  auxiliaryHeaderSize();
1313 
1314  for (auto *Sec : Sections) {
1315  if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)
1316  continue;
1317 
1318  Sec->FileOffsetToData = RawPointer;
1319  RawPointer += Sec->Size;
1320  if (RawPointer > MaxRawDataSize)
1321  report_fatal_error("Section raw data overflowed this object file.");
1322  }
1323 
1324  // Increase the raw pointer for the padding bytes between csect sections and
1325  // DWARF sections.
1326  if (!DwarfSections.empty())
1327  RawPointer += PaddingsBeforeDwarf;
1328 
1329  for (auto &DwarfSection : DwarfSections) {
1330  DwarfSection.FileOffsetToData = RawPointer;
1331 
1332  RawPointer += DwarfSection.MemorySize;
1333 
1334  assert(RawPointer <= MaxRawDataSize &&
1335  "Section raw data overflowed this object file.");
1336  }
1337 
1338  if (hasExceptionSection()) {
1339  ExceptionSection.FileOffsetToData = RawPointer;
1340  RawPointer += ExceptionSection.Size;
1341 
1342  assert(RawPointer <= MaxRawDataSize &&
1343  "Section raw data overflowed this object file.");
1344  }
1345 
1346  RelocationEntryOffset = RawPointer;
1347 }
1348 
1349 void XCOFFObjectWriter::writeSectionForControlSectionEntry(
1350  const MCAssembler &Asm, const MCAsmLayout &Layout,
1351  const CsectSectionEntry &CsectEntry, uint64_t &CurrentAddressLocation) {
1352  // Nothing to write for this Section.
1353  if (CsectEntry.Index == SectionEntry::UninitializedIndex)
1354  return;
1355 
1356  // There could be a gap (without corresponding zero padding) between
1357  // sections.
1358  // There could be a gap (without corresponding zero padding) between
1359  // sections.
1360  assert(((CurrentAddressLocation <= CsectEntry.Address) ||
1361  (CsectEntry.Flags == XCOFF::STYP_TDATA) ||
1362  (CsectEntry.Flags == XCOFF::STYP_TBSS)) &&
1363  "CurrentAddressLocation should be less than or equal to section "
1364  "address if the section is not TData or TBSS.");
1365 
1366  CurrentAddressLocation = CsectEntry.Address;
1367 
1368  // For virtual sections, nothing to write. But need to increase
1369  // CurrentAddressLocation for later sections like DWARF section has a correct
1370  // writing location.
1371  if (CsectEntry.IsVirtual) {
1372  CurrentAddressLocation += CsectEntry.Size;
1373  return;
1374  }
1375 
1376  for (const auto &Group : CsectEntry.Groups) {
1377  for (const auto &Csect : *Group) {
1378  if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)
1379  W.OS.write_zeros(PaddingSize);
1380  if (Csect.Size)
1381  Asm.writeSectionData(W.OS, Csect.MCSec, Layout);
1382  CurrentAddressLocation = Csect.Address + Csect.Size;
1383  }
1384  }
1385 
1386  // The size of the tail padding in a section is the end virtual address of
1387  // the current section minus the the end virtual address of the last csect
1388  // in that section.
1389  if (uint64_t PaddingSize =
1390  CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) {
1391  W.OS.write_zeros(PaddingSize);
1392  CurrentAddressLocation += PaddingSize;
1393  }
1394 }
1395 
1396 void XCOFFObjectWriter::writeSectionForDwarfSectionEntry(
1397  const MCAssembler &Asm, const MCAsmLayout &Layout,
1398  const DwarfSectionEntry &DwarfEntry, uint64_t &CurrentAddressLocation) {
1399  // There could be a gap (without corresponding zero padding) between
1400  // sections. For example DWARF section alignment is bigger than
1401  // DefaultSectionAlign.
1402  assert(CurrentAddressLocation <= DwarfEntry.Address &&
1403  "CurrentAddressLocation should be less than or equal to section "
1404  "address.");
1405 
1406  if (uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation)
1407  W.OS.write_zeros(PaddingSize);
1408 
1409  if (DwarfEntry.Size)
1410  Asm.writeSectionData(W.OS, DwarfEntry.DwarfSect->MCSec, Layout);
1411 
1412  CurrentAddressLocation = DwarfEntry.Address + DwarfEntry.Size;
1413 
1414  // DWARF section size is not aligned to DefaultSectionAlign.
1415  // Make sure CurrentAddressLocation is aligned to DefaultSectionAlign.
1416  uint32_t Mod = CurrentAddressLocation % DefaultSectionAlign;
1417  uint32_t TailPaddingSize = Mod ? DefaultSectionAlign - Mod : 0;
1418  if (TailPaddingSize)
1419  W.OS.write_zeros(TailPaddingSize);
1420 
1421  CurrentAddressLocation += TailPaddingSize;
1422 }
1423 
1424 void XCOFFObjectWriter::writeSectionForExceptionSectionEntry(
1425  const MCAssembler &Asm, const MCAsmLayout &Layout,
1426  ExceptionSectionEntry &ExceptionEntry, uint64_t &CurrentAddressLocation) {
1427  for (auto it = ExceptionEntry.ExceptionTable.begin();
1428  it != ExceptionEntry.ExceptionTable.end(); it++) {
1429  // For every symbol that has exception entries, you must start the entries
1430  // with an initial symbol table index entry
1431  W.write<uint32_t>(SymbolIndexMap[it->second.FunctionSymbol]);
1432  if (is64Bit()) {
1433  // 4-byte padding on 64-bit.
1434  W.OS.write_zeros(4);
1435  }
1436  W.OS.write_zeros(2);
1437  for (auto &TrapEntry : it->second.Entries) {
1438  writeWord(TrapEntry.TrapAddress);
1439  W.write<uint8_t>(TrapEntry.Lang);
1440  W.write<uint8_t>(TrapEntry.Reason);
1441  }
1442  }
1443 
1444  CurrentAddressLocation += getExceptionSectionSize();
1445 }
1446 
1447 // Takes the log base 2 of the alignment and shifts the result into the 5 most
1448 // significant bits of a byte, then or's in the csect type into the least
1449 // significant 3 bits.
1450 uint8_t getEncodedType(const MCSectionXCOFF *Sec) {
1451  unsigned Log2Align = Log2(Sec->getAlign());
1452  // Result is a number in the range [0, 31] which fits in the 5 least
1453  // significant bits. Shift this value into the 5 most significant bits, and
1454  // bitwise-or in the csect type.
1455  uint8_t EncodedAlign = Log2Align << 3;
1456  return EncodedAlign | Sec->getCSectType();
1457 }
1458 
1459 } // end anonymous namespace
1460 
1461 std::unique_ptr<MCObjectWriter>
1462 llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
1463  raw_pwrite_stream &OS) {
1464  return std::make_unique<XCOFFObjectWriter>(std::move(MOTW), OS);
1465 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
alignTo
static int alignTo(int Num, int PowOf2)
Definition: AArch64LoadStoreOptimizer.cpp:1204
llvm::MCSectionXCOFF::getCSectType
XCOFF::SymbolType getCSectType() const
Definition: MCSectionXCOFF.h:106
llvm::XCOFF::XTY_ER
@ XTY_ER
External reference.
Definition: XCOFF.h:228
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::XCOFF::C_DWARF
@ C_DWARF
Definition: XCOFF.h:173
it
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in it
Definition: README-SSE.txt:81
llvm::MCSectionXCOFF
Definition: MCSectionXCOFF.h:32
llvm::XCOFF::STYP_EXCEPT
@ STYP_EXCEPT
Definition: XCOFF.h:127
llvm::XCOFF::SectionHeaderSize64
constexpr size_t SectionHeaderSize64
Definition: XCOFF.h:36
llvm::MCAsmBackend::getFixupKindInfo
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Definition: MCAsmBackend.cpp:81
llvm::XCOFF::XTY_LD
@ XTY_LD
Label definition. Defines an entry point to an initialized csect.
Definition: XCOFF.h:230
llvm::MCSymbol::isExternal
bool isExternal() const
Definition: MCSymbol.h:401
llvm::XCOFF::RelocationSerializationSize64
constexpr size_t RelocationSerializationSize64
Definition: XCOFF.h:39
llvm::XCOFF::XMC_TD
@ XMC_TD
Scalar data item in the TOC.
Definition: XCOFF.h:107
is64Bit
static bool is64Bit(const char *name)
Definition: X86Disassembler.cpp:1018
llvm::MCSymbolXCOFF::getSymbolTableName
StringRef getSymbolTableName() const
Definition: MCSymbolXCOFF.h:60
llvm::XCOFF::STYP_BSS
@ STYP_BSS
Definition: XCOFF.h:126
llvm::XCOFF::XMC_TE
@ XMC_TE
Symbol mapped at the end of TOC.
Definition: XCOFF.h:115
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:266
llvm::XCOFF::C_FILE
@ C_FILE
Definition: XCOFF.h:159
llvm::XCOFF::VisibilityType
VisibilityType
Values for visibility as they would appear when encoded in the high 4 bits of the 16-bit unsigned n_t...
Definition: XCOFF.h:238
ErrorHandling.h
llvm::XCOFF::SectionHeaderSize32
constexpr size_t SectionHeaderSize32
Definition: XCOFF.h:35
llvm::XCOFF::SymbolType
SymbolType
Definition: XCOFF.h:227
llvm::XCOFF::XMC_PR
@ XMC_PR
Program Code.
Definition: XCOFF.h:92
MCAssembler.h
llvm::MCSectionXCOFF::isCsect
bool isCsect() const
Definition: MCSectionXCOFF.h:119
llvm::XCOFF::NEW_XCOFF_INTERPRET
@ NEW_XCOFF_INTERPRET
Definition: XCOFF.h:62
llvm::MCSymbol::getFragment
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:392
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::MCSymbol::isDefined
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
Definition: MCSymbol.h:243
Groups
static const X86InstrFMA3Group Groups[]
Definition: X86InstrFMA3Info.cpp:73
llvm::XCOFF::XMC_TC
@ XMC_TC
General TOC item.
Definition: XCOFF.h:106
llvm::MCFragment::getParent
MCSection * getParent() const
Definition: MCFragment.h:95
MCFixupKindInfo.h
llvm::MCSymbolXCOFF::getVisibilityType
XCOFF::VisibilityType getVisibilityType() const
Definition: MCSymbolXCOFF.h:54
llvm::Lo_32
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition: MathExtras.h:335
llvm::support::endian::Writer
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:52
llvm::MCSymbolXCOFF::getRepresentedCsect
MCSectionXCOFF * getRepresentedCsect() const
Definition: MCSymbolXCOFF.cpp:13
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::XCOFF::STYP_DWARF
@ STYP_DWARF
Definition: XCOFF.h:123
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::createXCOFFObjectWriter
std::unique_ptr< MCObjectWriter > createXCOFFObjectWriter(std::unique_ptr< MCXCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
Definition: XCOFFObjectWriter.cpp:1462
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
XCOFF.h
llvm::MCFragment
Definition: MCFragment.h:30
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1734
StringTableBuilder.h
llvm::XCOFF::XCOFF32
@ XCOFF32
Definition: XCOFF.h:47
llvm::MCAsmBackend
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:42
llvm::XCOFF::XMC_RO
@ XMC_RO
Read Only Constant.
Definition: XCOFF.h:93
MCAsmBackend.h
llvm::COFF::NameSize
@ NameSize
Definition: COFF.h:57
llvm::XCOFF::R_TLS
@ R_TLS
General-dynamic reference to TLS symbol.
Definition: XCOFF.h:296
llvm::Log2
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:209
llvm::XCOFF::AUX_SECT
@ AUX_SECT
Identifies a SECT auxiliary entry.
Definition: XCOFF.h:334
StorageClass
COFF::SymbolStorageClass StorageClass
Definition: COFFYAML.cpp:361
llvm::XCOFF::AUX_EXCEPT
@ AUX_EXCEPT
Identifies an exception auxiliary entry.
Definition: XCOFF.h:329
llvm::XCOFF::R_POS
@ R_POS
Positive relocation. Provides the address of the referenced symbol.
Definition: XCOFF.h:250
llvm::XCOFF::XCOFF64
@ XCOFF64
Definition: XCOFF.h:47
UINT64_MAX
#define UINT64_MAX
Definition: DataTypes.h:77
false
Definition: StackSlotColoring.cpp:141
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::XCOFF::ExceptionSectionEntrySize32
constexpr size_t ExceptionSectionEntrySize32
Definition: XCOFF.h:40
llvm::MCSection::getAlign
Align getAlign() const
Definition: MCSection.h:140
llvm::SectionEntry::SectionEntry
SectionEntry(StringRef name, uint8_t *address, size_t size, size_t allocationSize, uintptr_t objAddress)
Definition: RuntimeDyldImpl.h:74
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::MCSectionXCOFF::getMappingClass
XCOFF::StorageMappingClass getMappingClass() const
Definition: MCSectionXCOFF.h:96
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
llvm::XCOFF::XTY_SD
@ XTY_SD
Csect definition for initialized storage.
Definition: XCOFF.h:229
llvm::XCOFF::N_DEBUG
@ N_DEBUG
Definition: XCOFF.h:45
MCSectionXCOFF.h
llvm::MCSymbolXCOFF::getStorageClass
XCOFF::StorageClass getStorageClass() const
Definition: MCSymbolXCOFF.h:41
llvm::MCFixupKindInfo::Flags
unsigned Flags
Flags describing additional information on this fixup kind.
Definition: MCFixupKindInfo.h:45
llvm::XCOFF::R_NEG
@ R_NEG
Negative relocation. Provides the negative of the address of the referenced symbol.
Definition: XCOFF.h:255
llvm::XCOFF::StorageMappingClass
StorageMappingClass
Storage Mapping Class definitions.
Definition: XCOFF.h:90
llvm::Hi_32
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:330
llvm::XCOFF::NameSize
constexpr size_t NameSize
Definition: XCOFF.h:29
llvm::MCID::Trap
@ Trap
Definition: MCInstrDesc.h:186
llvm::XCOFF::STYP_TDATA
@ STYP_TDATA
Definition: XCOFF.h:129
llvm::XCOFF::StorageClass
StorageClass
Definition: XCOFF.h:157
llvm::pdb::PDB_ColorItem::Address
@ Address
llvm::MCAssembler
Definition: MCAssembler.h:73
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::clear
void clear()
Definition: DenseMap.h:110
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
uint64_t
llvm::raw_pwrite_stream
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:415
llvm::XCOFF::XTY_CM
@ XTY_CM
Common csect definition. For uninitialized storage.
Definition: XCOFF.h:232
s
multiplies can be turned into SHL s
Definition: README.txt:370
llvm::XCOFF::XMC_TL
@ XMC_TL
Initialized thread-local variable.
Definition: XCOFF.h:113
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
llvm::DenseMap
Definition: DenseMap.h:714
MCSymbolXCOFF.h
MCXCOFFObjectWriter.h
llvm::SectionEntry
SectionEntry - represents a section emitted into memory by the dynamic linker.
Definition: RuntimeDyldImpl.h:45
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1861
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::XCOFF::AuxFileHeaderSizeShort
constexpr size_t AuxFileHeaderSizeShort
Definition: XCOFF.h:34
llvm::irsymtab::storage::Word
support::ulittle32_t Word
Definition: IRSymtab.h:52
llvm::ArrayRef< char >
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:215
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
MCFixup.h
llvm::MCObjectWriter
Defines the object file and target independent interfaces used by the assembler backend to write nati...
Definition: MCObjectWriter.h:34
llvm::XCOFF::FileHeaderSize64
constexpr size_t FileHeaderSize64
Definition: XCOFF.h:31
llvm::XCOFF::SectionTypeFlags
SectionTypeFlags
Definition: XCOFF.h:121
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::XCOFF::R_TOC
@ R_TOC
Relative to the TOC relocation. Provides a displacement that is the difference between the address of...
Definition: XCOFF.h:261
Trap
@ Trap
Definition: WholeProgramDevirt.cpp:180
llvm::XCOFF::FileHeaderSize32
constexpr size_t FileHeaderSize32
Definition: XCOFF.h:30
llvm::MCAsmLayout::getFragmentOffset
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Definition: MCFragment.cpp:96
MCAsmLayout.h
llvm::MCSection::getName
StringRef getName() const
Definition: MCSection.h:124
llvm::XCOFF::N_UNDEF
@ N_UNDEF
Definition: XCOFF.h:45
llvm::MCSectionXCOFF::isDwarfSect
bool isDwarfSect() const
Definition: MCSectionXCOFF.h:120
MCObjectWriter.h
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::XCOFF::SYM_V_UNSPECIFIED
@ SYM_V_UNSPECIFIED
Definition: XCOFF.h:239
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
EndianStream.h
uint16_t
llvm::MCAsmLayout
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:84
Casting.h
llvm::ms_demangle::NodeKind::FunctionSymbol
@ FunctionSymbol
llvm::XCOFF::AUX_CSECT
@ AUX_CSECT
Identifies a csect auxiliary entry.
Definition: XCOFF.h:333
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::XCOFF::XMC_TC0
@ XMC_TC0
TOC Anchor for TOC Addressability.
Definition: XCOFF.h:105
llvm::MCAsmLayout::getSymbolOffset
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
Definition: MCFragment.cpp:152
llvm::StringTableBuilder
Utility for building string tables with deduplicated suffixes.
Definition: StringTableBuilder.h:24
MCValue.h
llvm::XCOFF::XMC_DS
@ XMC_DS
Descriptor csect.
Definition: XCOFF.h:108
llvm::XCOFF::AUX_FCN
@ AUX_FCN
Identifies a function auxiliary entry.
Definition: XCOFF.h:330
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::XCOFF::STYP_DATA
@ STYP_DATA
Definition: XCOFF.h:125
llvm::MCSymbolXCOFF
Definition: MCSymbolXCOFF.h:20
llvm::XCOFF::STYP_TEXT
@ STYP_TEXT
Definition: XCOFF.h:124
llvm::XCOFF::XMC_RW
@ XMC_RW
Read Write Data.
Definition: XCOFF.h:104
llvm::MCSectionXCOFF::getVisibilityType
XCOFF::VisibilityType getVisibilityType() const
Definition: MCSectionXCOFF.h:103
N
#define N
llvm::MCSectionXCOFF::getQualNameSymbol
MCSymbolXCOFF * getQualNameSymbol() const
Definition: MCSectionXCOFF.h:110
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
writeSymbolTable
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t PrevMemberOffset=0)
Definition: ArchiveWriter.cpp:401
llvm::XCOFF::ExceptionSectionEntrySize64
constexpr size_t ExceptionSectionEntrySize64
Definition: XCOFF.h:41
llvm::XCOFF::R_TOCL
@ R_TOCL
Relative to TOC lower. Specifies the low-order 16 bits of a large code model TOC-relative relocation.
Definition: XCOFF.h:306
llvm::msgpack::Type
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
Definition: MsgPackReader.h:48
llvm::logicalview::LVOutputKind::Text
@ Text
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:36
llvm::omp::RTLDependInfoFields::Flags
@ Flags
llvm::XCOFF::RelocationSerializationSize32
constexpr size_t RelocationSerializationSize32
Definition: XCOFF.h:38
llvm::MCSectionXCOFF::getSymbolTableName
StringRef getSymbolTableName() const
Definition: MCSectionXCOFF.h:117
llvm::XCOFF::STYP_TBSS
@ STYP_TBSS
Definition: XCOFF.h:130
llvm::MCAsmLayout::getSectionAddressSize
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
Definition: MCFragment.cpp:198
Mod
Module * Mod
Definition: PassBuilderBindings.cpp:54
llvm::MCSectionXCOFF::getDwarfSubtypeFlags
Optional< XCOFF::DwarfSectionSubtypeFlags > getDwarfSubtypeFlags() const
Definition: MCSectionXCOFF.h:121
llvm::XCOFF::XMC_UL
@ XMC_UL
Uninitialized thread-local variable.
Definition: XCOFF.h:114
llvm::MCFixup
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
llvm::XCOFF::RelocOverflow
constexpr uint16_t RelocOverflow
Definition: XCOFF.h:42
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::XCOFF::R_TLSM
@ R_TLSM
Module reference to TLS. Provides a handle for the module containing the referenced symbol.
Definition: XCOFF.h:300
llvm::support::big
@ big
Definition: Endian.h:27
llvm::XCOFF::XMC_BS
@ XMC_BS
BSS class (uninitialized static internal)
Definition: XCOFF.h:110