@@ -1459,20 +1459,21 @@ void Writer::createStartFunction() {
1459
1459
void Writer::createApplyDataRelocationsFunction () {
1460
1460
LLVM_DEBUG (dbgs () << " createApplyDataRelocationsFunction\n " );
1461
1461
// First write the body's contents to a string.
1462
- std::string bodyContent ;
1462
+ std::vector<std:: string> funcs ;
1463
1463
{
1464
- raw_string_ostream os (bodyContent);
1465
- writeUleb128 (os, 0 , " num locals" );
1466
- bool generated = false ;
1467
1464
for (const OutputSegment *seg : segments)
1468
1465
if (!ctx.arg .sharedMemory || !seg->isTLS ())
1469
1466
for (const InputChunk *inSeg : seg->inputSegments )
1470
- generated |= inSeg->generateRelocationCode (os);
1467
+ inSeg->generateRelocationCode (funcs);
1468
+ }
1471
1469
1472
- if (!generated) {
1473
- LLVM_DEBUG (dbgs () << " skipping empty __wasm_apply_data_relocs\n " );
1474
- return ;
1475
- }
1470
+ if (funcs.empty ()) {
1471
+ LLVM_DEBUG (dbgs () << " skipping empty __wasm_apply_data_relocs\n " );
1472
+ return ;
1473
+ }
1474
+
1475
+ for (auto &func : funcs) {
1476
+ raw_string_ostream os (func);
1476
1477
writeU8 (os, WASM_OPCODE_END, " END" );
1477
1478
}
1478
1479
@@ -1485,24 +1486,67 @@ void Writer::createApplyDataRelocationsFunction() {
1485
1486
make<SyntheticFunction>(nullSignature, " __wasm_apply_data_relocs" ));
1486
1487
def->markLive ();
1487
1488
1488
- createFunction (def, bodyContent);
1489
+ if (funcs.size () == 1 ) {
1490
+ createFunction (def, funcs.back ());
1491
+ return ;
1492
+ }
1493
+
1494
+ std::string body;
1495
+ {
1496
+ raw_string_ostream os (body);
1497
+ writeUleb128 (os, 0 , " num locals" );
1498
+
1499
+ for (std::size_t i = 0 ; i < funcs.size (); ++i) {
1500
+ auto &name =
1501
+ *make<std::string>(" __wasm_apply_data_relocs_" + std::to_string (i));
1502
+ auto *func = make<SyntheticFunction>(nullSignature, name);
1503
+ auto *def = symtab->addSyntheticFunction (
1504
+ name, WASM_SYMBOL_VISIBILITY_HIDDEN, func);
1505
+ def->markLive ();
1506
+ // Normally this shouldn't be called manually for a synthetic
1507
+ // function, since the function indices in
1508
+ // ctx.syntheticFunctions will be calculated later (check
1509
+ // functionSec->addFunction call hierarchy for details).
1510
+ // However, at this point we already need the correct index. The
1511
+ // solution is to place the new synthetic function eagerly, and
1512
+ // also making addFunction idempotent by skipping when there's
1513
+ // already a function index.
1514
+ out.functionSec ->addFunction (func);
1515
+ createFunction (def, funcs[i]);
1516
+
1517
+ writeU8 (os, WASM_OPCODE_CALL, " CALL" );
1518
+ writeUleb128 (os, def->getFunctionIndex (), " function index" );
1519
+ }
1520
+
1521
+ writeU8 (os, WASM_OPCODE_END, " END" );
1522
+ }
1523
+ createFunction (def, body);
1489
1524
}
1490
1525
1491
1526
void Writer::createApplyTLSRelocationsFunction () {
1492
1527
LLVM_DEBUG (dbgs () << " createApplyTLSRelocationsFunction\n " );
1493
- std::string bodyContent ;
1528
+ std::vector<std:: string> funcs ;
1494
1529
{
1495
- raw_string_ostream os (bodyContent);
1496
- writeUleb128 (os, 0 , " num locals" );
1497
1530
for (const OutputSegment *seg : segments)
1498
1531
if (seg->isTLS ())
1499
1532
for (const InputChunk *inSeg : seg->inputSegments )
1500
- inSeg->generateRelocationCode (os);
1533
+ inSeg->generateRelocationCode (funcs);
1534
+ }
1501
1535
1536
+ if (funcs.empty ()) {
1537
+ funcs.emplace_back (std::string ());
1538
+ raw_string_ostream os (funcs.back ());
1539
+ writeUleb128 (os, 0 , " num locals" );
1540
+ }
1541
+
1542
+ for (auto &func : funcs) {
1543
+ raw_string_ostream os (func);
1502
1544
writeU8 (os, WASM_OPCODE_END, " END" );
1503
1545
}
1504
1546
1505
- createFunction (WasmSym::applyTLSRelocs, bodyContent);
1547
+ assert (funcs.size () == 1 );
1548
+
1549
+ createFunction (WasmSym::applyTLSRelocs, funcs.back ());
1506
1550
}
1507
1551
1508
1552
// Similar to createApplyDataRelocationsFunction but generates relocation code
0 commit comments