| ... | ... | @@ -5400,6 +5400,21 @@ fn writeSymbolTable(self: *MachO) !void { |
| 5400 | 5400 | try locals.append(sym); |
| 5401 | 5401 | } |
| 5402 | 5402 | |
| 5403 | // TODO How do we handle null global symbols in incremental context? |
| 5404 | var undefs = std.ArrayList(macho.nlist_64).init(self.base.allocator); |
| 5405 | defer undefs.deinit(); |
| 5406 | var undefs_table = std.AutoHashMap(u32, u32).init(self.base.allocator); |
| 5407 | defer undefs_table.deinit(); |
| 5408 | try undefs.ensureTotalCapacity(self.undefs.items.len); |
| 5409 | try undefs_table.ensureTotalCapacity(@intCast(u32, self.undefs.items.len)); |
| 5410 | |
| 5411 | for (self.undefs.items) |sym, i| { |
| 5412 | if (sym.n_strx == 0) continue; |
| 5413 | const new_index = @intCast(u32, undefs.items.len); |
| 5414 | undefs.appendAssumeCapacity(sym); |
| 5415 | undefs_table.putAssumeCapacityNoClobber(@intCast(u32, i), new_index); |
| 5416 | } |
| 5417 | |
| 5403 | 5418 | if (self.has_stabs) { |
| 5404 | 5419 | for (self.objects.items) |object| { |
| 5405 | 5420 | if (object.debug_info == null) continue; |
| ... | ... | @@ -5456,7 +5471,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 5456 | 5471 | |
| 5457 | 5472 | const nlocals = locals.items.len; |
| 5458 | 5473 | const nexports = self.globals.items.len; |
| 5459 | | const nundefs = self.undefs.items.len; |
| 5474 | const nundefs = undefs.items.len; |
| 5460 | 5475 | |
| 5461 | 5476 | const locals_off = symtab.symoff; |
| 5462 | 5477 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| ... | ... | @@ -5471,7 +5486,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 5471 | 5486 | const undefs_off = exports_off + exports_size; |
| 5472 | 5487 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 5473 | 5488 | log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 5474 | | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off); |
| 5489 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); |
| 5475 | 5490 | |
| 5476 | 5491 | symtab.nsyms = @intCast(u32, nlocals + nexports + nundefs); |
| 5477 | 5492 | seg.inner.filesize += locals_size + exports_size + undefs_size; |
| ... | ... | @@ -5513,10 +5528,10 @@ fn writeSymbolTable(self: *MachO) !void { |
| 5513 | 5528 | |
| 5514 | 5529 | stubs.reserved1 = 0; |
| 5515 | 5530 | for (self.stubs_map.keys()) |key| { |
| 5516 | | const resolv = self.symbol_resolver.get(key) orelse continue; |
| 5531 | const resolv = self.symbol_resolver.get(key).?; |
| 5517 | 5532 | switch (resolv.where) { |
| 5518 | 5533 | .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 5519 | | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index), |
| 5534 | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + undefs_table.get(resolv.where_index).?), |
| 5520 | 5535 | } |
| 5521 | 5536 | } |
| 5522 | 5537 | |
| ... | ... | @@ -5525,10 +5540,10 @@ fn writeSymbolTable(self: *MachO) !void { |
| 5525 | 5540 | switch (key) { |
| 5526 | 5541 | .local => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 5527 | 5542 | .global => |n_strx| { |
| 5528 | | const resolv = self.symbol_resolver.get(n_strx) orelse continue; |
| 5543 | const resolv = self.symbol_resolver.get(n_strx).?; |
| 5529 | 5544 | switch (resolv.where) { |
| 5530 | 5545 | .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 5531 | | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index), |
| 5546 | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + undefs_table.get(resolv.where_index).?), |
| 5532 | 5547 | } |
| 5533 | 5548 | }, |
| 5534 | 5549 | } |
| ... | ... | @@ -5536,10 +5551,10 @@ fn writeSymbolTable(self: *MachO) !void { |
| 5536 | 5551 | |
| 5537 | 5552 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 5538 | 5553 | for (self.stubs_map.keys()) |key| { |
| 5539 | | const resolv = self.symbol_resolver.get(key) orelse continue; |
| 5554 | const resolv = self.symbol_resolver.get(key).?; |
| 5540 | 5555 | switch (resolv.where) { |
| 5541 | 5556 | .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 5542 | | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index), |
| 5557 | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + undefs_table.get(resolv.where_index).?), |
| 5543 | 5558 | } |
| 5544 | 5559 | } |
| 5545 | 5560 | |