@@ -1172,37 +1172,16 @@ static CIE parseCIE(const InputSection *isec, const EhReader &reader,
1172
1172
//
1173
1173
// Concretely, we expect our relocations to write the value of `PC -
1174
1174
// target_addr` to `PC`. `PC` itself is denoted by a minuend relocation that
1175
- // points to a symbol plus an addend.
1176
- //
1177
- // It is important that the minuend relocation point to a symbol within the
1178
- // same section as the fixup value, since sections may get moved around.
1179
- //
1180
- // For example, for arm64, llvm-mc emits relocations for the target function
1181
- // address like so:
1182
- //
1183
- // ltmp:
1184
- // <CIE start>
1185
- // ...
1186
- // <CIE end>
1187
- // ... multiple FDEs ...
1188
- // <FDE start>
1189
- // <target function address - (ltmp + pcrel offset)>
1190
- // ...
1191
- //
1192
- // If any of the FDEs in `multiple FDEs` get dead-stripped, then `FDE start`
1193
- // will move to an earlier address, and `ltmp + pcrel offset` will no longer
1194
- // reflect an accurate pcrel value. To avoid this problem, we "canonicalize"
1195
- // our relocation by adding an `EH_Frame` symbol at `FDE start`, and updating
1196
- // the reloc to be `target function address - (EH_Frame + new pcrel offset)`.
1175
+ // points to a symbol or section plus an addend.
1197
1176
//
1198
1177
// If `Invert` is set, then we instead expect `target_addr - PC` to be written
1199
1178
// to `PC`.
1200
1179
template <bool Invert = false >
1201
1180
Defined *
1202
- targetSymFromCanonicalSubtractor (const InputSection *isec,
1203
- std::vector<macho::Reloc>::iterator relocIt) {
1204
- macho::Reloc &subtrahend = *relocIt;
1205
- macho::Reloc &minuend = *std::next (relocIt);
1181
+ getTargetSymbolFromSubtraction (const InputSection *isec,
1182
+ std::vector<macho::Reloc>::iterator relocIt) {
1183
+ const macho::Reloc &subtrahend = *relocIt;
1184
+ const macho::Reloc &minuend = *std::next (relocIt);
1206
1185
assert (target->hasAttr (subtrahend.type , RelocAttrBits::SUBTRAHEND));
1207
1186
assert (target->hasAttr (minuend.type , RelocAttrBits::UNSIGNED));
1208
1187
// Note: pcSym may *not* be exactly at the PC; there's usually a non-zero
@@ -1217,21 +1196,9 @@ targetSymFromCanonicalSubtractor(const InputSection *isec,
1217
1196
}
1218
1197
if (Invert)
1219
1198
std::swap (pcSym, target);
1220
- if (pcSym->isec == isec) {
1221
- if (pcSym->value - (Invert ? -1 : 1 ) * minuend.addend != subtrahend.offset )
1222
- fatal (" invalid FDE relocation in __eh_frame" );
1223
- } else {
1224
- // Ensure the pcReloc points to a symbol within the current EH frame.
1225
- // HACK: we should really verify that the original relocation's semantics
1226
- // are preserved. In particular, we should have
1227
- // `oldSym->value + oldOffset == newSym + newOffset`. However, we don't
1228
- // have an easy way to access the offsets from this point in the code; some
1229
- // refactoring is needed for that.
1230
- macho::Reloc &pcReloc = Invert ? minuend : subtrahend;
1231
- pcReloc.referent = isec->symbols [0 ];
1232
- assert (isec->symbols [0 ]->value == 0 );
1233
- minuend.addend = pcReloc.offset * (Invert ? 1LL : -1LL );
1234
- }
1199
+ if (pcSym->isec != isec ||
1200
+ pcSym->value - (Invert ? -1 : 1 ) * minuend.addend != subtrahend.offset )
1201
+ fatal (" invalid FDE relocation in __eh_frame" );
1235
1202
return target;
1236
1203
}
1237
1204
@@ -1288,7 +1255,7 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) {
1288
1255
if (cieOffRelocIt != isec->relocs .end ()) {
1289
1256
// We already have an explicit relocation for the CIE offset.
1290
1257
cieIsec =
1291
- targetSymFromCanonicalSubtractor </* Invert=*/ true >(isec, cieOffRelocIt)
1258
+ getTargetSymbolFromSubtraction </* Invert=*/ true >(isec, cieOffRelocIt)
1292
1259
->isec ;
1293
1260
dataOff += sizeof (uint32_t );
1294
1261
} else {
@@ -1343,7 +1310,7 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) {
1343
1310
1344
1311
Defined *funcSym;
1345
1312
if (funcAddrRelocIt != isec->relocs .end ()) {
1346
- funcSym = targetSymFromCanonicalSubtractor (isec, funcAddrRelocIt);
1313
+ funcSym = getTargetSymbolFromSubtraction (isec, funcAddrRelocIt);
1347
1314
} else {
1348
1315
funcSym = findSymbolAtAddress (sections, funcAddr);
1349
1316
ehRelocator.makePcRel (funcAddrOff, funcSym, target->p2WordSize );
@@ -1358,7 +1325,7 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) {
1358
1325
1359
1326
InputSection *lsdaIsec = nullptr ;
1360
1327
if (lsdaAddrRelocIt != isec->relocs .end ()) {
1361
- lsdaIsec = targetSymFromCanonicalSubtractor (isec, lsdaAddrRelocIt)->isec ;
1328
+ lsdaIsec = getTargetSymbolFromSubtraction (isec, lsdaAddrRelocIt)->isec ;
1362
1329
} else if (lsdaAddrOpt) {
1363
1330
uint64_t lsdaAddr = *lsdaAddrOpt;
1364
1331
Section *sec = findContainingSection (sections, &lsdaAddr);
0 commit comments