authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-05-20 17:08:42+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-05-26 06:30:28+01:00
log2f9cae345a309bfc28b0cc09bc57247fe0f07a9a
treed63b4efbebe5b2507b415320990cf60ec70eb0ba
parentf097b4c3daff18d5dce1178831f294601f023b7b
signaturelock-open Commit is signed but in an unrecognized format.

Elf2: handle STB_GNU_UNIQUE in input objects


1 files changed, 14 insertions(+), 6 deletions(-)

src/link/Elf2.zig+14-6
...@@ -3264,20 +3264,24 @@ fn loadObject(...@@ -3264,20 +3264,24 @@ fn loadObject(
3264 };3264 };
32653265
3266 if (input_sym.shndx == std.elf.SHN_UNDEF) switch (input_sym.info.bind) {3266 if (input_sym.shndx == std.elf.SHN_UNDEF) switch (input_sym.info.bind) {
3267 _ => |bind| return diags.failParse(3267 else => |bind| return diags.failParse(
3268 path,3268 path,
3269 "symbol '{s}' has unsupported binding (0x{x})",3269 "symbol '{s}' has unsupported binding (0x{x})",
3270 .{ name, bind },3270 .{ name, bind },
3271 ),3271 ),
3272 .LOCAL => continue,3272 .LOCAL => continue,
3273 .GLOBAL, .WEAK => |bind| {3273 .GLOBAL, .WEAK, .GNU_UNIQUE => |bind| {
3274 si.* = elf.addGlobalSymbolAssumeCapacity(.{3274 si.* = elf.addGlobalSymbolAssumeCapacity(.{
3275 .node = .none,3275 .node = .none,
3276 .name = try .string(elf, name),3276 .name = try .string(elf, name),
3277 .value = input_sym.value,3277 .value = input_sym.value,
3278 .size = input_sym.size,3278 .size = input_sym.size,
3279 .type = sym_type,3279 .type = sym_type,
3280 .bind = if (bind == .WEAK) .weak else .strong,3280 .bind = switch (bind) {
3281 .WEAK, .GNU_UNIQUE => .weak,
3282 .GLOBAL => .strong,
3283 else => unreachable,
3284 },
3281 .visibility = input_sym.other.visibility,3285 .visibility = input_sym.other.visibility,
3282 .shndx = .UNDEF,3286 .shndx = .UNDEF,
3283 }) catch |err| switch (err) {3287 }) catch |err| switch (err) {
...@@ -3290,7 +3294,7 @@ fn loadObject(...@@ -3290,7 +3294,7 @@ fn loadObject(
3290 const input_section_node = (sections[input_sym.shndx].isi orelse continue).node(elf);3294 const input_section_node = (sections[input_sym.shndx].isi orelse continue).node(elf);
32913295
3292 switch (input_sym.info.bind) {3296 switch (input_sym.info.bind) {
3293 _ => |bind| return diags.failParse(3297 else => |bind| return diags.failParse(
3294 path,3298 path,
3295 "symbol '{s}' has unsupported binding (0x{x})",3299 "symbol '{s}' has unsupported binding (0x{x})",
3296 .{ name, bind },3300 .{ name, bind },
...@@ -3306,14 +3310,18 @@ fn loadObject(...@@ -3306,14 +3310,18 @@ fn loadObject(
3306 });3310 });
3307 si.* = .local(lsi);3311 si.* = .local(lsi);
3308 },3312 },
3309 .GLOBAL, .WEAK => |bind| {3313 .GLOBAL, .WEAK, .GNU_UNIQUE => |bind| {
3310 si.* = elf.addGlobalSymbolAssumeCapacity(.{3314 si.* = elf.addGlobalSymbolAssumeCapacity(.{
3311 .node = input_section_node,3315 .node = input_section_node,
3312 .name = try .string(elf, name),3316 .name = try .string(elf, name),
3313 .value = input_sym.value,3317 .value = input_sym.value,
3314 .size = input_sym.size,3318 .size = input_sym.size,
3315 .type = sym_type,3319 .type = sym_type,
3316 .bind = if (bind == .WEAK) .weak else .strong,3320 .bind = switch (bind) {
3321 .WEAK, .GNU_UNIQUE => .weak,
3322 .GLOBAL => .strong,
3323 else => unreachable,
3324 },
3317 .visibility = input_sym.other.visibility,3325 .visibility = input_sym.other.visibility,
3318 .shndx = elf.getNodeShndx(input_section_node),3326 .shndx = elf.getNodeShndx(input_section_node),
3319 }) catch |err| switch (err) {3327 }) catch |err| switch (err) {