@@ -61,6 +61,14 @@ template <typename CRTPImpl, size_t PtrSize> struct CompactUnwindTraits {
6161 return support::endian::read32<CRTPImpl::Endianness>(RecordContent.data () +
6262 EncodingFieldOffset);
6363 }
64+
65+ static std::optional<uint32_t > encodeDWARFOffset (size_t Delta) {
66+ uint32_t Encoded =
67+ static_cast <uint32_t >(Delta) & CRTPImpl::DWARFSectionOffsetMask;
68+ if (Encoded != Delta)
69+ return std::nullopt ;
70+ return Encoded;
71+ }
6472};
6573
6674// / Architecture specific implementation of CompactUnwindManager.
@@ -133,19 +141,22 @@ template <typename CURecTraits> class CompactUnwindManager {
133141 << Fn.getName () << " \n " ;
134142 });
135143 continue ;
136- } else {
137- LLVM_DEBUG ({
138- dbgs () << " Found record for function " ;
139- if (Fn.hasName ())
140- dbgs () << Fn.getName ();
141- else
142- dbgs () << " <anon @ " << Fn.getAddress () << ' >' ;
143- dbgs () << ' \n ' ;
144- });
145144 }
146145
147- bool NeedsDWARF = CURecTraits::encodingSpecifiesDWARF (
148- CURecTraits::readEncoding (B->getContent ()));
146+ uint32_t Encoding = CURecTraits::readEncoding (B->getContent ());
147+ bool NeedsDWARF = CURecTraits::encodingSpecifiesDWARF (Encoding);
148+
149+ LLVM_DEBUG ({
150+ dbgs () << " Found record for function " ;
151+ if (Fn.hasName ())
152+ dbgs () << Fn.getName ();
153+ else
154+ dbgs () << " <anon @ " << Fn.getAddress () << ' >' ;
155+ dbgs () << " : encoding = " << formatv (" {0:x}" , Encoding);
156+ if (NeedsDWARF)
157+ dbgs () << " (needs DWARF)" ;
158+ dbgs () << " \n " ;
159+ });
149160
150161 auto &CURecSym =
151162 G.addAnonymousSymbol (*B, 0 , CURecTraits::Size, false , false );
@@ -170,7 +181,7 @@ template <typename CURecTraits> class CompactUnwindManager {
170181 KeepAliveAlreadyPresent = true ;
171182 if (NeedsDWARF) {
172183 LLVM_DEBUG ({
173- dbgs () << " Needs DWARF: adding keep-alive edge to FDE at "
184+ dbgs () << " Adding keep-alive edge to FDE at "
174185 << FDE.getAddress () << " \n " ;
175186 });
176187 B->addEdge (Edge::KeepAlive, 0 , FDE, 0 );
@@ -595,8 +606,24 @@ template <typename CURecTraits> class CompactUnwindManager {
595606 " , delta to function at " + formatv (" {0:x}" , R.Fn ->getAddress ()) +
596607 " exceeds 32 bits" );
597608
609+ auto Encoding = R.Encoding ;
610+
611+ if (LLVM_UNLIKELY (CURecTraits::encodingSpecifiesDWARF (R.Encoding ))) {
612+ if (!EHFrameBase)
613+ EHFrameBase = SectionRange (R.FDE ->getSection ()).getStart ();
614+ auto FDEDelta = R.FDE ->getAddress () - EHFrameBase;
615+
616+ if (auto EncodedFDEDelta = CURecTraits::encodeDWARFOffset (FDEDelta))
617+ Encoding |= *EncodedFDEDelta;
618+ else
619+ return make_error<JITLinkError>(
620+ " In " + G.getName () + " " + UnwindInfoSectionName +
621+ " , cannot encode delta " + formatv (" {0:x}" , FDEDelta) +
622+ " to FDE at " + formatv (" {0:x}" , R.FDE ->getAddress ()));
623+ }
624+
598625 cantFail (W.writeInteger <uint32_t >(FnDelta));
599- cantFail (W.writeInteger <uint32_t >(R. Encoding ));
626+ cantFail (W.writeInteger <uint32_t >(Encoding));
600627
601628 ++RecordIdx;
602629 }
@@ -639,6 +666,7 @@ template <typename CURecTraits> class CompactUnwindManager {
639666 StringRef UnwindInfoSectionName;
640667 StringRef EHFrameSectionName;
641668 Symbol *CompactUnwindBase = nullptr ;
669+ orc::ExecutorAddr EHFrameBase;
642670
643671 size_t NumLSDAs = 0 ;
644672 size_t NumSecondLevelPages = 0 ;
0 commit comments