| author | |
| committer | |
| log | 8142925c7e5cb6ec21ca7046b37140a735735b51 |
| tree | a63d8afa243a16248b85266e80f19ab0d09a3872 |
| parent | 55fa8a04f1853deb473339cdc610cbf012ae0d61 |
5 files changed, 61 insertions(+), 27 deletions(-)
src/link/Elf.zig+6-1| ... | ... | @@ -288,7 +288,9 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 288 | 288 | const index = @as(File.Index, @intCast(try self.files.addOne(allocator))); |
| 289 | 289 | self.files.set(index, .{ .zig_object = .{ |
| 290 | 290 | .index = index, |
| 291 | .path = options.module.?.main_mod.root_src_path, | |
| 291 | .path = try std.fmt.allocPrint(self.base.allocator, "{s}.o", .{std.fs.path.stem( | |
| 292 | options.module.?.main_mod.root_src_path, | |
| 293 | )}), | |
| 292 | 294 | } }); |
| 293 | 295 | self.zig_object_index = index; |
| 294 | 296 | try self.zigObjectPtr().?.init(self); |
| ... | ... | @@ -1553,6 +1555,9 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void |
| 1553 | 1555 | var files = std.ArrayList(File.Index).init(gpa); |
| 1554 | 1556 | defer files.deinit(); |
| 1555 | 1557 | try files.ensureTotalCapacityPrecise(self.objects.items.len + 1); |
| 1558 | // Note to self: we currently must have ZigObject written out first as we write the object | |
| 1559 | // file into the same file descriptor and then re-read its contents. | |
| 1560 | // TODO implement writing ZigObject to a buffer instead of file. | |
| 1556 | 1561 | if (self.zigObjectPtr()) |zig_object| files.appendAssumeCapacity(zig_object.index); |
| 1557 | 1562 | for (self.objects.items) |index| files.appendAssumeCapacity(index); |
| 1558 | 1563 |
src/link/Elf/Archive.zig+4| ... | ... | @@ -142,6 +142,7 @@ const SYMDEFNAME = genSpecialMemberName("__.SYMDEF"); |
| 142 | 142 | const SYMDEFSORTEDNAME = genSpecialMemberName("__.SYMDEF SORTED"); |
| 143 | 143 | |
| 144 | 144 | const strtab_delimiter = '\n'; |
| 145 | pub const max_member_name_len = 15; | |
| 145 | 146 | |
| 146 | 147 | pub const ar_hdr = extern struct { |
| 147 | 148 | /// Member file name, sometimes / terminated. |
| ... | ... | @@ -248,6 +249,9 @@ pub const ArSymtab = struct { |
| 248 | 249 | if (elf_file.zigObjectPtr()) |zig_object| { |
| 249 | 250 | offsets.putAssumeCapacityNoClobber(zig_object.index, zig_object.output_ar_state.file_off); |
| 250 | 251 | } |
| 252 | for (elf_file.objects.items) |index| { | |
| 253 | offsets.putAssumeCapacityNoClobber(index, elf_file.file(index).?.object.output_ar_state.file_off); | |
| 254 | } | |
| 251 | 255 | |
| 252 | 256 | // Number of symbols |
| 253 | 257 | try writer.writeInt(u64, @as(u64, @intCast(ar.symtab.items.len)), .big); |
src/link/Elf/Object.zig+30| ... | ... | @@ -654,6 +654,36 @@ pub fn allocateAtoms(self: Object, elf_file: *Elf) void { |
| 654 | 654 | } |
| 655 | 655 | } |
| 656 | 656 | |
| 657 | pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { | |
| 658 | const gpa = elf_file.base.allocator; | |
| 659 | const start = self.first_global orelse self.symtab.items.len; | |
| 660 | ||
| 661 | try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.symtab.items.len - start); | |
| 662 | ||
| 663 | for (self.symtab.items[start..]) |sym| { | |
| 664 | if (sym.st_shndx == elf.SHN_UNDEF) continue; | |
| 665 | const off = try ar_symtab.strtab.insert(gpa, self.getString(sym.st_name)); | |
| 666 | ar_symtab.symtab.appendAssumeCapacity(.{ .off = off, .file_index = self.index }); | |
| 667 | } | |
| 668 | } | |
| 669 | ||
| 670 | pub fn updateArSize(self: *Object) void { | |
| 671 | self.output_ar_state.size = self.data.len; | |
| 672 | } | |
| 673 | ||
| 674 | pub fn writeAr(self: Object, writer: anytype) !void { | |
| 675 | const name = self.path; | |
| 676 | const hdr = Archive.setArHdr(.{ | |
| 677 | .name = if (name.len <= Archive.max_member_name_len) | |
| 678 | .{ .name = name } | |
| 679 | else | |
| 680 | .{ .name_off = self.output_ar_state.name_off }, | |
| 681 | .size = @intCast(self.data.len), | |
| 682 | }); | |
| 683 | try writer.writeAll(mem.asBytes(&hdr)); | |
| 684 | try writer.writeAll(self.data); | |
| 685 | } | |
| 686 | ||
| 657 | 687 | pub fn locals(self: Object) []const Symbol.Index { |
| 658 | 688 | const end = self.first_global orelse self.symbols.items.len; |
| 659 | 689 | return self.symbols.items[0..end]; |
src/link/Elf/ZigObject.zig+8-19| ... | ... | @@ -3,7 +3,6 @@ |
| 3 | 3 | //! and any relocations that may have been emitted. |
| 4 | 4 | //! Think about this as fake in-memory Object file for the Zig module. |
| 5 | 5 | |
| 6 | /// Path is owned by Module and lives as long as *Module. | |
| 7 | 6 | path: []const u8, |
| 8 | 7 | index: File.Index, |
| 9 | 8 | |
| ... | ... | @@ -78,7 +77,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 78 | 77 | try self.atoms.append(gpa, 0); // null input section |
| 79 | 78 | try self.strtab.buffer.append(gpa, 0); |
| 80 | 79 | |
| 81 | const name_off = try self.strtab.insert(gpa, std.fs.path.stem(self.path)); | |
| 80 | const name_off = try self.strtab.insert(gpa, self.path); | |
| 82 | 81 | const symbol_index = try elf_file.addSymbol(); |
| 83 | 82 | try self.local_symbols.append(gpa, symbol_index); |
| 84 | 83 | const symbol_ptr = elf_file.symbol(symbol_index); |
| ... | ... | @@ -98,6 +97,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 98 | 97 | } |
| 99 | 98 | |
| 100 | 99 | pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 100 | allocator.free(self.path); | |
| 101 | 101 | self.local_esyms.deinit(allocator); |
| 102 | 102 | self.global_esyms.deinit(allocator); |
| 103 | 103 | self.strtab.deinit(allocator); |
| ... | ... | @@ -512,25 +512,13 @@ pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: * |
| 512 | 512 | const global = elf_file.symbol(global_index); |
| 513 | 513 | const file_ptr = global.file(elf_file).?; |
| 514 | 514 | assert(file_ptr.index() == self.index); |
| 515 | if (global.type(elf_file) == elf.SHN_UNDEF) continue; | |
| 515 | if (global.outputShndx() == null) continue; | |
| 516 | 516 | |
| 517 | 517 | const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file)); |
| 518 | 518 | ar_symtab.symtab.appendAssumeCapacity(.{ .off = off, .file_index = self.index }); |
| 519 | 519 | } |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | pub fn updateArStrtab( | |
| 523 | self: *ZigObject, | |
| 524 | allocator: Allocator, | |
| 525 | ar_strtab: *Archive.ArStrtab, | |
| 526 | ) error{OutOfMemory}!void { | |
| 527 | const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)}); | |
| 528 | defer allocator.free(name); | |
| 529 | if (name.len <= 15) return; | |
| 530 | const name_off = try ar_strtab.insert(allocator, name); | |
| 531 | self.output_ar_state.name_off = name_off; | |
| 532 | } | |
| 533 | ||
| 534 | 522 | pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void { |
| 535 | 523 | var end_pos: u64 = elf_file.shdr_table_offset.?; |
| 536 | 524 | for (elf_file.shdrs.items) |shdr| { |
| ... | ... | @@ -549,11 +537,12 @@ pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void { |
| 549 | 537 | const amt = try elf_file.base.file.?.preadAll(contents, 0); |
| 550 | 538 | if (amt != self.output_ar_state.size) return error.InputOutput; |
| 551 | 539 | |
| 552 | const name = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(self.path)}); | |
| 553 | defer gpa.free(name); | |
| 554 | ||
| 540 | const name = self.path; | |
| 555 | 541 | const hdr = Archive.setArHdr(.{ |
| 556 | .name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off }, | |
| 542 | .name = if (name.len <= Archive.max_member_name_len) | |
| 543 | .{ .name = name } | |
| 544 | else | |
| 545 | .{ .name_off = self.output_ar_state.name_off }, | |
| 557 | 546 | .size = @intCast(size), |
| 558 | 547 | }); |
| 559 | 548 | try writer.writeAll(mem.asBytes(&hdr)); |
src/link/Elf/file.zig+13-7| ... | ... | @@ -199,23 +199,30 @@ pub const File = union(enum) { |
| 199 | 199 | pub fn updateArSymtab(file: File, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { |
| 200 | 200 | return switch (file) { |
| 201 | 201 | .zig_object => |x| x.updateArSymtab(ar_symtab, elf_file), |
| 202 | .object => @panic("TODO"), | |
| 202 | .object => |x| x.updateArSymtab(ar_symtab, elf_file), | |
| 203 | 203 | inline else => unreachable, |
| 204 | 204 | }; |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | 207 | pub fn updateArStrtab(file: File, allocator: Allocator, ar_strtab: *Archive.ArStrtab) !void { |
| 208 | return switch (file) { | |
| 209 | .zig_object => |x| x.updateArStrtab(allocator, ar_strtab), | |
| 210 | .object => @panic("TODO"), | |
| 208 | const path = switch (file) { | |
| 209 | .zig_object => |x| x.path, | |
| 210 | .object => |x| x.path, | |
| 211 | inline else => unreachable, | |
| 212 | }; | |
| 213 | const state = switch (file) { | |
| 214 | .zig_object => |x| &x.output_ar_state, | |
| 215 | .object => |x| &x.output_ar_state, | |
| 211 | 216 | inline else => unreachable, |
| 212 | 217 | }; |
| 218 | if (path.len <= Archive.max_member_name_len) return; | |
| 219 | state.name_off = try ar_strtab.insert(allocator, path); | |
| 213 | 220 | } |
| 214 | 221 | |
| 215 | 222 | pub fn updateArSize(file: File, elf_file: *Elf) void { |
| 216 | 223 | return switch (file) { |
| 217 | 224 | .zig_object => |x| x.updateArSize(elf_file), |
| 218 | .object => @panic("TODO"), | |
| 225 | .object => |x| x.updateArSize(), | |
| 219 | 226 | inline else => unreachable, |
| 220 | 227 | }; |
| 221 | 228 | } |
| ... | ... | @@ -223,8 +230,7 @@ pub const File = union(enum) { |
| 223 | 230 | pub fn writeAr(file: File, elf_file: *Elf, writer: anytype) !void { |
| 224 | 231 | return switch (file) { |
| 225 | 232 | .zig_object => |x| x.writeAr(elf_file, writer), |
| 226 | // .object => |x| x.writeAr(elf_file, writer), | |
| 227 | .object => @panic("TODO"), | |
| 233 | .object => |x| x.writeAr(writer), | |
| 228 | 234 | inline else => unreachable, |
| 229 | 235 | }; |
| 230 | 236 | } |