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