LLVM  14.0.0git
XCOFFObjectFile.cpp
Go to the documentation of this file.
1 //===--- XCOFFObjectFile.cpp - XCOFF object file implementation -----------===//
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 defines the XCOFFObjectFile class.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/StringSwitch.h"
17 #include <cstddef>
18 #include <cstring>
19 
20 namespace llvm {
21 
22 using namespace XCOFF;
23 
24 namespace object {
25 
26 static const uint8_t FunctionSym = 0x20;
27 static const uint16_t NoRelMask = 0x0001;
28 static const size_t SymbolAuxTypeOffset = 17;
29 
30 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
31 // 'M'. Returns a pointer to the underlying object on success.
32 template <typename T>
33 static Expected<const T *> getObject(MemoryBufferRef M, const void *Ptr,
34  const uint64_t Size = sizeof(T)) {
35  uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
36  if (Error E = Binary::checkOffset(M, Addr, Size))
37  return std::move(E);
38  return reinterpret_cast<const T *>(Addr);
39 }
40 
41 static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset) {
42  return reinterpret_cast<uintptr_t>(reinterpret_cast<const char *>(Base) +
43  Offset);
44 }
45 
46 template <typename T> static const T *viewAs(uintptr_t in) {
47  return reinterpret_cast<const T *>(in);
48 }
49 
51  auto NulCharPtr =
52  static_cast<const char *>(memchr(Name, '\0', XCOFF::NameSize));
53  return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
55 }
56 
57 template <typename T> StringRef XCOFFSectionHeader<T>::getName() const {
58  const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
59  return generateXCOFFFixedNameStringRef(DerivedXCOFFSectionHeader.Name);
60 }
61 
62 template <typename T> uint16_t XCOFFSectionHeader<T>::getSectionType() const {
63  const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
64  return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
65 }
66 
67 template <typename T>
69  return getSectionType() & SectionFlagsReservedMask;
70 }
71 
72 template <typename AddressType>
74  return Info & XR_SIGN_INDICATOR_MASK;
75 }
76 
77 template <typename AddressType>
79  return Info & XR_FIXUP_INDICATOR_MASK;
80 }
81 
82 template <typename AddressType>
84  // The relocation encodes the bit length being relocated minus 1. Add back
85  // the 1 to get the actual length being relocated.
86  return (Info & XR_BIASED_LENGTH_MASK) + 1;
87 }
88 
89 uintptr_t
90 XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
91  uint32_t Distance) {
92  return getWithOffset(CurrentAddress, Distance * XCOFF::SymbolTableEntrySize);
93 }
94 
96 XCOFFObjectFile::getSymbolAuxType(uintptr_t AuxEntryAddress) const {
97  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
98  return viewAs<XCOFF::SymbolAuxType>(
99  getWithOffset(AuxEntryAddress, SymbolAuxTypeOffset));
100 }
101 
102 void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
103  uintptr_t TableAddress) const {
104  if (Addr < TableAddress)
105  report_fatal_error("Section header outside of section header table.");
106 
107  uintptr_t Offset = Addr - TableAddress;
108  if (Offset >= getSectionHeaderSize() * getNumberOfSections())
109  report_fatal_error("Section header outside of section header table.");
110 
111  if (Offset % getSectionHeaderSize() != 0)
113  "Section header pointer does not point to a valid section header.");
114 }
115 
116 const XCOFFSectionHeader32 *
117 XCOFFObjectFile::toSection32(DataRefImpl Ref) const {
118  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
119 #ifndef NDEBUG
120  checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
121 #endif
122  return viewAs<XCOFFSectionHeader32>(Ref.p);
123 }
124 
125 const XCOFFSectionHeader64 *
126 XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
127  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
128 #ifndef NDEBUG
129  checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
130 #endif
131  return viewAs<XCOFFSectionHeader64>(Ref.p);
132 }
133 
134 XCOFFSymbolRef XCOFFObjectFile::toSymbolRef(DataRefImpl Ref) const {
135  assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
136 #ifndef NDEBUG
137  checkSymbolEntryPointer(Ref.p);
138 #endif
139  return XCOFFSymbolRef(Ref, this);
140 }
141 
142 const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
143  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
144  return static_cast<const XCOFFFileHeader32 *>(FileHeader);
145 }
146 
147 const XCOFFFileHeader64 *XCOFFObjectFile::fileHeader64() const {
148  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
149  return static_cast<const XCOFFFileHeader64 *>(FileHeader);
150 }
151 
152 const XCOFFAuxiliaryHeader32 *XCOFFObjectFile::auxiliaryHeader32() const {
153  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
154  return static_cast<const XCOFFAuxiliaryHeader32 *>(AuxiliaryHeader);
155 }
156 
157 const XCOFFAuxiliaryHeader64 *XCOFFObjectFile::auxiliaryHeader64() const {
158  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
159  return static_cast<const XCOFFAuxiliaryHeader64 *>(AuxiliaryHeader);
160 }
161 
162 template <typename T> const T *XCOFFObjectFile::sectionHeaderTable() const {
163  return static_cast<const T *>(SectionHeaderTable);
164 }
165 
166 const XCOFFSectionHeader32 *
167 XCOFFObjectFile::sectionHeaderTable32() const {
168  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
169  return static_cast<const XCOFFSectionHeader32 *>(SectionHeaderTable);
170 }
171 
172 const XCOFFSectionHeader64 *
173 XCOFFObjectFile::sectionHeaderTable64() const {
174  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
175  return static_cast<const XCOFFSectionHeader64 *>(SectionHeaderTable);
176 }
177 
178 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
179  uintptr_t NextSymbolAddr = getAdvancedSymbolEntryAddress(
180  Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
181 #ifndef NDEBUG
182  // This function is used by basic_symbol_iterator, which allows to
183  // point to the end-of-symbol-table address.
184  if (NextSymbolAddr != getEndOfSymbolTableAddress())
185  checkSymbolEntryPointer(NextSymbolAddr);
186 #endif
187  Symb.p = NextSymbolAddr;
188 }
189 
191 XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
192  // The byte offset is relative to the start of the string table.
193  // A byte offset value of 0 is a null or zero-length symbol
194  // name. A byte offset in the range 1 to 3 (inclusive) points into the length
195  // field; as a soft-error recovery mechanism, we treat such cases as having an
196  // offset of 0.
197  if (Offset < 4)
198  return StringRef(nullptr, 0);
199 
200  if (StringTable.Data != nullptr && StringTable.Size > Offset)
201  return (StringTable.Data + Offset);
202 
203  return createError("entry with offset 0x" + Twine::utohexstr(Offset) +
204  " in a string table with size 0x" +
205  Twine::utohexstr(StringTable.Size) + " is invalid");
206 }
207 
208 StringRef XCOFFObjectFile::getStringTable() const {
209  // If the size is less than or equal to 4, then the string table contains no
210  // string data.
211  return StringRef(StringTable.Data,
212  StringTable.Size <= 4 ? 0 : StringTable.Size);
213 }
214 
216 XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
217  if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
218  return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
219  return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
220 }
221 
223  return toSymbolRef(Symb).getName();
224 }
225 
226 Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
227  return toSymbolRef(Symb).getValue();
228 }
229 
230 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
231  return toSymbolRef(Symb).getValue();
232 }
233 
234 uint32_t XCOFFObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
235  uint64_t Result = 0;
236  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
237  if (XCOFFSym.isCsectSymbol()) {
238  Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
239  XCOFFSym.getXCOFFCsectAuxRef();
240  if (!CsectAuxRefOrError)
241  // TODO: report the error up the stack.
242  consumeError(CsectAuxRefOrError.takeError());
243  else
244  Result = 1ULL << CsectAuxRefOrError.get().getAlignmentLog2();
245  }
246  return Result;
247 }
248 
249 uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
250  uint64_t Result = 0;
251  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
252  if (XCOFFSym.isCsectSymbol()) {
253  Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
254  XCOFFSym.getXCOFFCsectAuxRef();
255  if (!CsectAuxRefOrError)
256  // TODO: report the error up the stack.
257  consumeError(CsectAuxRefOrError.takeError());
258  else {
259  XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
260  assert(CsectAuxRef.getSymbolType() == XCOFF::XTY_CM);
261  Result = CsectAuxRef.getSectionOrLength();
262  }
263  }
264  return Result;
265 }
266 
269  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
270 
271  if (XCOFFSym.isFunction())
272  return SymbolRef::ST_Function;
273 
274  if (XCOFF::C_FILE == XCOFFSym.getStorageClass())
275  return SymbolRef::ST_File;
276 
277  int16_t SecNum = XCOFFSym.getSectionNumber();
278  if (SecNum <= 0)
279  return SymbolRef::ST_Other;
280 
281  Expected<DataRefImpl> SecDRIOrErr =
282  getSectionByNum(XCOFFSym.getSectionNumber());
283 
284  if (!SecDRIOrErr)
285  return SecDRIOrErr.takeError();
286 
287  DataRefImpl SecDRI = SecDRIOrErr.get();
288 
289  Expected<StringRef> SymNameOrError = XCOFFSym.getName();
290  if (SymNameOrError) {
291  // The "TOC" symbol is treated as SymbolRef::ST_Other.
292  if (SymNameOrError.get() == "TOC")
293  return SymbolRef::ST_Other;
294 
295  // The symbol for a section name is treated as SymbolRef::ST_Other.
296  StringRef SecName;
297  if (is64Bit())
298  SecName = XCOFFObjectFile::toSection64(SecDRIOrErr.get())->getName();
299  else
300  SecName = XCOFFObjectFile::toSection32(SecDRIOrErr.get())->getName();
301 
302  if (SecName == SymNameOrError.get())
303  return SymbolRef::ST_Other;
304  } else
305  return SymNameOrError.takeError();
306 
307  if (isSectionData(SecDRI) || isSectionBSS(SecDRI))
308  return SymbolRef::ST_Data;
309 
310  if (isDebugSection(SecDRI))
311  return SymbolRef::ST_Debug;
312 
313  return SymbolRef::ST_Other;
314 }
315 
317 XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
318  const int16_t SectNum = toSymbolRef(Symb).getSectionNumber();
319 
320  if (isReservedSectionNumber(SectNum))
321  return section_end();
322 
323  Expected<DataRefImpl> ExpSec = getSectionByNum(SectNum);
324  if (!ExpSec)
325  return ExpSec.takeError();
326 
327  return section_iterator(SectionRef(ExpSec.get(), this));
328 }
329 
330 void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
331  const char *Ptr = reinterpret_cast<const char *>(Sec.p);
332  Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
333 }
334 
335 Expected<StringRef> XCOFFObjectFile::getSectionName(DataRefImpl Sec) const {
336  return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec));
337 }
338 
339 uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
340  // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
341  // with MSVC.
342  if (is64Bit())
343  return toSection64(Sec)->VirtualAddress;
344 
345  return toSection32(Sec)->VirtualAddress;
346 }
347 
348 uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
349  // Section numbers in XCOFF are numbered beginning at 1. A section number of
350  // zero is used to indicate that a symbol is being imported or is undefined.
351  if (is64Bit())
352  return toSection64(Sec) - sectionHeaderTable64() + 1;
353  else
354  return toSection32(Sec) - sectionHeaderTable32() + 1;
355 }
356 
357 uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
358  // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
359  // with MSVC.
360  if (is64Bit())
361  return toSection64(Sec)->SectionSize;
362 
363  return toSection32(Sec)->SectionSize;
364 }
365 
367 XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
368  if (isSectionVirtual(Sec))
369  return ArrayRef<uint8_t>();
370 
371  uint64_t OffsetToRaw;
372  if (is64Bit())
373  OffsetToRaw = toSection64(Sec)->FileOffsetToRawData;
374  else
375  OffsetToRaw = toSection32(Sec)->FileOffsetToRawData;
376 
377  const uint8_t * ContentStart = base() + OffsetToRaw;
378  uint64_t SectionSize = getSectionSize(Sec);
379  if (Error E = Binary::checkOffset(
380  Data, reinterpret_cast<uintptr_t>(ContentStart), SectionSize))
381  return createError(
382  toString(std::move(E)) + ": section data with offset 0x" +
383  Twine::utohexstr(OffsetToRaw) + " and size 0x" +
384  Twine::utohexstr(SectionSize) + " goes past the end of the file");
385 
386  return makeArrayRef(ContentStart,SectionSize);
387 }
388 
389 uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
390  uint64_t Result = 0;
391  llvm_unreachable("Not yet implemented!");
392  return Result;
393 }
394 
395 Expected<uintptr_t> XCOFFObjectFile::getLoaderSectionAddress() const {
396  uint64_t OffsetToLoaderSection = 0;
397  uint64_t SizeOfLoaderSection = 0;
398 
399  if (is64Bit()) {
400  for (const auto &Sec64 : sections64())
401  if (Sec64.getSectionType() == XCOFF::STYP_LOADER) {
402  OffsetToLoaderSection = Sec64.FileOffsetToRawData;
403  SizeOfLoaderSection = Sec64.SectionSize;
404  break;
405  }
406  } else {
407  for (const auto &Sec32 : sections32())
408  if (Sec32.getSectionType() == XCOFF::STYP_LOADER) {
409  OffsetToLoaderSection = Sec32.FileOffsetToRawData;
410  SizeOfLoaderSection = Sec32.SectionSize;
411  break;
412  }
413  }
414 
415  // No loader section is not an error.
416  if (!SizeOfLoaderSection)
417  return 0;
418 
419  uintptr_t LoderSectionStart =
420  reinterpret_cast<uintptr_t>(base() + OffsetToLoaderSection);
421  if (Error E =
422  Binary::checkOffset(Data, LoderSectionStart, SizeOfLoaderSection))
423  return createError(toString(std::move(E)) +
424  ": loader section with offset 0x" +
425  Twine::utohexstr(OffsetToLoaderSection) +
426  " and size 0x" + Twine::utohexstr(SizeOfLoaderSection) +
427  " goes past the end of the file");
428 
429  return LoderSectionStart;
430 }
431 
432 bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
433  return false;
434 }
435 
436 bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
437  return getSectionFlags(Sec) & XCOFF::STYP_TEXT;
438 }
439 
440 bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const {
441  uint32_t Flags = getSectionFlags(Sec);
442  return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
443 }
444 
445 bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
446  uint32_t Flags = getSectionFlags(Sec);
447  return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
448 }
449 
450 bool XCOFFObjectFile::isDebugSection(DataRefImpl Sec) const {
451  uint32_t Flags = getSectionFlags(Sec);
452  return Flags & (XCOFF::STYP_DEBUG | XCOFF::STYP_DWARF);
453 }
454 
455 bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
456  return is64Bit() ? toSection64(Sec)->FileOffsetToRawData == 0
457  : toSection32(Sec)->FileOffsetToRawData == 0;
458 }
459 
460 relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
462  if (is64Bit()) {
463  const XCOFFSectionHeader64 *SectionEntPtr = toSection64(Sec);
464  auto RelocationsOrErr =
465  relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr);
466  if (Error E = RelocationsOrErr.takeError()) {
467  // TODO: report the error up the stack.
470  }
471  Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
472  } else {
473  const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
474  auto RelocationsOrErr =
475  relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr);
476  if (Error E = RelocationsOrErr.takeError()) {
477  // TODO: report the error up the stack.
480  }
481  Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
482  }
483  return relocation_iterator(RelocationRef(Ret, this));
484 }
485 
486 relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
488  if (is64Bit()) {
489  const XCOFFSectionHeader64 *SectionEntPtr = toSection64(Sec);
490  auto RelocationsOrErr =
491  relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr);
492  if (Error E = RelocationsOrErr.takeError()) {
493  // TODO: report the error up the stack.
496  }
497  Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
498  } else {
499  const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
500  auto RelocationsOrErr =
501  relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr);
502  if (Error E = RelocationsOrErr.takeError()) {
503  // TODO: report the error up the stack.
506  }
507  Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
508  }
509  return relocation_iterator(RelocationRef(Ret, this));
510 }
511 
512 void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
513  if (is64Bit())
514  Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation64>(Rel.p) + 1);
515  else
516  Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation32>(Rel.p) + 1);
517 }
518 
519 uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
520  if (is64Bit()) {
521  const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p);
522  const XCOFFSectionHeader64 *Sec64 = sectionHeaderTable64();
523  const uint64_t RelocAddress = Reloc->VirtualAddress;
524  const uint16_t NumberOfSections = getNumberOfSections();
525  for (uint16_t I = 0; I < NumberOfSections; ++I) {
526  // Find which section this relocation belongs to, and get the
527  // relocation offset relative to the start of the section.
528  if (Sec64->VirtualAddress <= RelocAddress &&
529  RelocAddress < Sec64->VirtualAddress + Sec64->SectionSize) {
530  return RelocAddress - Sec64->VirtualAddress;
531  }
532  ++Sec64;
533  }
534  } else {
535  const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
536  const XCOFFSectionHeader32 *Sec32 = sectionHeaderTable32();
537  const uint32_t RelocAddress = Reloc->VirtualAddress;
538  const uint16_t NumberOfSections = getNumberOfSections();
539  for (uint16_t I = 0; I < NumberOfSections; ++I) {
540  // Find which section this relocation belongs to, and get the
541  // relocation offset relative to the start of the section.
542  if (Sec32->VirtualAddress <= RelocAddress &&
543  RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) {
544  return RelocAddress - Sec32->VirtualAddress;
545  }
546  ++Sec32;
547  }
548  }
549  return InvalidRelocOffset;
550 }
551 
552 symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
553  uint32_t Index;
554  if (is64Bit()) {
555  const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p);
556  Index = Reloc->SymbolIndex;
557 
558  if (Index >= getNumberOfSymbolTableEntries64())
559  return symbol_end();
560  } else {
561  const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
562  Index = Reloc->SymbolIndex;
563 
564  if (Index >= getLogicalNumberOfSymbolTableEntries32())
565  return symbol_end();
566  }
567  DataRefImpl SymDRI;
568  SymDRI.p = getSymbolEntryAddressByIndex(Index);
569  return symbol_iterator(SymbolRef(SymDRI, this));
570 }
571 
572 uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
573  if (is64Bit())
574  return viewAs<XCOFFRelocation64>(Rel.p)->Type;
575  return viewAs<XCOFFRelocation32>(Rel.p)->Type;
576 }
577 
578 void XCOFFObjectFile::getRelocationTypeName(
579  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
580  StringRef Res;
581  if (is64Bit()) {
582  const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p);
583  Res = XCOFF::getRelocationTypeString(Reloc->Type);
584  } else {
585  const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
586  Res = XCOFF::getRelocationTypeString(Reloc->Type);
587  }
588  Result.append(Res.begin(), Res.end());
589 }
590 
591 Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
592  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
593  uint32_t Result = SymbolRef::SF_None;
594 
595  if (XCOFFSym.getSectionNumber() == XCOFF::N_ABS)
596  Result |= SymbolRef::SF_Absolute;
597 
599  if (XCOFF::C_EXT == SC || XCOFF::C_WEAKEXT == SC)
600  Result |= SymbolRef::SF_Global;
601 
602  if (XCOFF::C_WEAKEXT == SC)
603  Result |= SymbolRef::SF_Weak;
604 
605  if (XCOFFSym.isCsectSymbol()) {
606  Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr =
607  XCOFFSym.getXCOFFCsectAuxRef();
608  if (CsectAuxEntOrErr) {
609  if (CsectAuxEntOrErr.get().getSymbolType() == XCOFF::XTY_CM)
610  Result |= SymbolRef::SF_Common;
611  } else
612  return CsectAuxEntOrErr.takeError();
613  }
614 
615  if (XCOFFSym.getSectionNumber() == XCOFF::N_UNDEF)
616  Result |= SymbolRef::SF_Undefined;
617 
618  return Result;
619 }
620 
621 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
622  DataRefImpl SymDRI;
623  SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
624  return basic_symbol_iterator(SymbolRef(SymDRI, this));
625 }
626 
627 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
628  DataRefImpl SymDRI;
629  const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
630  SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
631  return basic_symbol_iterator(SymbolRef(SymDRI, this));
632 }
633 
634 section_iterator XCOFFObjectFile::section_begin() const {
635  DataRefImpl DRI;
636  DRI.p = getSectionHeaderTableAddress();
637  return section_iterator(SectionRef(DRI, this));
638 }
639 
640 section_iterator XCOFFObjectFile::section_end() const {
641  DataRefImpl DRI;
642  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
643  getNumberOfSections() * getSectionHeaderSize());
644  return section_iterator(SectionRef(DRI, this));
645 }
646 
647 uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }
648 
649 StringRef XCOFFObjectFile::getFileFormatName() const {
650  return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
651 }
652 
653 Triple::ArchType XCOFFObjectFile::getArch() const {
654  return is64Bit() ? Triple::ppc64 : Triple::ppc;
655 }
656 
658  return SubtargetFeatures();
659 }
660 
661 bool XCOFFObjectFile::isRelocatableObject() const {
662  if (is64Bit())
663  return !(fileHeader64()->Flags & NoRelMask);
664  return !(fileHeader32()->Flags & NoRelMask);
665 }
666 
667 Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
668  // TODO FIXME Should get from auxiliary_header->o_entry when support for the
669  // auxiliary_header is added.
670  return 0;
671 }
672 
673 StringRef XCOFFObjectFile::mapDebugSectionName(StringRef Name) const {
675  .Case("dwinfo", "debug_info")
676  .Case("dwline", "debug_line")
677  .Case("dwpbnms", "debug_pubnames")
678  .Case("dwpbtyp", "debug_pubtypes")
679  .Case("dwarnge", "debug_aranges")
680  .Case("dwabrev", "debug_abbrev")
681  .Case("dwstr", "debug_str")
682  .Case("dwrnges", "debug_ranges")
683  .Case("dwloc", "debug_loc")
684  .Case("dwframe", "debug_frame")
685  .Case("dwmac", "debug_macinfo")
686  .Default(Name);
687 }
688 
689 size_t XCOFFObjectFile::getFileHeaderSize() const {
690  return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
691 }
692 
693 size_t XCOFFObjectFile::getSectionHeaderSize() const {
694  return is64Bit() ? sizeof(XCOFFSectionHeader64) :
695  sizeof(XCOFFSectionHeader32);
696 }
697 
699  return Binary::ID_XCOFF64 == getType();
700 }
701 
703  return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
704 }
705 
706 Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
707  if (Num <= 0 || Num > getNumberOfSections())
708  return createStringError(object_error::invalid_section_index,
709  "the section index (" + Twine(Num) +
710  ") is invalid");
711 
712  DataRefImpl DRI;
713  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
714  getSectionHeaderSize() * (Num - 1));
715  return DRI;
716 }
717 
719 XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
720  const int16_t SectionNum = SymEntPtr.getSectionNumber();
721 
722  switch (SectionNum) {
723  case XCOFF::N_DEBUG:
724  return "N_DEBUG";
725  case XCOFF::N_ABS:
726  return "N_ABS";
727  case XCOFF::N_UNDEF:
728  return "N_UNDEF";
729  default:
730  Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
731  if (SecRef)
733  getSectionNameInternal(SecRef.get()));
734  return SecRef.takeError();
735  }
736 }
737 
739  XCOFFSymbolRef XCOFFSymRef(Sym.getRawDataRefImpl(), this);
740  return XCOFFSymRef.getSectionNumber();
741 }
742 
743 bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
744  return (SectionNumber <= 0 && SectionNumber >= -2);
745 }
746 
747 uint16_t XCOFFObjectFile::getNumberOfSections() const {
748  return is64Bit() ? fileHeader64()->NumberOfSections
749  : fileHeader32()->NumberOfSections;
750 }
751 
752 int32_t XCOFFObjectFile::getTimeStamp() const {
753  return is64Bit() ? fileHeader64()->TimeStamp : fileHeader32()->TimeStamp;
754 }
755 
756 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
757  return is64Bit() ? fileHeader64()->AuxHeaderSize
758  : fileHeader32()->AuxHeaderSize;
759 }
760 
761 uint32_t XCOFFObjectFile::getSymbolTableOffset32() const {
762  return fileHeader32()->SymbolTableOffset;
763 }
764 
765 int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries32() const {
766  // As far as symbol table size is concerned, if this field is negative it is
767  // to be treated as a 0. However since this field is also used for printing we
768  // don't want to truncate any negative values.
769  return fileHeader32()->NumberOfSymTableEntries;
770 }
771 
772 uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries32() const {
773  return (fileHeader32()->NumberOfSymTableEntries >= 0
774  ? fileHeader32()->NumberOfSymTableEntries
775  : 0);
776 }
777 
778 uint64_t XCOFFObjectFile::getSymbolTableOffset64() const {
779  return fileHeader64()->SymbolTableOffset;
780 }
781 
782 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
783  return fileHeader64()->NumberOfSymTableEntries;
784 }
785 
786 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
787  return is64Bit() ? getNumberOfSymbolTableEntries64()
788  : getLogicalNumberOfSymbolTableEntries32();
789 }
790 
791 uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
792  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
793  return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
794  XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
795 }
796 
797 void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
798  if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
799  report_fatal_error("Symbol table entry is outside of symbol table.");
800 
801  if (SymbolEntPtr >= getEndOfSymbolTableAddress())
802  report_fatal_error("Symbol table entry is outside of symbol table.");
803 
804  ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
805  reinterpret_cast<const char *>(SymbolTblPtr);
806 
809  "Symbol table entry position is not valid inside of symbol table.");
810 }
811 
812 uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
813  return (reinterpret_cast<const char *>(SymbolEntPtr) -
814  reinterpret_cast<const char *>(SymbolTblPtr)) /
816 }
817 
818 uint64_t XCOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
819  uint64_t Result = 0;
820  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
821  if (XCOFFSym.isCsectSymbol()) {
822  Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
823  XCOFFSym.getXCOFFCsectAuxRef();
824  if (!CsectAuxRefOrError)
825  // TODO: report the error up the stack.
826  consumeError(CsectAuxRefOrError.takeError());
827  else {
828  XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
829  uint8_t SymType = CsectAuxRef.getSymbolType();
830  if (SymType == XCOFF::XTY_SD || SymType == XCOFF::XTY_CM)
831  Result = CsectAuxRef.getSectionOrLength();
832  }
833  }
834  return Result;
835 }
836 
837 uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
838  return getAdvancedSymbolEntryAddress(
839  reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
840 }
841 
843 XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
844  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
845 
846  if (Index >= NumberOfSymTableEntries)
847  return createError("symbol index " + Twine(Index) +
848  " exceeds symbol count " +
849  Twine(NumberOfSymTableEntries));
850 
851  DataRefImpl SymDRI;
852  SymDRI.p = getSymbolEntryAddressByIndex(Index);
853  return getSymbolName(SymDRI);
854 }
855 
857  return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
858 }
859 
860 const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
861  return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
862 }
863 
864 uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
865  return reinterpret_cast<uintptr_t>(SectionHeaderTable);
866 }
867 
869  return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
870 }
871 
872 XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
873  : ObjectFile(Type, Object) {
875 }
876 
878  assert(is64Bit() && "64-bit interface called for non 64-bit file.");
879  const XCOFFSectionHeader64 *TablePtr = sectionHeaderTable64();
880  return ArrayRef<XCOFFSectionHeader64>(TablePtr,
881  TablePtr + getNumberOfSections());
882 }
883 
885  assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
886  const XCOFFSectionHeader32 *TablePtr = sectionHeaderTable32();
887  return ArrayRef<XCOFFSectionHeader32>(TablePtr,
888  TablePtr + getNumberOfSections());
889 }
890 
891 // In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
892 // section header contains the actual count of relocation entries in the s_paddr
893 // field. STYP_OVRFLO headers contain the section index of their corresponding
894 // sections as their raw "NumberOfRelocations" field value.
895 template <typename T>
897  const XCOFFSectionHeader<T> &Sec) const {
898  const T &Section = static_cast<const T &>(Sec);
899  if (is64Bit())
900  return Section.NumberOfRelocations;
901 
902  uint16_t SectionIndex = &Section - sectionHeaderTable<T>() + 1;
903  if (Section.NumberOfRelocations < XCOFF::RelocOverflow)
904  return Section.NumberOfRelocations;
905  for (const auto &Sec : sections32()) {
906  if (Sec.Flags == XCOFF::STYP_OVRFLO &&
907  Sec.NumberOfRelocations == SectionIndex)
908  return Sec.PhysicalAddress;
909  }
911 }
912 
913 template <typename Shdr, typename Reloc>
915  uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
916  Sec.FileOffsetToRelocationInfo);
917  auto NumRelocEntriesOrErr = getNumberOfRelocationEntries(Sec);
918  if (Error E = NumRelocEntriesOrErr.takeError())
919  return std::move(E);
920 
921  uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
922  static_assert((sizeof(Reloc) == XCOFF::RelocationSerializationSize64 ||
923  sizeof(Reloc) == XCOFF::RelocationSerializationSize32),
924  "Relocation structure is incorrect");
925  auto RelocationOrErr =
926  getObject<Reloc>(Data, reinterpret_cast<void *>(RelocAddr),
927  NumRelocEntries * sizeof(Reloc));
928  if (!RelocationOrErr)
929  return createError(
930  toString(RelocationOrErr.takeError()) + ": relocations with offset 0x" +
931  Twine::utohexstr(Sec.FileOffsetToRelocationInfo) + " and size 0x" +
932  Twine::utohexstr(NumRelocEntries * sizeof(Reloc)) +
933  " go past the end of the file");
934 
935  const Reloc *StartReloc = RelocationOrErr.get();
936 
937  return ArrayRef<Reloc>(StartReloc, StartReloc + NumRelocEntries);
938 }
939 
941 XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
942  // If there is a string table, then the buffer must contain at least 4 bytes
943  // for the string table's size. Not having a string table is not an error.
945  Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
947  return XCOFFStringTable{0, nullptr};
948  }
949 
950  // Read the size out of the buffer.
952 
953  // If the size is less then 4, then the string table is just a size and no
954  // string data.
955  if (Size <= 4)
956  return XCOFFStringTable{4, nullptr};
957 
958  auto StringTableOrErr =
959  getObject<char>(Obj->Data, Obj->base() + Offset, Size);
960  if (!StringTableOrErr)
961  return createError(toString(StringTableOrErr.takeError()) +
962  ": string table with offset 0x" +
963  Twine::utohexstr(Offset) + " and size 0x" +
965  " goes past the end of the file");
966 
967  const char *StringTablePtr = StringTableOrErr.get();
968  if (StringTablePtr[Size - 1] != '\0')
970 
971  return XCOFFStringTable{Size, StringTablePtr};
972 }
973 
974 // This function returns the import file table. Each entry in the import file
975 // table consists of: "path_name\0base_name\0archive_member_name\0".
977  Expected<uintptr_t> LoaderSectionAddrOrError = getLoaderSectionAddress();
978  if (!LoaderSectionAddrOrError)
979  return LoaderSectionAddrOrError.takeError();
980 
981  uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
982  if (!LoaderSectionAddr)
983  return StringRef();
984 
985  uint64_t OffsetToImportFileTable = 0;
986  uint64_t LengthOfImportFileTable = 0;
987  if (is64Bit()) {
988  const LoaderSectionHeader64 *LoaderSec64 =
989  viewAs<LoaderSectionHeader64>(LoaderSectionAddr);
990  OffsetToImportFileTable = LoaderSec64->OffsetToImpid;
991  LengthOfImportFileTable = LoaderSec64->LengthOfImpidStrTbl;
992  } else {
993  const LoaderSectionHeader32 *LoaderSec32 =
994  viewAs<LoaderSectionHeader32>(LoaderSectionAddr);
995  OffsetToImportFileTable = LoaderSec32->OffsetToImpid;
996  LengthOfImportFileTable = LoaderSec32->LengthOfImpidStrTbl;
997  }
998 
999  auto ImportTableOrErr = getObject<char>(
1000  Data,
1001  reinterpret_cast<void *>(LoaderSectionAddr + OffsetToImportFileTable),
1002  LengthOfImportFileTable);
1003  if (!ImportTableOrErr)
1004  return createError(
1005  toString(ImportTableOrErr.takeError()) +
1006  ": import file table with offset 0x" +
1007  Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1008  " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1009  " goes past the end of the file");
1010 
1011  const char *ImportTablePtr = ImportTableOrErr.get();
1012  if (ImportTablePtr[LengthOfImportFileTable - 1] != '\0')
1013  return createError(
1014  ": import file name table with offset 0x" +
1015  Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1016  " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1017  " must end with a null terminator");
1018 
1019  return StringRef(ImportTablePtr, LengthOfImportFileTable);
1020 }
1021 
1023 XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
1024  // Can't use std::make_unique because of the private constructor.
1025  std::unique_ptr<XCOFFObjectFile> Obj;
1026  Obj.reset(new XCOFFObjectFile(Type, MBR));
1027 
1028  uint64_t CurOffset = 0;
1029  const auto *Base = Obj->base();
1030  MemoryBufferRef Data = Obj->Data;
1031 
1032  // Parse file header.
1033  auto FileHeaderOrErr =
1034  getObject<void>(Data, Base + CurOffset, Obj->getFileHeaderSize());
1035  if (Error E = FileHeaderOrErr.takeError())
1036  return std::move(E);
1037  Obj->FileHeader = FileHeaderOrErr.get();
1038 
1039  CurOffset += Obj->getFileHeaderSize();
1040 
1041  if (Obj->getOptionalHeaderSize()) {
1042  auto AuxiliaryHeaderOrErr =
1043  getObject<void>(Data, Base + CurOffset, Obj->getOptionalHeaderSize());
1044  if (Error E = AuxiliaryHeaderOrErr.takeError())
1045  return std::move(E);
1046  Obj->AuxiliaryHeader = AuxiliaryHeaderOrErr.get();
1047  }
1048 
1049  CurOffset += Obj->getOptionalHeaderSize();
1050 
1051  // Parse the section header table if it is present.
1052  if (Obj->getNumberOfSections()) {
1053  uint64_t SectionHeadersSize =
1054  Obj->getNumberOfSections() * Obj->getSectionHeaderSize();
1055  auto SecHeadersOrErr =
1056  getObject<void>(Data, Base + CurOffset, SectionHeadersSize);
1057  if (!SecHeadersOrErr)
1058  return createError(toString(SecHeadersOrErr.takeError()) +
1059  ": section headers with offset 0x" +
1060  Twine::utohexstr(CurOffset) + " and size 0x" +
1061  Twine::utohexstr(SectionHeadersSize) +
1062  " go past the end of the file");
1063 
1064  Obj->SectionHeaderTable = SecHeadersOrErr.get();
1065  }
1066 
1067  const uint32_t NumberOfSymbolTableEntries =
1068  Obj->getNumberOfSymbolTableEntries();
1069 
1070  // If there is no symbol table we are done parsing the memory buffer.
1071  if (NumberOfSymbolTableEntries == 0)
1072  return std::move(Obj);
1073 
1074  // Parse symbol table.
1075  CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
1076  : Obj->getSymbolTableOffset32();
1077  const uint64_t SymbolTableSize =
1078  static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
1079  NumberOfSymbolTableEntries;
1080  auto SymTableOrErr =
1081  getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
1082  if (!SymTableOrErr)
1083  return createError(
1084  toString(SymTableOrErr.takeError()) + ": symbol table with offset 0x" +
1085  Twine::utohexstr(CurOffset) + " and size 0x" +
1086  Twine::utohexstr(SymbolTableSize) + " goes past the end of the file");
1087 
1088  Obj->SymbolTblPtr = SymTableOrErr.get();
1089  CurOffset += SymbolTableSize;
1090 
1091  // Parse String table.
1092  Expected<XCOFFStringTable> StringTableOrErr =
1093  parseStringTable(Obj.get(), CurOffset);
1094  if (Error E = StringTableOrErr.takeError())
1095  return std::move(E);
1096  Obj->StringTable = StringTableOrErr.get();
1097 
1098  return std::move(Obj);
1099 }
1100 
1101 Expected<std::unique_ptr<ObjectFile>>
1103  unsigned FileType) {
1104  return XCOFFObjectFile::create(FileType, MemBufRef);
1105 }
1106 
1108  if (!isCsectSymbol())
1109  return false;
1110 
1111  if (getSymbolType() & FunctionSym)
1112  return true;
1113 
1115  if (!ExpCsectAuxEnt) {
1116  // If we could not get the CSECT auxiliary entry, then treat this symbol as
1117  // if it isn't a function. Consume the error and return `false` to move on.
1118  consumeError(ExpCsectAuxEnt.takeError());
1119  return false;
1120  }
1121 
1122  const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
1123 
1124  // A function definition should be a label definition.
1125  // FIXME: This is not necessarily the case when -ffunction-sections is
1126  // enabled.
1127  if (!CsectAuxRef.isLabel())
1128  return false;
1129 
1130  if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
1131  return false;
1132 
1133  const int16_t SectNum = getSectionNumber();
1134  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
1135  if (!SI) {
1136  // If we could not get the section, then this symbol should not be
1137  // a function. So consume the error and return `false` to move on.
1138  consumeError(SI.takeError());
1139  return false;
1140  }
1141 
1142  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
1143 }
1144 
1147  return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
1148  SC == XCOFF::C_HIDEXT);
1149 }
1150 
1152  assert(isCsectSymbol() &&
1153  "Calling csect symbol interface with a non-csect symbol.");
1154 
1155  uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();
1156 
1157  Expected<StringRef> NameOrErr = getName();
1158  if (auto Err = NameOrErr.takeError())
1159  return std::move(Err);
1160 
1161  uint32_t SymbolIdx = OwningObjectPtr->getSymbolIndex(getEntryAddress());
1162  if (!NumberOfAuxEntries) {
1163  return createError("csect symbol \"" + *NameOrErr + "\" with index " +
1164  Twine(SymbolIdx) + " contains no auxiliary entry");
1165  }
1166 
1167  if (!OwningObjectPtr->is64Bit()) {
1168  // In XCOFF32, the csect auxilliary entry is always the last auxiliary
1169  // entry for the symbol.
1171  getEntryAddress(), NumberOfAuxEntries);
1172  return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
1173  }
1174 
1175  // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
1176  // We need to iterate through all the auxiliary entries to find it.
1177  for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
1179  getEntryAddress(), Index);
1180  if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
1182 #ifndef NDEBUG
1183  OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
1184 #endif
1185  return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
1186  }
1187  }
1188 
1189  return createError(
1190  "a csect auxiliary entry has not been found for symbol \"" + *NameOrErr +
1191  "\" with index " + Twine(SymbolIdx));
1192 }
1193 
1195  // A storage class value with the high-order bit on indicates that the name is
1196  // a symbolic debugger stabstring.
1197  if (getStorageClass() & 0x80)
1198  return StringRef("Unimplemented Debug Name");
1199 
1200  if (Entry32) {
1203 
1204  return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
1205  }
1206 
1207  return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
1208 }
1209 
1210 // Explictly instantiate template classes.
1213 
1216 
1220  llvm::object::XCOFFSectionHeader64 const &) const;
1224  llvm::object::XCOFFSectionHeader32 const &) const;
1225 
1227  if (Bytes.size() < 4)
1228  return false;
1229 
1230  return support::endian::read32be(Bytes.data()) == 0;
1231 }
1232 
1233 #define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
1234 #define GETVALUEWITHMASKSHIFT(X, S) \
1235  ((Data & (TracebackTable::X)) >> (TracebackTable::S))
1236 
1238  Error Err = Error::success();
1239  TBVectorExt TBTVecExt(TBvectorStrRef, Err);
1240  if (Err)
1241  return std::move(Err);
1242  return TBTVecExt;
1243 }
1244 
1245 TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
1246  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
1248  uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
1249  unsigned ParmsNum =
1250  GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
1251 
1252  ErrorAsOutParameter EAO(&Err);
1253  Expected<SmallString<32>> VecParmsTypeOrError =
1254  parseVectorParmsType(VecParmsTypeValue, ParmsNum);
1255  if (!VecParmsTypeOrError)
1256  Err = VecParmsTypeOrError.takeError();
1257  else
1258  VecParmsInfo = VecParmsTypeOrError.get();
1259 }
1260 
1262  return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
1263 }
1264 
1266  return GETVALUEWITHMASK(IsVRSavedOnStackMask);
1267 }
1268 
1270  return GETVALUEWITHMASK(HasVarArgsMask);
1271 }
1272 
1274  return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
1275  NumberOfVectorParmsShift);
1276 }
1277 
1279  return GETVALUEWITHMASK(HasVMXInstructionMask);
1280 }
1281 #undef GETVALUEWITHMASK
1282 #undef GETVALUEWITHMASKSHIFT
1283 
1285  uint64_t &Size) {
1286  Error Err = Error::success();
1287  XCOFFTracebackTable TBT(Ptr, Size, Err);
1288  if (Err)
1289  return std::move(Err);
1290  return TBT;
1291 }
1292 
1293 XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
1294  Error &Err)
1295  : TBPtr(Ptr) {
1296  ErrorAsOutParameter EAO(&Err);
1297  DataExtractor DE(ArrayRef<uint8_t>(Ptr, Size), /*IsLittleEndian=*/false,
1298  /*AddressSize=*/0);
1299  DataExtractor::Cursor Cur(/*Offset=*/0);
1300 
1301  // Skip 8 bytes of mandatory fields.
1302  DE.getU64(Cur);
1303 
1304  unsigned FixedParmsNum = getNumberOfFixedParms();
1305  unsigned FloatingParmsNum = getNumberOfFPParms();
1306  uint32_t ParamsTypeValue = 0;
1307 
1308  // Begin to parse optional fields.
1309  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
1310  ParamsTypeValue = DE.getU32(Cur);
1311 
1312  if (Cur && hasTraceBackTableOffset())
1313  TraceBackTableOffset = DE.getU32(Cur);
1314 
1315  if (Cur && isInterruptHandler())
1316  HandlerMask = DE.getU32(Cur);
1317 
1318  if (Cur && hasControlledStorage()) {
1319  NumOfCtlAnchors = DE.getU32(Cur);
1320  if (Cur && NumOfCtlAnchors) {
1322  Disp.reserve(NumOfCtlAnchors.getValue());
1323  for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
1324  Disp.push_back(DE.getU32(Cur));
1325  if (Cur)
1326  ControlledStorageInfoDisp = std::move(Disp);
1327  }
1328  }
1329 
1330  if (Cur && isFuncNamePresent()) {
1331  uint16_t FunctionNameLen = DE.getU16(Cur);
1332  if (Cur)
1333  FunctionName = DE.getBytes(Cur, FunctionNameLen);
1334  }
1335 
1336  if (Cur && isAllocaUsed())
1337  AllocaRegister = DE.getU8(Cur);
1338 
1339  unsigned VectorParmsNum = 0;
1340  if (Cur && hasVectorInfo()) {
1341  StringRef VectorExtRef = DE.getBytes(Cur, 6);
1342  if (Cur) {
1343  Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
1344  if (!TBVecExtOrErr) {
1345  Err = TBVecExtOrErr.takeError();
1346  return;
1347  }
1348  VecExt = TBVecExtOrErr.get();
1349  VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
1350  }
1351  }
1352 
1353  // As long as there is no fixed-point or floating-point parameter, this
1354  // field remains not present even when hasVectorInfo gives true and
1355  // indicates the presence of vector parameters.
1356  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
1357  Expected<SmallString<32>> ParmsTypeOrError =
1358  hasVectorInfo()
1359  ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
1360  FloatingParmsNum, VectorParmsNum)
1361  : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
1362 
1363  if (!ParmsTypeOrError) {
1364  Err = ParmsTypeOrError.takeError();
1365  return;
1366  }
1367  ParmsType = ParmsTypeOrError.get();
1368  }
1369 
1370  if (Cur && hasExtensionTable())
1371  ExtensionTable = DE.getU8(Cur);
1372 
1373  if (!Cur)
1374  Err = Cur.takeError();
1375 
1376  Size = Cur.tell();
1377 }
1378 
1379 #define GETBITWITHMASK(P, X) \
1380  (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
1381 #define GETBITWITHMASKSHIFT(P, X, S) \
1382  ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >> \
1383  (TracebackTable::S))
1384 
1386  return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
1387 }
1388 
1390  return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
1391 }
1392 
1394  return GETBITWITHMASK(0, IsGlobaLinkageMask);
1395 }
1396 
1398  return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
1399 }
1400 
1402  return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
1403 }
1404 
1406  return GETBITWITHMASK(0, IsInternalProcedureMask);
1407 }
1408 
1410  return GETBITWITHMASK(0, HasControlledStorageMask);
1411 }
1412 
1414  return GETBITWITHMASK(0, IsTOClessMask);
1415 }
1416 
1418  return GETBITWITHMASK(0, IsFloatingPointPresentMask);
1419 }
1420 
1422  return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
1423 }
1424 
1426  return GETBITWITHMASK(0, IsInterruptHandlerMask);
1427 }
1428 
1430  return GETBITWITHMASK(0, IsFunctionNamePresentMask);
1431 }
1432 
1434  return GETBITWITHMASK(0, IsAllocaUsedMask);
1435 }
1436 
1438  return GETBITWITHMASKSHIFT(0, OnConditionDirectiveMask,
1439  OnConditionDirectiveShift);
1440 }
1441 
1443  return GETBITWITHMASK(0, IsCRSavedMask);
1444 }
1445 
1447  return GETBITWITHMASK(0, IsLRSavedMask);
1448 }
1449 
1451  return GETBITWITHMASK(4, IsBackChainStoredMask);
1452 }
1453 
1455  return GETBITWITHMASK(4, IsFixupMask);
1456 }
1457 
1459  return GETBITWITHMASKSHIFT(4, FPRSavedMask, FPRSavedShift);
1460 }
1461 
1463  return GETBITWITHMASK(4, HasExtensionTableMask);
1464 }
1465 
1467  return GETBITWITHMASK(4, HasVectorInfoMask);
1468 }
1469 
1471  return GETBITWITHMASKSHIFT(4, GPRSavedMask, GPRSavedShift);
1472 }
1473 
1475  return GETBITWITHMASKSHIFT(4, NumberOfFixedParmsMask,
1476  NumberOfFixedParmsShift);
1477 }
1478 
1480  return GETBITWITHMASKSHIFT(4, NumberOfFloatingPointParmsMask,
1481  NumberOfFloatingPointParmsShift);
1482 }
1483 
1485  return GETBITWITHMASK(4, HasParmsOnStackMask);
1486 }
1487 
1488 #undef GETBITWITHMASK
1489 #undef GETBITWITHMASKSHIFT
1490 } // namespace object
1491 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
llvm::object::XCOFFTracebackTable::isTOCless
bool isTOCless() const
Definition: XCOFFObjectFile.cpp:1413
llvm::object::XCOFFTracebackTable::isInterruptHandler
bool isInterruptHandler() const
Definition: XCOFFObjectFile.cpp:1425
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm::object::XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC
@ NAME_IN_STR_TBL_MAGIC
Definition: XCOFFObjectFile.h:675
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:22
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::object::XCOFFSectionHeader32
Definition: XCOFFObjectFile.h:168
llvm::object::XCOFFTracebackTable::hasParmsOnStack
bool hasParmsOnStack() const
Definition: XCOFFObjectFile.cpp:1484
llvm::object::XCOFFSymbolRef::getXCOFFCsectAuxRef
Expected< XCOFFCsectAuxRef > getXCOFFCsectAuxRef() const
Definition: XCOFFObjectFile.cpp:1151
llvm::object::TBVectorExt::hasVarArgs
bool hasVarArgs() const
Definition: XCOFFObjectFile.cpp:1269
llvm::object::XCOFFSymbolRef::getName
Expected< StringRef > getName() const
Definition: XCOFFObjectFile.cpp:1194
llvm::object::XCOFFObjectFile::getSymbolIndex
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const
Definition: XCOFFObjectFile.cpp:812
llvm::XCOFF::RelocationSerializationSize64
constexpr size_t RelocationSerializationSize64
Definition: XCOFF.h:38
llvm::object::XCOFFFileHeader32
Definition: XCOFFObjectFile.h:26
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:182
is64Bit
static bool is64Bit(const char *name)
Definition: X86Disassembler.cpp:1019
llvm::XCOFF::STYP_BSS
@ STYP_BSS
Definition: XCOFF.h:95
llvm::toString
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:1028
llvm::SmallVector< uint32_t, 8 >
llvm::object::XCOFFRelocation::VirtualAddress
AddressType VirtualAddress
Definition: XCOFFObjectFile.h:418
llvm::XCOFF::C_FILE
@ C_FILE
Definition: XCOFF.h:128
llvm::object::XCOFFTracebackTable::isFloatingPointPresent
bool isFloatingPointPresent() const
Definition: XCOFFObjectFile.cpp:1417
llvm::object::NoRelMask
static const uint16_t NoRelMask
Definition: XCOFFObjectFile.cpp:27
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::object::XCOFFTracebackTable::getVersion
uint8_t getVersion() const
Definition: XCOFFObjectFile.cpp:1385
llvm::XCOFF::XMC_PR
@ XMC_PR
Program Code.
Definition: XCOFF.h:61
llvm::object::XCOFFTracebackTable::isBackChainStored
bool isBackChainStored() const
Definition: XCOFFObjectFile.cpp:1450
llvm::object::LoaderSectionHeader64::OffsetToImpid
support::big64_t OffsetToImpid
Definition: XCOFFObjectFile.h:213
llvm::object::XCOFFSectionHeader
Definition: XCOFFObjectFile.h:149
llvm::object::getWithOffset
static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset)
Definition: XCOFFObjectFile.cpp:41
llvm::object::relocation_iterator
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:75
llvm::object::XCOFFObjectFile::is64Bit
bool is64Bit() const
Definition: XCOFFObjectFile.cpp:698
llvm::object::XCOFFTracebackTable::isOutOfLineEpilogOrPrologue
bool isOutOfLineEpilogOrPrologue() const
Definition: XCOFFObjectFile.cpp:1397
llvm::object::XCOFFAuxiliaryHeader64
Definition: XCOFFObjectFile.h:116
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::object::XCOFFRelocation64
Definition: XCOFFObjectFile.h:438
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
llvm::object::XCOFFFileAuxEnt::NameInStrTblType::Magic
support::big32_t Magic
Definition: XCOFFObjectFile.h:331
llvm::Triple::ppc
@ ppc
Definition: Triple.h:66
llvm::object::TBVectorExt::hasVMXInstruction
bool hasVMXInstruction() const
Definition: XCOFFObjectFile.cpp:1278
T
#define T
Definition: Mips16ISelLowering.cpp:341
GETBITWITHMASKSHIFT
#define GETBITWITHMASKSHIFT(P, X, S)
Definition: XCOFFObjectFile.cpp:1381
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:80
llvm::object::XCOFFFileAuxEnt::Name
char Name[XCOFF::NameSize+XCOFF::FileNamePadSize]
Definition: XCOFFObjectFile.h:336
llvm::RawInstrProf::getMagic
uint64_t getMagic()
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::support::endian::read32be
uint32_t read32be(const void *P)
Definition: Endian.h:384
llvm::XCOFF::STYP_LOADER
@ STYP_LOADER
Definition: XCOFF.h:100
llvm::object::XCOFFSymbolRef::getNumberOfAuxEntries
uint8_t getNumberOfAuxEntries() const
Definition: XCOFFObjectFile.h:716
llvm::object::XCOFFFileHeader64
Definition: XCOFFObjectFile.h:40
llvm::object::LoaderSectionHeader64::LengthOfImpidStrTbl
support::ubig32_t LengthOfImpidStrTbl
Definition: XCOFFObjectFile.h:210
llvm::object::XCOFFCsectAuxRef::getSymbolType
uint8_t getSymbolType() const
Definition: XCOFFObjectFile.h:297
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::object::XCOFFCsectAuxRef::getSectionOrLength
uint64_t getSectionOrLength() const
Definition: XCOFFObjectFile.h:260
llvm::object::XCOFFSymbolRef::isFunction
bool isFunction() const
Definition: XCOFFObjectFile.cpp:1107
llvm::XCOFF::STYP_DWARF
@ STYP_DWARF
Definition: XCOFF.h:92
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:160
llvm::object::XCOFFCsectAuxRef
Definition: XCOFFObjectFile.h:246
llvm::object::XCOFFObjectFile::getImportFileTable
Expected< StringRef > getImportFileTable() const
Definition: XCOFFObjectFile.cpp:976
llvm::object::XCOFFSymbolRef
Definition: XCOFFObjectFile.h:673
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
llvm::object::XCOFFSectionHeader32::VirtualAddress
support::ubig32_t VirtualAddress
Definition: XCOFFObjectFile.h:171
llvm::object::XCOFFObjectFile::getSectionByNum
Expected< DataRefImpl > getSectionByNum(int16_t Num) const
Definition: XCOFFObjectFile.cpp:706
getSectionFlags
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
Definition: MachOObjectFile.cpp:178
llvm::object::XCOFFTracebackTable::isFuncNamePresent
bool isFuncNamePresent() const
Definition: XCOFFObjectFile.cpp:1429
llvm::Intrinsic::getType
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
Definition: Function.cpp:1356
llvm::object::XCOFFTracebackTable::getNumOfGPRsSaved
uint8_t getNumOfGPRsSaved() const
Definition: XCOFFObjectFile.cpp:1470
llvm::XCOFF::N_ABS
@ N_ABS
Definition: XCOFF.h:42
SubtargetFeature.h
llvm::object::XCOFFFileAuxEnt::NameInStrTblType::Offset
support::ubig32_t Offset
Definition: XCOFFObjectFile.h:332
llvm::Triple::ArchType
ArchType
Definition: Triple.h:46
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:418
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
ptrdiff_t
GETVALUEWITHMASK
#define GETVALUEWITHMASK(X)
Definition: XCOFFObjectFile.cpp:1233
llvm::object::XCOFFObjectFile::getStringTableEntry
Expected< StringRef > getStringTableEntry(uint32_t Offset) const
Definition: XCOFFObjectFile.cpp:191
llvm::object::BasicSymbolRef::getRawDataRefImpl
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:206
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::object::TBVectorExt::getNumberOfVectorParms
uint8_t getNumberOfVectorParms() const
Definition: XCOFFObjectFile.cpp:1273
llvm::object::XCOFFObjectFile::getAdvancedSymbolEntryAddress
static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress, uint32_t Distance)
Definition: XCOFFObjectFile.cpp:90
llvm::object::XCOFFTracebackTable::isFixup
bool isFixup() const
Definition: XCOFFObjectFile.cpp:1454
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:90
llvm::SubtargetFeatures
Manages the enabling and disabling of subtarget specific features.
Definition: SubtargetFeature.h:184
XCOFFObjectFile.h
llvm::object::viewAs
static const T * viewAs(uintptr_t in)
Definition: XCOFFObjectFile.cpp:46
llvm::createError
static Error createError(const Twine &Err)
Definition: APFloat.cpp:232
llvm::object::XCOFFSectionHeader64::SectionSize
support::ubig64_t SectionSize
Definition: XCOFFObjectFile.h:185
llvm::Triple::ppc64
@ ppc64
Definition: Triple.h:68
llvm::XCOFF::SymbolTableEntrySize
constexpr size_t SymbolTableEntrySize
Definition: XCOFF.h:36
in
The object format emitted by the WebAssembly backed is documented in
Definition: README.txt:11
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:143
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1097
llvm::object::object_error::parse_failed
@ parse_failed
llvm::object::XCOFFTracebackTable::isGlobalLinkage
bool isGlobalLinkage() const
Definition: XCOFFObjectFile.cpp:1393
llvm::object::DataRefImpl::p
uintptr_t p
Definition: SymbolicFile.h:39
llvm::object::XCOFFObjectFile::getSectionFlags
int32_t getSectionFlags(DataRefImpl Sec) const
Definition: XCOFFObjectFile.cpp:868
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::XCOFF::XTY_SD
@ XTY_SD
Csect definition for initialized storage.
Definition: XCOFF.h:198
llvm::XCOFF::N_DEBUG
@ N_DEBUG
Definition: XCOFF.h:42
llvm::object::XCOFFObjectFile::relocations
Expected< ArrayRef< Reloc > > relocations(const Shdr &Sec) const
Definition: XCOFFObjectFile.cpp:914
llvm::object::XCOFFRelocation::Type
XCOFF::RelocationType Type
Definition: XCOFFObjectFile.h:424
llvm::object::LoaderSectionHeader32
Definition: XCOFFObjectFile.h:195
llvm::object::XCOFFCsectAuxRef::isLabel
bool isLabel() const
Definition: XCOFFObjectFile.h:301
llvm::XCOFF::C_EXT
@ C_EXT
Definition: XCOFF.h:154
llvm::object::XCOFFTracebackTable::isLRSaved
bool isLRSaved() const
Definition: XCOFFObjectFile.cpp:1446
llvm::MachO::FileType
FileType
Defines the file type this file represents.
Definition: InterfaceFile.h:53
llvm::object::XCOFFObjectFile::checkSymbolEntryPointer
void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const
Definition: XCOFFObjectFile.cpp:797
llvm::XCOFF::NameSize
constexpr size_t NameSize
Definition: XCOFF.h:29
llvm::OutputFileType::Object
@ Object
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:79
llvm::object::XCOFFTracebackTable::isCRSaved
bool isCRSaved() const
Definition: XCOFFObjectFile.cpp:1442
llvm::object::XCOFFCsectAuxRef::getStorageMappingClass
XCOFF::StorageMappingClass getStorageMappingClass() const
Definition: XCOFFObjectFile.h:283
llvm::object::XCOFFSymbolEntry32::NameInStrTblType::Offset
support::ubig32_t Offset
Definition: XCOFFObjectFile.h:639
llvm::XCOFF::STYP_TDATA
@ STYP_TDATA
Definition: XCOFF.h:98
llvm::XCOFF::StorageClass
StorageClass
Definition: XCOFF.h:126
llvm::object::TBVectorExt::create
static Expected< TBVectorExt > create(StringRef TBvectorStrRef)
Definition: XCOFFObjectFile.cpp:1237
llvm::object::LoaderSectionHeader64
Definition: XCOFFObjectFile.h:206
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:408
llvm::object::XCOFFSymbolEntry64::Offset
support::ubig32_t Offset
Definition: XCOFFObjectFile.h:661
llvm::object::XCOFFTracebackTable::getNumberOfFPParms
uint8_t getNumberOfFPParms() const
Definition: XCOFFObjectFile.cpp:1479
llvm::XCOFF::parseParmsTypeWithVecInfo
Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
Definition: XCOFF.cpp:188
llvm::object::FunctionSym
static const uint8_t FunctionSym
Definition: XCOFFObjectFile.cpp:26
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
uint64_t
llvm::object::object_error::string_table_non_null_end
@ string_table_non_null_end
llvm::object::symbol_iterator
Definition: ObjectFile.h:206
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:130
getSymbolType
static std::unique_ptr< PDBSymbol > getSymbolType(const PDBSymbol &Symbol)
Definition: UDTLayout.cpp:33
llvm::XCOFF::parseVectorParmsType
Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)
Definition: XCOFF.cpp:240
llvm::XCOFF::STYP_OVRFLO
@ STYP_OVRFLO
Definition: XCOFF.h:103
llvm::XCOFF::XTY_CM
@ XTY_CM
Common csect definition. For uninitialized storage.
Definition: XCOFF.h:201
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::object::XCOFFObjectFile::getNumberOfRelocationEntries
Expected< uint32_t > getNumberOfRelocationEntries(const XCOFFSectionHeader< T > &Sec) const
Definition: XCOFFObjectFile.cpp:896
llvm::object::XCOFFTracebackTable::hasTraceBackTableOffset
bool hasTraceBackTableOffset() const
Definition: XCOFFObjectFile.cpp:1401
llvm::XCOFF::C_HIDEXT
@ C_HIDEXT
Definition: XCOFF.h:162
llvm::object::TBVectorExt
Definition: XCOFFObjectFile.h:736
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI
StandardInstrumentations SI(Debug, VerifyEach)
base
therefore end up llgh r3 lr r0 br r14 but truncating the load would lh r3 br r14 Functions ret i64 and ought to be implemented ngr r0 br r14 but two address optimizations reverse the order of the AND and ngr r2 lgr r0 br r14 CodeGen SystemZ and ll has several examples of this Out of range displacements are usually handled by loading the full address into a register In many cases it would be better to create an anchor point instead E g i64 base
Definition: README.txt:125
llvm::object::content_iterator
Definition: SymbolicFile.h:67
llvm::object::XCOFFSymbolRef::getSectionNumber
int16_t getSectionNumber() const
Definition: XCOFFObjectFile.h:698
llvm::object::ObjectFile::base
const uint8_t * base() const
Definition: ObjectFile.h:233
llvm::object::XCOFFStringTable
Definition: XCOFFObjectFile.h:220
llvm::DataExtractor::Cursor
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Definition: DataExtractor.h:54
llvm::object::ObjectFile::createXCOFFObjectFile
static Expected< std::unique_ptr< ObjectFile > > createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType)
Definition: XCOFFObjectFile.cpp:1102
llvm::XCOFF::parseParmsType
Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
Definition: XCOFF.cpp:110
llvm::ArrayRef< uint8_t >
llvm::object::section_iterator
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:46
llvm::object::generateXCOFFFixedNameStringRef
static StringRef generateXCOFFFixedNameStringRef(const char *Name)
Definition: XCOFFObjectFile.cpp:50
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::object::XCOFFSymbolRef::getStorageClass
XCOFF::StorageClass getStorageClass() const
Definition: XCOFFObjectFile.h:714
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:227
llvm::object::XCOFFTracebackTable::create
static Expected< XCOFFTracebackTable > create(const uint8_t *Ptr, uint64_t &Size)
Parse an XCOFF Traceback Table from Ptr with Size bytes.
Definition: XCOFFObjectFile.cpp:1284
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::object::XCOFFTracebackTable::hasControlledStorage
bool hasControlledStorage() const
Definition: XCOFFObjectFile.cpp:1409
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
llvm::XCOFF::C_WEAKEXT
@ C_WEAKEXT
Definition: XCOFF.h:155
llvm::object::XCOFFRelocation::SymbolIndex
support::ubig32_t SymbolIndex
Definition: XCOFFObjectFile.h:419
uint32_t
llvm::COFF::SectionSize
@ SectionSize
Definition: COFF.h:61
llvm::object::XCOFFObjectFile::sections32
ArrayRef< XCOFFSectionHeader32 > sections32() const
Definition: XCOFFObjectFile.cpp:884
llvm::object::XCOFFAuxiliaryHeader32
Definition: XCOFFObjectFile.h:69
llvm::object::DataRefImpl
Definition: SymbolicFile.h:33
llvm::object::LoaderSectionHeader32::OffsetToImpid
support::big32_t OffsetToImpid
Definition: XCOFFObjectFile.h:201
llvm::XCOFF::SymbolAuxType
SymbolAuxType
Definition: XCOFF.h:295
llvm::object::XCOFFFileAuxEnt::NameInStrTbl
NameInStrTblType NameInStrTbl
Definition: XCOFFObjectFile.h:337
llvm::object::TBVectorExt::getNumberOfVRSaved
uint8_t getNumberOfVRSaved() const
Definition: XCOFFObjectFile.cpp:1261
llvm::object::XCOFFObjectFile::getSymbolAuxType
const XCOFF::SymbolAuxType * getSymbolAuxType(uintptr_t AuxEntryAddress) const
Definition: XCOFFObjectFile.cpp:96
llvm::XCOFF::N_UNDEF
@ N_UNDEF
Definition: XCOFF.h:42
llvm::object::XCOFFObjectFile::sections64
ArrayRef< XCOFFSectionHeader64 > sections64() const
Definition: XCOFFObjectFile.cpp:877
llvm::object::SymbolAuxTypeOffset
static const size_t SymbolAuxTypeOffset
Definition: XCOFFObjectFile.cpp:28
GETBITWITHMASK
#define GETBITWITHMASK(P, X)
Definition: XCOFFObjectFile.cpp:1379
llvm::object::XCOFFObjectFile::getNumberOfSections
uint16_t getNumberOfSections() const
Definition: XCOFFObjectFile.cpp:747
llvm::object::XCOFFTracebackTable::isAllocaUsed
bool isAllocaUsed() const
Definition: XCOFFObjectFile.cpp:1433
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::object::Binary::ID_XCOFF32
@ ID_XCOFF32
Definition: Binary.h:57
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::object::XCOFFSectionHeader32::SectionSize
support::ubig32_t SectionSize
Definition: XCOFFObjectFile.h:172
uint16_t
getFlags
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:23
llvm::XCOFF::STYP_DEBUG
@ STYP_DEBUG
Definition: XCOFF.h:101
llvm::object::XCOFFTracebackTable::getNumberOfFixedParms
uint8_t getNumberOfFixedParms() const
Definition: XCOFFObjectFile.cpp:1474
llvm::object::XCOFFTracebackTable::hasExtensionTable
bool hasExtensionTable() const
Definition: XCOFFObjectFile.cpp:1462
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
getObject
static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
Definition: COFFObjectFile.cpp:58
llvm::object::XCOFFTracebackTable::isInternalProcedure
bool isInternalProcedure() const
Definition: XCOFFObjectFile.cpp:1405
DataExtractor.h
llvm::object::XCOFFTracebackTable::getNumOfFPRsSaved
uint8_t getNumOfFPRsSaved() const
Definition: XCOFFObjectFile.cpp:1458
llvm::XCOFF::AUX_CSECT
@ AUX_CSECT
Identifies a csect auxiliary entry.
Definition: XCOFF.h:300
StringSwitch.h
llvm::object::XCOFFRelocation32
Definition: XCOFFObjectFile.h:437
llvm::XCOFF::getRelocationTypeString
StringRef getRelocationTypeString(XCOFF::RelocationType Type)
Definition: XCOFF.cpp:53
llvm::object::XCOFFSectionHeader64::VirtualAddress
support::ubig64_t VirtualAddress
Definition: XCOFFObjectFile.h:184
llvm::object::TBVectorExt::isVRSavedOnStack
bool isVRSavedOnStack() const
Definition: XCOFFObjectFile.cpp:1265
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:474
getFeatures
static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Definition: MCSubtargetInfo.cpp:150
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::object::XCOFFSectionHeader64
Definition: XCOFFObjectFile.h:181
llvm::object::XCOFFSymbolEntry32::SymbolName
char SymbolName[XCOFF::NameSize]
Definition: XCOFFObjectFile.h:643
llvm::object::Binary::ID_XCOFF64
@ ID_XCOFF64
Definition: Binary.h:58
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::object::XCOFFTracebackTable::getOnConditionDirective
uint8_t getOnConditionDirective() const
Definition: XCOFFObjectFile.cpp:1437
llvm::XCOFF::STYP_DATA
@ STYP_DATA
Definition: XCOFF.h:94
getSymbolSectionID
static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym)
Definition: SymbolSize.cpp:39
GETVALUEWITHMASKSHIFT
#define GETVALUEWITHMASKSHIFT(X, S)
Definition: XCOFFObjectFile.cpp:1234
llvm::COFF::isReservedSectionNumber
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: COFF.h:730
llvm::XCOFF::STYP_TEXT
@ STYP_TEXT
Definition: XCOFF.h:93
llvm::object::XCOFFTracebackTable::isFloatingPointOperationLogOrAbortEnabled
bool isFloatingPointOperationLogOrAbortEnabled() const
Definition: XCOFFObjectFile.cpp:1421
llvm::object::XCOFFSymbolRef::isCsectSymbol
bool isCsectSymbol() const
Definition: XCOFFObjectFile.cpp:1145
llvm::object::XCOFFObjectFile
Definition: XCOFFObjectFile.h:442
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::object::XCOFFTracebackTable
This class provides methods to extract traceback table data from a buffer.
Definition: XCOFFObjectFile.h:755
llvm::object::Binary::checkOffset
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
Definition: Binary.h:166
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:149
llvm::SmallVectorImpl< char >
llvm::object::XCOFFSymbolRef::getSymbolType
uint16_t getSymbolType() const
Definition: XCOFFObjectFile.h:700
llvm::object::SymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:166
llvm::object::createError
Error createError(const Twine &Err)
Definition: Error.h:83
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
llvm::object::XCOFFSymbolRef::getEntryAddress
uintptr_t getEntryAddress() const
Definition: XCOFFObjectFile.h:720
llvm::XCOFF::RelocationSerializationSize32
constexpr size_t RelocationSerializationSize32
Definition: XCOFF.h:37
llvm::XCOFF::STYP_TBSS
@ STYP_TBSS
Definition: XCOFF.h:99
llvm::object::RelocationRef
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:50
getSymbolName
static StringRef getSymbolName(SymbolKind SymKind)
Definition: CodeViewDebug.cpp:3114
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:633
llvm::object::XCOFFSymbolEntry32::NameInStrTbl
NameInStrTblType NameInStrTbl
Definition: XCOFFObjectFile.h:644
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::object::XCOFFFileAuxEnt
Definition: XCOFFObjectFile.h:329
llvm::XCOFF::RelocOverflow
constexpr uint16_t RelocOverflow
Definition: XCOFF.h:39
llvm::object::basic_symbol_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:141
llvm::object::XCOFFRelocation
Definition: XCOFFObjectFile.h:402
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:282
llvm::object::doesXCOFFTracebackTableBegin
bool doesXCOFFTracebackTableBegin(ArrayRef< uint8_t > Bytes)
Definition: XCOFFObjectFile.cpp:1226
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::object::XCOFFTracebackTable::hasVectorInfo
bool hasVectorInfo() const
Definition: XCOFFObjectFile.cpp:1466
Shdr
Elf_Shdr Shdr
Definition: ELFObjHandler.cpp:78
llvm::object::LoaderSectionHeader32::LengthOfImpidStrTbl
support::ubig32_t LengthOfImpidStrTbl
Definition: XCOFFObjectFile.h:199
llvm::object::XCOFFSymbolEntry32::NameInStrTblType::Magic
support::big32_t Magic
Definition: XCOFFObjectFile.h:638
llvm::support::endian::read16be
uint16_t read16be(const void *P)
Definition: Endian.h:383
llvm::object::XCOFFTracebackTable::getLanguageID
uint8_t getLanguageID() const
Definition: XCOFFObjectFile.cpp:1389