| ... | @@ -5885,6 +5885,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { | ... | @@ -5885,6 +5885,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 5885 | reloc: struct { | 5885 | reloc: struct { |
| 5886 | type: MachineRelocType, | 5886 | type: MachineRelocType, |
| 5887 | dynsym_index: u32, | 5887 | dynsym_index: u32, |
| | 5888 | addend: i64, |
| 5888 | }, | 5889 | }, |
| 5889 | } = switch (elf.got.keys()[got_index]) { | 5890 | } = switch (elf.got.keys()[got_index]) { |
| 5890 | .reserved => .{ .unsigned = 0 }, | 5891 | .reserved => .{ .unsigned = 0 }, |
| ... | @@ -5918,20 +5919,25 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { | ... | @@ -5918,20 +5919,25 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 5918 | const sym_value = sym_id.value(elf); | 5919 | const sym_value = sym_id.value(elf); |
| 5919 | break :val .{ .signed = @bitCast(sym_value -% tls_size) }; | 5920 | break :val .{ .signed = @bitCast(sym_value -% tls_size) }; |
| 5920 | } | 5921 | } |
| 5921 | break :val .{ | 5922 | const reloc_type: MachineRelocType = switch (elf.ehdrField(.machine)) { |
| 5922 | .reloc = .{ | 5923 | else => |machine| @panic(@tagName(machine)), |
| 5923 | .type = switch (elf.ehdrField(.machine)) { | 5924 | .X86_64 => .{ .X86_64 = .TPOFF64 }, |
| 5924 | else => |machine| @panic(@tagName(machine)), | 5925 | .LOONGARCH => .{ .LOONGARCH = if (elf.identClass() == .@"64") .TLS_TPREL64 else .TLS_TPREL32 }, |
| 5925 | .X86_64 => .{ .X86_64 = .TPOFF64 }, | 5926 | }; |
| 5926 | .LOONGARCH => .{ .LOONGARCH = if (elf.identClass() == .@"64") .TLS_TPREL64 else .TLS_TPREL32 }, | 5927 | break :val switch (sym_id.unwrap()) { |
| 5927 | }, | 5928 | // For global symbols, just target the right dynsym with no addend. |
| 5928 | .dynsym_index = switch (sym_id.unwrap()) { | 5929 | .global => |name| .{ .reloc = .{ |
| 5929 | .global => |name| elf.globalByName(name).?.dynsym_index, | 5930 | .type = reloc_type, |
| 5930 | // TODO: I have no idea if compilers are even allowed to emit this, but if they | 5931 | .dynsym_index = elf.globalByName(name).?.dynsym_index, |
| 5931 | // are then I guess we need to add this local symbol to `.dynsym`? | 5932 | .addend = 0, |
| 5932 | .local => @panic("TODO(Elf2): GOT tpoff entry referencing local symbol"), | 5933 | } }, |
| 5933 | }, | 5934 | // For local symbols, target the null symbol (index 0) so we get the offset to the |
| 5934 | }, | 5935 | // base of our TLS block, and then use `addend` to offset to the right symbol. |
| | 5936 | .local => .{ .reloc = .{ |
| | 5937 | .type = reloc_type, |
| | 5938 | .dynsym_index = 0, |
| | 5939 | .addend = @intCast(sym_id.value(elf)), |
| | 5940 | } }, |
| 5935 | }; | 5941 | }; |
| 5936 | }, | 5942 | }, |
| 5937 | .symbol, .tlsgd1 => |sym_id, tag| val: { | 5943 | .symbol, .tlsgd1 => |sym_id, tag| val: { |
| ... | @@ -5974,6 +5980,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { | ... | @@ -5974,6 +5980,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 5974 | break :val .{ .reloc = .{ | 5980 | break :val .{ .reloc = .{ |
| 5975 | .type = if (tag == .symbol) .globDat(elf) else .dtpOffAddr(elf), | 5981 | .type = if (tag == .symbol) .globDat(elf) else .dtpOffAddr(elf), |
| 5976 | .dynsym_index = elf.globalByName(name).?.dynsym_index, | 5982 | .dynsym_index = elf.globalByName(name).?.dynsym_index, |
| | 5983 | .addend = 0, |
| 5977 | } }; | 5984 | } }; |
| 5978 | }, | 5985 | }, |
| 5979 | .tlsgd0 => |sym| switch (elf.shndx.dynamic) { | 5986 | .tlsgd0 => |sym| switch (elf.shndx.dynamic) { |
| ... | @@ -6010,6 +6017,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { | ... | @@ -6010,6 +6017,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 6010 | break :dsi elf.globalByName(name).?.dynsym_index; | 6017 | break :dsi elf.globalByName(name).?.dynsym_index; |
| 6011 | }, | 6018 | }, |
| 6012 | }, | 6019 | }, |
| | 6020 | .addend = 0, |
| 6013 | }, | 6021 | }, |
| 6014 | }, | 6022 | }, |
| 6015 | }, | 6023 | }, |
| ... | @@ -6022,6 +6030,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { | ... | @@ -6022,6 +6030,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 6022 | .LOONGARCH => .{ .LOONGARCH = if (elf.identClass() == .@"64") .TLS_DTPMOD64 else .TLS_DTPMOD32 }, | 6030 | .LOONGARCH => .{ .LOONGARCH = if (elf.identClass() == .@"64") .TLS_DTPMOD64 else .TLS_DTPMOD32 }, |
| 6023 | }, | 6031 | }, |
| 6024 | .dynsym_index = 0, | 6032 | .dynsym_index = 0, |
| | 6033 | .addend = 0, |
| 6025 | } }, | 6034 | } }, |
| 6026 | }, | 6035 | }, |
| 6027 | .tlsld1 => .{ .unsigned = 0 }, | 6036 | .tlsld1 => .{ .unsigned = 0 }, |
| ... | @@ -6065,7 +6074,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { | ... | @@ -6065,7 +6074,7 @@ fn updateGotEntry(elf: *Elf, got_index: usize) void { |
| 6065 | .type = reloc.type, | 6074 | .type = reloc.type, |
| 6066 | .offset = got_entry_addr, | 6075 | .offset = got_entry_addr, |
| 6067 | .raw_sym_index = reloc.dynsym_index, | 6076 | .raw_sym_index = reloc.dynsym_index, |
| 6068 | .addend = 0, | 6077 | .addend = reloc.addend, |
| 6069 | }).toOptional(), | 6078 | }).toOptional(), |
| 6070 | }; | 6079 | }; |
| 6071 | } | 6080 | } |