summaryrefslogtreecommitdiff
path: root/compiler/llvmGen
diff options
context:
space:
mode:
authorBen Lippmeier <benl@ouroborus.net>2010-12-10 04:59:22 +0000
committerBen Lippmeier <benl@ouroborus.net>2010-12-10 04:59:22 +0000
commit4caf239d368ef26c8d5ae7835355123b77f9a035 (patch)
tree5c38349cc7360e2e4bc4ba77fae5e92e0f01d245 /compiler/llvmGen
parent157161bae885f02930ca194f704393012ed25b6e (diff)
downloadhaskell-4caf239d368ef26c8d5ae7835355123b77f9a035.tar.gz
Defensify naked read in LLVM mangler
Diffstat (limited to 'compiler/llvmGen')
-rw-r--r--compiler/llvmGen/LlvmMangler.hs37
1 files changed, 27 insertions, 10 deletions
diff --git a/compiler/llvmGen/LlvmMangler.hs b/compiler/llvmGen/LlvmMangler.hs
index 91f22bc2e1..27d2a84782 100644
--- a/compiler/llvmGen/LlvmMangler.hs
+++ b/compiler/llvmGen/LlvmMangler.hs
@@ -19,8 +19,11 @@ import qualified Data.ByteString.Char8 as BS
import LlvmCodeGen.Ppr ( infoSection, iTableSuf )
+import Data.Char
+import Outputable
import Util
+
{- Configuration. -}
newSection, oldSection, functionSuf, tableSuf, funDivider, eol :: ByteString
newSection = BS.pack "\n.text\n"
@@ -161,10 +164,11 @@ replaceSection sec =
fixupStack :: ByteString -> ByteString -> ByteString
fixupStack fun nfun | BS.null nfun =
let -- fixup sub op
- (a, b) = BS.breakSubstring (BS.pack ", %esp\n") fun
- (a', num) = BS.breakEnd dollarPred a
- num' = BS.pack $ show (read (BS.unpack num) + 4::Int)
- fix = a' `BS.append` num'
+ (a, b) = BS.breakSubstring (BS.pack ", %esp\n") fun
+ (a', strNum) = BS.breakEnd dollarPred a
+ Just num = readInt (BS.unpack strNum)
+ num' = BS.pack $ show (num + 4::Int)
+ fix = a' `BS.append` num'
in if BS.null b
then nfun `BS.append` a
else fixupStack b (nfun `BS.append` fix)
@@ -174,15 +178,28 @@ fixupStack fun nfun =
(a, b) = BS.breakSubstring (BS.pack "jmp") fun
-- We need to avoid processing jumps to labels, they are of the form:
-- jmp\tL..., jmp\t_f..., jmpl\t_f..., jmpl\t*%eax...
- labelJump = BS.index b 4 == 'L'
- (jmp, b') = BS.break eolPred b
- (a', numx) = BS.breakEnd dollarPred a
- (num, x) = BS.break commaPred numx
- num' = BS.pack $ show (read (BS.unpack num) + 4::Int)
- fix = a' `BS.append` num' `BS.append` x `BS.append` jmp
+ labelJump = BS.index b 4 == 'L'
+ (jmp, b') = BS.break eolPred b
+ (a', numx) = BS.breakEnd dollarPred a
+ (strNum, x) = BS.break commaPred numx
+ Just num = readInt (BS.unpack strNum)
+ num' = BS.pack $ show (num + 4::Int)
+ fix = a' `BS.append` num' `BS.append` x `BS.append` jmp
in if BS.null b
then nfun `BS.append` a
else if labelJump
then fixupStack b' (nfun `BS.append` a `BS.append` jmp)
else fixupStack b' (nfun `BS.append` fix)
+
+-- | 'read' is one of my least favourite functions.
+readInt :: String -> Maybe Int
+readInt str
+ | not $ null $ filter (not . isDigit) str
+ = pprTrace "LLvmMangler"
+ (text "Cannot read" <+> text (show str) <+> text "as it's not an Int")
+ Nothing
+
+ | otherwise
+ = Just $ read str
+