XCOFFReader.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //===- XCOFFReader.cpp ----------------------------------------------------===//
  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. #include "XCOFFReader.h"
  9. namespace llvm {
  10. namespace objcopy {
  11. namespace xcoff {
  12. using namespace object;
  13. Error XCOFFReader::readSections(Object &Obj) const {
  14. ArrayRef<XCOFFSectionHeader32> Sections = XCOFFObj.sections32();
  15. for (const XCOFFSectionHeader32 &Sec : Sections) {
  16. Section ReadSec;
  17. // Section header.
  18. ReadSec.SectionHeader = Sec;
  19. DataRefImpl SectionDRI;
  20. SectionDRI.p = reinterpret_cast<uintptr_t>(&Sec);
  21. // Section data.
  22. if (Sec.SectionSize) {
  23. Expected<ArrayRef<uint8_t>> ContentsRef =
  24. XCOFFObj.getSectionContents(SectionDRI);
  25. if (!ContentsRef)
  26. return ContentsRef.takeError();
  27. ReadSec.Contents = ContentsRef.get();
  28. }
  29. // Relocations.
  30. if (Sec.NumberOfRelocations) {
  31. auto Relocations =
  32. XCOFFObj.relocations<XCOFFSectionHeader32, XCOFFRelocation32>(Sec);
  33. if (!Relocations)
  34. return Relocations.takeError();
  35. for (const XCOFFRelocation32 &Rel : Relocations.get())
  36. ReadSec.Relocations.push_back(Rel);
  37. }
  38. Obj.Sections.push_back(std::move(ReadSec));
  39. }
  40. return Error::success();
  41. }
  42. Error XCOFFReader::readSymbols(Object &Obj) const {
  43. std::vector<Symbol> Symbols;
  44. Symbols.reserve(XCOFFObj.getNumberOfSymbolTableEntries());
  45. for (SymbolRef Sym : XCOFFObj.symbols()) {
  46. Symbol ReadSym;
  47. DataRefImpl SymbolDRI = Sym.getRawDataRefImpl();
  48. XCOFFSymbolRef SymbolEntRef = XCOFFObj.toSymbolRef(SymbolDRI);
  49. ReadSym.Sym = *SymbolEntRef.getSymbol32();
  50. // Auxiliary entries.
  51. if (SymbolEntRef.getNumberOfAuxEntries()) {
  52. const char *Start = reinterpret_cast<const char *>(
  53. SymbolDRI.p + XCOFF::SymbolTableEntrySize);
  54. Expected<StringRef> RawAuxEntriesOrError = XCOFFObj.getRawData(
  55. Start,
  56. XCOFF::SymbolTableEntrySize * SymbolEntRef.getNumberOfAuxEntries(),
  57. StringRef("symbol"));
  58. if (!RawAuxEntriesOrError)
  59. return RawAuxEntriesOrError.takeError();
  60. ReadSym.AuxSymbolEntries = RawAuxEntriesOrError.get();
  61. }
  62. Obj.Symbols.push_back(std::move(ReadSym));
  63. }
  64. return Error::success();
  65. }
  66. Expected<std::unique_ptr<Object>> XCOFFReader::create() const {
  67. auto Obj = std::make_unique<Object>();
  68. // Only 32-bit supported now.
  69. if (XCOFFObj.is64Bit())
  70. return createStringError(object_error::invalid_file_type,
  71. "64-bit XCOFF is not supported yet");
  72. // Read the file header.
  73. Obj->FileHeader = *XCOFFObj.fileHeader32();
  74. // Read the optional header.
  75. if (XCOFFObj.getOptionalHeaderSize())
  76. Obj->OptionalFileHeader = *XCOFFObj.auxiliaryHeader32();
  77. // Read each section.
  78. Obj->Sections.reserve(XCOFFObj.getNumberOfSections());
  79. if (Error E = readSections(*Obj))
  80. return std::move(E);
  81. // Read each symbol.
  82. Obj->Symbols.reserve(XCOFFObj.getRawNumberOfSymbolTableEntries32());
  83. if (Error E = readSymbols(*Obj))
  84. return std::move(E);
  85. // String table.
  86. Obj->StringTable = XCOFFObj.getStringTable();
  87. return std::move(Obj);
  88. }
  89. } // end namespace xcoff
  90. } // end namespace objcopy
  91. } // end namespace llvm