@@ -301,49 +301,48 @@ void InputFunction::writeTo(uint8_t *Buf) const {
301
301
// This is only called when generating shared libaries (PIC) where address are
302
302
// not known at static link time.
303
303
void InputSegment::generateRelocationCode (raw_ostream &OS) const {
304
+ LLVM_DEBUG (dbgs () << " generating runtime relocations: " << getName ()
305
+ << " count=" << Relocations.size () << " \n " );
306
+
307
+ // TODO(sbc): Encode the relocations in the data section and write a loop
308
+ // here to apply them.
304
309
uint32_t SegmentVA = OutputSeg->StartVA + OutputSegmentOffset;
305
310
for (const WasmRelocation &Rel : Relocations) {
306
311
uint32_t Offset = Rel.Offset - getInputSectionOffset ();
307
- uint32_t OutputVA = SegmentVA + Offset;
312
+ uint32_t OutputOffset = SegmentVA + Offset;
313
+
314
+ LLVM_DEBUG (dbgs () << " gen reloc: type=" << relocTypeToString (Rel.Type )
315
+ << " addend=" << Rel.Addend << " index=" << Rel.Index
316
+ << " output offset=" << OutputOffset << " \n " );
308
317
309
318
// Get __memory_base
310
319
writeU8 (OS, WASM_OPCODE_GLOBAL_GET, " GLOBAL_GET" );
311
320
writeUleb128 (OS, WasmSym::MemoryBase->getGlobalIndex (), " memory_base" );
312
321
313
322
// Add the offset of the relocation
314
323
writeU8 (OS, WASM_OPCODE_I32_CONST, " I32_CONST" );
315
- writeSleb128 (OS, OutputVA , " offset" );
324
+ writeSleb128 (OS, OutputOffset , " offset" );
316
325
writeU8 (OS, WASM_OPCODE_I32_ADD, " ADD" );
317
326
327
+ Symbol *Sym = File->getSymbol (Rel);
318
328
// Now figure out what we want to store
319
- switch (Rel.Type ) {
320
- case R_WASM_TABLE_INDEX_I32:
321
- // Add the table index to the __table_base
329
+ if (Sym->hasGOTIndex ()) {
322
330
writeU8 (OS, WASM_OPCODE_GLOBAL_GET, " GLOBAL_GET" );
323
- writeUleb128 (OS, WasmSym::TableBase->getGlobalIndex (), " table_base" );
324
- writeU8 (OS, WASM_OPCODE_I32_CONST, " CONST" );
325
- writeSleb128 (OS, File->calcNewValue (Rel), " new table index" );
326
- writeU8 (OS, WASM_OPCODE_I32_ADD, " ADD" );
327
- break ;
328
- case R_WASM_MEMORY_ADDR_I32: {
329
- Symbol *Sym = File->getSymbol (Rel);
330
- if (Sym->isLocal () || Sym->isHidden ()) {
331
- // Hidden/Local data symbols are accessed via known offset from
332
- // __memory_base
333
- writeU8 (OS, WASM_OPCODE_GLOBAL_GET, " GLOBAL_GET" );
334
- writeUleb128 (OS, WasmSym::MemoryBase->getGlobalIndex (), " memory_base" );
331
+ writeUleb128 (OS, Sym->getGOTIndex (), " global index" );
332
+ if (Rel.Addend ) {
335
333
writeU8 (OS, WASM_OPCODE_I32_CONST, " CONST" );
336
- writeSleb128 (OS, File-> calcNewValue ( Rel) , " new memory offset " );
334
+ writeSleb128 (OS, Rel. Addend , " addend " );
337
335
writeU8 (OS, WASM_OPCODE_I32_ADD, " ADD" );
338
- } else {
339
- // Default data symbols are accessed via imported GOT globals
340
- writeU8 (OS, WASM_OPCODE_GLOBAL_GET, " GLOBAL_GET" );
341
- writeUleb128 (OS, Sym->getGOTIndex (), " global index" );
342
336
}
343
- break ;
344
- }
345
- default :
346
- llvm_unreachable (" unexpected relocation type in data segment" );
337
+ } else {
338
+ const GlobalSymbol* BaseSymbol = WasmSym::MemoryBase;
339
+ if (Rel.Type == R_WASM_TABLE_INDEX_I32)
340
+ BaseSymbol = WasmSym::TableBase;
341
+ writeU8 (OS, WASM_OPCODE_GLOBAL_GET, " GLOBAL_GET" );
342
+ writeUleb128 (OS, BaseSymbol->getGlobalIndex (), " base" );
343
+ writeU8 (OS, WASM_OPCODE_I32_CONST, " CONST" );
344
+ writeSleb128 (OS, File->calcNewValue (Rel), " offset" );
345
+ writeU8 (OS, WASM_OPCODE_I32_ADD, " ADD" );
347
346
}
348
347
349
348
// Store that value at the virtual address
0 commit comments