summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-12-02 12:48:23 -0500
committerBen Gamari <ben@smart-cactus.org>2019-12-02 13:16:40 -0500
commitc8a5e73efca10e431ed9b9bbb635f889bfc4103c (patch)
tree7287decb4621aae1c28eb5d0e59b4a68821a604f
parent3a96a0b6db6a32457ae2f91bb711c2481c767656 (diff)
downloadhaskell-wip/fix-link-info-note.tar.gz
Elf: Fix link info note generationwip/fix-link-info-note
Previously we would use the `.int` assembler directive to generate 32-bit words in the note section. However, `.int` is note guaranteed to produce 4-bytes; in fact, on some platforms (e.g. AArch64) it produces 8-bytes. Use the `.4bytes` directive to avoid this. Moreover, we used the `.align` directive, which is quite platform dependent. On AArch64 it appears to not even be idempotent (despite what the documentation claims). `.balign` is consequentially preferred as it offers consistent behavior across platforms.
-rw-r--r--compiler/main/Elf.hs16
1 files changed, 4 insertions, 12 deletions
diff --git a/compiler/main/Elf.hs b/compiler/main/Elf.hs
index 648f20aad9..9e19de12dd 100644
--- a/compiler/main/Elf.hs
+++ b/compiler/main/Elf.hs
@@ -408,15 +408,6 @@ readElfNoteAsString dflags path sectionName noteId = action `catchIO` \_ -> do
-- | Generate the GAS code to create a Note section
--
-- Header fields for notes are 32-bit long (see Note [ELF specification]).
---
--- It seems there is no easy way to force GNU AS to generate a 32-bit word in
--- every case. Hence we use .int directive to create them: however "The byte
--- order and bit size of the number depends on what kind of target the assembly
--- is for." (https://sourceware.org/binutils/docs/as/Int.html#Int)
---
--- If we add new target platforms, we need to check that the generated words
--- are 32-bit long, otherwise we need to use platform specific directives to
--- force 32-bit .int in asWord32.
makeElfNote :: String -> String -> Word32 -> String -> SDoc
makeElfNote sectionName noteName typ contents = hcat [
text "\t.section ",
@@ -424,6 +415,7 @@ makeElfNote sectionName noteName typ contents = hcat [
text ",\"\",",
sectionType "note",
text "\n",
+ text "\t.balign 4\n",
-- note name length (+ 1 for ending \0)
asWord32 (length noteName + 1),
@@ -438,20 +430,20 @@ makeElfNote sectionName noteName typ contents = hcat [
text "\t.asciz \"",
text noteName,
text "\"\n",
- text "\t.align 4\n",
+ text "\t.balign 4\n",
-- note contents (.ascii to avoid ending \0) + padding
text "\t.ascii \"",
text (escape contents),
text "\"\n",
- text "\t.align 4\n"]
+ text "\t.balign 4\n"]
where
escape :: String -> String
escape = concatMap (charToC.fromIntegral.ord)
asWord32 :: Show a => a -> SDoc
asWord32 x = hcat [
- text "\t.int ",
+ text "\t.4byte ",
text (show x),
text "\n"]