LLVM  10.0.0svn
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 <cstddef>
15 #include <cstring>
16 
17 namespace llvm {
18 namespace object {
19 
20 enum { FUNCTION_SYM = 0x20, SYM_TYPE_MASK = 0x07, RELOC_OVERFLOW = 65535 };
21 
22 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
23 // 'M'. Returns a pointer to the underlying object on success.
24 template <typename T>
25 static Expected<const T *> getObject(MemoryBufferRef M, const void *Ptr,
26  const uint64_t Size = sizeof(T)) {
27  uintptr_t Addr = uintptr_t(Ptr);
28  if (std::error_code EC = Binary::checkOffset(M, Addr, Size))
29  return errorCodeToError(EC);
30  return reinterpret_cast<const T *>(Addr);
31 }
32 
33 static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset) {
34  return reinterpret_cast<uintptr_t>(reinterpret_cast<const char *>(Base) +
35  Offset);
36 }
37 
38 template <typename T> static const T *viewAs(uintptr_t in) {
39  return reinterpret_cast<const T *>(in);
40 }
41 
43  auto NulCharPtr =
44  static_cast<const char *>(memchr(Name, '\0', XCOFF::NameSize));
45  return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
46  : StringRef(Name, XCOFF::NameSize);
47 }
48 
51 }
52 
55 }
56 
58  // The relocation encodes the bit length being relocated minus 1. Add back
59  // the 1 to get the actual length being relocated.
60  return (Info & XR_BIASED_LENGTH_MASK) + 1;
61 }
62 
63 void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
64  uintptr_t TableAddress) const {
65  if (Addr < TableAddress)
66  report_fatal_error("Section header outside of section header table.");
67 
68  uintptr_t Offset = Addr - TableAddress;
69  if (Offset >= getSectionHeaderSize() * getNumberOfSections())
70  report_fatal_error("Section header outside of section header table.");
71 
72  if (Offset % getSectionHeaderSize() != 0)
74  "Section header pointer does not point to a valid section header.");
75 }
76 
78 XCOFFObjectFile::toSection32(DataRefImpl Ref) const {
79  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
80 #ifndef NDEBUG
81  checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
82 #endif
83  return viewAs<XCOFFSectionHeader32>(Ref.p);
84 }
85 
87 XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
88  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
89 #ifndef NDEBUG
90  checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
91 #endif
92  return viewAs<XCOFFSectionHeader64>(Ref.p);
93 }
94 
96  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
97  assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
98 #ifndef NDEBUG
99  checkSymbolEntryPointer(Ref.p);
100 #endif
101  auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
102  return SymEntPtr;
103 }
104 
105 const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
106  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
107  return static_cast<const XCOFFFileHeader32 *>(FileHeader);
108 }
109 
110 const XCOFFFileHeader64 *XCOFFObjectFile::fileHeader64() const {
111  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
112  return static_cast<const XCOFFFileHeader64 *>(FileHeader);
113 }
114 
115 const XCOFFSectionHeader32 *
116 XCOFFObjectFile::sectionHeaderTable32() const {
117  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
118  return static_cast<const XCOFFSectionHeader32 *>(SectionHeaderTable);
119 }
120 
121 const XCOFFSectionHeader64 *
122 XCOFFObjectFile::sectionHeaderTable64() const {
123  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
124  return static_cast<const XCOFFSectionHeader64 *>(SectionHeaderTable);
125 }
126 
128  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
129  SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
130 #ifndef NDEBUG
131  // This function is used by basic_symbol_iterator, which allows to
132  // point to the end-of-symbol-table address.
133  if (reinterpret_cast<uintptr_t>(SymEntPtr) != getEndOfSymbolTableAddress())
134  checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr));
135 #endif
136  Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
137 }
138 
140 XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
141  // The byte offset is relative to the start of the string table.
142  // A byte offset value of 0 is a null or zero-length symbol
143  // name. A byte offset in the range 1 to 3 (inclusive) points into the length
144  // field; as a soft-error recovery mechanism, we treat such cases as having an
145  // offset of 0.
146  if (Offset < 4)
147  return StringRef(nullptr, 0);
148 
149  if (StringTable.Data != nullptr && StringTable.Size > Offset)
150  return (StringTable.Data + Offset);
151 
152  return make_error<GenericBinaryError>("Bad offset for string table entry",
154 }
155 
158  if (CFileEntPtr->NameInStrTbl.Magic !=
160  return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
161  return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
162 }
163 
165  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
166 
167  // A storage class value with the high-order bit on indicates that the name is
168  // a symbolic debugger stabstring.
169  if (SymEntPtr->StorageClass & 0x80)
170  return StringRef("Unimplemented Debug Name");
171 
173  return generateXCOFFFixedNameStringRef(SymEntPtr->SymbolName);
174 
175  return getStringTableEntry(SymEntPtr->NameInStrTbl.Offset);
176 }
177 
179  uint64_t Result = 0;
180  llvm_unreachable("Not yet implemented!");
181  return Result;
182 }
183 
185  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
186  return toSymbolEntry(Symb)->Value;
187 }
188 
190  uint64_t Result = 0;
191  llvm_unreachable("Not yet implemented!");
192  return Result;
193 }
194 
197  llvm_unreachable("Not yet implemented!");
198  return SymbolRef::ST_Other;
199 }
200 
203  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
204  int16_t SectNum = SymEntPtr->SectionNumber;
205 
206  if (isReservedSectionNumber(SectNum))
207  return section_end();
208 
209  Expected<DataRefImpl> ExpSec = getSectionByNum(SectNum);
210  if (!ExpSec)
211  return ExpSec.takeError();
212 
213  return section_iterator(SectionRef(ExpSec.get(), this));
214 }
215 
217  const char *Ptr = reinterpret_cast<const char *>(Sec.p);
218  Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
219 }
220 
222  return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec));
223 }
224 
226  // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
227  // with MSVC.
228  if (is64Bit())
229  return toSection64(Sec)->VirtualAddress;
230 
231  return toSection32(Sec)->VirtualAddress;
232 }
233 
235  // Section numbers in XCOFF are numbered beginning at 1. A section number of
236  // zero is used to indicate that a symbol is being imported or is undefined.
237  if (is64Bit())
238  return toSection64(Sec) - sectionHeaderTable64() + 1;
239  else
240  return toSection32(Sec) - sectionHeaderTable32() + 1;
241 }
242 
244  // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
245  // with MSVC.
246  if (is64Bit())
247  return toSection64(Sec)->SectionSize;
248 
249  return toSection32(Sec)->SectionSize;
250 }
251 
254  llvm_unreachable("Not yet implemented!");
255 }
256 
258  uint64_t Result = 0;
259  llvm_unreachable("Not yet implemented!");
260  return Result;
261 }
262 
264  bool Result = false;
265  llvm_unreachable("Not yet implemented!");
266  return Result;
267 }
268 
270  return getSectionFlags(Sec) & XCOFF::STYP_TEXT;
271 }
272 
274  uint32_t Flags = getSectionFlags(Sec);
275  return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
276 }
277 
279  uint32_t Flags = getSectionFlags(Sec);
280  return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
281 }
282 
284  bool Result = false;
285  llvm_unreachable("Not yet implemented!");
286  return Result;
287 }
288 
290  llvm_unreachable("Not yet implemented!");
292 }
293 
295  llvm_unreachable("Not yet implemented!");
297 }
298 
300  llvm_unreachable("Not yet implemented!");
301  return;
302 }
303 
305  llvm_unreachable("Not yet implemented!");
306  uint64_t Result = 0;
307  return Result;
308 }
309 
311  llvm_unreachable("Not yet implemented!");
312  return symbol_iterator(SymbolRef());
313 }
314 
316  llvm_unreachable("Not yet implemented!");
317  uint64_t Result = 0;
318  return Result;
319 }
320 
322  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
323  llvm_unreachable("Not yet implemented!");
324  return;
325 }
326 
328  uint32_t Result = 0;
329  llvm_unreachable("Not yet implemented!");
330  return Result;
331 }
332 
334  assert(!is64Bit() && "64-bit support not implemented yet.");
335  DataRefImpl SymDRI;
336  SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
337  return basic_symbol_iterator(SymbolRef(SymDRI, this));
338 }
339 
341  assert(!is64Bit() && "64-bit support not implemented yet.");
342  DataRefImpl SymDRI;
343  SymDRI.p = reinterpret_cast<uintptr_t>(
344  SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
345  return basic_symbol_iterator(SymbolRef(SymDRI, this));
346 }
347 
349  DataRefImpl DRI;
350  DRI.p = getSectionHeaderTableAddress();
351  return section_iterator(SectionRef(DRI, this));
352 }
353 
355  DataRefImpl DRI;
356  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
357  getNumberOfSections() * getSectionHeaderSize());
358  return section_iterator(SectionRef(DRI, this));
359 }
360 
361 uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }
362 
364  return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
365 }
366 
368  return is64Bit() ? Triple::ppc64 : Triple::ppc;
369 }
370 
372  llvm_unreachable("Not yet implemented!");
373  return SubtargetFeatures();
374 }
375 
377  bool Result = false;
378  llvm_unreachable("Not yet implemented!");
379  return Result;
380 }
381 
383  // TODO FIXME Should get from auxiliary_header->o_entry when support for the
384  // auxiliary_header is added.
385  return 0;
386 }
387 
388 size_t XCOFFObjectFile::getFileHeaderSize() const {
389  return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
390 }
391 
392 size_t XCOFFObjectFile::getSectionHeaderSize() const {
393  return is64Bit() ? sizeof(XCOFFSectionHeader64) :
394  sizeof(XCOFFSectionHeader32);
395 }
396 
398  return Binary::ID_XCOFF64 == getType();
399 }
400 
401 uint16_t XCOFFObjectFile::getMagic() const {
402  return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
403 }
404 
406  if (Num <= 0 || Num > getNumberOfSections())
408 
409  DataRefImpl DRI;
410  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
411  getSectionHeaderSize() * (Num - 1));
412  return DRI;
413 }
414 
417  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
418  int16_t SectionNum = SymEntPtr->SectionNumber;
419 
420  switch (SectionNum) {
421  case XCOFF::N_DEBUG:
422  return "N_DEBUG";
423  case XCOFF::N_ABS:
424  return "N_ABS";
425  case XCOFF::N_UNDEF:
426  return "N_UNDEF";
427  default:
428  Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
429  if (SecRef)
431  getSectionNameInternal(SecRef.get()));
432  return SecRef.takeError();
433  }
434 }
435 
436 bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
437  return (SectionNumber <= 0 && SectionNumber >= -2);
438 }
439 
441  return is64Bit() ? fileHeader64()->NumberOfSections
442  : fileHeader32()->NumberOfSections;
443 }
444 
446  return is64Bit() ? fileHeader64()->TimeStamp : fileHeader32()->TimeStamp;
447 }
448 
450  return is64Bit() ? fileHeader64()->AuxHeaderSize
451  : fileHeader32()->AuxHeaderSize;
452 }
453 
455  return fileHeader32()->SymbolTableOffset;
456 }
457 
459  // As far as symbol table size is concerned, if this field is negative it is
460  // to be treated as a 0. However since this field is also used for printing we
461  // don't want to truncate any negative values.
462  return fileHeader32()->NumberOfSymTableEntries;
463 }
464 
466  return (fileHeader32()->NumberOfSymTableEntries >= 0
467  ? fileHeader32()->NumberOfSymTableEntries
468  : 0);
469 }
470 
472  return fileHeader64()->SymbolTableOffset;
473 }
474 
476  return fileHeader64()->NumberOfSymTableEntries;
477 }
478 
479 uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
480  uint32_t NumberOfSymTableEntries =
481  is64Bit() ? getNumberOfSymbolTableEntries64()
482  : getLogicalNumberOfSymbolTableEntries32();
483  return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
484  XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
485 }
486 
487 void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
488  if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
489  report_fatal_error("Symbol table entry is outside of symbol table.");
490 
491  if (SymbolEntPtr >= getEndOfSymbolTableAddress())
492  report_fatal_error("Symbol table entry is outside of symbol table.");
493 
494  ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
495  reinterpret_cast<const char *>(SymbolTblPtr);
496 
497  if (Offset % XCOFF::SymbolTableEntrySize != 0)
499  "Symbol table entry position is not valid inside of symbol table.");
500 }
501 
502 uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
503  return (reinterpret_cast<const char *>(SymbolEntPtr) -
504  reinterpret_cast<const char *>(SymbolTblPtr)) /
506 }
507 
510  if (is64Bit())
511  report_fatal_error("64-bit symbol table support not implemented yet.");
512 
513  if (Index >= getLogicalNumberOfSymbolTableEntries32())
515 
516  DataRefImpl SymDRI;
517  SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
518  return getSymbolName(SymDRI);
519 }
520 
521 uint16_t XCOFFObjectFile::getFlags() const {
522  return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
523 }
524 
525 const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
526  return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
527 }
528 
529 uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
530  return reinterpret_cast<uintptr_t>(SectionHeaderTable);
531 }
532 
534  return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
535 }
536 
537 XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
538  : ObjectFile(Type, Object) {
539  assert(Type == Binary::ID_XCOFF32 || Type == Binary::ID_XCOFF64);
540 }
541 
543  assert(is64Bit() && "64-bit interface called for non 64-bit file.");
544  const XCOFFSectionHeader64 *TablePtr = sectionHeaderTable64();
545  return ArrayRef<XCOFFSectionHeader64>(TablePtr,
546  TablePtr + getNumberOfSections());
547 }
548 
550  assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
551  const XCOFFSectionHeader32 *TablePtr = sectionHeaderTable32();
552  return ArrayRef<XCOFFSectionHeader32>(TablePtr,
553  TablePtr + getNumberOfSections());
554 }
555 
556 // In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
557 // section header contains the actual count of relocation entries in the s_paddr
558 // field. STYP_OVRFLO headers contain the section index of their corresponding
559 // sections as their raw "NumberOfRelocations" field value.
561  const XCOFFSectionHeader32 &Sec) const {
562 
563  uint16_t SectionIndex = &Sec - sectionHeaderTable32() + 1;
564 
566  return Sec.NumberOfRelocations;
567  for (const auto &Sec : sections32()) {
568  if (Sec.Flags == XCOFF::STYP_OVRFLO &&
569  Sec.NumberOfRelocations == SectionIndex)
570  return Sec.PhysicalAddress;
571  }
573 }
574 
577  uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
579  auto NumRelocEntriesOrErr = getLogicalNumberOfRelocationEntries(Sec);
580  if (Error E = NumRelocEntriesOrErr.takeError())
581  return std::move(E);
582 
583  uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
584 
585  auto RelocationOrErr =
586  getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
587  NumRelocEntries * sizeof(XCOFFRelocation32));
588  if (Error E = RelocationOrErr.takeError())
589  return std::move(E);
590 
591  const XCOFFRelocation32 *StartReloc = RelocationOrErr.get();
592 
593  return ArrayRef<XCOFFRelocation32>(StartReloc, StartReloc + NumRelocEntries);
594 }
595 
597 XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
598  // If there is a string table, then the buffer must contain at least 4 bytes
599  // for the string table's size. Not having a string table is not an error.
600  if (auto EC = Binary::checkOffset(
601  Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4))
602  return XCOFFStringTable{0, nullptr};
603 
604  // Read the size out of the buffer.
606 
607  // If the size is less then 4, then the string table is just a size and no
608  // string data.
609  if (Size <= 4)
610  return XCOFFStringTable{4, nullptr};
611 
612  auto StringTableOrErr =
613  getObject<char>(Obj->Data, Obj->base() + Offset, Size);
614  if (Error E = StringTableOrErr.takeError())
615  return std::move(E);
616 
617  const char *StringTablePtr = StringTableOrErr.get();
618  if (StringTablePtr[Size - 1] != '\0')
620 
621  return XCOFFStringTable{Size, StringTablePtr};
622 }
623 
625 XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
626  // Can't use std::make_unique because of the private constructor.
627  std::unique_ptr<XCOFFObjectFile> Obj;
628  Obj.reset(new XCOFFObjectFile(Type, MBR));
629 
630  uint64_t CurOffset = 0;
631  const auto *Base = Obj->base();
632  MemoryBufferRef Data = Obj->Data;
633 
634  // Parse file header.
635  auto FileHeaderOrErr =
636  getObject<void>(Data, Base + CurOffset, Obj->getFileHeaderSize());
637  if (Error E = FileHeaderOrErr.takeError())
638  return std::move(E);
639  Obj->FileHeader = FileHeaderOrErr.get();
640 
641  CurOffset += Obj->getFileHeaderSize();
642  // TODO FIXME we don't have support for an optional header yet, so just skip
643  // past it.
644  CurOffset += Obj->getOptionalHeaderSize();
645 
646  // Parse the section header table if it is present.
647  if (Obj->getNumberOfSections()) {
648  auto SecHeadersOrErr = getObject<void>(Data, Base + CurOffset,
649  Obj->getNumberOfSections() *
650  Obj->getSectionHeaderSize());
651  if (Error E = SecHeadersOrErr.takeError())
652  return std::move(E);
653  Obj->SectionHeaderTable = SecHeadersOrErr.get();
654  }
655 
656  // 64-bit object supports only file header and section headers for now.
657  if (Obj->is64Bit())
658  return std::move(Obj);
659 
660  // If there is no symbol table we are done parsing the memory buffer.
661  if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
662  return std::move(Obj);
663 
664  // Parse symbol table.
665  CurOffset = Obj->fileHeader32()->SymbolTableOffset;
666  uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
667  Obj->getLogicalNumberOfSymbolTableEntries32();
668  auto SymTableOrErr =
669  getObject<XCOFFSymbolEntry>(Data, Base + CurOffset, SymbolTableSize);
670  if (Error E = SymTableOrErr.takeError())
671  return std::move(E);
672  Obj->SymbolTblPtr = SymTableOrErr.get();
673  CurOffset += SymbolTableSize;
674 
675  // Parse String table.
676  Expected<XCOFFStringTable> StringTableOrErr =
677  parseStringTable(Obj.get(), CurOffset);
678  if (Error E = StringTableOrErr.takeError())
679  return std::move(E);
680  Obj->StringTable = StringTableOrErr.get();
681 
682  return std::move(Obj);
683 }
684 
687  unsigned FileType) {
688  return XCOFFObjectFile::create(FileType, MemBufRef);
689 }
690 
693 }
694 
697 }
698 
700  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
701 }
702 
704  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
705 }
706 
708  assert(!OwningObjectPtr->is64Bit() &&
709  "32-bit interface called on 64-bit object file.");
710  assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
711 
712  // In XCOFF32, the csect auxilliary entry is always the last auxiliary
713  // entry for the symbol.
714  uintptr_t AuxAddr = getWithOffset(
715  SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
716 
717 #ifndef NDEBUG
718  OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
719 #endif
720 
721  return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
722 }
723 
724 uint16_t XCOFFSymbolRef::getType() const {
725  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
726 }
727 
729  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
730 }
731 
733  XCOFF::StorageClass SC = getStorageClass();
734  return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
735  SC == XCOFF::C_HIDEXT);
736 }
737 
739  if (OwningObjectPtr->is64Bit())
740  report_fatal_error("64-bit support is unimplemented yet.");
741 
742  if (getType() & FUNCTION_SYM)
743  return true;
744 
745  if (!hasCsectAuxEnt())
746  return false;
747 
748  const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
749 
750  // A function definition should be a label definition.
751  if ((CsectAuxEnt->SymbolAlignmentAndType & SYM_TYPE_MASK) != XCOFF::XTY_LD)
752  return false;
753 
754  if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
755  return false;
756 
757  int16_t SectNum = getSectionNumber();
758  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
759  if (!SI)
760  return false;
761 
762  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
763 }
764 
765 } // namespace object
766 } // namespace llvm
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
Expected< StringRef > getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const
uint64_t getRelocationType(DataRefImpl Rel) const override
bool isSectionData(DataRefImpl Sec) const override
void moveRelocationNext(DataRefImpl &Rel) const override
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static constexpr uint8_t XR_BIASED_LENGTH_MASK
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
basic_symbol_iterator symbol_end() const override
static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
Definition: Binary.h:163
XCOFF::StorageMappingClass StorageMappingClass
This class is the base class for all object file types.
Definition: ObjectFile.h:221
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
const uint8_t * base() const
Definition: ObjectFile.h:227
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
Expected< uint64_t > getStartAddress() const override
static Expected< std::unique_ptr< ObjectFile > > createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType)
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
uint32_t getSymbolFlags(DataRefImpl Symb) const override
ArrayRef< XCOFFSectionHeader64 > sections64() const
void moveSectionNext(DataRefImpl &Sec) const override
relocation_iterator section_rel_end(DataRefImpl Sec) const override
uint32_t getLogicalNumberOfSymbolTableEntries32() const
uint32_t read32be(const void *P)
Definition: Endian.h:386
const XCOFFSymbolEntry * toSymbolEntry(DataRefImpl Ref) const
static StringRef getSymbolName(SymbolKind SymKind)
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:52
static Expected< const T * > getObject(MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
The access may reference the value stored in memory.
uint64_t getRelocationOffset(DataRefImpl Rel) const override
static constexpr uint8_t XR_FIXUP_INDICATOR_MASK
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
section_iterator section_begin() const override
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: COFF.h:722
int32_t getRawNumberOfSymbolTableEntries32() const
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:48
StorageClass
Definition: XCOFF.h:76
char SymbolName[XCOFF::NameSize]
uint16_t getOptionalHeaderSize() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
Expected< uint32_t > getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32 &Sec) const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
SubtargetFeatures getFeatures() const override
uint64_t getSectionAlignment(DataRefImpl Sec) const override
support::ubig32_t FileOffsetToRelocationInfo
void moveSymbolNext(DataRefImpl &Symb) const override
Program Code.
Definition: XCOFF.h:30
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
uint64_t getSectionAddress(DataRefImpl Sec) const override
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
int32_t getSectionFlags(DataRefImpl Sec) const
static bool is64Bit(const char *name)
uint32_t getNumberOfSymbolTableEntries64() const
bool isSectionText(DataRefImpl Sec) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const
Label definition.
Definition: XCOFF.h:146
Triple::ArchType getArch() const override
XCOFF::StorageClass StorageClass
basic_symbol_iterator symbol_begin() const override
static constexpr uint8_t XR_SIGN_INDICATOR_MASK
const XCOFFCsectAuxEnt32 * getXCOFFCsectAuxEnt32() const
static wasm::ValType getType(const TargetRegisterClass *RC)
static const T * viewAs(uintptr_t in)
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getSectionSize(DataRefImpl Sec) const override
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
section_iterator section_end() const override
FileType
Defines the file type this file represents.
Definition: InterfaceFile.h:57
XCOFF::StorageClass getStorageClass() const
CHAIN = SC CHAIN, Imm128 - System call.
bool isSectionCompressed(DataRefImpl Sec) const override
reference get()
Returns a reference to the stored T value.
Definition: Error.h:532
bool isSectionBSS(DataRefImpl Sec) const override
Expected< ArrayRef< XCOFFRelocation32 > > relocations(const XCOFFSectionHeader32 &) const
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:138
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
MemoryBufferRef Data
Definition: Binary.h:37
Manages the enabling and disabling of subtarget specific features.
uint64_t getSymbolTableOffset64() const
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: ObjectFile.h:160
Expected< StringRef > getSymbolNameByIndex(uint32_t SymbolTableIndex) const
uint32_t getSymbolTableOffset32() const
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Expected< DataRefImpl > getSectionByNum(int16_t Num) const
uint32_t Size
Definition: Profile.cpp:46
static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset)
uint64_t getSectionIndex(DataRefImpl Sec) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef getFileFormatName() const override
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:77
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Expected< StringRef > getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const
char Name[XCOFF::NameSize+XCOFF::FileNamePadSize]
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const
static StringRef generateXCOFFFixedNameStringRef(const char *Name)
bool isSectionVirtual(DataRefImpl Sec) const override
ArrayRef< XCOFFSectionHeader32 > sections32() const
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81