From: Davis Goodin Date: Wed, 22 Nov 2023 01:12:48 +0000 (-0800) Subject: cmd/link/internal/loadpe: fix .xdata unwind info parsing X-Git-Tag: go1.22rc1~165 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d4430f6913b0eacb662a69884d12850864616c37;p=gostls13.git cmd/link/internal/loadpe: fix .xdata unwind info parsing Unwind info in .xdata was being parsed incorrectly, causing targetOff to be incorrect and miss finding data in .xdata that it should have found. This causes a linker issue when using the MinGW MSVCRT compiler. Contains several fixes based on the exception handling docs: the offset used to get the number of unwind codes, the calculation of the target offset based on the dynamic size of the unwind data, and the UNW_FLAG_CHAININFO flag's value. Fixes #64200 Change-Id: I6483d921b2bf8a2512a95223bf3c8ce8bc63dc4a Reviewed-on: https://go-review.googlesource.com/c/go/+/544415 TryBot-Result: Gopher Robot LUCI-TryBot-Result: Go LUCI Reviewed-by: Quim Muntal Run-TryBot: Quim Muntal Reviewed-by: Than McIntosh Reviewed-by: Michael Knyszek --- diff --git a/src/cmd/link/internal/loadpe/seh.go b/src/cmd/link/internal/loadpe/seh.go index 0e2cda21dd..545958f1d6 100644 --- a/src/cmd/link/internal/loadpe/seh.go +++ b/src/cmd/link/internal/loadpe/seh.go @@ -16,8 +16,9 @@ import ( const ( UNW_FLAG_EHANDLER = 1 << 3 UNW_FLAG_UHANDLER = 2 << 3 - UNW_FLAG_CHAININFO = 3 << 3 - unwStaticDataSize = 8 + UNW_FLAG_CHAININFO = 4 << 3 + unwStaticDataSize = 4 // Bytes of unwind data before the variable length part. + unwCodeSize = 2 // Bytes per unwind code. ) // processSEH walks all pdata relocations looking for exception handler function symbols. @@ -81,14 +82,14 @@ func findHandlerInXDataAMD64(ldr *loader.Loader, xsym sym.LoaderSym, add int64) // Nothing to do. return 0 } - codes := data[3] + codes := data[2] if codes%2 != 0 { // There are always an even number of unwind codes, even if the last one is unused. codes += 1 } // The exception handler relocation is the first relocation after the unwind codes, // unless it is chained, but we will handle this case later. - targetOff := add + unwStaticDataSize*(1+int64(codes)) + targetOff := add + unwStaticDataSize + unwCodeSize*int64(codes) xrels := ldr.Relocs(xsym) xrelsCount := xrels.Count() idx := sort.Search(xrelsCount, func(i int) bool {