| ... | ... | @@ -1678,6 +1678,8 @@ fn parseLibrary( |
| 1678 | 1678 | |
| 1679 | 1679 | if (Archive.isArchive(in_file)) { |
| 1680 | 1680 | try self.parseArchive(in_file, lib.path, must_link, ctx); |
| 1681 | } else if (SharedObject.isSharedObject(in_file)) { |
| 1682 | try self.parseSharedObject(in_file, lib, ctx); |
| 1681 | 1683 | } else return error.UnknownFileType; |
| 1682 | 1684 | } |
| 1683 | 1685 | |
| ... | ... | @@ -1732,6 +1734,34 @@ fn parseArchive( |
| 1732 | 1734 | } |
| 1733 | 1735 | } |
| 1734 | 1736 | |
| 1737 | fn parseSharedObject( |
| 1738 | self: *Elf, |
| 1739 | in_file: std.fs.File, |
| 1740 | lib: SystemLib, |
| 1741 | ctx: *ParseErrorCtx, |
| 1742 | ) ParseError!void { |
| 1743 | const tracy = trace(@src()); |
| 1744 | defer tracy.end(); |
| 1745 | |
| 1746 | const gpa = self.base.allocator; |
| 1747 | const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32)); |
| 1748 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| 1749 | self.files.set(index, .{ .shared_object = .{ |
| 1750 | .path = lib.path, |
| 1751 | .data = data, |
| 1752 | .index = index, |
| 1753 | .needed = lib.needed, |
| 1754 | .alive = lib.needed, |
| 1755 | } }); |
| 1756 | try self.shared_objects.append(gpa, index); |
| 1757 | |
| 1758 | const shared_object = self.file(index).?.shared_object; |
| 1759 | try shared_object.parse(self); |
| 1760 | |
| 1761 | ctx.detected_cpu_arch = shared_object.header.?.e_machine.toTargetCpuArch().?; |
| 1762 | if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch; |
| 1763 | } |
| 1764 | |
| 1735 | 1765 | /// When resolving symbols, we approach the problem similarly to `mold`. |
| 1736 | 1766 | /// 1. Resolve symbols across all objects (including those preemptively extracted archives). |
| 1737 | 1767 | /// 2. Resolve symbols across all shared objects. |
| ... | ... | @@ -3437,23 +3467,23 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3437 | 3467 | self.rela_iplt_start_index = try linker_defined.addGlobal("__rela_iplt_start", self); |
| 3438 | 3468 | self.rela_iplt_end_index = try linker_defined.addGlobal("__rela_iplt_end", self); |
| 3439 | 3469 | |
| 3440 | | // for (self.objects.items) |index| { |
| 3441 | | // const object = self.getFile(index).?.object; |
| 3442 | | // for (object.atoms.items) |atom_index| { |
| 3443 | | // if (self.getStartStopBasename(atom_index)) |name| { |
| 3444 | | // const gpa = self.base.allocator; |
| 3445 | | // try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2); |
| 3446 | | |
| 3447 | | // const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 3448 | | // defer gpa.free(start); |
| 3449 | | // const stop = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); |
| 3450 | | // defer gpa.free(stop); |
| 3451 | | |
| 3452 | | // self.start_stop_indexes.appendAssumeCapacity(try internal.addSyntheticGlobal(start, self)); |
| 3453 | | // self.start_stop_indexes.appendAssumeCapacity(try internal.addSyntheticGlobal(stop, self)); |
| 3454 | | // } |
| 3455 | | // } |
| 3456 | | // } |
| 3470 | for (self.objects.items) |index| { |
| 3471 | const object = self.file(index).?.object; |
| 3472 | for (object.atoms.items) |atom_index| { |
| 3473 | if (self.getStartStopBasename(atom_index)) |name| { |
| 3474 | const gpa = self.base.allocator; |
| 3475 | try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2); |
| 3476 | |
| 3477 | const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 3478 | defer gpa.free(start); |
| 3479 | const stop = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); |
| 3480 | defer gpa.free(stop); |
| 3481 | |
| 3482 | self.start_stop_indexes.appendAssumeCapacity(try linker_defined.addGlobal(start, self)); |
| 3483 | self.start_stop_indexes.appendAssumeCapacity(try linker_defined.addGlobal(stop, self)); |
| 3484 | } |
| 3485 | } |
| 3486 | } |
| 3457 | 3487 | |
| 3458 | 3488 | linker_defined.resolveSymbols(self); |
| 3459 | 3489 | } |
| ... | ... | @@ -5199,6 +5229,15 @@ pub fn isCIdentifier(name: []const u8) bool { |
| 5199 | 5229 | return true; |
| 5200 | 5230 | } |
| 5201 | 5231 | |
| 5232 | fn getStartStopBasename(self: *Elf, atom_index: Atom.Index) ?[]const u8 { |
| 5233 | const atom_ptr = self.atom(atom_index) orelse return null; |
| 5234 | const name = atom_ptr.name(self); |
| 5235 | if (atom_ptr.inputShdr(self).sh_flags & elf.SHF_ALLOC != 0 and name.len > 0) { |
| 5236 | if (isCIdentifier(name)) return name; |
| 5237 | } |
| 5238 | return null; |
| 5239 | } |
| 5240 | |
| 5202 | 5241 | pub fn atom(self: *Elf, atom_index: Atom.Index) ?*Atom { |
| 5203 | 5242 | if (atom_index == 0) return null; |
| 5204 | 5243 | assert(atom_index < self.atoms.items.len); |