diff options
author | Jacek Caban <jacek@codeweavers.com> | 2024-08-09 15:55:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-09 15:55:28 +0200 |
commit | 1d77dd50f1bab20d2025d25f79784d5be1520847 (patch) | |
tree | 4fc063bf23f7dcb46fdbc4c631d44f71cb3fe2b2 /llvm/lib/Object/COFFObjectFile.cpp | |
parent | cf54cae26b65fc3201eff7200ffb9b0c9e8f9a13 (diff) | |
download | llvm-1d77dd50f1bab20d2025d25f79784d5be1520847.zip llvm-1d77dd50f1bab20d2025d25f79784d5be1520847.tar.gz llvm-1d77dd50f1bab20d2025d25f79784d5be1520847.tar.bz2 |
[llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (#102245)
Diffstat (limited to 'llvm/lib/Object/COFFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 64b5eaf..ff7129b 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -1489,6 +1489,54 @@ StringRef COFFObjectFile::mapDebugSectionName(StringRef Name) const { .Default(Name); } +std::unique_ptr<MemoryBuffer> COFFObjectFile::getHybridObjectView() const { + if (getMachine() != COFF::IMAGE_FILE_MACHINE_ARM64X) + return nullptr; + + std::unique_ptr<WritableMemoryBuffer> HybridView; + + for (auto DynReloc : dynamic_relocs()) { + if (DynReloc.getType() != COFF::IMAGE_DYNAMIC_RELOCATION_ARM64X) + continue; + + for (auto reloc : DynReloc.arm64x_relocs()) { + if (!HybridView) { + HybridView = + WritableMemoryBuffer::getNewUninitMemBuffer(Data.getBufferSize()); + memcpy(HybridView->getBufferStart(), Data.getBufferStart(), + Data.getBufferSize()); + } + + uint32_t RVA = reloc.getRVA(); + void *Ptr; + uintptr_t IntPtr; + if (RVA & ~0xfff) { + cantFail(getRvaPtr(RVA, IntPtr)); + Ptr = HybridView->getBufferStart() + IntPtr - + reinterpret_cast<uintptr_t>(base()); + } else { + // PE header relocation. + Ptr = HybridView->getBufferStart() + RVA; + } + + switch (reloc.getType()) { + case COFF::IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL: + memset(Ptr, 0, reloc.getSize()); + break; + case COFF::IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE: { + auto Value = static_cast<ulittle64_t>(reloc.getValue()); + memcpy(Ptr, &Value, reloc.getSize()); + break; + } + case COFF::IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA: + *reinterpret_cast<ulittle32_t *>(Ptr) += reloc.getValue(); + break; + } + } + } + return HybridView; +} + bool ImportDirectoryEntryRef:: operator==(const ImportDirectoryEntryRef &Other) const { return ImportTable == Other.ImportTable && Index == Other.Index; |