authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-11-10 02:26:02-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-11-11 01:47:27-05:00
log79a9f3a4180dfe395c816b86a2afc79edc302e65
tree30c2e85005c886d946973c9b42ff1a148a021be7
parent8647e4d3110dd269f6c377ecd8315a19e094758a

Elf2: fix relocations against untyped symbols


1 files changed, 20 insertions(+), 21 deletions(-)

src/link/Elf2.zig+20-21
...@@ -1444,15 +1444,9 @@ pub fn symtabSlice(elf: *Elf) SymtabSlice {...@@ -1444,15 +1444,9 @@ pub fn symtabSlice(elf: *Elf) SymtabSlice {
1444 const slice = elf.si.symtab.node(elf).slice(&elf.mf);1444 const slice = elf.si.symtab.node(elf).slice(&elf.mf);
1445 return switch (elf.identClass()) {1445 return switch (elf.identClass()) {
1446 .NONE, _ => unreachable,1446 .NONE, _ => unreachable,
1447 inline else => |class| @unionInit(1447 inline else => |class| @unionInit(SymtabSlice, @tagName(class), @ptrCast(@alignCast(
1448 SymtabSlice,1448 slice[0..std.mem.alignBackwardAnyAlign(usize, slice.len, @sizeOf(class.ElfN().Sym))],
1449 @tagName(class),1449 ))),
1450 @ptrCast(@alignCast(slice[0..std.mem.alignBackwardAnyAlign(
1451 usize,
1452 slice.len,
1453 @sizeOf(class.ElfN().Sym),
1454 )])),
1455 ),
1456 };1450 };
1457}1451}
14581452
...@@ -1471,11 +1465,9 @@ pub fn dynsymSlice(elf: *Elf) SymtabSlice {...@@ -1471,11 +1465,9 @@ pub fn dynsymSlice(elf: *Elf) SymtabSlice {
1471 const slice = elf.si.dynsym.node(elf).slice(&elf.mf);1465 const slice = elf.si.dynsym.node(elf).slice(&elf.mf);
1472 return switch (elf.identClass()) {1466 return switch (elf.identClass()) {
1473 .NONE, _ => unreachable,1467 .NONE, _ => unreachable,
1474 inline else => |class| @unionInit(1468 inline else => |class| @unionInit(SymtabSlice, @tagName(class), @ptrCast(@alignCast(
1475 SymtabSlice,1469 slice[0..std.mem.alignBackwardAnyAlign(usize, slice.len, @sizeOf(class.ElfN().Sym))],
1476 @tagName(class),1470 ))),
1477 @ptrCast(@alignCast(slice)),
1478 ),
1479 };1471 };
1480}1472}
14811473
...@@ -1853,7 +1845,7 @@ fn loadObject(...@@ -1853,7 +1845,7 @@ fn loadObject(
1853 break :strtab strtab;1845 break :strtab strtab;
1854 };1846 };
1855 defer gpa.free(strtab);1847 defer gpa.free(strtab);
1856 const symnum = std.math.divExact(1848 const symnum = std.math.sub(u32, std.math.divExact(
1857 u32,1849 u32,
1858 @intCast(symtab.shdr.size),1850 @intCast(symtab.shdr.size),
1859 @intCast(symtab.shdr.entsize),1851 @intCast(symtab.shdr.entsize),
...@@ -1861,9 +1853,9 @@ fn loadObject(...@@ -1861,9 +1853,9 @@ fn loadObject(
1861 path,1853 path,
1862 "symtab section size (0x{x}) is not a multiple of entsize (0x{x})",1854 "symtab section size (0x{x}) is not a multiple of entsize (0x{x})",
1863 .{ symtab.shdr.size, symtab.shdr.entsize },1855 .{ symtab.shdr.size, symtab.shdr.entsize },
1864 );1856 ), 1) catch continue;
1865 symmap.clearRetainingCapacity();1857 symmap.clearRetainingCapacity();
1866 try symmap.resize(gpa, std.math.sub(u32, symnum, 1) catch continue);1858 try symmap.resize(gpa, symnum);
1867 try elf.symtab.ensureUnusedCapacity(gpa, symnum);1859 try elf.symtab.ensureUnusedCapacity(gpa, symnum);
1868 try elf.globals.ensureUnusedCapacity(gpa, symnum);1860 try elf.globals.ensureUnusedCapacity(gpa, symnum);
1869 try fr.seekTo(fl.offset + symtab.shdr.offset + symtab.shdr.entsize);1861 try fr.seekTo(fl.offset + symtab.shdr.offset + symtab.shdr.entsize);
...@@ -1874,13 +1866,13 @@ fn loadObject(...@@ -1874,13 +1866,13 @@ fn loadObject(
1874 if (input_sym.name >= strtab.len or input_sym.shndx == std.elf.SHN_UNDEF or1866 if (input_sym.name >= strtab.len or input_sym.shndx == std.elf.SHN_UNDEF or
1875 input_sym.shndx >= ehdr.shnum) continue;1867 input_sym.shndx >= ehdr.shnum) continue;
1876 switch (input_sym.info.type) {1868 switch (input_sym.info.type) {
1877 else => continue,1869 .NOTYPE, .OBJECT, .FUNC => {},
1878 .SECTION => {1870 .SECTION => {
1879 const section = &sections[input_sym.shndx];1871 const section = &sections[input_sym.shndx];
1880 if (input_sym.value == section.shdr.addr) si.* = section.si;1872 if (input_sym.value == section.shdr.addr) si.* = section.si;
1881 continue;1873 continue;
1882 },1874 },
1883 .OBJECT, .FUNC => {},1875 else => continue,
1884 }1876 }
1885 const name = std.mem.sliceTo(strtab[input_sym.name..], 0);1877 const name = std.mem.sliceTo(strtab[input_sym.name..], 0);
1886 const parent_si = sections[input_sym.shndx].si;1878 const parent_si = sections[input_sym.shndx].si;
...@@ -1935,8 +1927,13 @@ fn loadObject(...@@ -1935,8 +1927,13 @@ fn loadObject(
1935 };1927 };
1936 if (rels.shdr.entsize < @sizeOf(Rel))1928 if (rels.shdr.entsize < @sizeOf(Rel))
1937 return diags.failParse(path, "unsupported rel entsize", .{});1929 return diags.failParse(path, "unsupported rel entsize", .{});
1930
1938 const loc_sec = &sections[rels.shdr.info];1931 const loc_sec = &sections[rels.shdr.info];
1939 if (loc_sec.si == .null) continue;1932 if (loc_sec.si == .null) continue;
1933 const loc_sym = loc_sec.si.get(elf);
1934 assert(loc_sym.loc_relocs == .none);
1935 loc_sym.loc_relocs = @enumFromInt(elf.relocs.items.len);
1936
1940 const relnum = std.math.divExact(1937 const relnum = std.math.divExact(
1941 u32,1938 u32,
1942 @intCast(rels.shdr.size),1939 @intCast(rels.shdr.size),
...@@ -1951,7 +1948,7 @@ fn loadObject(...@@ -1951,7 +1948,7 @@ fn loadObject(
1951 for (0..relnum) |_| {1948 for (0..relnum) |_| {
1952 const rel = try r.peekStruct(Rel, target_endian);1949 const rel = try r.peekStruct(Rel, target_endian);
1953 try r.discardAll64(rels.shdr.entsize);1950 try r.discardAll64(rels.shdr.entsize);
1954 if (rel.info.sym >= symnum) continue;1951 if (rel.info.sym == 0 or rel.info.sym > symnum) continue;
1955 const target_si = symmap.items[rel.info.sym - 1];1952 const target_si = symmap.items[rel.info.sym - 1];
1956 if (target_si == .null) continue;1953 if (target_si == .null) continue;
1957 elf.addRelocAssumeCapacity(1954 elf.addRelocAssumeCapacity(
...@@ -2854,10 +2851,12 @@ fn flushInputSection(elf: *Elf, isi: Node.InputSectionIndex) !void {...@@ -2854,10 +2851,12 @@ fn flushInputSection(elf: *Elf, isi: Node.InputSectionIndex) !void {
2854 var fr = file.reader(comp.io, &.{});2851 var fr = file.reader(comp.io, &.{});
2855 try fr.seekTo(file_loc.offset);2852 try fr.seekTo(file_loc.offset);
2856 var nw: MappedFile.Node.Writer = undefined;2853 var nw: MappedFile.Node.Writer = undefined;
2857 isi.symbol(elf).node(elf).writer(&elf.mf, gpa, &nw);2854 const si = isi.symbol(elf);
2855 si.node(elf).writer(&elf.mf, gpa, &nw);
2858 defer nw.deinit();2856 defer nw.deinit();
2859 if (try nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) != file_loc.size)2857 if (try nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) != file_loc.size)
2860 return error.EndOfStream;2858 return error.EndOfStream;
2859 si.applyLocationRelocs(elf);
2861}2860}
28622861
2863fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void {2862fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void {