Skip to content

Commit

Permalink
Merge pull request #21681 from ziglang/reduce-flush
Browse files Browse the repository at this point in the history
link.Elf: eliminate an O(N^2) algorithm in flush()
  • Loading branch information
andrewrk authored Oct 12, 2024
2 parents 7e530c1 + de04a8a commit f7c5882
Show file tree
Hide file tree
Showing 20 changed files with 806 additions and 740 deletions.
11 changes: 5 additions & 6 deletions lib/compiler/objcopy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,6 @@ fn ElfFile(comptime is_64: bool) type {
const Elf_Shdr = if (is_64) elf.Elf64_Shdr else elf.Elf32_Shdr;
const Elf_Chdr = if (is_64) elf.Elf64_Chdr else elf.Elf32_Chdr;
const Elf_Sym = if (is_64) elf.Elf64_Sym else elf.Elf32_Sym;
const Elf_Verdef = if (is_64) elf.Elf64_Verdef else elf.Elf32_Verdef;
const Elf_OffSize = if (is_64) elf.Elf64_Off else elf.Elf32_Off;

return struct {
Expand Down Expand Up @@ -1179,11 +1178,11 @@ fn ElfFile(comptime is_64: bool) type {
const data = try allocator.alignedAlloc(u8, section_memory_align, src_data.len);
@memcpy(data, src_data);

const defs = @as([*]Elf_Verdef, @ptrCast(data))[0 .. @as(usize, @intCast(src.sh_size)) / @sizeOf(Elf_Verdef)];
for (defs) |*def| {
if (def.vd_ndx != elf.SHN_UNDEF)
def.vd_ndx = sections_update[src.sh_info].remap_idx;
}
const defs = @as([*]elf.Verdef, @ptrCast(data))[0 .. @as(usize, @intCast(src.sh_size)) / @sizeOf(elf.Verdef)];
for (defs) |*def| switch (def.ndx) {
.LOCAL, .GLOBAL => {},
else => def.ndx = @enumFromInt(sections_update[src.sh_info].remap_idx),
};

break :dst_data data;
},
Expand Down
8 changes: 8 additions & 0 deletions lib/std/Build/Cache.zig
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ pub const File = struct {
inode: fs.File.INode,
size: u64,
mtime: i128,

pub fn fromFs(fs_stat: fs.File.Stat) Stat {
return .{
.inode = fs_stat.inode,
.size = fs_stat.size,
.mtime = fs_stat.mtime,
};
}
};

pub fn deinit(self: *File, gpa: Allocator) void {
Expand Down
30 changes: 14 additions & 16 deletions lib/std/dynamic_library.zig
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub const ElfDynLib = struct {
strings: [*:0]u8,
syms: [*]elf.Sym,
hashtab: [*]posix.Elf_Symndx,
versym: ?[*]u16,
versym: ?[*]elf.Versym,
verdef: ?*elf.Verdef,
memory: []align(mem.page_size) u8,

Expand Down Expand Up @@ -319,19 +319,19 @@ pub const ElfDynLib = struct {
var maybe_strings: ?[*:0]u8 = null;
var maybe_syms: ?[*]elf.Sym = null;
var maybe_hashtab: ?[*]posix.Elf_Symndx = null;
var maybe_versym: ?[*]u16 = null;
var maybe_versym: ?[*]elf.Versym = null;
var maybe_verdef: ?*elf.Verdef = null;

{
var i: usize = 0;
while (dynv[i] != 0) : (i += 2) {
const p = base + dynv[i + 1];
switch (dynv[i]) {
elf.DT_STRTAB => maybe_strings = @as([*:0]u8, @ptrFromInt(p)),
elf.DT_SYMTAB => maybe_syms = @as([*]elf.Sym, @ptrFromInt(p)),
elf.DT_HASH => maybe_hashtab = @as([*]posix.Elf_Symndx, @ptrFromInt(p)),
elf.DT_VERSYM => maybe_versym = @as([*]u16, @ptrFromInt(p)),
elf.DT_VERDEF => maybe_verdef = @as(*elf.Verdef, @ptrFromInt(p)),
elf.DT_STRTAB => maybe_strings = @ptrFromInt(p),
elf.DT_SYMTAB => maybe_syms = @ptrFromInt(p),
elf.DT_HASH => maybe_hashtab = @ptrFromInt(p),
elf.DT_VERSYM => maybe_versym = @ptrFromInt(p),
elf.DT_VERDEF => maybe_verdef = @ptrFromInt(p),
else => {},
}
}
Expand Down Expand Up @@ -399,18 +399,16 @@ pub const ElfDynLib = struct {
}
};

fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [*:0]u8) bool {
fn checkver(def_arg: *elf.Verdef, vsym_arg: elf.Versym, vername: []const u8, strings: [*:0]u8) bool {
var def = def_arg;
const vsym = @as(u32, @bitCast(vsym_arg)) & 0x7fff;
const vsym_index = vsym_arg.VERSION;
while (true) {
if (0 == (def.vd_flags & elf.VER_FLG_BASE) and (def.vd_ndx & 0x7fff) == vsym)
break;
if (def.vd_next == 0)
return false;
def = @as(*elf.Verdef, @ptrFromInt(@intFromPtr(def) + def.vd_next));
if (0 == (def.flags & elf.VER_FLG_BASE) and @intFromEnum(def.ndx) == vsym_index) break;
if (def.next == 0) return false;
def = @ptrFromInt(@intFromPtr(def) + def.next);
}
const aux = @as(*elf.Verdaux, @ptrFromInt(@intFromPtr(def) + def.vd_aux));
return mem.eql(u8, vername, mem.sliceTo(strings + aux.vda_name, 0));
const aux: *elf.Verdaux = @ptrFromInt(@intFromPtr(def) + def.aux);
return mem.eql(u8, vername, mem.sliceTo(strings + aux.name, 0));
}

test "ElfDynLib" {
Expand Down
Loading

0 comments on commit f7c5882

Please sign in to comment.