@@ -2603,7 +2603,9 @@ void RewriteInstance::readRelocations(const SectionRef &Section) {
26032603void RewriteInstance::handleRelocation (const SectionRef &RelocatedSection,
26042604 const RelocationRef &Rel) {
26052605 const bool IsAArch64 = BC->isAArch64 ();
2606+ const bool IsX86 = BC->isX86 ();
26062607 const bool IsFromCode = RelocatedSection.isText ();
2608+ const bool IsWritable = BinarySection (*BC, RelocatedSection).isWritable ();
26072609
26082610 SmallString<16 > TypeName;
26092611 Rel.getTypeName (TypeName);
@@ -2612,15 +2614,15 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
26122614 return ;
26132615
26142616 // Adjust the relocation type as the linker might have skewed it.
2615- if (BC-> isX86 () && (RType & ELF::R_X86_64_converted_reloc_bit)) {
2617+ if (IsX86 && (RType & ELF::R_X86_64_converted_reloc_bit)) {
26162618 if (opts::Verbosity >= 1 )
26172619 dbgs () << " BOLT-WARNING: ignoring R_X86_64_converted_reloc_bit\n " ;
26182620 RType &= ~ELF::R_X86_64_converted_reloc_bit;
26192621 }
26202622
26212623 if (Relocation::isTLS (RType)) {
26222624 // No special handling required for TLS relocations on X86.
2623- if (BC-> isX86 () )
2625+ if (IsX86 )
26242626 return ;
26252627
26262628 // The non-got related TLS relocations on AArch64 and RISC-V also could be
@@ -2661,6 +2663,30 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
26612663 return ;
26622664 }
26632665
2666+ if (!IsFromCode && !IsWritable && (IsX86 || IsAArch64) &&
2667+ Relocation::isPCRelative (RType)) {
2668+ BinaryData *BD = BC->getBinaryDataContainingAddress (Rel.getOffset ());
2669+ if (BD && (BD->nameStartsWith (" _ZTV" ) || // vtable
2670+ BD->nameStartsWith (" _ZTCN" ))) { // construction vtable
2671+ BinaryFunction *BF = BC->getBinaryFunctionContainingAddress (
2672+ SymbolAddress, /* CheckPastEnd*/ false , /* UseMaxSize*/ true );
2673+ if (!BF || BF->getAddress () != SymbolAddress) {
2674+ BC->errs ()
2675+ << " BOLT-ERROR: the virtual function table entry at offset 0x"
2676+ << Twine::utohexstr (Rel.getOffset ());
2677+ if (BF)
2678+ BC->errs () << " points to the middle of a function @ 0x"
2679+ << Twine::utohexstr (BF->getAddress ()) << " \n " ;
2680+ else
2681+ BC->errs () << " does not point to any function\n " ;
2682+ exit (1 );
2683+ }
2684+ BC->addRelocation (Rel.getOffset (), BF->getSymbol (), RType, Addend,
2685+ ExtractedValue);
2686+ return ;
2687+ }
2688+ }
2689+
26642690 const uint64_t Address = SymbolAddress + Addend;
26652691
26662692 LLVM_DEBUG ({
@@ -2724,7 +2750,7 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
27242750 const bool IsToCode = ReferencedSection && ReferencedSection->isText ();
27252751
27262752 // Special handling of PC-relative relocations.
2727- if (BC-> isX86 () && Relocation::isPCRelative (RType)) {
2753+ if (IsX86 && Relocation::isPCRelative (RType)) {
27282754 if (!IsFromCode && IsToCode) {
27292755 // PC-relative relocations from data to code are tricky since the
27302756 // original information is typically lost after linking, even with
0 commit comments