authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-05 07:44:35+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-07 10:21:02+02:00
log137d43c0ea77d5cc21040eadbd38fdfd945a3216
treed0317c251f8fbd503e8c35d441123200fb16b186
parent26da7c8207ff73927bcc8d5608703175074e266f

elf: get hello-world glibc working again


5 files changed, 92 insertions(+), 116 deletions(-)

src/link/Elf.zig+13-6
......@@ -2060,6 +2060,9 @@ fn scanRelocs(self: *Elf) !void {
20602060 for (self.objects.items) |index| {
20612061 try self.file(index).?.createSymbolIndirection(self);
20622062 }
2063 for (self.shared_objects.items) |index| {
2064 try self.file(index).?.createSymbolIndirection(self);
2065 }
20632066 if (self.got.flags.needs_tlsld) {
20642067 log.debug("program needs TLSLD", .{});
20652068 try self.got.addTlsLdSymbol(self);
......@@ -4431,11 +4434,13 @@ pub fn updateSymtabSize(self: *Elf) !void {
44314434 strsize += ctx.strsize;
44324435 }
44334436
4434 if (self.zig_got_section_index) |_| {
4435 self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
4436 self.zig_got.updateSymtabSize(self);
4437 nlocals += self.zig_got.output_symtab_ctx.nlocals;
4438 strsize += self.zig_got.output_symtab_ctx.strsize;
4437 if (self.zigObjectPtr()) |_| {
4438 if (self.zig_got_section_index) |_| {
4439 self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
4440 self.zig_got.updateSymtabSize(self);
4441 nlocals += self.zig_got.output_symtab_ctx.nlocals;
4442 strsize += self.zig_got.output_symtab_ctx.strsize;
4443 }
44394444 }
44404445
44414446 if (self.got_section_index) |_| {
......@@ -4574,7 +4579,9 @@ fn writeSyntheticSections(self: *Elf) !void {
45744579 const shdr = self.shdrs.items[shndx];
45754580 try self.got.addRela(self);
45764581 try self.copy_rel.addRela(self);
4577 try self.zig_got.addRela(self);
4582 if (self.zigObjectPtr()) |_| {
4583 try self.zig_got.addRela(self);
4584 }
45784585 self.sortRelaDyn();
45794586 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
45804587 }
src/link/Elf/Object.zig-45
......@@ -561,51 +561,6 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
561561 }
562562}
563563
564pub fn createSymbolIndirection(self: *Object, elf_file: *Elf) !void {
565 for (self.symbols.items, 0..) |*sym, i| {
566 const ref = self.resolveSymbol(@intCast(i), elf_file);
567 const ref_sym = elf_file.symbol(ref) orelse continue;
568 if (ref_sym.file(elf_file).?.index() != self.index) continue;
569 if (!sym.isLocal(elf_file) and !sym.flags.has_dynamic) {
570 log.debug("'{s}' is non-local", .{sym.name(elf_file)});
571 try elf_file.dynsym.addSymbol(ref, elf_file);
572 }
573 if (sym.flags.needs_got) {
574 log.debug("'{s}' needs GOT", .{sym.name(elf_file)});
575 _ = try elf_file.got.addGotSymbol(ref, elf_file);
576 }
577 if (sym.flags.needs_plt) {
578 if (sym.flags.is_canonical) {
579 log.debug("'{s}' needs CPLT", .{sym.name(elf_file)});
580 sym.flags.@"export" = true;
581 try elf_file.plt.addSymbol(ref, elf_file);
582 } else if (sym.flags.needs_got) {
583 log.debug("'{s}' needs PLTGOT", .{sym.name(elf_file)});
584 try elf_file.plt_got.addSymbol(ref, elf_file);
585 } else {
586 log.debug("'{s}' needs PLT", .{sym.name(elf_file)});
587 try elf_file.plt.addSymbol(ref, elf_file);
588 }
589 }
590 if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
591 log.debug("'{s}' needs COPYREL", .{sym.name(elf_file)});
592 try elf_file.copy_rel.addSymbol(ref, elf_file);
593 }
594 if (sym.flags.needs_tlsgd) {
595 log.debug("'{s}' needs TLSGD", .{sym.name(elf_file)});
596 try elf_file.got.addTlsGdSymbol(ref, elf_file);
597 }
598 if (sym.flags.needs_gottp) {
599 log.debug("'{s}' needs GOTTP", .{sym.name(elf_file)});
600 try elf_file.got.addGotTpSymbol(ref, elf_file);
601 }
602 if (sym.flags.needs_tlsdesc) {
603 log.debug("'{s}' needs TLSDESC", .{sym.name(elf_file)});
604 try elf_file.got.addTlsDescSymbol(ref, elf_file);
605 }
606 }
607}
608
609564pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
610565 const gpa = elf_file.base.comp.gpa;
611566
src/link/Elf/SharedObject.zig+10-3
......@@ -219,9 +219,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct {
219219 self.versionString(self.versyms.items[i]),
220220 });
221221 defer gpa.free(mangled);
222 const name_off = @as(u32, @intCast(self.strtab.items.len));
223 try self.strtab.writer(gpa).print("{s}\x00", .{mangled});
224 break :blk name_off;
222 break :blk try self.addString(gpa, mangled);
225223 } else sym.st_name;
226224 const out_esym_index: u32 = @intCast(self.symtab.items.len);
227225 const out_esym = self.symtab.addOneAssumeCapacity();
......@@ -230,6 +228,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct {
230228 const out_sym_index = self.addSymbolAssumeCapacity();
231229 const out_sym = &self.symbols.items[out_sym_index];
232230 out_sym.value = @intCast(out_esym.st_value);
231 out_sym.name_offset = name_off;
233232 out_sym.ref = .{ .index = 0, .file = 0 };
234233 out_sym.esym_index = out_esym_index;
235234 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
394393 return aliases.items[start..end];
395394}
396395
396fn addString(self: *SharedObject, allocator: Allocator, str: []const u8) !u32 {
397 const off: u32 = @intCast(self.strtab.items.len);
398 try self.strtab.ensureUnusedCapacity(allocator, str.len + 1);
399 self.strtab.appendSliceAssumeCapacity(str);
400 self.strtab.appendAssumeCapacity(0);
401 return off;
402}
403
397404pub fn getString(self: SharedObject, off: u32) [:0]const u8 {
398405 assert(off < self.strtab.items.len);
399406 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);
src/link/Elf/ZigObject.zig-58
......@@ -442,64 +442,6 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
442442 }
443443}
444444
445pub fn createSymbolIndirection(self: *ZigObject, elf_file: *Elf) !void {
446 const impl = struct {
447 fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
448 if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
449 log.debug("'{s}' is non-local", .{sym.name(ef)});
450 try ef.dynsym.addSymbol(ref, ef);
451 }
452 if (sym.flags.needs_got) {
453 log.debug("'{s}' needs GOT", .{sym.name(ef)});
454 _ = try ef.got.addGotSymbol(ref, ef);
455 }
456 if (sym.flags.needs_plt) {
457 if (sym.flags.is_canonical) {
458 log.debug("'{s}' needs CPLT", .{sym.name(ef)});
459 sym.flags.@"export" = true;
460 try ef.plt.addSymbol(ref, ef);
461 } else if (sym.flags.needs_got) {
462 log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
463 try ef.plt_got.addSymbol(ref, ef);
464 } else {
465 log.debug("'{s}' needs PLT", .{sym.name(ef)});
466 try ef.plt.addSymbol(ref, ef);
467 }
468 }
469 if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
470 log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
471 try ef.copy_rel.addSymbol(ref, ef);
472 }
473 if (sym.flags.needs_tlsgd) {
474 log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
475 try ef.got.addTlsGdSymbol(ref, ef);
476 }
477 if (sym.flags.needs_gottp) {
478 log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
479 try ef.got.addGotTpSymbol(ref, ef);
480 }
481 if (sym.flags.needs_tlsdesc) {
482 log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
483 try ef.got.addTlsDescSymbol(ref, ef);
484 }
485 }
486 }.impl;
487 for (self.local_symbols.items, 0..) |index, i| {
488 const sym = &self.symbols.items[index];
489 const ref = self.resolveSymbol(@intCast(i), elf_file);
490 const ref_sym = elf_file.symbol(ref) orelse continue;
491 if (ref_sym.file(elf_file).?.index() != self.index) continue;
492 try impl(sym, ref, elf_file);
493 }
494 for (self.global_symbols.items, 0..) |index, i| {
495 const sym = &self.symbols.items[index];
496 const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
497 const ref_sym = elf_file.symbol(ref) orelse continue;
498 if (ref_sym.file(elf_file).?.index() != self.index) continue;
499 try impl(sym, ref, elf_file);
500 }
501}
502
503445pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
504446 for (self.global_symbols.items, 0..) |index, i| {
505447 const global = self.symbols.items[index];
src/link/Elf/file.zig+69-4
......@@ -101,10 +101,74 @@ pub const File = union(enum) {
101101 }
102102
103103 pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void {
104 return switch (file) {
105 .linker_defined, .shared_object => unreachable,
106 inline else => |x| x.createSymbolIndirection(elf_file),
107 };
104 const impl = struct {
105 fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
106 if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
107 log.debug("'{s}' is non-local", .{sym.name(ef)});
108 try ef.dynsym.addSymbol(ref, ef);
109 }
110 if (sym.flags.needs_got) {
111 log.debug("'{s}' needs GOT", .{sym.name(ef)});
112 _ = try ef.got.addGotSymbol(ref, ef);
113 }
114 if (sym.flags.needs_plt) {
115 if (sym.flags.is_canonical) {
116 log.debug("'{s}' needs CPLT", .{sym.name(ef)});
117 sym.flags.@"export" = true;
118 try ef.plt.addSymbol(ref, ef);
119 } else if (sym.flags.needs_got) {
120 log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
121 try ef.plt_got.addSymbol(ref, ef);
122 } else {
123 log.debug("'{s}' needs PLT", .{sym.name(ef)});
124 try ef.plt.addSymbol(ref, ef);
125 }
126 }
127 if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
128 log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
129 try ef.copy_rel.addSymbol(ref, ef);
130 }
131 if (sym.flags.needs_tlsgd) {
132 log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
133 try ef.got.addTlsGdSymbol(ref, ef);
134 }
135 if (sym.flags.needs_gottp) {
136 log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
137 try ef.got.addGotTpSymbol(ref, ef);
138 }
139 if (sym.flags.needs_tlsdesc) {
140 log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
141 try ef.got.addTlsDescSymbol(ref, ef);
142 }
143 }
144 }.impl;
145
146 switch (file) {
147 .zig_object => |x| {
148 for (x.local_symbols.items, 0..) |idx, i| {
149 const sym = &x.symbols.items[idx];
150 const ref = x.resolveSymbol(@intCast(i), elf_file);
151 const ref_sym = elf_file.symbol(ref) orelse continue;
152 if (ref_sym.file(elf_file).?.index() != x.index) continue;
153 try impl(sym, ref, elf_file);
154 }
155 for (x.global_symbols.items, 0..) |idx, i| {
156 const sym = &x.symbols.items[idx];
157 const ref = x.resolveSymbol(@intCast(i | ZigObject.global_symbol_bit), elf_file);
158 const ref_sym = elf_file.symbol(ref) orelse continue;
159 if (ref_sym.file(elf_file).?.index() != x.index) continue;
160 try impl(sym, ref, elf_file);
161 }
162 },
163 inline else => |x| {
164 for (x.symbols.items, 0..) |*sym, i| {
165 const ref = x.resolveSymbol(@intCast(i), elf_file);
166 const ref_sym = elf_file.symbol(ref) orelse continue;
167 if (ref_sym.file(elf_file).?.index() != x.index) continue;
168 try impl(sym, ref, elf_file);
169 }
170 },
171 }
108172 }
109173
110174 pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {
......@@ -239,6 +303,7 @@ pub const File = union(enum) {
239303
240304const std = @import("std");
241305const elf = std.elf;
306const log = std.log.scoped(.link);
242307
243308const Allocator = std.mem.Allocator;
244309const Archive = @import("Archive.zig");