| ... | @@ -77,7 +77,7 @@ const RelocatableData = struct { | ... | @@ -77,7 +77,7 @@ const RelocatableData = struct { |
| 77 | /// The size in bytes of the data representing the segment within the section | 77 | /// The size in bytes of the data representing the segment within the section |
| 78 | size: u32, | 78 | size: u32, |
| 79 | /// The index within the section itself, or in case of a debug section, | 79 | /// The index within the section itself, or in case of a debug section, |
| 80 | /// the offset within the `debug_names` table. | 80 | /// the offset within the `string_table`. |
| 81 | index: u32, | 81 | index: u32, |
| 82 | /// The offset within the section where the data starts | 82 | /// The offset within the section where the data starts |
| 83 | offset: u32, | 83 | offset: u32, |
| ... | @@ -101,9 +101,16 @@ const RelocatableData = struct { | ... | @@ -101,9 +101,16 @@ const RelocatableData = struct { |
| 101 | return switch (self.type) { | 101 | return switch (self.type) { |
| 102 | .data => .data, | 102 | .data => .data, |
| 103 | .code => .function, | 103 | .code => .function, |
| 104 | .debug => unreachable, // illegal, debug sections are not represented by a symbol | 104 | .debug => .section, |
| 105 | }; | 105 | }; |
| 106 | } | 106 | } |
| | 107 | |
| | 108 | /// Returns the index within a section itself, or in case of a debug section, |
| | 109 | /// returns the section index within the object file. |
| | 110 | pub fn getIndex(self: RelocatableData) u32 { |
| | 111 | if (self.type == .debug) return self.section_index; |
| | 112 | return self.index; |
| | 113 | } |
| 107 | }; | 114 | }; |
| 108 | | 115 | |
| 109 | pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadError; | 116 | pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadError; |
| ... | @@ -205,7 +212,7 @@ pub fn importedCountByKind(self: *const Object, kind: std.wasm.ExternalKind) u32 | ... | @@ -205,7 +212,7 @@ pub fn importedCountByKind(self: *const Object, kind: std.wasm.ExternalKind) u32 |
| 205 | | 212 | |
| 206 | /// From a given `RelocatableDate`, find the corresponding debug section name | 213 | /// From a given `RelocatableDate`, find the corresponding debug section name |
| 207 | pub fn getDebugName(self: *const Object, relocatable_data: RelocatableData) []const u8 { | 214 | pub fn getDebugName(self: *const Object, relocatable_data: RelocatableData) []const u8 { |
| 208 | return std.mem.sliceTo(self.debug_names[relocatable_data.index..], 0); | 215 | return self.string_table.get(relocatable_data.index); |
| 209 | } | 216 | } |
| 210 | | 217 | |
| 211 | /// Checks if the object file is an MVP version. | 218 | /// Checks if the object file is an MVP version. |
| ... | @@ -363,6 +370,7 @@ fn Parser(comptime ReaderType: type) type { | ... | @@ -363,6 +370,7 @@ fn Parser(comptime ReaderType: type) type { |
| 363 | | 370 | |
| 364 | if (std.mem.eql(u8, name, "linking")) { | 371 | if (std.mem.eql(u8, name, "linking")) { |
| 365 | is_object_file.* = true; | 372 | is_object_file.* = true; |
| | 373 | self.object.relocatable_data = relocatable_data.items; // at this point no new relocatable sections will appear so we're free to store them. |
| 366 | try self.parseMetadata(gpa, @intCast(usize, reader.context.bytes_left)); | 374 | try self.parseMetadata(gpa, @intCast(usize, reader.context.bytes_left)); |
| 367 | } else if (std.mem.startsWith(u8, name, "reloc")) { | 375 | } else if (std.mem.startsWith(u8, name, "reloc")) { |
| 368 | try self.parseRelocations(gpa); | 376 | try self.parseRelocations(gpa); |
| ... | @@ -374,19 +382,16 @@ fn Parser(comptime ReaderType: type) type { | ... | @@ -374,19 +382,16 @@ fn Parser(comptime ReaderType: type) type { |
| 374 | errdefer gpa.free(debug_content); | 382 | errdefer gpa.free(debug_content); |
| 375 | try reader.readNoEof(debug_content); | 383 | try reader.readNoEof(debug_content); |
| 376 | | 384 | |
| 377 | const debug_name_index = @intCast(u32, debug_names.items.len); | | |
| 378 | try debug_names.ensureUnusedCapacity(name.len + 1); | | |
| 379 | debug_names.appendSliceAssumeCapacity(try gpa.dupe(u8, name)); | | |
| 380 | debug_names.appendAssumeCapacity(0); | | |
| 381 | try relocatable_data.append(.{ | 385 | try relocatable_data.append(.{ |
| 382 | .type = .debug, | 386 | .type = .debug, |
| 383 | .data = debug_content.ptr, | 387 | .data = debug_content.ptr, |
| 384 | .size = debug_size, | 388 | .size = debug_size, |
| 385 | .index = debug_name_index, | 389 | .index = try self.object.string_table.put(gpa, name), |
| 386 | .offset = len - debug_size, | 390 | .offset = len - debug_size, |
| 387 | .section_index = section_index, | 391 | .section_index = section_index, |
| 388 | }); | 392 | }); |
| 389 | } else { | 393 | } else { |
| | 394 | log.info("found unknown custom section '{s}' - skipping parsing", .{name}); |
| 390 | try reader.skipBytes(reader.context.bytes_left, .{}); | 395 | try reader.skipBytes(reader.context.bytes_left, .{}); |
| 391 | } | 396 | } |
| 392 | }, | 397 | }, |
| ... | @@ -551,9 +556,6 @@ fn Parser(comptime ReaderType: type) type { | ... | @@ -551,9 +556,6 @@ fn Parser(comptime ReaderType: type) type { |
| 551 | else => |e| return e, | 556 | else => |e| return e, |
| 552 | } | 557 | } |
| 553 | self.object.relocatable_data = relocatable_data.toOwnedSlice(); | 558 | self.object.relocatable_data = relocatable_data.toOwnedSlice(); |
| 554 | | | |
| 555 | const names = debug_names.toOwnedSlice(); | | |
| 556 | self.object.debug_names = names[0 .. names.len - 1 :0]; | | |
| 557 | } | 559 | } |
| 558 | | 560 | |
| 559 | /// Based on the "features" custom section, parses it into a list of | 561 | /// Based on the "features" custom section, parses it into a list of |
| ... | @@ -774,7 +776,12 @@ fn Parser(comptime ReaderType: type) type { | ... | @@ -774,7 +776,12 @@ fn Parser(comptime ReaderType: type) type { |
| 774 | }, | 776 | }, |
| 775 | .section => { | 777 | .section => { |
| 776 | symbol.index = try leb.readULEB128(u32, reader); | 778 | symbol.index = try leb.readULEB128(u32, reader); |
| 777 | symbol.name = try self.object.string_table.put(gpa, @tagName(symbol.tag)); | 779 | for (self.object.relocatable_data) |data| { |
| | 780 | if (data.section_index == symbol.index) { |
| | 781 | symbol.name = data.index; |
| | 782 | break; |
| | 783 | } |
| | 784 | } |
| 778 | }, | 785 | }, |
| 779 | else => { | 786 | else => { |
| 780 | symbol.index = try leb.readULEB128(u32, reader); | 787 | symbol.index = try leb.readULEB128(u32, reader); |
| ... | @@ -864,7 +871,6 @@ fn assertEnd(reader: anytype) !void { | ... | @@ -864,7 +871,6 @@ fn assertEnd(reader: anytype) !void { |
| 864 | | 871 | |
| 865 | /// Parses an object file into atoms, for code and data sections | 872 | /// Parses an object file into atoms, for code and data sections |
| 866 | pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin: *Wasm) !void { | 873 | pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin: *Wasm) !void { |
| 867 | log.debug("Parsing data section into atoms", .{}); | | |
| 868 | const Key = struct { | 874 | const Key = struct { |
| 869 | kind: Symbol.Tag, | 875 | kind: Symbol.Tag, |
| 870 | index: u32, | 876 | index: u32, |
| ... | @@ -876,7 +882,7 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin | ... | @@ -876,7 +882,7 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin |
| 876 | | 882 | |
| 877 | for (self.symtable) |symbol, symbol_index| { | 883 | for (self.symtable) |symbol, symbol_index| { |
| 878 | switch (symbol.tag) { | 884 | switch (symbol.tag) { |
| 879 | .function, .data => if (!symbol.isUndefined()) { | 885 | .function, .data, .section => if (!symbol.isUndefined()) { |
| 880 | const gop = try symbol_for_segment.getOrPut(.{ .kind = symbol.tag, .index = symbol.index }); | 886 | const gop = try symbol_for_segment.getOrPut(.{ .kind = symbol.tag, .index = symbol.index }); |
| 881 | const sym_idx = @intCast(u32, symbol_index); | 887 | const sym_idx = @intCast(u32, symbol_index); |
| 882 | if (!gop.found_existing) { | 888 | if (!gop.found_existing) { |
| ... | @@ -925,13 +931,11 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin | ... | @@ -925,13 +931,11 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin |
| 925 | | 931 | |
| 926 | try atom.code.appendSlice(gpa, relocatable_data.data[0..relocatable_data.size]); | 932 | try atom.code.appendSlice(gpa, relocatable_data.data[0..relocatable_data.size]); |
| 927 | | 933 | |
| 928 | if (relocatable_data.type != .debug) { | 934 | if (symbol_for_segment.getPtr(.{ |
| 929 | const symbols = symbol_for_segment.getPtr(.{ | 935 | .kind = relocatable_data.getSymbolKind(), |
| 930 | .kind = relocatable_data.getSymbolKind(), | 936 | .index = relocatable_data.getIndex(), |
| 931 | .index = @intCast(u32, relocatable_data.index), | 937 | })) |symbols| { |
| 932 | }) orelse continue; // encountered a segment we do not create an atom for | 938 | atom.sym_index = symbols.pop(); |
| 933 | const sym_index = symbols.pop(); | | |
| 934 | atom.sym_index = sym_index; | | |
| 935 | | 939 | |
| 936 | // symbols referencing the same atom will be added as alias | 940 | // symbols referencing the same atom will be added as alias |
| 937 | // or as 'parent' when they are global. | 941 | // or as 'parent' when they are global. |
| ... | @@ -957,7 +961,7 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin | ... | @@ -957,7 +961,7 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin |
| 957 | } else { | 961 | } else { |
| 958 | try wasm_bin.atoms.putNoClobber(gpa, final_index, atom); | 962 | try wasm_bin.atoms.putNoClobber(gpa, final_index, atom); |
| 959 | } | 963 | } |
| 960 | log.debug("Parsed into atom: '{s}'", .{self.string_table.get(self.symtable[atom.sym_index].name)}); | 964 | log.debug("Parsed into atom: '{s}' at segment index {d}", .{ self.string_table.get(self.symtable[atom.sym_index].name), final_index }); |
| 961 | } | 965 | } |
| 962 | } | 966 | } |
| 963 | | 967 | |