mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 01:27:16 +08:00
proc: round TLS segment size to its alignment (#1682)
The fix for #1428 was buggy, partly because I communicated poorly. Sorry about that. The size of the TLS segment should be padded such that TLS addresses are congruent in the file to where they will end up memory, i.e. (tlsoffset%align) == (vaddr%align). In most cases, vaddr will be aligned and it won't matter, but if not then simply aligning the end of the segment is incorrect. This should be right. (For the record, the current rounding logic is working in bits, but PtrSize is in bytes, so it wasn't working as originally intended either.)
This commit is contained in:
committed by
Derek Parker
parent
dd3c2d63cc
commit
8954858ee8
@ -980,9 +980,13 @@ func (bi *BinaryInfo) setGStructOffsetElf(image *Image, exe *elf.File, wg *sync.
|
||||
bi.gStructOffset = ^uint64(8) + 1 // -8
|
||||
return
|
||||
}
|
||||
memsz := tls.Memsz
|
||||
|
||||
memsz = (memsz + uint64(bi.Arch.PtrSize()) - 1) & ^uint64(bi.Arch.PtrSize()-1) // align to pointer-sized-boundary
|
||||
// According to https://reviews.llvm.org/D61824, linkers must pad the actual
|
||||
// size of the TLS segment to ensure that (tlsoffset%align) == (vaddr%align).
|
||||
// This formula, copied from the lld code, matches that.
|
||||
// https://github.com/llvm-mirror/lld/blob/9aef969544981d76bea8e4d1961d3a6980980ef9/ELF/InputSection.cpp#L643
|
||||
memsz := tls.Memsz + (-tls.Vaddr-tls.Memsz)&(tls.Align-1)
|
||||
|
||||
// The TLS register points to the end of the TLS block, which is
|
||||
// tls.Memsz long. runtime.tlsg is an offset from the beginning of that block.
|
||||
bi.gStructOffset = ^(memsz) + 1 + tlsg.Value // -tls.Memsz + tlsg.Value
|
||||
|
||||
Reference in New Issue
Block a user