Make the NCG distinguish between the read-only data section and the
"relocatable read-only data" section.
Read-only data is supposed to be _really_ read-only, whereas "relrodata"
can have relocations, but should not be modified by the program at runtime.
For Linux, put relrodata into ".data" by default, as the dynamic linker
tends to do evil things to avoid relocating things in read-only sections.
= Text
| Data
| ReadOnlyData
= Text
| Data
| ReadOnlyData
+ | RelocatableReadOnlyData
| UninitialisedData
| OtherSection String
| UninitialisedData
| OtherSection String
Text -> section <+> doubleQuotes (ptext SLIT("text"))
Data -> section <+> doubleQuotes (ptext SLIT("data"))
ReadOnlyData -> section <+> doubleQuotes (ptext SLIT("readonly"))
Text -> section <+> doubleQuotes (ptext SLIT("text"))
Data -> section <+> doubleQuotes (ptext SLIT("data"))
ReadOnlyData -> section <+> doubleQuotes (ptext SLIT("readonly"))
+ RelocatableReadOnlyData
+ -> section <+> doubleQuotes (ptext SLIT("relreadonly"))
UninitialisedData -> section <+> doubleQuotes (ptext SLIT("uninitialised"))
OtherSection s' -> section <+> doubleQuotes (text s')
where
UninitialisedData -> section <+> doubleQuotes (ptext SLIT("uninitialised"))
OtherSection s' -> section <+> doubleQuotes (text s')
where
emitRODataLits :: CLabel -> [CmmLit] -> Code
-- Emit a read-only data block
emitRODataLits lbl lits
emitRODataLits :: CLabel -> [CmmLit] -> Code
-- Emit a read-only data block
emitRODataLits lbl lits
- = emitData ReadOnlyData (CmmDataLabel lbl : map CmmStaticLit lits)
+ = emitData section (CmmDataLabel lbl : map CmmStaticLit lits)
+ where section | any needsRelocation lits = RelocatableReadOnlyData
+ | otherwise = ReadOnlyData
+ needsRelocation (CmmLabel _) = True
+ needsRelocation (CmmLabelOff _ _) = True
+ needsRelocation _ = False
mkStringCLit :: String -> FCode CmmLit
-- Make a global definition for the string,
mkStringCLit :: String -> FCode CmmLit
-- Make a global definition for the string,
dynRef <- cmmMakeDynamicReference addImportNat False lbl
(tableReg,t_code) <- getSomeReg $ dynRef
let
dynRef <- cmmMakeDynamicReference addImportNat False lbl
(tableReg,t_code) <- getSomeReg $ dynRef
let
- jumpTable = map jumpTableEntry ids
-
+ jumpTable = map jumpTableEntryRel ids
+
+ jumpTableEntryRel Nothing
+ = CmmStaticLit (CmmInt 0 wordRep)
+ jumpTableEntryRel (Just (BlockId id))
+ = CmmStaticLit (CmmLabelDiffOff blockLabel lbl 0)
+ where blockLabel = mkAsmTempLabel id
+
code = e_code `appOL` t_code `appOL` toOL [
LDATA ReadOnlyData (CmmDataLabel lbl : jumpTable),
SLW tmp reg (RIImm (ImmInt 2)),
LD I32 tmp (AddrRegReg tableReg tmp),
code = e_code `appOL` t_code `appOL` toOL [
LDATA ReadOnlyData (CmmDataLabel lbl : jumpTable),
SLW tmp reg (RIImm (ImmInt 2)),
LD I32 tmp (AddrRegReg tableReg tmp),
+ ADD tmp tmp (RIReg tableReg),
MTCTR tmp,
BCTR [ id | Just id <- ids ]
]
MTCTR tmp,
BCTR [ id | Just id <- ids ]
]
-- -----------------------------------------------------------------------------
-- pprData: print a 'CmmStatic'
-- -----------------------------------------------------------------------------
-- pprData: print a 'CmmStatic'
-#if defined(linux_TARGET_OS)
-#if defined(powerpc_TARGET_ARCH) || defined(i386_TARGET_ARCH)
- -- Hack to make dynamic linking work
-pprSectionHeader ReadOnlyData
- | not opt_PIC && not opt_Static
- = pprSectionHeader Data
-#endif
-#endif
-
pprSectionHeader Text
= ptext
IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
pprSectionHeader Text
= ptext
IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
- ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
+ ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const\n.align 2"),
SLIT(".section .rodata\n\t.align 2"))
,))))
SLIT(".section .rodata\n\t.align 2"))
,))))
+pprSectionHeader RelocatableReadOnlyData
+ = ptext
+ IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
+ ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
+ ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
+ ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
+ SLIT(".data\n\t.align 2"))
+ ,))))
pprSectionHeader UninitialisedData
= ptext
IF_ARCH_alpha(SLIT("\t.bss\n\t.align 3")
pprSectionHeader UninitialisedData
= ptext
IF_ARCH_alpha(SLIT("\t.bss\n\t.align 3")