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