unify parsing codepaths between relocatable and non
This commit is contained in:
@@ -765,6 +765,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
|
||||
const target = self.getTarget();
|
||||
const debug_fmt_strip = comp.config.debug_format == .strip;
|
||||
const default_sym_version = self.default_sym_version;
|
||||
const is_static_lib = self.base.isStaticLib();
|
||||
|
||||
if (comp.verbose_link) {
|
||||
const argv = &self.dump_argv_list;
|
||||
@@ -780,7 +781,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
|
||||
.res => unreachable,
|
||||
.dso_exact => @panic("TODO"),
|
||||
.object => |obj| try parseObject(self, obj),
|
||||
.archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, &self.first_eflags, target, debug_fmt_strip, default_sym_version, &self.objects, obj),
|
||||
.archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, &self.first_eflags, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib),
|
||||
.dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target),
|
||||
}
|
||||
}
|
||||
@@ -823,17 +824,17 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| try zig_object.flush(self, tid);
|
||||
|
||||
if (module_obj_path) |path| openParseObjectReportingFailure(self, path);
|
||||
|
||||
switch (comp.config.output_mode) {
|
||||
.Obj => return relocatable.flushObject(self, comp, module_obj_path),
|
||||
.Obj => return relocatable.flushObject(self, comp),
|
||||
.Lib => switch (comp.config.link_mode) {
|
||||
.dynamic => {},
|
||||
.static => return relocatable.flushStaticLib(self, comp, module_obj_path),
|
||||
.static => return relocatable.flushStaticLib(self, comp),
|
||||
},
|
||||
.Exe => {},
|
||||
}
|
||||
|
||||
if (module_obj_path) |path| openParseObjectReportingFailure(self, path);
|
||||
|
||||
if (diags.hasErrors()) return error.FlushFailure;
|
||||
|
||||
// If we haven't already, create a linker-generated input file comprising of
|
||||
@@ -1149,7 +1150,10 @@ fn parseObject(self: *Elf, obj: link.Input.Object) ParseError!void {
|
||||
try self.objects.append(gpa, index);
|
||||
|
||||
const object = self.file(index).?.object;
|
||||
try object.parse(gpa, diags, obj.path, handle, first_eflags, target, debug_fmt_strip, default_sym_version);
|
||||
try object.parseCommon(gpa, diags, obj.path, handle, target, first_eflags);
|
||||
if (!self.base.isStaticLib()) {
|
||||
try object.parse(gpa, diags, obj.path, handle, target, debug_fmt_strip, default_sym_version);
|
||||
}
|
||||
}
|
||||
|
||||
fn parseArchive(
|
||||
@@ -1163,6 +1167,7 @@ fn parseArchive(
|
||||
default_sym_version: elf.Versym,
|
||||
objects: *std.ArrayListUnmanaged(File.Index),
|
||||
obj: link.Input.Object,
|
||||
is_static_lib: bool,
|
||||
) ParseError!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@@ -1171,13 +1176,17 @@ fn parseArchive(
|
||||
var archive = try Archive.parse(gpa, diags, file_handles, obj.path, fh);
|
||||
defer archive.deinit(gpa);
|
||||
|
||||
const init_alive = if (is_static_lib) true else obj.must_link;
|
||||
|
||||
for (archive.objects) |extracted| {
|
||||
const index: File.Index = @intCast(try files.addOne(gpa));
|
||||
files.set(index, .{ .object = extracted });
|
||||
const object = &files.items(.data)[index].object;
|
||||
object.index = index;
|
||||
object.alive = obj.must_link;
|
||||
try object.parse(gpa, diags, obj.path, obj.file, first_eflags, target, debug_fmt_strip, default_sym_version);
|
||||
object.alive = init_alive;
|
||||
try object.parseCommon(gpa, diags, obj.path, obj.file, target, first_eflags);
|
||||
if (!is_static_lib)
|
||||
try object.parse(gpa, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version);
|
||||
try objects.append(gpa, index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +69,10 @@ pub fn parse(
|
||||
/// For error reporting purposes only.
|
||||
path: Path,
|
||||
handle: fs.File,
|
||||
first_eflags: *?elf.Word,
|
||||
target: std.Target,
|
||||
debug_fmt_strip: bool,
|
||||
default_sym_version: elf.Versym,
|
||||
) !void {
|
||||
try self.parseCommon(gpa, diags, path, handle, first_eflags, target);
|
||||
|
||||
// Append null input merge section
|
||||
try self.input_merge_sections.append(gpa, .{});
|
||||
// Allocate atom index 0 to null atom
|
||||
@@ -95,14 +92,14 @@ pub fn parse(
|
||||
}
|
||||
}
|
||||
|
||||
fn parseCommon(
|
||||
pub fn parseCommon(
|
||||
self: *Object,
|
||||
gpa: Allocator,
|
||||
diags: *Diags,
|
||||
path: Path,
|
||||
handle: fs.File,
|
||||
first_eflags: *?elf.Word,
|
||||
target: std.Target,
|
||||
first_eflags: *?elf.Word,
|
||||
) !void {
|
||||
const offset = if (self.archive) |ar| ar.offset else 0;
|
||||
const file_size = (try handle.stat()).size;
|
||||
@@ -1036,15 +1033,6 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parseAr(self: *Object, path: Path, elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const diags = &elf_file.base.comp.link_diags;
|
||||
const handle = elf_file.fileHandle(self.file_handle);
|
||||
const first_eflags = &elf_file.first_eflags;
|
||||
const target = elf_file.base.comp.root_mod.resolved_target.result;
|
||||
try self.parseCommon(gpa, diags, path, handle, first_eflags, target);
|
||||
}
|
||||
|
||||
pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void {
|
||||
pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void {
|
||||
const gpa = comp.gpa;
|
||||
const diags = &comp.link_diags;
|
||||
|
||||
if (module_obj_path) |path| {
|
||||
parseObjectStaticLibReportingFailure(elf_file, path);
|
||||
}
|
||||
|
||||
if (diags.hasErrors()) return error.FlushFailure;
|
||||
|
||||
// First, we flush relocatable object file generated with our backends.
|
||||
@@ -134,11 +130,9 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path
|
||||
if (diags.hasErrors()) return error.FlushFailure;
|
||||
}
|
||||
|
||||
pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void {
|
||||
pub fn flushObject(elf_file: *Elf, comp: *Compilation) link.File.FlushError!void {
|
||||
const diags = &comp.link_diags;
|
||||
|
||||
if (module_obj_path) |path| elf_file.openParseObjectReportingFailure(path);
|
||||
|
||||
if (diags.hasErrors()) return error.FlushFailure;
|
||||
|
||||
// Now, we are ready to resolve the symbols across all input files.
|
||||
@@ -188,36 +182,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?Path) l
|
||||
if (diags.hasErrors()) return error.FlushFailure;
|
||||
}
|
||||
|
||||
fn parseObjectStaticLibReportingFailure(elf_file: *Elf, path: Path) void {
|
||||
const diags = &elf_file.base.comp.link_diags;
|
||||
parseObjectStaticLib(elf_file, path) catch |err| switch (err) {
|
||||
error.LinkFailure => return,
|
||||
else => |e| diags.addParseError(path, "parsing object failed: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn parseObjectStaticLib(elf_file: *Elf, path: Path) Elf.ParseError!void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const file_handles = &elf_file.file_handles;
|
||||
|
||||
const handle = try path.root_dir.handle.openFile(path.sub_path, .{});
|
||||
const fh = try Elf.addFileHandle(gpa, file_handles, handle);
|
||||
|
||||
const index: File.Index = @intCast(try elf_file.files.addOne(gpa));
|
||||
elf_file.files.set(index, .{ .object = .{
|
||||
.path = .{
|
||||
.root_dir = path.root_dir,
|
||||
.sub_path = try gpa.dupe(u8, path.sub_path),
|
||||
},
|
||||
.file_handle = fh,
|
||||
.index = index,
|
||||
} });
|
||||
try elf_file.objects.append(gpa, index);
|
||||
|
||||
const object = elf_file.file(index).?.object;
|
||||
try object.parseAr(path, elf_file);
|
||||
}
|
||||
|
||||
fn claimUnresolved(elf_file: *Elf) void {
|
||||
if (elf_file.zigObjectPtr()) |zig_object| {
|
||||
zig_object.claimUnresolvedRelocatable(elf_file);
|
||||
|
||||
Reference in New Issue
Block a user