void StackMapJITEventListener::NotifyObjectEmitted(const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &LoadedObj) { std::error_code errorCode; for (const object::SectionRef& section: Obj.sections()) { StringRef name; errorCode = section.getName(name); assert(!errorCode); if (name == ".llvm_stackmaps") { uint64_t stackMapAddress = LoadedObj.getSectionLoadAddress(name); assert(stackMapAddress > 0); uint64_t expectedSize = section.getSize(); // check is made by the callee StackMap *map = parseStackMapFromAddress(stackMapAddress, expectedSize); Maps->push_back(map); } } }
void ObjectLoadListener::recordRelocations( const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) { for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); SI != SE; ++SI) { section_iterator Section = SI->getRelocatedSection(); if (Section == SE) { continue; } StringRef SectionName; std::error_code ErrorCode = Section->getName(SectionName); if (ErrorCode) { assert(false && ErrorCode.message().c_str()); } if (SectionName.startswith(".debug") || SectionName.startswith(".rela.debug") || !SectionName.compare(".pdata") || SectionName.startswith(".eh_frame") || SectionName.startswith(".rela.eh_frame")) { // Skip sections whose contents are not directly reported to the EE continue; } relocation_iterator I = SI->relocation_begin(); relocation_iterator E = SI->relocation_end(); for (; I != E; ++I) { symbol_iterator Symbol = I->getSymbol(); assert(Symbol != Obj.symbol_end()); ErrorOr<section_iterator> SymbolSectionOrErr = Symbol->getSection(); assert(!SymbolSectionOrErr.getError()); object::section_iterator SymbolSection = *SymbolSectionOrErr; const bool IsExtern = SymbolSection == Obj.section_end(); uint64_t RelType = I->getType(); uint64_t Offset = I->getOffset(); uint8_t *RelocationTarget; if (IsExtern) { // This is an external symbol. Verify that it's one we created for // a global variable and report the relocation via Jit interface. ErrorOr<StringRef> NameOrError = Symbol->getName(); assert(NameOrError); StringRef TargetName = NameOrError.get(); auto MapIter = Context->NameToHandleMap.find(TargetName); if (MapIter == Context->NameToHandleMap.end()) { // The xdata gets a pointer to our personality routine, which we // dummied up. We can safely skip it since the EE isn't actually // going to use the value (it inserts the correct one before handing // the xdata off to the OS). assert(!TargetName.compare("ProcessCLRException")); assert(SectionName.startswith(".xdata")); continue; } else { assert(MapIter->second == Context->NameToHandleMap[TargetName]); RelocationTarget = (uint8_t *)MapIter->second; } } else { RelocationTarget = (uint8_t *)(L.getSectionLoadAddress(*SymbolSection) + Symbol->getValue()); } uint64_t Addend = 0; uint64_t EERelType = getRelocationType(RelType); uint64_t SectionAddress = L.getSectionLoadAddress(*Section); assert(SectionAddress != 0); uint8_t *FixupAddress = (uint8_t *)(SectionAddress + Offset); if (Obj.isELF()) { // Addend is part of the relocation ELFRelocationRef ElfReloc(*I); ErrorOr<uint64_t> ElfAddend = ElfReloc.getAddend(); assert(!ElfAddend.getError()); Addend = ElfAddend.get(); } else { // Addend is read from the location to be fixed up Addend = getRelocationAddend(RelType, FixupAddress); } Context->JitInfo->recordRelocation(FixupAddress, RelocationTarget + Addend, EERelType); } } }
void ObjectLoadListener::recordRelocations( const ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &L) { for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); SI != SE; ++SI) { section_iterator Section = SI->getRelocatedSection(); if (Section == SE) { continue; } StringRef SectionName; std::error_code ErrorCode = Section->getName(SectionName); if (ErrorCode) { assert(false && ErrorCode.message().c_str()); } if (SectionName.startswith(".debug") || SectionName.startswith(".rela.debug") || !SectionName.compare(".pdata") || SectionName.startswith(".eh_frame") || SectionName.startswith(".rela.eh_frame")) { // Skip sections whose contents are not directly reported to the EE continue; } relocation_iterator I = SI->relocation_begin(); relocation_iterator E = SI->relocation_end(); for (; I != E; ++I) { symbol_iterator Symbol = I->getSymbol(); assert(Symbol != Obj.symbol_end()); ErrorOr<section_iterator> SymbolSectionOrErr = Symbol->getSection(); assert(!SymbolSectionOrErr.getError()); object::section_iterator SymbolSection = *SymbolSectionOrErr; const bool IsExtern = SymbolSection == Obj.section_end(); uint64_t RelType = I->getType(); uint64_t Offset = I->getOffset(); uint8_t *RelocationTarget = nullptr; if (IsExtern) { // This is an external symbol. Verify that it's one we created for // a global variable and report the relocation via Jit interface. ErrorOr<StringRef> NameOrError = Symbol->getName(); assert(NameOrError); StringRef TargetName = NameOrError.get(); assert(Context->NameToHandleMap.count(TargetName) == 1); RelocationTarget = (uint8_t *)Context->NameToHandleMap[TargetName]; } else { RelocationTarget = (uint8_t *)(L.getSectionLoadAddress(*SymbolSection) + Symbol->getValue()); } uint64_t Addend = 0; uint64_t EERelType = getRelocationType(RelType); uint64_t SectionAddress = L.getSectionLoadAddress(*Section); assert(SectionAddress != 0); uint8_t *FixupAddress = (uint8_t *)(SectionAddress + Offset); if (Obj.isELF()) { // Addend is part of the relocation ELFRelocationRef ElfReloc(*I); ErrorOr<uint64_t> ElfAddend = ElfReloc.getAddend(); assert(!ElfAddend.getError()); Addend = ElfAddend.get(); } else { // Addend is read from the location to be fixed up Addend = getRelocationAddend(RelType, FixupAddress); } Context->JitInfo->recordRelocation(FixupAddress, RelocationTarget + Addend, EERelType); } } }