@@ -683,10 +683,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
683683 .__wasm_init_memory = > @panic ("TODO lower __wasm_init_memory " ),
684684 .__wasm_init_tls = > @panic ("TODO lower __wasm_init_tls " ),
685685 .object_function = > | i | {
686- _ = i ;
687- @panic ("TODO lower object function code and apply relocations" );
688- //try leb.writeUleb128(binary_writer, atom.code.len);
689- //try binary_bytes.appendSlice(gpa, atom.code.slice(wasm));
686+ const ptr = i .ptr (wasm );
687+ const code = ptr .code .slice (wasm );
688+ try leb .writeUleb128 (binary_writer , code .len );
689+ const code_start = binary_bytes .items .len ;
690+ try binary_bytes .appendSlice (gpa , code );
691+ if (! is_obj ) applyRelocs (binary_bytes .items [code_start .. ], ptr .offset , ptr .relocations (wasm ), wasm );
690692 },
691693 .zcu_func = > | i | {
692694 const code_start = try reserveSize (gpa , binary_bytes );
@@ -699,7 +701,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
699701 };
700702
701703 replaceVecSectionHeader (binary_bytes , header_offset , .code , @intCast (wasm .functions .entries .len ));
702- if (is_obj ) @panic ("TODO apply offset to code relocs" );
703704 code_section_index = section_index ;
704705 section_index += 1 ;
705706 }
@@ -801,7 +802,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
801802 }
802803
803804 if (is_obj ) {
804- @panic ("TODO emit link section for object file and apply relocations" );
805+ @panic ("TODO emit link section for object file and emit modified relocations" );
805806 //var symbol_table = std.AutoArrayHashMap(SymbolLoc, u32).init(arena);
806807 //try wasm.emitLinkSection(binary_bytes, &symbol_table);
807808 //if (code_section_index) |code_index| {
@@ -1420,3 +1421,141 @@ fn emitErrorNameTable(
14201421 mem .writeInt (Int , code .addManyAsArrayAssumeCapacity (ptr_size_bytes ), name_len , .little );
14211422 }
14221423}
1424+
1425+ fn applyRelocs (code : []u8 , code_offset : u32 , relocs : Wasm.ObjectRelocation.IterableSlice , wasm : * const Wasm ) void {
1426+ for (
1427+ relocs .slice .tags (wasm ),
1428+ relocs .slice .pointees (wasm ),
1429+ relocs .slice .offsets (wasm ),
1430+ relocs .slice .addends (wasm ),
1431+ ) | tag , pointee , offset , * addend | {
1432+ if (offset >= relocs .end ) break ;
1433+ const sliced_code = code [offset - code_offset .. ];
1434+ switch (tag ) {
1435+ .function_index_i32 = > reloc_u32_function (sliced_code , .fromObjectFunction (wasm , pointee .function )),
1436+ .function_index_leb = > reloc_leb_function (sliced_code , .fromObjectFunction (wasm , pointee .function )),
1437+ .function_offset_i32 = > @panic ("TODO this value is not known yet" ),
1438+ .function_offset_i64 = > @panic ("TODO this value is not known yet" ),
1439+ .table_index_i32 = > @panic ("TODO indirect function table needs to support object functions too" ),
1440+ .table_index_i64 = > @panic ("TODO indirect function table needs to support object functions too" ),
1441+ .table_index_rel_sleb = > @panic ("TODO indirect function table needs to support object functions too" ),
1442+ .table_index_rel_sleb64 = > @panic ("TODO indirect function table needs to support object functions too" ),
1443+ .table_index_sleb = > @panic ("TODO indirect function table needs to support object functions too" ),
1444+ .table_index_sleb64 = > @panic ("TODO indirect function table needs to support object functions too" ),
1445+
1446+ .function_import_index_i32 = > reloc_u32_function (sliced_code , .fromSymbolName (wasm , pointee .symbol_name )),
1447+ .function_import_index_leb = > reloc_leb_function (sliced_code , .fromSymbolName (wasm , pointee .symbol_name )),
1448+ .function_import_offset_i32 = > @panic ("TODO this value is not known yet" ),
1449+ .function_import_offset_i64 = > @panic ("TODO this value is not known yet" ),
1450+ .table_import_index_i32 = > @panic ("TODO indirect function table needs to support object functions too" ),
1451+ .table_import_index_i64 = > @panic ("TODO indirect function table needs to support object functions too" ),
1452+ .table_import_index_rel_sleb = > @panic ("TODO indirect function table needs to support object functions too" ),
1453+ .table_import_index_rel_sleb64 = > @panic ("TODO indirect function table needs to support object functions too" ),
1454+ .table_import_index_sleb = > @panic ("TODO indirect function table needs to support object functions too" ),
1455+ .table_import_index_sleb64 = > @panic ("TODO indirect function table needs to support object functions too" ),
1456+
1457+ .global_index_i32 = > reloc_u32_global (sliced_code , .fromObjectGlobal (wasm , pointee .global )),
1458+ .global_index_leb = > reloc_leb_global (sliced_code , .fromObjectGlobal (wasm , pointee .global )),
1459+
1460+ .global_import_index_i32 = > reloc_u32_global (sliced_code , .fromSymbolName (wasm , pointee .symbol_name )),
1461+ .global_import_index_leb = > reloc_leb_global (sliced_code , .fromSymbolName (wasm , pointee .symbol_name )),
1462+
1463+ .memory_addr_i32 = > reloc_u32_addr (sliced_code , .fromObjectData (wasm , pointee .data , addend .* )),
1464+ .memory_addr_i64 = > reloc_u64_addr (sliced_code , .fromObjectData (wasm , pointee .data , addend .* )),
1465+ .memory_addr_leb = > reloc_leb_addr (sliced_code , .fromObjectData (wasm , pointee .data , addend .* )),
1466+ .memory_addr_leb64 = > reloc_leb64_addr (sliced_code , .fromObjectData (wasm , pointee .data , addend .* )),
1467+ .memory_addr_locrel_i32 = > @panic ("TODO implement relocation memory_addr_locrel_i32" ),
1468+ .memory_addr_rel_sleb = > @panic ("TODO implement relocation memory_addr_rel_sleb" ),
1469+ .memory_addr_rel_sleb64 = > @panic ("TODO implement relocation memory_addr_rel_sleb64" ),
1470+ .memory_addr_sleb = > reloc_sleb_addr (sliced_code , .fromObjectData (wasm , pointee .data , addend .* )),
1471+ .memory_addr_sleb64 = > reloc_sleb64_addr (sliced_code , .fromObjectData (wasm , pointee .data , addend .* )),
1472+ .memory_addr_tls_sleb = > @panic ("TODO implement relocation memory_addr_tls_sleb" ),
1473+ .memory_addr_tls_sleb64 = > @panic ("TODO implement relocation memory_addr_tls_sleb64" ),
1474+
1475+ .memory_addr_import_i32 = > reloc_u32_addr (sliced_code , .fromSymbolName (wasm , pointee .symbol_name , addend .* )),
1476+ .memory_addr_import_i64 = > reloc_u64_addr (sliced_code , .fromSymbolName (wasm , pointee .symbol_name , addend .* )),
1477+ .memory_addr_import_leb = > reloc_leb_addr (sliced_code , .fromSymbolName (wasm , pointee .symbol_name , addend .* )),
1478+ .memory_addr_import_leb64 = > reloc_leb64_addr (sliced_code , .fromSymbolName (wasm , pointee .symbol_name , addend .* )),
1479+ .memory_addr_import_locrel_i32 = > @panic ("TODO implement relocation memory_addr_import_locrel_i32" ),
1480+ .memory_addr_import_rel_sleb = > @panic ("TODO implement relocation memory_addr_import_rel_sleb" ),
1481+ .memory_addr_import_rel_sleb64 = > @panic ("TODO implement memory_addr_import_rel_sleb64" ),
1482+ .memory_addr_import_sleb = > reloc_sleb_addr (sliced_code , .fromSymbolName (wasm , pointee .symbol_name , addend .* )),
1483+ .memory_addr_import_sleb64 = > reloc_sleb64_addr (sliced_code , .fromSymbolName (wasm , pointee .symbol_name , addend .* )),
1484+ .memory_addr_import_tls_sleb = > @panic ("TODO" ),
1485+ .memory_addr_import_tls_sleb64 = > @panic ("TODO" ),
1486+
1487+ .section_offset_i32 = > @panic ("TODO this value is not known yet" ),
1488+
1489+ .table_number_leb = > reloc_leb_table (sliced_code , .fromObjectTable (wasm , pointee .table )),
1490+ .table_import_number_leb = > reloc_leb_table (sliced_code , .fromSymbolName (wasm , pointee .symbol_name )),
1491+
1492+ .type_index_leb = > reloc_leb_type (sliced_code , pointee .type_index ),
1493+ }
1494+ }
1495+ }
1496+
1497+ fn reloc_u32_function (code : []u8 , function : Wasm.OutputFunctionIndex ) void {
1498+ mem .writeInt (u32 , code [0.. 4], @intFromEnum (function ), .little );
1499+ }
1500+
1501+ fn reloc_leb_function (code : []u8 , function : Wasm.OutputFunctionIndex ) void {
1502+ leb .writeUnsignedFixed (5 , code [0.. 5], @intFromEnum (function ));
1503+ }
1504+
1505+ fn reloc_u32_global (code : []u8 , global : Wasm.GlobalIndex ) void {
1506+ mem .writeInt (u32 , code [0.. 4], @intFromEnum (global ), .little );
1507+ }
1508+
1509+ fn reloc_leb_global (code : []u8 , global : Wasm.GlobalIndex ) void {
1510+ leb .writeUnsignedFixed (5 , code [0.. 5], @intFromEnum (global ));
1511+ }
1512+
1513+ const RelocAddr = struct {
1514+ addr : u32 ,
1515+
1516+ fn fromObjectData (wasm : * const Wasm , i : Wasm.ObjectData.Index , addend : i32 ) RelocAddr {
1517+ const ptr = i .ptr (wasm );
1518+ const f = & wasm .flush_buffer ;
1519+ const addr = f .data_segments .get (.fromObjectDataSegment (wasm , ptr .segment )).? ;
1520+ return .{ .addr = @intCast (@as (i64 , addr ) + addend ) };
1521+ }
1522+
1523+ fn fromSymbolName (wasm : * const Wasm , name : String , addend : i32 ) RelocAddr {
1524+ _ = wasm ;
1525+ _ = name ;
1526+ _ = addend ;
1527+ @panic ("TODO implement data symbol resolution" );
1528+ }
1529+ };
1530+
1531+ fn reloc_u32_addr (code : []u8 , ra : RelocAddr ) void {
1532+ mem .writeInt (u32 , code [0.. 4], ra .addr , .little );
1533+ }
1534+
1535+ fn reloc_u64_addr (code : []u8 , ra : RelocAddr ) void {
1536+ mem .writeInt (u64 , code [0.. 8], ra .addr , .little );
1537+ }
1538+
1539+ fn reloc_leb_addr (code : []u8 , ra : RelocAddr ) void {
1540+ leb .writeUnsignedFixed (5 , code [0.. 5], ra .addr );
1541+ }
1542+
1543+ fn reloc_leb64_addr (code : []u8 , ra : RelocAddr ) void {
1544+ leb .writeUnsignedFixed (11 , code [0.. 11], ra .addr );
1545+ }
1546+
1547+ fn reloc_sleb_addr (code : []u8 , ra : RelocAddr ) void {
1548+ leb .writeSignedFixed (5 , code [0.. 5], ra .addr );
1549+ }
1550+
1551+ fn reloc_sleb64_addr (code : []u8 , ra : RelocAddr ) void {
1552+ leb .writeSignedFixed (11 , code [0.. 11], ra .addr );
1553+ }
1554+
1555+ fn reloc_leb_table (code : []u8 , table : Wasm.TableIndex ) void {
1556+ leb .writeUnsignedFixed (5 , code [0.. 5], @intFromEnum (table ));
1557+ }
1558+
1559+ fn reloc_leb_type (code : []u8 , index : Wasm.FunctionType.Index ) void {
1560+ leb .writeUnsignedFixed (5 , code [0.. 5], @intFromEnum (index ));
1561+ }
0 commit comments