@@ -126,16 +126,23 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
126
126
}
127
127
128
128
// Find the offsets of any existing edges from this block.
129
- BlockEdgeMap BlockEdges;
129
+ BlockEdgesInfo BlockEdges;
130
130
for (auto &E : B.edges ())
131
131
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
+ }
139
146
}
140
147
141
148
BinaryStreamReader BlockReader (
@@ -172,7 +179,7 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
172
179
173
180
Error EHFrameEdgeFixer::processCIE (ParseContext &PC, Block &B,
174
181
size_t CIEDeltaFieldOffset,
175
- const BlockEdgeMap &BlockEdges) {
182
+ const BlockEdgesInfo &BlockEdges) {
176
183
177
184
LLVM_DEBUG (dbgs () << " Record is CIE\n " );
178
185
@@ -285,7 +292,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
285
292
Error EHFrameEdgeFixer::processFDE (ParseContext &PC, Block &B,
286
293
size_t CIEDeltaFieldOffset,
287
294
uint32_t CIEDelta,
288
- const BlockEdgeMap &BlockEdges) {
295
+ const BlockEdgesInfo &BlockEdges) {
289
296
LLVM_DEBUG (dbgs () << " Record is FDE\n " );
290
297
291
298
orc::ExecutorAddr RecordAddress = B.getAddress ();
@@ -303,12 +310,17 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
303
310
304
311
{
305
312
// 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);
307
319
308
320
orc::ExecutorAddr CIEAddress =
309
321
RecordAddress + orc::ExecutorAddrDiff (CIEDeltaFieldOffset) -
310
322
orc::ExecutorAddrDiff (CIEDelta);
311
- if (CIEEdgeItr == BlockEdges.end ()) {
323
+ if (CIEEdgeItr == BlockEdges.TargetMap . end ()) {
312
324
LLVM_DEBUG ({
313
325
dbgs () << " Adding edge at "
314
326
<< (RecordAddress + CIEDeltaFieldOffset)
@@ -497,7 +509,7 @@ Error EHFrameEdgeFixer::skipEncodedPointer(uint8_t PointerEncoding,
497
509
}
498
510
499
511
Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge (
500
- ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
512
+ ParseContext &PC, const BlockEdgesInfo &BlockEdges, uint8_t PointerEncoding,
501
513
BinaryStreamReader &RecordReader, Block &BlockToFix,
502
514
size_t PointerFieldOffset, const char *FieldName) {
503
515
using namespace dwarf ;
@@ -508,8 +520,8 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
508
520
// If there's already an edge here then just skip the encoded pointer and
509
521
// return the edge's target.
510
522
{
511
- auto EdgeI = BlockEdges.find (PointerFieldOffset);
512
- if (EdgeI != BlockEdges.end ()) {
523
+ auto EdgeI = BlockEdges.TargetMap . find (PointerFieldOffset);
524
+ if (EdgeI != BlockEdges.TargetMap . end ()) {
513
525
LLVM_DEBUG ({
514
526
dbgs () << " Existing edge at "
515
527
<< (BlockToFix.getAddress () + PointerFieldOffset) << " to "
@@ -522,6 +534,10 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
522
534
return std::move (Err);
523
535
return EdgeI->second .Target ;
524
536
}
537
+
538
+ if (BlockEdges.Multiple .contains (PointerFieldOffset))
539
+ return make_error<JITLinkError>(" Multiple relocations at offset " +
540
+ formatv (" {0:x16}" , PointerFieldOffset));
525
541
}
526
542
527
543
// Switch absptr to corresponding udata encoding.
0 commit comments