@@ -544,6 +544,14 @@ static void flushOpcodes(const BindIR &op, raw_svector_ostream &os) {
544
544
}
545
545
}
546
546
547
+ static bool needsWeakBind (const Symbol &sym) {
548
+ if (auto *dysym = dyn_cast<DylibSymbol>(&sym))
549
+ return dysym->isWeakDef ();
550
+ if (auto *defined = dyn_cast<Defined>(&sym))
551
+ return defined->isExternalWeakDef ();
552
+ return false ;
553
+ }
554
+
547
555
// Non-weak bindings need to have their dylib ordinal encoded as well.
548
556
static int16_t ordinalForDylibSymbol (const DylibSymbol &dysym) {
549
557
if (config->namespaceKind == NamespaceKind::flat || dysym.isDynamicLookup ())
@@ -553,6 +561,8 @@ static int16_t ordinalForDylibSymbol(const DylibSymbol &dysym) {
553
561
}
554
562
555
563
static int16_t ordinalForSymbol (const Symbol &sym) {
564
+ if (config->emitChainedFixups && needsWeakBind (sym))
565
+ return BIND_SPECIAL_DYLIB_WEAK_LOOKUP;
556
566
if (const auto *dysym = dyn_cast<DylibSymbol>(&sym))
557
567
return ordinalForDylibSymbol (*dysym);
558
568
assert (cast<Defined>(&sym)->interposable );
@@ -2276,14 +2286,6 @@ bool ChainedFixupsSection::isNeeded() const {
2276
2286
return true ;
2277
2287
}
2278
2288
2279
- static bool needsWeakBind (const Symbol &sym) {
2280
- if (auto *dysym = dyn_cast<DylibSymbol>(&sym))
2281
- return dysym->isWeakDef ();
2282
- if (auto *defined = dyn_cast<Defined>(&sym))
2283
- return defined->isExternalWeakDef ();
2284
- return false ;
2285
- }
2286
-
2287
2289
void ChainedFixupsSection::addBinding (const Symbol *sym,
2288
2290
const InputSection *isec, uint64_t offset,
2289
2291
int64_t addend) {
@@ -2312,7 +2314,7 @@ ChainedFixupsSection::getBinding(const Symbol *sym, int64_t addend) const {
2312
2314
return {it->second , 0 };
2313
2315
}
2314
2316
2315
- static size_t writeImport (uint8_t *buf, int format, uint32_t libOrdinal,
2317
+ static size_t writeImport (uint8_t *buf, int format, int16_t libOrdinal,
2316
2318
bool weakRef, uint32_t nameOffset, int64_t addend) {
2317
2319
switch (format) {
2318
2320
case DYLD_CHAINED_IMPORT: {
@@ -2430,11 +2432,8 @@ void ChainedFixupsSection::writeTo(uint8_t *buf) const {
2430
2432
uint64_t nameOffset = 0 ;
2431
2433
for (auto [import, idx] : bindings) {
2432
2434
const Symbol &sym = *import.first ;
2433
- int16_t libOrdinal = needsWeakBind (sym)
2434
- ? (int64_t )BIND_SPECIAL_DYLIB_WEAK_LOOKUP
2435
- : ordinalForSymbol (sym);
2436
- buf += writeImport (buf, importFormat, libOrdinal, sym.isWeakRef (),
2437
- nameOffset, import.second );
2435
+ buf += writeImport (buf, importFormat, ordinalForSymbol (sym),
2436
+ sym.isWeakRef (), nameOffset, import.second );
2438
2437
nameOffset += sym.getName ().size () + 1 ;
2439
2438
}
2440
2439
@@ -2459,7 +2458,12 @@ void ChainedFixupsSection::finalizeContents() {
2459
2458
error (" cannot encode chained fixups: imported symbols table size " +
2460
2459
Twine (symtabSize) + " exceeds 4 GiB" );
2461
2460
2462
- if (needsLargeAddend || !isUInt<23 >(symtabSize))
2461
+ bool needsLargeOrdinal = any_of (bindings, [](const auto &p) {
2462
+ // 0xF1 - 0xFF are reserved for special ordinals in the 8-bit encoding.
2463
+ return ordinalForSymbol (*p.first .first ) > 0xF0 ;
2464
+ });
2465
+
2466
+ if (needsLargeAddend || !isUInt<23 >(symtabSize) || needsLargeOrdinal)
2463
2467
importFormat = DYLD_CHAINED_IMPORT_ADDEND64;
2464
2468
else if (needsAddend)
2465
2469
importFormat = DYLD_CHAINED_IMPORT_ADDEND;
0 commit comments