mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
elf: get hello-world glibc working again
This commit is contained in:
parent
26da7c8207
commit
137d43c0ea
@ -2060,6 +2060,9 @@ fn scanRelocs(self: *Elf) !void {
|
|||||||
for (self.objects.items) |index| {
|
for (self.objects.items) |index| {
|
||||||
try self.file(index).?.createSymbolIndirection(self);
|
try self.file(index).?.createSymbolIndirection(self);
|
||||||
}
|
}
|
||||||
|
for (self.shared_objects.items) |index| {
|
||||||
|
try self.file(index).?.createSymbolIndirection(self);
|
||||||
|
}
|
||||||
if (self.got.flags.needs_tlsld) {
|
if (self.got.flags.needs_tlsld) {
|
||||||
log.debug("program needs TLSLD", .{});
|
log.debug("program needs TLSLD", .{});
|
||||||
try self.got.addTlsLdSymbol(self);
|
try self.got.addTlsLdSymbol(self);
|
||||||
@ -4431,11 +4434,13 @@ pub fn updateSymtabSize(self: *Elf) !void {
|
|||||||
strsize += ctx.strsize;
|
strsize += ctx.strsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.zig_got_section_index) |_| {
|
if (self.zigObjectPtr()) |_| {
|
||||||
self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
|
if (self.zig_got_section_index) |_| {
|
||||||
self.zig_got.updateSymtabSize(self);
|
self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
|
||||||
nlocals += self.zig_got.output_symtab_ctx.nlocals;
|
self.zig_got.updateSymtabSize(self);
|
||||||
strsize += self.zig_got.output_symtab_ctx.strsize;
|
nlocals += self.zig_got.output_symtab_ctx.nlocals;
|
||||||
|
strsize += self.zig_got.output_symtab_ctx.strsize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.got_section_index) |_| {
|
if (self.got_section_index) |_| {
|
||||||
@ -4574,7 +4579,9 @@ fn writeSyntheticSections(self: *Elf) !void {
|
|||||||
const shdr = self.shdrs.items[shndx];
|
const shdr = self.shdrs.items[shndx];
|
||||||
try self.got.addRela(self);
|
try self.got.addRela(self);
|
||||||
try self.copy_rel.addRela(self);
|
try self.copy_rel.addRela(self);
|
||||||
try self.zig_got.addRela(self);
|
if (self.zigObjectPtr()) |_| {
|
||||||
|
try self.zig_got.addRela(self);
|
||||||
|
}
|
||||||
self.sortRelaDyn();
|
self.sortRelaDyn();
|
||||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
|
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -561,51 +561,6 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createSymbolIndirection(self: *Object, elf_file: *Elf) !void {
|
|
||||||
for (self.symbols.items, 0..) |*sym, i| {
|
|
||||||
const ref = self.resolveSymbol(@intCast(i), elf_file);
|
|
||||||
const ref_sym = elf_file.symbol(ref) orelse continue;
|
|
||||||
if (ref_sym.file(elf_file).?.index() != self.index) continue;
|
|
||||||
if (!sym.isLocal(elf_file) and !sym.flags.has_dynamic) {
|
|
||||||
log.debug("'{s}' is non-local", .{sym.name(elf_file)});
|
|
||||||
try elf_file.dynsym.addSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_got) {
|
|
||||||
log.debug("'{s}' needs GOT", .{sym.name(elf_file)});
|
|
||||||
_ = try elf_file.got.addGotSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_plt) {
|
|
||||||
if (sym.flags.is_canonical) {
|
|
||||||
log.debug("'{s}' needs CPLT", .{sym.name(elf_file)});
|
|
||||||
sym.flags.@"export" = true;
|
|
||||||
try elf_file.plt.addSymbol(ref, elf_file);
|
|
||||||
} else if (sym.flags.needs_got) {
|
|
||||||
log.debug("'{s}' needs PLTGOT", .{sym.name(elf_file)});
|
|
||||||
try elf_file.plt_got.addSymbol(ref, elf_file);
|
|
||||||
} else {
|
|
||||||
log.debug("'{s}' needs PLT", .{sym.name(elf_file)});
|
|
||||||
try elf_file.plt.addSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
|
|
||||||
log.debug("'{s}' needs COPYREL", .{sym.name(elf_file)});
|
|
||||||
try elf_file.copy_rel.addSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_tlsgd) {
|
|
||||||
log.debug("'{s}' needs TLSGD", .{sym.name(elf_file)});
|
|
||||||
try elf_file.got.addTlsGdSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_gottp) {
|
|
||||||
log.debug("'{s}' needs GOTTP", .{sym.name(elf_file)});
|
|
||||||
try elf_file.got.addGotTpSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_tlsdesc) {
|
|
||||||
log.debug("'{s}' needs TLSDESC", .{sym.name(elf_file)});
|
|
||||||
try elf_file.got.addTlsDescSymbol(ref, elf_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
|
pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
|
||||||
const gpa = elf_file.base.comp.gpa;
|
const gpa = elf_file.base.comp.gpa;
|
||||||
|
|
||||||
|
|||||||
@ -219,9 +219,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct {
|
|||||||
self.versionString(self.versyms.items[i]),
|
self.versionString(self.versyms.items[i]),
|
||||||
});
|
});
|
||||||
defer gpa.free(mangled);
|
defer gpa.free(mangled);
|
||||||
const name_off = @as(u32, @intCast(self.strtab.items.len));
|
break :blk try self.addString(gpa, mangled);
|
||||||
try self.strtab.writer(gpa).print("{s}\x00", .{mangled});
|
|
||||||
break :blk name_off;
|
|
||||||
} else sym.st_name;
|
} else sym.st_name;
|
||||||
const out_esym_index: u32 = @intCast(self.symtab.items.len);
|
const out_esym_index: u32 = @intCast(self.symtab.items.len);
|
||||||
const out_esym = self.symtab.addOneAssumeCapacity();
|
const out_esym = self.symtab.addOneAssumeCapacity();
|
||||||
@ -230,6 +228,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct {
|
|||||||
const out_sym_index = self.addSymbolAssumeCapacity();
|
const out_sym_index = self.addSymbolAssumeCapacity();
|
||||||
const out_sym = &self.symbols.items[out_sym_index];
|
const out_sym = &self.symbols.items[out_sym_index];
|
||||||
out_sym.value = @intCast(out_esym.st_value);
|
out_sym.value = @intCast(out_esym.st_value);
|
||||||
|
out_sym.name_offset = name_off;
|
||||||
out_sym.ref = .{ .index = 0, .file = 0 };
|
out_sym.ref = .{ .index = 0, .file = 0 };
|
||||||
out_sym.esym_index = out_esym_index;
|
out_sym.esym_index = out_esym_index;
|
||||||
out_sym.version_index = self.versyms.items[out_esym_index];
|
out_sym.version_index = self.versyms.items[out_esym_index];
|
||||||
@ -394,6 +393,14 @@ pub fn symbolAliases(self: *SharedObject, index: u32, elf_file: *Elf) []const u3
|
|||||||
return aliases.items[start..end];
|
return aliases.items[start..end];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addString(self: *SharedObject, allocator: Allocator, str: []const u8) !u32 {
|
||||||
|
const off: u32 = @intCast(self.strtab.items.len);
|
||||||
|
try self.strtab.ensureUnusedCapacity(allocator, str.len + 1);
|
||||||
|
self.strtab.appendSliceAssumeCapacity(str);
|
||||||
|
self.strtab.appendAssumeCapacity(0);
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getString(self: SharedObject, off: u32) [:0]const u8 {
|
pub fn getString(self: SharedObject, off: u32) [:0]const u8 {
|
||||||
assert(off < self.strtab.items.len);
|
assert(off < self.strtab.items.len);
|
||||||
return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);
|
return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);
|
||||||
|
|||||||
@ -442,64 +442,6 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createSymbolIndirection(self: *ZigObject, elf_file: *Elf) !void {
|
|
||||||
const impl = struct {
|
|
||||||
fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
|
|
||||||
if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
|
|
||||||
log.debug("'{s}' is non-local", .{sym.name(ef)});
|
|
||||||
try ef.dynsym.addSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_got) {
|
|
||||||
log.debug("'{s}' needs GOT", .{sym.name(ef)});
|
|
||||||
_ = try ef.got.addGotSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_plt) {
|
|
||||||
if (sym.flags.is_canonical) {
|
|
||||||
log.debug("'{s}' needs CPLT", .{sym.name(ef)});
|
|
||||||
sym.flags.@"export" = true;
|
|
||||||
try ef.plt.addSymbol(ref, ef);
|
|
||||||
} else if (sym.flags.needs_got) {
|
|
||||||
log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
|
|
||||||
try ef.plt_got.addSymbol(ref, ef);
|
|
||||||
} else {
|
|
||||||
log.debug("'{s}' needs PLT", .{sym.name(ef)});
|
|
||||||
try ef.plt.addSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
|
|
||||||
log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
|
|
||||||
try ef.copy_rel.addSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_tlsgd) {
|
|
||||||
log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
|
|
||||||
try ef.got.addTlsGdSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_gottp) {
|
|
||||||
log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
|
|
||||||
try ef.got.addGotTpSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
if (sym.flags.needs_tlsdesc) {
|
|
||||||
log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
|
|
||||||
try ef.got.addTlsDescSymbol(ref, ef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.impl;
|
|
||||||
for (self.local_symbols.items, 0..) |index, i| {
|
|
||||||
const sym = &self.symbols.items[index];
|
|
||||||
const ref = self.resolveSymbol(@intCast(i), elf_file);
|
|
||||||
const ref_sym = elf_file.symbol(ref) orelse continue;
|
|
||||||
if (ref_sym.file(elf_file).?.index() != self.index) continue;
|
|
||||||
try impl(sym, ref, elf_file);
|
|
||||||
}
|
|
||||||
for (self.global_symbols.items, 0..) |index, i| {
|
|
||||||
const sym = &self.symbols.items[index];
|
|
||||||
const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
|
|
||||||
const ref_sym = elf_file.symbol(ref) orelse continue;
|
|
||||||
if (ref_sym.file(elf_file).?.index() != self.index) continue;
|
|
||||||
try impl(sym, ref, elf_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
|
pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
|
||||||
for (self.global_symbols.items, 0..) |index, i| {
|
for (self.global_symbols.items, 0..) |index, i| {
|
||||||
const global = self.symbols.items[index];
|
const global = self.symbols.items[index];
|
||||||
|
|||||||
@ -101,10 +101,74 @@ pub const File = union(enum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void {
|
pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void {
|
||||||
return switch (file) {
|
const impl = struct {
|
||||||
.linker_defined, .shared_object => unreachable,
|
fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
|
||||||
inline else => |x| x.createSymbolIndirection(elf_file),
|
if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
|
||||||
};
|
log.debug("'{s}' is non-local", .{sym.name(ef)});
|
||||||
|
try ef.dynsym.addSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
if (sym.flags.needs_got) {
|
||||||
|
log.debug("'{s}' needs GOT", .{sym.name(ef)});
|
||||||
|
_ = try ef.got.addGotSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
if (sym.flags.needs_plt) {
|
||||||
|
if (sym.flags.is_canonical) {
|
||||||
|
log.debug("'{s}' needs CPLT", .{sym.name(ef)});
|
||||||
|
sym.flags.@"export" = true;
|
||||||
|
try ef.plt.addSymbol(ref, ef);
|
||||||
|
} else if (sym.flags.needs_got) {
|
||||||
|
log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
|
||||||
|
try ef.plt_got.addSymbol(ref, ef);
|
||||||
|
} else {
|
||||||
|
log.debug("'{s}' needs PLT", .{sym.name(ef)});
|
||||||
|
try ef.plt.addSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
|
||||||
|
log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
|
||||||
|
try ef.copy_rel.addSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
if (sym.flags.needs_tlsgd) {
|
||||||
|
log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
|
||||||
|
try ef.got.addTlsGdSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
if (sym.flags.needs_gottp) {
|
||||||
|
log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
|
||||||
|
try ef.got.addGotTpSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
if (sym.flags.needs_tlsdesc) {
|
||||||
|
log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
|
||||||
|
try ef.got.addTlsDescSymbol(ref, ef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.impl;
|
||||||
|
|
||||||
|
switch (file) {
|
||||||
|
.zig_object => |x| {
|
||||||
|
for (x.local_symbols.items, 0..) |idx, i| {
|
||||||
|
const sym = &x.symbols.items[idx];
|
||||||
|
const ref = x.resolveSymbol(@intCast(i), elf_file);
|
||||||
|
const ref_sym = elf_file.symbol(ref) orelse continue;
|
||||||
|
if (ref_sym.file(elf_file).?.index() != x.index) continue;
|
||||||
|
try impl(sym, ref, elf_file);
|
||||||
|
}
|
||||||
|
for (x.global_symbols.items, 0..) |idx, i| {
|
||||||
|
const sym = &x.symbols.items[idx];
|
||||||
|
const ref = x.resolveSymbol(@intCast(i | ZigObject.global_symbol_bit), elf_file);
|
||||||
|
const ref_sym = elf_file.symbol(ref) orelse continue;
|
||||||
|
if (ref_sym.file(elf_file).?.index() != x.index) continue;
|
||||||
|
try impl(sym, ref, elf_file);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inline else => |x| {
|
||||||
|
for (x.symbols.items, 0..) |*sym, i| {
|
||||||
|
const ref = x.resolveSymbol(@intCast(i), elf_file);
|
||||||
|
const ref_sym = elf_file.symbol(ref) orelse continue;
|
||||||
|
if (ref_sym.file(elf_file).?.index() != x.index) continue;
|
||||||
|
try impl(sym, ref, elf_file);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {
|
pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {
|
||||||
@ -239,6 +303,7 @@ pub const File = union(enum) {
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const elf = std.elf;
|
const elf = std.elf;
|
||||||
|
const log = std.log.scoped(.link);
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Archive = @import("Archive.zig");
|
const Archive = @import("Archive.zig");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user