LLVM  15.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 
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  // There is no visibility in old 32 bit XCOFF object file interpret.
619  if (is64Bit() || (auxiliaryHeader32() && (auxiliaryHeader32()->getVersion() ==
621  uint16_t SymType = XCOFFSym.getSymbolType();
622  if ((SymType & VISIBILITY_MASK) == SYM_V_HIDDEN)
623  Result |= SymbolRef::SF_Hidden;
624 
625  if ((SymType & VISIBILITY_MASK) == SYM_V_EXPORTED)
626  Result |= SymbolRef::SF_Exported;
627  }
628  return Result;
629 }
630 
631 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
632  DataRefImpl SymDRI;
633  SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
634  return basic_symbol_iterator(SymbolRef(SymDRI, this));
635 }
636 
637 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
638  DataRefImpl SymDRI;
639  const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
640  SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
641  return basic_symbol_iterator(SymbolRef(SymDRI, this));
642 }
643 
644 section_iterator XCOFFObjectFile::section_begin() const {
645  DataRefImpl DRI;
646  DRI.p = getSectionHeaderTableAddress();
647  return section_iterator(SectionRef(DRI, this));
648 }
649 
650 section_iterator XCOFFObjectFile::section_end() const {
651  DataRefImpl DRI;
652  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
653  getNumberOfSections() * getSectionHeaderSize());
654  return section_iterator(SectionRef(DRI, this));
655 }
656 
657 uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }
658 
659 StringRef XCOFFObjectFile::getFileFormatName() const {
660  return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
661 }
662 
663 Triple::ArchType XCOFFObjectFile::getArch() const {
664  return is64Bit() ? Triple::ppc64 : Triple::ppc;
665 }
666 
668  return SubtargetFeatures();
669 }
670 
671 bool XCOFFObjectFile::isRelocatableObject() const {
672  if (is64Bit())
673  return !(fileHeader64()->Flags & NoRelMask);
674  return !(fileHeader32()->Flags & NoRelMask);
675 }
676 
677 Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
678  // TODO FIXME Should get from auxiliary_header->o_entry when support for the
679  // auxiliary_header is added.
680  return 0;
681 }
682 
683 StringRef XCOFFObjectFile::mapDebugSectionName(StringRef Name) const {
685  .Case("dwinfo", "debug_info")
686  .Case("dwline", "debug_line")
687  .Case("dwpbnms", "debug_pubnames")
688  .Case("dwpbtyp", "debug_pubtypes")
689  .Case("dwarnge", "debug_aranges")
690  .Case("dwabrev", "debug_abbrev")
691  .Case("dwstr", "debug_str")
692  .Case("dwrnges", "debug_ranges")
693  .Case("dwloc", "debug_loc")
694  .Case("dwframe", "debug_frame")
695  .Case("dwmac", "debug_macinfo")
696  .Default(Name);
697 }
698 
699 size_t XCOFFObjectFile::getFileHeaderSize() const {
700  return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
701 }
702 
703 size_t XCOFFObjectFile::getSectionHeaderSize() const {
704  return is64Bit() ? sizeof(XCOFFSectionHeader64) :
705  sizeof(XCOFFSectionHeader32);
706 }
707 
709  return Binary::ID_XCOFF64 == getType();
710 }
711 
712 Expected<StringRef> XCOFFObjectFile::getRawData(const char *Start,
713  uint64_t Size,
714  StringRef Name) const {
715  uintptr_t StartPtr = reinterpret_cast<uintptr_t>(Start);
716  // TODO: this path is untested.
717  if (Error E = Binary::checkOffset(Data, StartPtr, Size))
718  return createError(toString(std::move(E)) + ": " + Name.data() +
719  " data with offset 0x" + Twine::utohexstr(StartPtr) +
720  " and size 0x" + Twine::utohexstr(Size) +
721  " goes past the end of the file");
722  return StringRef(Start, Size);
723 }
724 
726  return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
727 }
728 
729 Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
730  if (Num <= 0 || Num > getNumberOfSections())
731  return createStringError(object_error::invalid_section_index,
732  "the section index (" + Twine(Num) +
733  ") is invalid");
734 
735  DataRefImpl DRI;
736  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
737  getSectionHeaderSize() * (Num - 1));
738  return DRI;
739 }
740 
742 XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
743  const int16_t SectionNum = SymEntPtr.getSectionNumber();
744 
745  switch (SectionNum) {
746  case XCOFF::N_DEBUG:
747  return "N_DEBUG";
748  case XCOFF::N_ABS:
749  return "N_ABS";
750  case XCOFF::N_UNDEF:
751  return "N_UNDEF";
752  default:
753  Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
754  if (SecRef)
756  getSectionNameInternal(SecRef.get()));
757  return SecRef.takeError();
758  }
759 }
760 
762  XCOFFSymbolRef XCOFFSymRef(Sym.getRawDataRefImpl(), this);
763  return XCOFFSymRef.getSectionNumber();
764 }
765 
766 bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
767  return (SectionNumber <= 0 && SectionNumber >= -2);
768 }
769 
770 uint16_t XCOFFObjectFile::getNumberOfSections() const {
771  return is64Bit() ? fileHeader64()->NumberOfSections
772  : fileHeader32()->NumberOfSections;
773 }
774 
775 int32_t XCOFFObjectFile::getTimeStamp() const {
776  return is64Bit() ? fileHeader64()->TimeStamp : fileHeader32()->TimeStamp;
777 }
778 
779 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
780  return is64Bit() ? fileHeader64()->AuxHeaderSize
781  : fileHeader32()->AuxHeaderSize;
782 }
783 
784 uint32_t XCOFFObjectFile::getSymbolTableOffset32() const {
785  return fileHeader32()->SymbolTableOffset;
786 }
787 
788 int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries32() const {
789  // As far as symbol table size is concerned, if this field is negative it is
790  // to be treated as a 0. However since this field is also used for printing we
791  // don't want to truncate any negative values.
792  return fileHeader32()->NumberOfSymTableEntries;
793 }
794 
795 uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries32() const {
796  return (fileHeader32()->NumberOfSymTableEntries >= 0
797  ? fileHeader32()->NumberOfSymTableEntries
798  : 0);
799 }
800 
801 uint64_t XCOFFObjectFile::getSymbolTableOffset64() const {
802  return fileHeader64()->SymbolTableOffset;
803 }
804 
805 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
806  return fileHeader64()->NumberOfSymTableEntries;
807 }
808 
809 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
810  return is64Bit() ? getNumberOfSymbolTableEntries64()
811  : getLogicalNumberOfSymbolTableEntries32();
812 }
813 
814 uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
815  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
816  return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
817  XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
818 }
819 
820 void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
821  if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
822  report_fatal_error("Symbol table entry is outside of symbol table.");
823 
824  if (SymbolEntPtr >= getEndOfSymbolTableAddress())
825  report_fatal_error("Symbol table entry is outside of symbol table.");
826 
827  ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
828  reinterpret_cast<const char *>(SymbolTblPtr);
829 
830  if (Offset % XCOFF::SymbolTableEntrySize != 0)
832  "Symbol table entry position is not valid inside of symbol table.");
833 }
834 
835 uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
836  return (reinterpret_cast<const char *>(SymbolEntPtr) -
837  reinterpret_cast<const char *>(SymbolTblPtr)) /
839 }
840 
841 uint64_t XCOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
842  uint64_t Result = 0;
843  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
844  if (XCOFFSym.isCsectSymbol()) {
845  Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
846  XCOFFSym.getXCOFFCsectAuxRef();
847  if (!CsectAuxRefOrError)
848  // TODO: report the error up the stack.
849  consumeError(CsectAuxRefOrError.takeError());
850  else {
851  XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
852  uint8_t SymType = CsectAuxRef.getSymbolType();
853  if (SymType == XCOFF::XTY_SD || SymType == XCOFF::XTY_CM)
854  Result = CsectAuxRef.getSectionOrLength();
855  }
856  }
857  return Result;
858 }
859 
860 uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
861  return getAdvancedSymbolEntryAddress(
862  reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
863 }
864 
866 XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
867  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
868 
869  if (Index >= NumberOfSymTableEntries)
870  return createError("symbol index " + Twine(Index) +
871  " exceeds symbol count " +
872  Twine(NumberOfSymTableEntries));
873 
874  DataRefImpl SymDRI;
875  SymDRI.p = getSymbolEntryAddressByIndex(Index);
876  return getSymbolName(SymDRI);
877 }
878 
880  return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
881 }
882 
883 const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
884  return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
885 }
886 
887 uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
888  return reinterpret_cast<uintptr_t>(SectionHeaderTable);
889 }
890 
892  return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
893 }
894 
895 XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
896  : ObjectFile(Type, Object) {
898 }
899 
901  assert(is64Bit() && "64-bit interface called for non 64-bit file.");
902  const XCOFFSectionHeader64 *TablePtr = sectionHeaderTable64();
903  return ArrayRef<XCOFFSectionHeader64>(TablePtr,
904  TablePtr + getNumberOfSections());
905 }
906 
908  assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
909  const XCOFFSectionHeader32 *TablePtr = sectionHeaderTable32();
910  return ArrayRef<XCOFFSectionHeader32>(TablePtr,
911  TablePtr + getNumberOfSections());
912 }
913 
914 // In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
915 // section header contains the actual count of relocation entries in the s_paddr
916 // field. STYP_OVRFLO headers contain the section index of their corresponding
917 // sections as their raw "NumberOfRelocations" field value.
918 template <typename T>
920  const XCOFFSectionHeader<T> &Sec) const {
921  const T &Section = static_cast<const T &>(Sec);
922  if (is64Bit())
923  return Section.NumberOfRelocations;
924 
925  uint16_t SectionIndex = &Section - sectionHeaderTable<T>() + 1;
926  if (Section.NumberOfRelocations < XCOFF::RelocOverflow)
927  return Section.NumberOfRelocations;
928  for (const auto &Sec : sections32()) {
929  if (Sec.Flags == XCOFF::STYP_OVRFLO &&
930  Sec.NumberOfRelocations == SectionIndex)
931  return Sec.PhysicalAddress;
932  }
934 }
935 
936 template <typename Shdr, typename Reloc>
938  uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
939  Sec.FileOffsetToRelocationInfo);
940  auto NumRelocEntriesOrErr = getNumberOfRelocationEntries(Sec);
941  if (Error E = NumRelocEntriesOrErr.takeError())
942  return std::move(E);
943 
944  uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
945  static_assert((sizeof(Reloc) == XCOFF::RelocationSerializationSize64 ||
946  sizeof(Reloc) == XCOFF::RelocationSerializationSize32),
947  "Relocation structure is incorrect");
948  auto RelocationOrErr =
949  getObject<Reloc>(Data, reinterpret_cast<void *>(RelocAddr),
950  NumRelocEntries * sizeof(Reloc));
951  if (!RelocationOrErr)
952  return createError(
953  toString(RelocationOrErr.takeError()) + ": relocations with offset 0x" +
954  Twine::utohexstr(Sec.FileOffsetToRelocationInfo) + " and size 0x" +
955  Twine::utohexstr(NumRelocEntries * sizeof(Reloc)) +
956  " go past the end of the file");
957 
958  const Reloc *StartReloc = RelocationOrErr.get();
959 
960  return ArrayRef<Reloc>(StartReloc, StartReloc + NumRelocEntries);
961 }
962 
964 XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
965  // If there is a string table, then the buffer must contain at least 4 bytes
966  // for the string table's size. Not having a string table is not an error.
968  Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
970  return XCOFFStringTable{0, nullptr};
971  }
972 
973  // Read the size out of the buffer.
974  uint32_t Size = support::endian::read32be(Obj->base() + Offset);
975 
976  // If the size is less then 4, then the string table is just a size and no
977  // string data.
978  if (Size <= 4)
979  return XCOFFStringTable{4, nullptr};
980 
981  auto StringTableOrErr =
982  getObject<char>(Obj->Data, Obj->base() + Offset, Size);
983  if (!StringTableOrErr)
984  return createError(toString(StringTableOrErr.takeError()) +
985  ": string table with offset 0x" +
986  Twine::utohexstr(Offset) + " and size 0x" +
987  Twine::utohexstr(Size) +
988  " goes past the end of the file");
989 
990  const char *StringTablePtr = StringTableOrErr.get();
991  if (StringTablePtr[Size - 1] != '\0')
993 
994  return XCOFFStringTable{Size, StringTablePtr};
995 }
996 
997 // This function returns the import file table. Each entry in the import file
998 // table consists of: "path_name\0base_name\0archive_member_name\0".
1000  Expected<uintptr_t> LoaderSectionAddrOrError = getLoaderSectionAddress();
1001  if (!LoaderSectionAddrOrError)
1002  return LoaderSectionAddrOrError.takeError();
1003 
1004  uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
1005  if (!LoaderSectionAddr)
1006  return StringRef();
1007 
1008  uint64_t OffsetToImportFileTable = 0;
1009  uint64_t LengthOfImportFileTable = 0;
1010  if (is64Bit()) {
1011  const LoaderSectionHeader64 *LoaderSec64 =
1012  viewAs<LoaderSectionHeader64>(LoaderSectionAddr);
1013  OffsetToImportFileTable = LoaderSec64->OffsetToImpid;
1014  LengthOfImportFileTable = LoaderSec64->LengthOfImpidStrTbl;
1015  } else {
1016  const LoaderSectionHeader32 *LoaderSec32 =
1017  viewAs<LoaderSectionHeader32>(LoaderSectionAddr);
1018  OffsetToImportFileTable = LoaderSec32->OffsetToImpid;
1019  LengthOfImportFileTable = LoaderSec32->LengthOfImpidStrTbl;
1020  }
1021 
1022  auto ImportTableOrErr = getObject<char>(
1023  Data,
1024  reinterpret_cast<void *>(LoaderSectionAddr + OffsetToImportFileTable),
1025  LengthOfImportFileTable);
1026  if (!ImportTableOrErr)
1027  return createError(
1028  toString(ImportTableOrErr.takeError()) +
1029  ": import file table with offset 0x" +
1030  Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1031  " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1032  " goes past the end of the file");
1033 
1034  const char *ImportTablePtr = ImportTableOrErr.get();
1035  if (ImportTablePtr[LengthOfImportFileTable - 1] != '\0')
1036  return createError(
1037  ": import file name table with offset 0x" +
1038  Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1039  " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1040  " must end with a null terminator");
1041 
1042  return StringRef(ImportTablePtr, LengthOfImportFileTable);
1043 }
1044 
1046 XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
1047  // Can't use std::make_unique because of the private constructor.
1048  std::unique_ptr<XCOFFObjectFile> Obj;
1049  Obj.reset(new XCOFFObjectFile(Type, MBR));
1050 
1051  uint64_t CurOffset = 0;
1052  const auto *Base = Obj->base();
1053  MemoryBufferRef Data = Obj->Data;
1054 
1055  // Parse file header.
1056  auto FileHeaderOrErr =
1057  getObject<void>(Data, Base + CurOffset, Obj->getFileHeaderSize());
1058  if (Error E = FileHeaderOrErr.takeError())
1059  return std::move(E);
1060  Obj->FileHeader = FileHeaderOrErr.get();
1061 
1062  CurOffset += Obj->getFileHeaderSize();
1063 
1064  if (Obj->getOptionalHeaderSize()) {
1065  auto AuxiliaryHeaderOrErr =
1066  getObject<void>(Data, Base + CurOffset, Obj->getOptionalHeaderSize());
1067  if (Error E = AuxiliaryHeaderOrErr.takeError())
1068  return std::move(E);
1069  Obj->AuxiliaryHeader = AuxiliaryHeaderOrErr.get();
1070  }
1071 
1072  CurOffset += Obj->getOptionalHeaderSize();
1073 
1074  // Parse the section header table if it is present.
1075  if (Obj->getNumberOfSections()) {
1076  uint64_t SectionHeadersSize =
1077  Obj->getNumberOfSections() * Obj->getSectionHeaderSize();
1078  auto SecHeadersOrErr =
1079  getObject<void>(Data, Base + CurOffset, SectionHeadersSize);
1080  if (!SecHeadersOrErr)
1081  return createError(toString(SecHeadersOrErr.takeError()) +
1082  ": section headers with offset 0x" +
1083  Twine::utohexstr(CurOffset) + " and size 0x" +
1084  Twine::utohexstr(SectionHeadersSize) +
1085  " go past the end of the file");
1086 
1087  Obj->SectionHeaderTable = SecHeadersOrErr.get();
1088  }
1089 
1090  const uint32_t NumberOfSymbolTableEntries =
1091  Obj->getNumberOfSymbolTableEntries();
1092 
1093  // If there is no symbol table we are done parsing the memory buffer.
1094  if (NumberOfSymbolTableEntries == 0)
1095  return std::move(Obj);
1096 
1097  // Parse symbol table.
1098  CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
1099  : Obj->getSymbolTableOffset32();
1100  const uint64_t SymbolTableSize =
1101  static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
1102  NumberOfSymbolTableEntries;
1103  auto SymTableOrErr =
1104  getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
1105  if (!SymTableOrErr)
1106  return createError(
1107  toString(SymTableOrErr.takeError()) + ": symbol table with offset 0x" +
1108  Twine::utohexstr(CurOffset) + " and size 0x" +
1109  Twine::utohexstr(SymbolTableSize) + " goes past the end of the file");
1110 
1111  Obj->SymbolTblPtr = SymTableOrErr.get();
1112  CurOffset += SymbolTableSize;
1113 
1114  // Parse String table.
1115  Expected<XCOFFStringTable> StringTableOrErr =
1116  parseStringTable(Obj.get(), CurOffset);
1117  if (Error E = StringTableOrErr.takeError())
1118  return std::move(E);
1119  Obj->StringTable = StringTableOrErr.get();
1120 
1121  return std::move(Obj);
1122 }
1123 
1124 Expected<std::unique_ptr<ObjectFile>>
1126  unsigned FileType) {
1127  return XCOFFObjectFile::create(FileType, MemBufRef);
1128 }
1129 
1131  if (!isCsectSymbol())
1132  return false;
1133 
1134  if (getSymbolType() & FunctionSym)
1135  return true;
1136 
1138  if (!ExpCsectAuxEnt) {
1139  // If we could not get the CSECT auxiliary entry, then treat this symbol as
1140  // if it isn't a function. Consume the error and return `false` to move on.
1141  consumeError(ExpCsectAuxEnt.takeError());
1142  return false;
1143  }
1144 
1145  const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
1146 
1147  // A function definition should be a label definition.
1148  // FIXME: This is not necessarily the case when -ffunction-sections is
1149  // enabled.
1150  if (!CsectAuxRef.isLabel())
1151  return false;
1152 
1153  if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
1154  return false;
1155 
1156  const int16_t SectNum = getSectionNumber();
1157  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
1158  if (!SI) {
1159  // If we could not get the section, then this symbol should not be
1160  // a function. So consume the error and return `false` to move on.
1161  consumeError(SI.takeError());
1162  return false;
1163  }
1164 
1165  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
1166 }
1167 
1170  return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
1171  SC == XCOFF::C_HIDEXT);
1172 }
1173 
1175  assert(isCsectSymbol() &&
1176  "Calling csect symbol interface with a non-csect symbol.");
1177 
1178  uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();
1179 
1180  Expected<StringRef> NameOrErr = getName();
1181  if (auto Err = NameOrErr.takeError())
1182  return std::move(Err);
1183 
1184  uint32_t SymbolIdx = OwningObjectPtr->getSymbolIndex(getEntryAddress());
1185  if (!NumberOfAuxEntries) {
1186  return createError("csect symbol \"" + *NameOrErr + "\" with index " +
1187  Twine(SymbolIdx) + " contains no auxiliary entry");
1188  }
1189 
1190  if (!OwningObjectPtr->is64Bit()) {
1191  // In XCOFF32, the csect auxilliary entry is always the last auxiliary
1192  // entry for the symbol.
1194  getEntryAddress(), NumberOfAuxEntries);
1195  return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
1196  }
1197 
1198  // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
1199  // We need to iterate through all the auxiliary entries to find it.
1200  for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
1202  getEntryAddress(), Index);
1203  if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
1205 #ifndef NDEBUG
1206  OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
1207 #endif
1208  return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
1209  }
1210  }
1211 
1212  return createError(
1213  "a csect auxiliary entry has not been found for symbol \"" + *NameOrErr +
1214  "\" with index " + Twine(SymbolIdx));
1215 }
1216 
1218  // A storage class value with the high-order bit on indicates that the name is
1219  // a symbolic debugger stabstring.
1220  if (getStorageClass() & 0x80)
1221  return StringRef("Unimplemented Debug Name");
1222 
1223  if (Entry32) {
1226 
1227  return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
1228  }
1229 
1230  return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
1231 }
1232 
1233 // Explictly instantiate template classes.
1236 
1239 
1243  llvm::object::XCOFFSectionHeader64 const &) const;
1247  llvm::object::XCOFFSectionHeader32 const &) const;
1248 
1250  if (Bytes.size() < 4)
1251  return false;
1252 
1253  return support::endian::read32be(Bytes.data()) == 0;
1254 }
1255 
1256 #define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
1257 #define GETVALUEWITHMASKSHIFT(X, S) \
1258  ((Data & (TracebackTable::X)) >> (TracebackTable::S))
1259 
1261  Error Err = Error::success();
1262  TBVectorExt TBTVecExt(TBvectorStrRef, Err);
1263  if (Err)
1264  return std::move(Err);
1265  return TBTVecExt;
1266 }
1267 
1268 TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
1269  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
1271  uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
1272  unsigned ParmsNum =
1273  GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
1274 
1275  ErrorAsOutParameter EAO(&Err);
1276  Expected<SmallString<32>> VecParmsTypeOrError =
1277  parseVectorParmsType(VecParmsTypeValue, ParmsNum);
1278  if (!VecParmsTypeOrError)
1279  Err = VecParmsTypeOrError.takeError();
1280  else
1281  VecParmsInfo = VecParmsTypeOrError.get();
1282 }
1283 
1285  return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
1286 }
1287 
1289  return GETVALUEWITHMASK(IsVRSavedOnStackMask);
1290 }
1291 
1293  return GETVALUEWITHMASK(HasVarArgsMask);
1294 }
1295 
1297  return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
1298  NumberOfVectorParmsShift);
1299 }
1300 
1302  return GETVALUEWITHMASK(HasVMXInstructionMask);
1303 }
1304 #undef GETVALUEWITHMASK
1305 #undef GETVALUEWITHMASKSHIFT
1306 
1308  uint64_t &Size) {
1309  Error Err = Error::success();
1310  XCOFFTracebackTable TBT(Ptr, Size, Err);
1311  if (Err)
1312  return std::move(Err);
1313  return TBT;
1314 }
1315 
1316 XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
1317  Error &Err)
1318  : TBPtr(Ptr) {
1319  ErrorAsOutParameter EAO(&Err);
1320  DataExtractor DE(ArrayRef<uint8_t>(Ptr, Size), /*IsLittleEndian=*/false,
1321  /*AddressSize=*/0);
1322  DataExtractor::Cursor Cur(/*Offset=*/0);
1323 
1324  // Skip 8 bytes of mandatory fields.
1325  DE.getU64(Cur);
1326 
1327  unsigned FixedParmsNum = getNumberOfFixedParms();
1328  unsigned FloatingParmsNum = getNumberOfFPParms();
1329  uint32_t ParamsTypeValue = 0;
1330 
1331  // Begin to parse optional fields.
1332  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
1333  ParamsTypeValue = DE.getU32(Cur);
1334 
1335  if (Cur && hasTraceBackTableOffset())
1336  TraceBackTableOffset = DE.getU32(Cur);
1337 
1338  if (Cur && isInterruptHandler())
1339  HandlerMask = DE.getU32(Cur);
1340 
1341  if (Cur && hasControlledStorage()) {
1342  NumOfCtlAnchors = DE.getU32(Cur);
1343  if (Cur && NumOfCtlAnchors) {
1345  Disp.reserve(NumOfCtlAnchors.getValue());
1346  for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
1347  Disp.push_back(DE.getU32(Cur));
1348  if (Cur)
1349  ControlledStorageInfoDisp = std::move(Disp);
1350  }
1351  }
1352 
1353  if (Cur && isFuncNamePresent()) {
1354  uint16_t FunctionNameLen = DE.getU16(Cur);
1355  if (Cur)
1356  FunctionName = DE.getBytes(Cur, FunctionNameLen);
1357  }
1358 
1359  if (Cur && isAllocaUsed())
1360  AllocaRegister = DE.getU8(Cur);
1361 
1362  unsigned VectorParmsNum = 0;
1363  if (Cur && hasVectorInfo()) {
1364  StringRef VectorExtRef = DE.getBytes(Cur, 6);
1365  if (Cur) {
1366  Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
1367  if (!TBVecExtOrErr) {
1368  Err = TBVecExtOrErr.takeError();
1369  return;
1370  }
1371  VecExt = TBVecExtOrErr.get();
1372  VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
1373  }
1374  }
1375 
1376  // As long as there is no fixed-point or floating-point parameter, this
1377  // field remains not present even when hasVectorInfo gives true and
1378  // indicates the presence of vector parameters.
1379  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
1380  Expected<SmallString<32>> ParmsTypeOrError =
1381  hasVectorInfo()
1382  ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
1383  FloatingParmsNum, VectorParmsNum)
1384  : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
1385 
1386  if (!ParmsTypeOrError) {
1387  Err = ParmsTypeOrError.takeError();
1388  return;
1389  }
1390  ParmsType = ParmsTypeOrError.get();
1391  }
1392 
1393  if (Cur && hasExtensionTable())
1394  ExtensionTable = DE.getU8(Cur);
1395 
1396  if (!Cur)
1397  Err = Cur.takeError();
1398 
1399  Size = Cur.tell();
1400 }
1401 
1402 #define GETBITWITHMASK(P, X) \
1403  (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
1404 #define GETBITWITHMASKSHIFT(P, X, S) \
1405  ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >> \
1406  (TracebackTable::S))
1407 
1409  return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
1410 }
1411 
1413  return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
1414 }
1415 
1417  return GETBITWITHMASK(0, IsGlobaLinkageMask);
1418 }
1419 
1421  return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
1422 }
1423 
1425  return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
1426 }
1427 
1429  return GETBITWITHMASK(0, IsInternalProcedureMask);
1430 }
1431 
1433  return GETBITWITHMASK(0, HasControlledStorageMask);
1434 }
1435 
1437  return GETBITWITHMASK(0, IsTOClessMask);
1438 }
1439 
1441  return GETBITWITHMASK(0, IsFloatingPointPresentMask);
1442 }
1443 
1445  return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
1446 }
1447 
1449  return GETBITWITHMASK(0, IsInterruptHandlerMask);
1450 }
1451 
1453  return GETBITWITHMASK(0, IsFunctionNamePresentMask);
1454 }
1455 
1457  return GETBITWITHMASK(0, IsAllocaUsedMask);
1458 }
1459 
1461  return GETBITWITHMASKSHIFT(0, OnConditionDirectiveMask,
1462  OnConditionDirectiveShift);
1463 }
1464 
1466  return GETBITWITHMASK(0, IsCRSavedMask);
1467 }
1468 
1470  return GETBITWITHMASK(0, IsLRSavedMask);
1471 }
1472 
1474  return GETBITWITHMASK(4, IsBackChainStoredMask);
1475 }
1476 
1478  return GETBITWITHMASK(4, IsFixupMask);
1479 }
1480 
1482  return GETBITWITHMASKSHIFT(4, FPRSavedMask, FPRSavedShift);
1483 }
1484 
1486  return GETBITWITHMASK(4, HasExtensionTableMask);
1487 }
1488 
1490  return GETBITWITHMASK(4, HasVectorInfoMask);
1491 }
1492 
1494  return GETBITWITHMASKSHIFT(4, GPRSavedMask, GPRSavedShift);
1495 }
1496 
1498  return GETBITWITHMASKSHIFT(4, NumberOfFixedParmsMask,
1499  NumberOfFixedParmsShift);
1500 }
1501 
1503  return GETBITWITHMASKSHIFT(4, NumberOfFloatingPointParmsMask,
1504  NumberOfFloatingPointParmsShift);
1505 }
1506 
1508  return GETBITWITHMASK(4, HasParmsOnStackMask);
1509 }
1510 
1511 #undef GETBITWITHMASK
1512 #undef GETBITWITHMASKSHIFT
1513 } // namespace object
1514 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:76
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
llvm::object::XCOFFTracebackTable::isTOCless
bool isTOCless() const
Definition: XCOFFObjectFile.cpp:1436
llvm::object::XCOFFTracebackTable::isInterruptHandler
bool isInterruptHandler() const
Definition: XCOFFObjectFile.cpp:1448
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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:171
llvm::object::XCOFFTracebackTable::hasParmsOnStack
bool hasParmsOnStack() const
Definition: XCOFFObjectFile.cpp:1507
llvm::object::XCOFFSymbolRef::getXCOFFCsectAuxRef
Expected< XCOFFCsectAuxRef > getXCOFFCsectAuxRef() const
Definition: XCOFFObjectFile.cpp:1174
llvm::object::TBVectorExt::hasVarArgs
bool hasVarArgs() const
Definition: XCOFFObjectFile.cpp:1292
llvm::object::XCOFFSymbolRef::getName
Expected< StringRef > getName() const
Definition: XCOFFObjectFile.cpp:1217
llvm::object::XCOFFObjectFile::getSymbolIndex
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const
Definition: XCOFFObjectFile.cpp:835
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:183
is64Bit
static bool is64Bit(const char *name)
Definition: X86Disassembler.cpp:1019
llvm::XCOFF::STYP_BSS
@ STYP_BSS
Definition: XCOFF.h:123
llvm::SmallVector< uint32_t, 8 >
llvm::object::XCOFFRelocation::VirtualAddress
AddressType VirtualAddress
Definition: XCOFFObjectFile.h:421
llvm::XCOFF::C_FILE
@ C_FILE
Definition: XCOFF.h:156
llvm::object::XCOFFTracebackTable::isFloatingPointPresent
bool isFloatingPointPresent() const
Definition: XCOFFObjectFile.cpp:1440
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:1408
llvm::XCOFF::XMC_PR
@ XMC_PR
Program Code.
Definition: XCOFF.h:89
llvm::object::XCOFFTracebackTable::isBackChainStored
bool isBackChainStored() const
Definition: XCOFFObjectFile.cpp:1473
llvm::object::LoaderSectionHeader64::OffsetToImpid
support::big64_t OffsetToImpid
Definition: XCOFFObjectFile.h:216
llvm::object::XCOFFSectionHeader
Definition: XCOFFObjectFile.h:152
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:76
llvm::object::XCOFFObjectFile::is64Bit
bool is64Bit() const
Definition: XCOFFObjectFile.cpp:708
llvm::object::XCOFFTracebackTable::isOutOfLineEpilogOrPrologue
bool isOutOfLineEpilogOrPrologue() const
Definition: XCOFFObjectFile.cpp:1420
llvm::XCOFF::NEW_XCOFF_INTERPRET
@ NEW_XCOFF_INTERPRET
Definition: XCOFF.h:59
llvm::object::XCOFFAuxiliaryHeader64
Definition: XCOFFObjectFile.h:119
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:441
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
llvm::object::XCOFFFileAuxEnt::NameInStrTblType::Magic
support::big32_t Magic
Definition: XCOFFObjectFile.h:334
llvm::Triple::ppc
@ ppc
Definition: Triple.h:69
llvm::object::TBVectorExt::hasVMXInstruction
bool hasVMXInstruction() const
Definition: XCOFFObjectFile.cpp:1301
T
#define T
Definition: Mips16ISelLowering.cpp:341
GETBITWITHMASKSHIFT
#define GETBITWITHMASKSHIFT(P, X, S)
Definition: XCOFFObjectFile.cpp:1404
llvm::object::XCOFFFileAuxEnt::Name
char Name[XCOFF::NameSize+XCOFF::FileNamePadSize]
Definition: XCOFFObjectFile.h:339
llvm::RawInstrProf::getMagic
uint64_t getMagic()
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::support::endian::read32be
uint32_t read32be(const void *P)
Definition: Endian.h:384
llvm::XCOFF::STYP_LOADER
@ STYP_LOADER
Definition: XCOFF.h:128
llvm::object::XCOFFSymbolRef::getNumberOfAuxEntries
uint8_t getNumberOfAuxEntries() const
Definition: XCOFFObjectFile.h:723
llvm::object::XCOFFFileHeader64
Definition: XCOFFObjectFile.h:40
llvm::object::LoaderSectionHeader64::LengthOfImpidStrTbl
support::ubig32_t LengthOfImpidStrTbl
Definition: XCOFFObjectFile.h:213
llvm::object::XCOFFCsectAuxRef::getSymbolType
uint8_t getSymbolType() const
Definition: XCOFFObjectFile.h:300
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:263
llvm::object::XCOFFSymbolRef::isFunction
bool isFunction() const
Definition: XCOFFObjectFile.cpp:1130
llvm::XCOFF::STYP_DWARF
@ STYP_DWARF
Definition: XCOFF.h:120
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:161
llvm::object::XCOFFCsectAuxRef
Definition: XCOFFObjectFile.h:249
llvm::object::XCOFFObjectFile::getImportFileTable
Expected< StringRef > getImportFileTable() const
Definition: XCOFFObjectFile.cpp:999
llvm::object::XCOFFSymbolRef
Definition: XCOFFObjectFile.h:677
llvm::object::XCOFFSectionHeader32::VirtualAddress
support::ubig32_t VirtualAddress
Definition: XCOFFObjectFile.h:174
llvm::object::XCOFFObjectFile::getSectionByNum
Expected< DataRefImpl > getSectionByNum(int16_t Num) const
Definition: XCOFFObjectFile.cpp:729
getSectionFlags
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
Definition: MachOObjectFile.cpp:179
llvm::object::XCOFFTracebackTable::isFuncNamePresent
bool isFuncNamePresent() const
Definition: XCOFFObjectFile.cpp:1452
llvm::Intrinsic::getType
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
Definition: Function.cpp:1366
llvm::object::XCOFFTracebackTable::getNumOfGPRsSaved
uint8_t getNumOfGPRsSaved() const
Definition: XCOFFObjectFile.cpp:1493
llvm::XCOFF::N_ABS
@ N_ABS
Definition: XCOFF.h:42
SubtargetFeature.h
llvm::object::XCOFFFileAuxEnt::NameInStrTblType::Offset
support::ubig32_t Offset
Definition: XCOFFObjectFile.h:335
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:1256
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:208
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::object::TBVectorExt::getNumberOfVectorParms
uint8_t getNumberOfVectorParms() const
Definition: XCOFFObjectFile.cpp:1296
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:1477
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:183
llvm::object::Binary::ID_XCOFF32
@ ID_XCOFF32
Definition: Binary.h:57
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:188
llvm::Triple::ppc64
@ ppc64
Definition: Triple.h:71
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::object::XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC
@ NAME_IN_STR_TBL_MAGIC
Definition: XCOFFObjectFile.h:679
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1097
llvm::XCOFF::VISIBILITY_MASK
constexpr uint16_t VISIBILITY_MASK
Definition: XCOFF.h:243
llvm::object::object_error::parse_failed
@ parse_failed
llvm::object::XCOFFTracebackTable::isGlobalLinkage
bool isGlobalLinkage() const
Definition: XCOFFObjectFile.cpp:1416
llvm::object::DataRefImpl::p
uintptr_t p
Definition: SymbolicFile.h:41
llvm::object::XCOFFObjectFile::getSectionFlags
int32_t getSectionFlags(DataRefImpl Sec) const
Definition: XCOFFObjectFile.cpp:891
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::XCOFF::XTY_SD
@ XTY_SD
Csect definition for initialized storage.
Definition: XCOFF.h:226
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:937
llvm::object::XCOFFRelocation::Type
XCOFF::RelocationType Type
Definition: XCOFFObjectFile.h:427
llvm::object::LoaderSectionHeader32
Definition: XCOFFObjectFile.h:198
llvm::object::XCOFFCsectAuxRef::isLabel
bool isLabel() const
Definition: XCOFFObjectFile.h:304
llvm::XCOFF::C_EXT
@ C_EXT
Definition: XCOFF.h:182
llvm::object::XCOFFTracebackTable::isLRSaved
bool isLRSaved() const
Definition: XCOFFObjectFile.cpp:1469
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:820
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:80
llvm::object::XCOFFTracebackTable::isCRSaved
bool isCRSaved() const
Definition: XCOFFObjectFile.cpp:1465
llvm::object::XCOFFCsectAuxRef::getStorageMappingClass
XCOFF::StorageMappingClass getStorageMappingClass() const
Definition: XCOFFObjectFile.h:286
llvm::object::XCOFFSymbolEntry32::NameInStrTblType::Offset
support::ubig32_t Offset
Definition: XCOFFObjectFile.h:643
llvm::XCOFF::STYP_TDATA
@ STYP_TDATA
Definition: XCOFF.h:126
llvm::XCOFF::StorageClass
StorageClass
Definition: XCOFF.h:154
llvm::object::TBVectorExt::create
static Expected< TBVectorExt > create(StringRef TBvectorStrRef)
Definition: XCOFFObjectFile.cpp:1260
llvm::object::LoaderSectionHeader64
Definition: XCOFFObjectFile.h:209
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::XCOFF::SYM_V_EXPORTED
@ SYM_V_EXPORTED
Definition: XCOFF.h:240
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:665
llvm::object::XCOFFTracebackTable::getNumberOfFPParms
uint8_t getNumberOfFPParms() const
Definition: XCOFFObjectFile.cpp:1502
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
uint64_t
llvm::object::object_error::string_table_non_null_end
@ string_table_non_null_end
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:130
getSymbolType
static std::unique_ptr< PDBSymbol > getSymbolType(const PDBSymbol &Symbol)
Definition: UDTLayout.cpp:36
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:131
llvm::XCOFF::XTY_CM
@ XTY_CM
Common csect definition. For uninitialized storage.
Definition: XCOFF.h:229
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
llvm::object::Binary::ID_XCOFF64
@ ID_XCOFF64
Definition: Binary.h:58
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::COFF::SectionSize
@ SectionSize
Definition: COFF.h:60
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:919
llvm::object::XCOFFTracebackTable::hasTraceBackTableOffset
bool hasTraceBackTableOffset() const
Definition: XCOFFObjectFile.cpp:1424
llvm::XCOFF::C_HIDEXT
@ C_HIDEXT
Definition: XCOFF.h:190
llvm::object::TBVectorExt
Definition: XCOFFObjectFile.h:743
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Optional::getValue
constexpr const T & getValue() const &
Definition: Optional.h:279
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:69
llvm::object::XCOFFSymbolRef::getSectionNumber
int16_t getSectionNumber() const
Definition: XCOFFObjectFile.h:705
llvm::object::ObjectFile::base
const uint8_t * base() const
Definition: ObjectFile.h:234
llvm::object::XCOFFStringTable
Definition: XCOFFObjectFile.h:223
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:1125
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:47
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:721
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
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:1307
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::object::XCOFFTracebackTable::hasControlledStorage
bool hasControlledStorage() const
Definition: XCOFFObjectFile.cpp:1432
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:183
llvm::object::XCOFFRelocation::SymbolIndex
support::ubig32_t SymbolIndex
Definition: XCOFFObjectFile.h:422
uint32_t
llvm::object::XCOFFObjectFile::sections32
ArrayRef< XCOFFSectionHeader32 > sections32() const
Definition: XCOFFObjectFile.cpp:907
llvm::object::XCOFFAuxiliaryHeader32
Definition: XCOFFObjectFile.h:72
llvm::object::DataRefImpl
Definition: SymbolicFile.h:35
llvm::object::LoaderSectionHeader32::OffsetToImpid
support::big32_t OffsetToImpid
Definition: XCOFFObjectFile.h:204
llvm::XCOFF::SymbolAuxType
SymbolAuxType
Definition: XCOFF.h:325
llvm::object::XCOFFFileAuxEnt::NameInStrTbl
NameInStrTblType NameInStrTbl
Definition: XCOFFObjectFile.h:340
llvm::object::TBVectorExt::getNumberOfVRSaved
uint8_t getNumberOfVRSaved() const
Definition: XCOFFObjectFile.cpp:1284
llvm::object::XCOFFObjectFile::getSymbolAuxType
const XCOFF::SymbolAuxType * getSymbolAuxType(uintptr_t AuxEntryAddress) const
Definition: XCOFFObjectFile.cpp:96
llvm::XCOFF::SYM_V_HIDDEN
@ SYM_V_HIDDEN
Definition: XCOFF.h:238
llvm::XCOFF::N_UNDEF
@ N_UNDEF
Definition: XCOFF.h:42
llvm::object::XCOFFObjectFile::sections64
ArrayRef< XCOFFSectionHeader64 > sections64() const
Definition: XCOFFObjectFile.cpp:900
llvm::object::SymbolAuxTypeOffset
static const size_t SymbolAuxTypeOffset
Definition: XCOFFObjectFile.cpp:28
GETBITWITHMASK
#define GETBITWITHMASK(P, X)
Definition: XCOFFObjectFile.cpp:1402
llvm::object::XCOFFObjectFile::getNumberOfSections
uint16_t getNumberOfSections() const
Definition: XCOFFObjectFile.cpp:770
llvm::object::XCOFFTracebackTable::isAllocaUsed
bool isAllocaUsed() const
Definition: XCOFFObjectFile.cpp:1456
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
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:175
uint16_t
getFlags
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:27
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition: DWARFUnitIndex.h:67
llvm::XCOFF::STYP_DEBUG
@ STYP_DEBUG
Definition: XCOFF.h:129
llvm::object::XCOFFTracebackTable::getNumberOfFixedParms
uint8_t getNumberOfFixedParms() const
Definition: XCOFFObjectFile.cpp:1497
llvm::object::XCOFFTracebackTable::hasExtensionTable
bool hasExtensionTable() const
Definition: XCOFFObjectFile.cpp:1485
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:1428
DataExtractor.h
llvm::object::XCOFFTracebackTable::getNumOfFPRsSaved
uint8_t getNumOfFPRsSaved() const
Definition: XCOFFObjectFile.cpp:1481
llvm::XCOFF::AUX_CSECT
@ AUX_CSECT
Identifies a csect auxiliary entry.
Definition: XCOFF.h:330
StringSwitch.h
isDebugSection
static bool isDebugSection(const SectionBase &Sec)
Definition: ELFObjcopy.cpp:55
llvm::object::XCOFFRelocation32
Definition: XCOFFObjectFile.h:440
llvm::XCOFF::getRelocationTypeString
StringRef getRelocationTypeString(XCOFF::RelocationType Type)
Definition: XCOFF.cpp:53
llvm::object::XCOFFSectionHeader64::VirtualAddress
support::ubig64_t VirtualAddress
Definition: XCOFFObjectFile.h:187
llvm::object::TBVectorExt::isVRSavedOnStack
bool isVRSavedOnStack() const
Definition: XCOFFObjectFile.cpp:1288
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
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:184
llvm::object::XCOFFSymbolEntry32::SymbolName
char SymbolName[XCOFF::NameSize]
Definition: XCOFFObjectFile.h:647
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::object::XCOFFTracebackTable::getOnConditionDirective
uint8_t getOnConditionDirective() const
Definition: XCOFFObjectFile.cpp:1460
llvm::XCOFF::STYP_DATA
@ STYP_DATA
Definition: XCOFF.h:122
getSymbolSectionID
static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym)
Definition: SymbolSize.cpp:39
GETVALUEWITHMASKSHIFT
#define GETVALUEWITHMASKSHIFT(X, S)
Definition: XCOFFObjectFile.cpp:1257
llvm::COFF::isReservedSectionNumber
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: COFF.h:729
llvm::XCOFF::STYP_TEXT
@ STYP_TEXT
Definition: XCOFF.h:121
llvm::object::XCOFFTracebackTable::isFloatingPointOperationLogOrAbortEnabled
bool isFloatingPointOperationLogOrAbortEnabled() const
Definition: XCOFFObjectFile.cpp:1444
llvm::object::XCOFFSymbolRef::isCsectSymbol
bool isCsectSymbol() const
Definition: XCOFFObjectFile.cpp:1168
llvm::object::XCOFFObjectFile
Definition: XCOFFObjectFile.h:445
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::object::XCOFFTracebackTable
This class provides methods to extract traceback table data from a buffer.
Definition: XCOFFObjectFile.h:762
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:707
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:167
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:44
llvm::object::XCOFFSymbolRef::getEntryAddress
uintptr_t getEntryAddress() const
Definition: XCOFFObjectFile.h:727
llvm::XCOFF::RelocationSerializationSize32
constexpr size_t RelocationSerializationSize32
Definition: XCOFF.h:37
llvm::XCOFF::STYP_TBSS
@ STYP_TBSS
Definition: XCOFF.h:127
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:51
getSymbolName
static StringRef getSymbolName(SymbolKind SymKind)
Definition: CodeViewDebug.cpp:3108
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:644
llvm::object::XCOFFSymbolEntry32::NameInStrTbl
NameInStrTblType NameInStrTbl
Definition: XCOFFObjectFile.h:648
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::object::XCOFFFileAuxEnt
Definition: XCOFFObjectFile.h:332
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:143
llvm::object::XCOFFRelocation
Definition: XCOFFObjectFile.h:405
llvm::object::doesXCOFFTracebackTableBegin
bool doesXCOFFTracebackTableBegin(ArrayRef< uint8_t > Bytes)
Definition: XCOFFObjectFile.cpp:1249
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::object::XCOFFTracebackTable::hasVectorInfo
bool hasVectorInfo() const
Definition: XCOFFObjectFile.cpp:1489
Shdr
Elf_Shdr Shdr
Definition: ELFObjHandler.cpp:77
llvm::object::LoaderSectionHeader32::LengthOfImpidStrTbl
support::ubig32_t LengthOfImpidStrTbl
Definition: XCOFFObjectFile.h:202
llvm::object::XCOFFSymbolEntry32::NameInStrTblType::Magic
support::big32_t Magic
Definition: XCOFFObjectFile.h:642
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:1412