Elf: Fix link info note generation
authorBen Gamari <ben@smart-cactus.org>
Mon, 2 Dec 2019 17:48:23 +0000 (12:48 -0500)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Wed, 4 Dec 2019 02:05:27 +0000 (21:05 -0500)
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.

compiler/main/Elf.hs

index 648f20a..9e19de1 100644 (file)
@@ -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"]