| ... | ... | @@ -683,10 +683,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 683 | 683 | .__wasm_init_memory => @panic("TODO lower __wasm_init_memory "), |
| 684 | 684 | .__wasm_init_tls => @panic("TODO lower __wasm_init_tls "), |
| 685 | 685 | .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); |
| 690 | 692 | }, |
| 691 | 693 | .zcu_func => |i| { |
| 692 | 694 | const code_start = try reserveSize(gpa, binary_bytes); |
| ... | ... | @@ -699,7 +701,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 699 | 701 | }; |
| 700 | 702 | |
| 701 | 703 | replaceVecSectionHeader(binary_bytes, header_offset, .code, @intCast(wasm.functions.entries.len)); |
| 702 | | if (is_obj) @panic("TODO apply offset to code relocs"); |
| 703 | 704 | code_section_index = section_index; |
| 704 | 705 | section_index += 1; |
| 705 | 706 | } |
| ... | ... | @@ -801,7 +802,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 801 | 802 | } |
| 802 | 803 | |
| 803 | 804 | 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"); |
| 805 | 806 | //var symbol_table = std.AutoArrayHashMap(SymbolLoc, u32).init(arena); |
| 806 | 807 | //try wasm.emitLinkSection(binary_bytes, &symbol_table); |
| 807 | 808 | //if (code_section_index) |code_index| { |
| ... | ... | @@ -1420,3 +1421,141 @@ fn emitErrorNameTable( |
| 1420 | 1421 | mem.writeInt(Int, code.addManyAsArrayAssumeCapacity(ptr_size_bytes), name_len, .little); |
| 1421 | 1422 | } |
| 1422 | 1423 | } |
| 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 | } |