std.os.linux.tls: Fix layout computation for the modified Variant I.

This commit is contained in:
Alex Rønne Petersen 2024-07-29 12:19:15 +02:00
parent b52e054261
commit 37275c0f69
No known key found for this signature in database

View File

@ -313,7 +313,7 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void {
// Compute the total size of the ABI-specific data plus our own `ZigTcb` structure. All the
// offsets calculated here assume a well-aligned base address.
const area_size = switch (current_variant) {
.I_original, .I_modified => blk: {
.I_original => blk: {
var l: usize = 0;
dtv_offset = l;
l += @sizeOf(Dtv);
@ -330,6 +330,24 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void {
l += block_size;
break :blk l;
},
.I_modified => blk: {
var l: usize = 0;
dtv_offset = l;
l += @sizeOf(Dtv);
// In this variant, the TLS blocks must begin immediately after the end of the ABI TCB,
// with the TP pointing to the beginning of the TLS blocks. Add padding so that the TP
// (`abi_tcb_offset`) is aligned to `align_factor` and the `ZigTcb` structure can be
// found by subtracting `@sizeOf(AbiTcb) + @sizeOf(ZigTcb)` from the TP.
const delta = (l + @sizeOf(ZigTcb) + @sizeOf(AbiTcb)) & (align_factor - 1);
if (delta > 0)
l += align_factor - delta;
l += @sizeOf(ZigTcb);
abi_tcb_offset = l;
l += @sizeOf(AbiTcb);
block_offset = l;
l += block_size;
break :blk l;
},
.II => blk: {
var l: usize = 0;
block_offset = l;