@@ -126,16 +126,23 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
126126 }
127127
128128 // Find the offsets of any existing edges from this block.
129- BlockEdgeMap BlockEdges;
129+ BlockEdgesInfo BlockEdges;
130130 for (auto &E : B.edges ())
131131 if (E.isRelocation ()) {
132- if (BlockEdges.count (E.getOffset ()))
133- return make_error<JITLinkError>(
134- " Multiple relocations at offset " +
135- formatv (" {0:x16}" , E.getOffset ()) + " in " + EHFrameSectionName +
136- " block at address " + formatv (" {0:x16}" , B.getAddress ()));
137-
138- BlockEdges[E.getOffset ()] = EdgeTarget (E);
132+ // Check if we already saw more than one relocation at this offset.
133+ if (BlockEdges.Multiple .contains (E.getOffset ()))
134+ continue ;
135+
136+ // Otherwise check if we previously had exactly one relocation at this
137+ // offset. If so, we now have a second one and move it from the TargetMap
138+ // into the Multiple set.
139+ auto It = BlockEdges.TargetMap .find (E.getOffset ());
140+ if (It != BlockEdges.TargetMap .end ()) {
141+ BlockEdges.TargetMap .erase (It);
142+ BlockEdges.Multiple .insert (E.getOffset ());
143+ } else {
144+ BlockEdges.TargetMap [E.getOffset ()] = EdgeTarget (E);
145+ }
139146 }
140147
141148 BinaryStreamReader BlockReader (
@@ -172,7 +179,7 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
172179
173180Error EHFrameEdgeFixer::processCIE (ParseContext &PC, Block &B,
174181 size_t CIEDeltaFieldOffset,
175- const BlockEdgeMap &BlockEdges) {
182+ const BlockEdgesInfo &BlockEdges) {
176183
177184 LLVM_DEBUG (dbgs () << " Record is CIE\n " );
178185
@@ -285,7 +292,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
285292Error EHFrameEdgeFixer::processFDE (ParseContext &PC, Block &B,
286293 size_t CIEDeltaFieldOffset,
287294 uint32_t CIEDelta,
288- const BlockEdgeMap &BlockEdges) {
295+ const BlockEdgesInfo &BlockEdges) {
289296 LLVM_DEBUG (dbgs () << " Record is FDE\n " );
290297
291298 orc::ExecutorAddr RecordAddress = B.getAddress ();
@@ -303,12 +310,17 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
303310
304311 {
305312 // Process the CIE pointer field.
306- auto CIEEdgeItr = BlockEdges.find (CIEDeltaFieldOffset);
313+ if (BlockEdges.Multiple .contains (CIEDeltaFieldOffset))
314+ return make_error<JITLinkError>(
315+ " CIE pointer field already has multiple edges at " +
316+ formatv (" {0:x16}" , RecordAddress + CIEDeltaFieldOffset));
317+
318+ auto CIEEdgeItr = BlockEdges.TargetMap .find (CIEDeltaFieldOffset);
307319
308320 orc::ExecutorAddr CIEAddress =
309321 RecordAddress + orc::ExecutorAddrDiff (CIEDeltaFieldOffset) -
310322 orc::ExecutorAddrDiff (CIEDelta);
311- if (CIEEdgeItr == BlockEdges.end ()) {
323+ if (CIEEdgeItr == BlockEdges.TargetMap . end ()) {
312324 LLVM_DEBUG ({
313325 dbgs () << " Adding edge at "
314326 << (RecordAddress + CIEDeltaFieldOffset)
@@ -497,7 +509,7 @@ Error EHFrameEdgeFixer::skipEncodedPointer(uint8_t PointerEncoding,
497509}
498510
499511Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge (
500- ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
512+ ParseContext &PC, const BlockEdgesInfo &BlockEdges, uint8_t PointerEncoding,
501513 BinaryStreamReader &RecordReader, Block &BlockToFix,
502514 size_t PointerFieldOffset, const char *FieldName) {
503515 using namespace dwarf ;
@@ -508,8 +520,8 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
508520 // If there's already an edge here then just skip the encoded pointer and
509521 // return the edge's target.
510522 {
511- auto EdgeI = BlockEdges.find (PointerFieldOffset);
512- if (EdgeI != BlockEdges.end ()) {
523+ auto EdgeI = BlockEdges.TargetMap . find (PointerFieldOffset);
524+ if (EdgeI != BlockEdges.TargetMap . end ()) {
513525 LLVM_DEBUG ({
514526 dbgs () << " Existing edge at "
515527 << (BlockToFix.getAddress () + PointerFieldOffset) << " to "
@@ -522,6 +534,10 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
522534 return std::move (Err);
523535 return EdgeI->second .Target ;
524536 }
537+
538+ if (BlockEdges.Multiple .contains (PointerFieldOffset))
539+ return make_error<JITLinkError>(" Multiple relocations at offset " +
540+ formatv (" {0:x16}" , PointerFieldOffset));
525541 }
526542
527543 // Switch absptr to corresponding udata encoding.
0 commit comments