+class LoadedELFObjectInfo : public RuntimeDyld::LoadedObjectInfo {
+public:
+ LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
+ unsigned EndIdx)
+ : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
+
+ OwningBinary<ObjectFile>
+ getObjectForDebug(const ObjectFile &Obj) const override;
+};
+
+template <typename ELFT>
+std::unique_ptr<DyldELFObject<ELFT>>
+createRTDyldELFObject(MemoryBufferRef Buffer,
+ const LoadedELFObjectInfo &L,
+ std::error_code &ec) {
+ typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+ typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
+
+ std::unique_ptr<DyldELFObject<ELFT>> Obj =
+ llvm::make_unique<DyldELFObject<ELFT>>(Buffer, ec);
+
+ // Iterate over all sections in the object.
+ for (const auto &Sec : Obj->sections()) {
+ StringRef SectionName;
+ Sec.getName(SectionName);
+ if (SectionName != "") {
+ DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
+ Elf_Shdr *shdr = const_cast<Elf_Shdr *>(
+ reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
+
+ if (uint64_t SecLoadAddr = L.getSectionLoadAddress(SectionName)) {
+ // This assumes that the address passed in matches the target address
+ // bitness. The template-based type cast handles everything else.
+ shdr->sh_addr = static_cast<addr_type>(SecLoadAddr);
+ }
+ }
+ }
+
+ return Obj;
+}
+
+OwningBinary<ObjectFile> createELFDebugObject(const ObjectFile &Obj,
+ const LoadedELFObjectInfo &L) {
+ assert(Obj.isELF() && "Not an ELF object file.");
+
+ std::unique_ptr<MemoryBuffer> Buffer =
+ MemoryBuffer::getMemBufferCopy(Obj.getData(), Obj.getFileName());
+
+ std::error_code ec;
+
+ std::unique_ptr<ObjectFile> DebugObj;
+ if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian()) {
+ typedef ELFType<support::little, 2, false> ELF32LE;
+ DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), L, ec);
+ } else if (Obj.getBytesInAddress() == 4 && !Obj.isLittleEndian()) {
+ typedef ELFType<support::big, 2, false> ELF32BE;
+ DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), L, ec);
+ } else if (Obj.getBytesInAddress() == 8 && !Obj.isLittleEndian()) {
+ typedef ELFType<support::big, 2, true> ELF64BE;
+ DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), L, ec);
+ } else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian()) {
+ typedef ELFType<support::little, 2, true> ELF64LE;
+ DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), L, ec);
+ } else
+ llvm_unreachable("Unexpected ELF format");
+
+ assert(!ec && "Could not construct copy ELF object file");
+
+ return OwningBinary<ObjectFile>(std::move(DebugObj), std::move(Buffer));
+}
+
+OwningBinary<ObjectFile>
+LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const {
+ return createELFDebugObject(Obj, *this);
+}
+