From 358b508051333882d4099acca8f269e6fb2b7d65 Mon Sep 17 00:00:00 2001 From: Bertram Felgenhauer Date: Thu, 3 May 2018 18:03:53 +0300 Subject: [PATCH] Compute DW_FORM_block length correctly; also fixes #15068 Before this patch, the pprUnwindwExpr function computed the length of by the following assembly fragment: .uleb128 1f-.-1 1: That is, to compute the length, it takes the difference of the label 1 and the address of the .uleb128 directive, and subtracts 1. In #15068 it was reported that `as` from binutils 4.30 has trouble with evaluating the `.` part of the expression. However, there is actually a problem with the expression, if the length of the data ever becomes larger than 128: In that case, the .uleb128 directive will emit more than 1 byte, and the computed length will be wrong. The present patch changes the assembly fragment to use two labels, which fixes both these problems. .uleb128 2f-1f 1: 2: Test Plan: validate Reviewers: bgamari, osa1 Reviewed By: bgamari Subscribers: thomie, carter GHC Trac Issues: #15068 Differential Revision: https://phabricator.haskell.org/D4654 --- compiler/nativeGen/Dwarf/Types.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/nativeGen/Dwarf/Types.hs b/compiler/nativeGen/Dwarf/Types.hs index 23a2c920e7..579ed0d256 100644 --- a/compiler/nativeGen/Dwarf/Types.hs +++ b/compiler/nativeGen/Dwarf/Types.hs @@ -492,9 +492,11 @@ pprUnwindExpr spIsCFA expr pprE (UwPlus u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_plus pprE (UwMinus u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_minus pprE (UwTimes u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_mul - in text "\t.uleb128 1f-.-1" $$ -- DW_FORM_block length + in text "\t.uleb128 2f-1f" $$ -- DW_FORM_block length + -- computed as the difference of the following local labels 2: and 1: + text "1:" $$ pprE expr $$ - text "1:" + text "2:" -- | Generate code for re-setting the unwind information for a -- register to @undefined@ -- 2.17.0