Tag ForeignCalls with the package they correspond to
[ghc-hetmet.git] / compiler / nativeGen / PIC.hs
1 {-
2   This module handles generation of position independent code and
3   dynamic-linking related issues for the native code generator.
4
5   This depends both the architecture and OS, so we define it here
6   instead of in one of the architecture specific modules.
7   
8   Things outside this module which are related to this:
9   
10   + module CLabel
11     - PIC base label (pretty printed as local label 1)
12     - DynamicLinkerLabels - several kinds:
13         CodeStub, SymbolPtr, GotSymbolPtr, GotSymbolOffset
14     - labelDynamic predicate
15   + module Cmm
16     - The GlobalReg datatype has a PicBaseReg constructor
17     - The CmmLit datatype has a CmmLabelDiffOff constructor
18   + codeGen & RTS
19     - When tablesNextToCode, no absolute addresses are stored in info tables
20       any more. Instead, offsets from the info label are used.
21     - For Win32 only, SRTs might contain addresses of __imp_ symbol pointers
22       because Win32 doesn't support external references in data sections.
23       TODO: make sure this still works, it might be bitrotted
24   + NCG
25     - The cmmToCmm pass in AsmCodeGen calls cmmMakeDynamicReference for all
26       labels.
27     - nativeCodeGen calls pprImportedSymbol and pprGotDeclaration to output
28       all the necessary stuff for imported symbols.
29     - The NCG monad keeps track of a list of imported symbols.
30     - MachCodeGen invokes initializePicBase to generate code to initialize
31       the PIC base register when needed.
32     - MachCodeGen calls cmmMakeDynamicReference whenever it uses a CLabel
33       that wasn't in the original Cmm code (e.g. floating point literals).
34   + The Mangler
35     - The mangler converts absolure refs to relative refs in info tables
36     - Symbol pointers, stub code and PIC calculations that are generated
37       by GCC are left intact by the mangler (so far only on ppc-darwin
38       and ppc-linux).
39 -}
40
41 module PIC (
42         cmmMakeDynamicReference,
43         ReferenceKind(..),
44         needImportedSymbols,
45         pprImportedSymbol,
46         pprGotDeclaration,
47
48         initializePicBase_ppc,
49         initializePicBase_x86
50 )
51
52 where
53
54 import qualified PPC.Instr      as PPC
55 import qualified PPC.Regs       as PPC
56
57 import qualified X86.Instr      as X86
58
59 import Platform
60 import Instruction
61 import Size
62 import Reg
63 import NCGMonad
64
65
66 import Cmm
67 import CLabel           ( CLabel, ForeignLabelSource(..), pprCLabel,
68                           mkDynamicLinkerLabel, DynamicLinkerLabelInfo(..),
69                           dynamicLinkerLabelInfo, mkPicBaseLabel,
70                           labelDynamic, externallyVisibleCLabel )
71
72 import CLabel           ( mkForeignLabel, pprDebugCLabel )
73
74
75 import StaticFlags      ( opt_PIC, opt_Static )
76 import BasicTypes
77
78 import Pretty
79 import qualified Outputable
80
81 import Panic            ( panic )
82 import DynFlags
83 import FastString
84
85
86
87 --------------------------------------------------------------------------------
88 -- It gets called by the cmmToCmm pass for every CmmLabel in the Cmm
89 -- code. It does The Right Thing(tm) to convert the CmmLabel into a
90 -- position-independent, dynamic-linking-aware reference to the thing
91 -- in question.
92 -- Note that this also has to be called from MachCodeGen in order to
93 -- access static data like floating point literals (labels that were
94 -- created after the cmmToCmm pass).
95 -- The function must run in a monad that can keep track of imported symbols
96 -- A function for recording an imported symbol must be passed in:
97 -- - addImportCmmOpt for the CmmOptM monad
98 -- - addImportNat for the NatM monad.
99
100 data ReferenceKind 
101         = DataReference
102         | CallReference
103         | JumpReference
104         deriving(Eq)
105
106
107 cmmMakeDynamicReference
108   :: Monad m => DynFlags
109              -> (CLabel -> m ())  -- a monad & a function
110                                   -- used for recording imported symbols
111              -> ReferenceKind     -- whether this is the target of a jump
112              -> CLabel            -- the label
113              -> m CmmExpr
114
115 cmmMakeDynamicReference dflags addImport referenceKind lbl
116    = cmmMakeDynamicReference' dflags addImport referenceKind lbl
117
118   
119 cmmMakeDynamicReference' dflags addImport referenceKind lbl
120   | Just _ <- dynamicLinkerLabelInfo lbl
121   = return $ CmmLit $ CmmLabel lbl   -- already processed it, pass through
122
123   | otherwise 
124   = case howToAccessLabel 
125                 dflags 
126                 (platformArch $ targetPlatform dflags)
127                 (platformOS   $ targetPlatform dflags)
128                 referenceKind lbl of
129
130         AccessViaStub -> do
131               let stub = mkDynamicLinkerLabel CodeStub lbl
132               addImport stub
133               return $ CmmLit $ CmmLabel stub
134
135         AccessViaSymbolPtr -> do
136               let symbolPtr = mkDynamicLinkerLabel SymbolPtr lbl
137               addImport symbolPtr
138               return $ CmmLoad (cmmMakePicReference dflags symbolPtr) bWord
139
140         AccessDirectly -> case referenceKind of
141                 -- for data, we might have to make some calculations:
142               DataReference -> return $ cmmMakePicReference dflags lbl  
143                 -- all currently supported processors support
144                 -- PC-relative branch and call instructions,
145                 -- so just jump there if it's a call or a jump
146               _ -> return $ CmmLit $ CmmLabel lbl
147
148
149 -- -----------------------------------------------------------------------------
150 -- Create a position independent reference to a label.
151 -- (but do not bother with dynamic linking).
152 -- We calculate the label's address by adding some (platform-dependent)
153 -- offset to our base register; this offset is calculated by
154 -- the function picRelative in the platform-dependent part below.
155
156 cmmMakePicReference :: DynFlags -> CLabel -> CmmExpr
157 cmmMakePicReference dflags lbl
158
159         -- Windows doesn't need PIC,
160         -- everything gets relocated at runtime
161         | OSMinGW32     <- platformOS $ targetPlatform dflags
162         = CmmLit $ CmmLabel lbl
163
164
165         | (opt_PIC || not opt_Static) && absoluteLabel lbl 
166         = CmmMachOp (MO_Add wordWidth) 
167                 [ CmmReg (CmmGlobal PicBaseReg)
168                 , CmmLit $ picRelative 
169                                 (platformArch   $ targetPlatform dflags)
170                                 (platformOS     $ targetPlatform dflags)
171                                 lbl ]
172
173         | otherwise
174         = CmmLit $ CmmLabel lbl
175   
176   
177 absoluteLabel :: CLabel -> Bool
178 absoluteLabel lbl 
179  = case dynamicLinkerLabelInfo lbl of
180         Just (GotSymbolPtr, _)          -> False
181         Just (GotSymbolOffset, _)       -> False
182         _                               -> True
183
184
185 --------------------------------------------------------------------------------
186 -- Knowledge about how special dynamic linker labels like symbol
187 -- pointers, code stubs and GOT offsets look like is located in the
188 -- module CLabel.
189
190 -- We have to decide which labels need to be accessed
191 -- indirectly or via a piece of stub code.
192 data LabelAccessStyle 
193         = AccessViaStub
194         | AccessViaSymbolPtr
195         | AccessDirectly
196
197 howToAccessLabel 
198         :: DynFlags -> Arch -> OS -> ReferenceKind -> CLabel -> LabelAccessStyle
199
200
201 -- Windows
202 -- In Windows speak, a "module" is a set of objects linked into the
203 -- same Portable Exectuable (PE) file. (both .exe and .dll files are PEs).
204 --
205 -- If we're compiling a multi-module program then symbols from other modules
206 -- are accessed by a symbol pointer named __imp_SYMBOL. At runtime we have the
207 -- following.
208 --
209 --   (in the local module)
210 --     __imp_SYMBOL: addr of SYMBOL
211 --
212 --   (in the other module)
213 --     SYMBOL: the real function / data.
214 --
215 -- To access the function at SYMBOL from our local module, we just need to
216 -- dereference the local __imp_SYMBOL.
217 --
218 -- If opt_Static is set then we assume that all our code will be linked
219 -- into the same .exe file. In this case we always access symbols directly, 
220 -- and never use __imp_SYMBOL.
221 --
222 howToAccessLabel dflags _ OSMinGW32 _ lbl
223
224         -- Assume all symbols will be in the same PE, so just access them directly.
225         | opt_Static
226         = AccessDirectly
227         
228         -- If the target symbol is in another PE we need to access it via the
229         --      appropriate __imp_SYMBOL pointer.
230         | labelDynamic (thisPackage dflags) lbl 
231         = AccessViaSymbolPtr
232
233         -- Target symbol is in the same PE as the caller, so just access it directly.
234         | otherwise
235         = AccessDirectly
236
237
238 -- Mach-O (Darwin, Mac OS X)
239 --
240 -- Indirect access is required in the following cases:
241 --  * things imported from a dynamic library
242 --  * (not on x86_64) data from a different module, if we're generating PIC code
243 -- It is always possible to access something indirectly,
244 -- even when it's not necessary.
245 --
246 howToAccessLabel dflags arch OSDarwin DataReference lbl
247         -- data access to a dynamic library goes via a symbol pointer
248         | labelDynamic (thisPackage dflags) lbl 
249         = AccessViaSymbolPtr
250
251         -- when generating PIC code, all cross-module data references must
252         -- must go via a symbol pointer, too, because the assembler
253         -- cannot generate code for a label difference where one
254         -- label is undefined. Doesn't apply t x86_64.
255         -- Unfortunately, we don't know whether it's cross-module,
256         -- so we do it for all externally visible labels.
257         -- This is a slight waste of time and space, but otherwise
258         -- we'd need to pass the current Module all the way in to
259         -- this function.
260         | arch /= ArchX86_64
261         , opt_PIC && externallyVisibleCLabel lbl 
262         = AccessViaSymbolPtr
263          
264         | otherwise 
265         = AccessDirectly
266
267 howToAccessLabel dflags arch OSDarwin JumpReference lbl
268         -- dyld code stubs don't work for tailcalls because the
269         -- stack alignment is only right for regular calls.
270         -- Therefore, we have to go via a symbol pointer:
271         | arch == ArchX86 || arch == ArchX86_64
272         , labelDynamic (thisPackage dflags) lbl
273         = AccessViaSymbolPtr
274             
275
276 howToAccessLabel dflags arch OSDarwin _ lbl
277         -- Code stubs are the usual method of choice for imported code;
278         -- not needed on x86_64 because Apple's new linker, ld64, generates
279         -- them automatically.
280         | arch /= ArchX86_64
281         , labelDynamic (thisPackage dflags) lbl
282         = AccessViaStub
283
284         | otherwise
285         = AccessDirectly
286
287 -- ELF (Linux)
288 --
289 -- ELF tries to pretend to the main application code that dynamic linking does 
290 -- not exist. While this may sound convenient, it tends to mess things up in
291 -- very bad ways, so we have to be careful when we generate code for the main
292 -- program (-dynamic but no -fPIC).
293 --
294 -- Indirect access is required for references to imported symbols
295 -- from position independent code. It is also required from the main program
296 -- when dynamic libraries containing Haskell code are used.
297
298 howToAccessLabel _ ArchPPC_64 OSLinux kind _
299
300         -- ELF PPC64 (powerpc64-linux), AIX, MacOS 9, BeOS/PPC
301         | DataReference <- kind
302         = AccessViaSymbolPtr
303         
304         -- actually, .label instead of label
305         | otherwise
306         = AccessDirectly 
307
308 howToAccessLabel _ _ OSLinux _ _
309         -- no PIC -> the dynamic linker does everything for us;
310         --           if we don't dynamically link to Haskell code,
311         --           it actually manages to do so without messing thins up.
312         | not opt_PIC && opt_Static 
313         = AccessDirectly
314
315 howToAccessLabel dflags arch OSLinux DataReference lbl
316         -- A dynamic label needs to be accessed via a symbol pointer.
317         | labelDynamic (thisPackage dflags) lbl 
318         = AccessViaSymbolPtr
319
320         -- For PowerPC32 -fPIC, we have to access even static data
321         -- via a symbol pointer (see below for an explanation why
322         -- PowerPC32 Linux is especially broken).
323         | arch == ArchPPC
324         , opt_PIC
325         = AccessViaSymbolPtr
326         
327         | otherwise 
328         = AccessDirectly
329
330
331         -- In most cases, we have to avoid symbol stubs on ELF, for the following reasons:
332         --   on i386, the position-independent symbol stubs in the Procedure Linkage Table
333         --   require the address of the GOT to be loaded into register %ebx on entry.
334         --   The linker will take any reference to the symbol stub as a hint that
335         --   the label in question is a code label. When linking executables, this
336         --   will cause the linker to replace even data references to the label with
337         --   references to the symbol stub.
338
339         -- This leaves calling a (foreign) function from non-PIC code
340         -- (AccessDirectly, because we get an implicit symbol stub)
341         -- and calling functions from PIC code on non-i386 platforms (via a symbol stub) 
342
343 howToAccessLabel dflags arch OSLinux CallReference lbl
344         | labelDynamic (thisPackage dflags) lbl && not opt_PIC
345         = AccessDirectly
346
347         | arch /= ArchX86
348         , labelDynamic (thisPackage dflags) lbl && opt_PIC
349         = AccessViaStub
350
351 howToAccessLabel dflags _ OSLinux _ lbl
352         | labelDynamic (thisPackage dflags) lbl 
353         = AccessViaSymbolPtr
354
355         | otherwise 
356         = AccessDirectly
357
358 -- all other platforms
359 howToAccessLabel _ _ _ _ _
360         | not opt_PIC 
361         = AccessDirectly
362         
363         | otherwise
364         = panic "howToAccessLabel: PIC not defined for this platform"
365
366
367
368 -- -------------------------------------------------------------------
369 -- | Says what we we have to add to our 'PIC base register' in order to
370 --      get the address of a label.
371
372 picRelative :: Arch -> OS -> CLabel -> CmmLit
373
374 -- Darwin, but not x86_64:
375 -- The PIC base register points to the PIC base label at the beginning
376 -- of the current CmmTop. We just have to use a label difference to
377 -- get the offset.
378 -- We have already made sure that all labels that are not from the current
379 -- module are accessed indirectly ('as' can't calculate differences between
380 -- undefined labels).
381 picRelative arch OSDarwin lbl
382         | arch /= ArchX86_64
383         = CmmLabelDiffOff lbl mkPicBaseLabel 0
384         
385
386 -- PowerPC Linux:
387 -- The PIC base register points to our fake GOT. Use a label difference
388 -- to get the offset.
389 -- We have made sure that *everything* is accessed indirectly, so this
390 -- is only used for offsets from the GOT to symbol pointers inside the
391 -- GOT.
392 picRelative ArchPPC OSLinux lbl
393         = CmmLabelDiffOff lbl gotLabel 0
394
395
396 -- Most Linux versions:
397 -- The PIC base register points to the GOT. Use foo@got for symbol
398 -- pointers, and foo@gotoff for everything else.
399 -- Linux and Darwin on x86_64:
400 -- The PIC base register is %rip, we use foo@gotpcrel for symbol pointers,
401 -- and a GotSymbolOffset label for other things.
402 -- For reasons of tradition, the symbol offset label is written as a plain label.
403 picRelative arch os lbl
404         | os == OSLinux || (os == OSDarwin && arch == ArchX86_64)
405         = let   result
406                         | Just (SymbolPtr, lbl') <- dynamicLinkerLabelInfo lbl
407                         = CmmLabel $ mkDynamicLinkerLabel GotSymbolPtr lbl'
408
409                         | otherwise
410                         = CmmLabel $ mkDynamicLinkerLabel GotSymbolOffset lbl
411                         
412           in    result
413
414 picRelative _ _ _
415         = panic "PositionIndependentCode.picRelative undefined for this platform"
416
417
418
419 --------------------------------------------------------------------------------
420
421 -- utility function for pretty-printing asm-labels,
422 -- copied from PprMach
423 --
424 asmSDoc :: Outputable.SDoc -> Doc
425 asmSDoc d 
426         = Outputable.withPprStyleDoc 
427                 (Outputable.mkCodeStyle Outputable.AsmStyle) d
428
429 pprCLabel_asm :: CLabel -> Doc
430 pprCLabel_asm l 
431         = asmSDoc (pprCLabel l)
432
433
434 needImportedSymbols :: Arch -> OS -> Bool
435 needImportedSymbols arch os
436         | os    == OSDarwin
437         , arch  /= ArchX86_64
438         = True
439         
440         -- PowerPC Linux: -fPIC or -dynamic
441         | os    == OSLinux
442         , arch  == ArchPPC
443         = opt_PIC || not opt_Static
444
445         -- i386 (and others?): -dynamic but not -fPIC
446         | os    == OSLinux
447         , arch  /= ArchPPC_64
448         = not opt_Static && not opt_PIC
449
450         | otherwise
451         = False
452
453 -- gotLabel
454 -- The label used to refer to our "fake GOT" from
455 -- position-independent code.
456 gotLabel :: CLabel
457 gotLabel 
458         -- HACK: this label isn't really foreign
459         = mkForeignLabel 
460                 (fsLit ".LCTOC1") 
461                 Nothing ForeignLabelInThisPackage IsData
462
463
464
465 --------------------------------------------------------------------------------
466 -- We don't need to declare any offset tables.
467 -- However, for PIC on x86, we need a small helper function.
468 pprGotDeclaration :: Arch -> OS -> Doc
469 pprGotDeclaration ArchX86 OSDarwin
470         | opt_PIC
471         = vcat [
472                 ptext (sLit ".section __TEXT,__textcoal_nt,coalesced,no_toc"),
473                 ptext (sLit ".weak_definition ___i686.get_pc_thunk.ax"),
474                 ptext (sLit ".private_extern ___i686.get_pc_thunk.ax"),
475                 ptext (sLit "___i686.get_pc_thunk.ax:"),
476                 ptext (sLit "\tmovl (%esp), %eax"),
477                 ptext (sLit "\tret") ]
478
479 pprGotDeclaration _ OSDarwin
480         = Pretty.empty
481                 
482 -- pprGotDeclaration
483 -- Output whatever needs to be output once per .s file.
484 -- The .LCTOC1 label is defined to point 32768 bytes into the table,
485 -- to make the most of the PPC's 16-bit displacements.
486 -- Only needed for PIC.
487 pprGotDeclaration arch OSLinux
488         | arch  /= ArchPPC_64
489         , not opt_PIC 
490         = Pretty.empty
491
492         | arch  /= ArchPPC_64
493         = vcat [
494                 ptext (sLit ".section \".got2\",\"aw\""),
495                 ptext (sLit ".LCTOC1 = .+32768") ]
496
497 pprGotDeclaration _ _
498         = panic "pprGotDeclaration: no match"   
499
500
501 --------------------------------------------------------------------------------
502 -- On Darwin, we have to generate our own stub code for lazy binding..
503 -- For each processor architecture, there are two versions, one for PIC
504 -- and one for non-PIC.
505 --
506 -- Whenever you change something in this assembler output, make sure
507 -- the splitter in driver/split/ghc-split.lprl recognizes the new output
508
509 pprImportedSymbol :: Arch -> OS -> CLabel -> Doc
510 pprImportedSymbol ArchPPC OSDarwin importedLbl
511         | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl
512         = case opt_PIC of
513            False ->
514             vcat [
515                 ptext (sLit ".symbol_stub"),
516                 ptext (sLit "L") <> pprCLabel_asm lbl <> ptext (sLit "$stub:"),
517                     ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
518                     ptext (sLit "\tlis r11,ha16(L") <> pprCLabel_asm lbl
519                         <> ptext (sLit "$lazy_ptr)"),
520                     ptext (sLit "\tlwz r12,lo16(L") <> pprCLabel_asm lbl
521                         <> ptext (sLit "$lazy_ptr)(r11)"),
522                     ptext (sLit "\tmtctr r12"),
523                     ptext (sLit "\taddi r11,r11,lo16(L") <> pprCLabel_asm lbl
524                         <> ptext (sLit "$lazy_ptr)"),
525                     ptext (sLit "\tbctr")
526             ]
527            True ->
528             vcat [
529                 ptext (sLit ".section __TEXT,__picsymbolstub1,")
530                   <> ptext (sLit "symbol_stubs,pure_instructions,32"),
531                 ptext (sLit "\t.align 2"),
532                 ptext (sLit "L") <> pprCLabel_asm lbl <> ptext (sLit "$stub:"),
533                     ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
534                     ptext (sLit "\tmflr r0"),
535                     ptext (sLit "\tbcl 20,31,L0$") <> pprCLabel_asm lbl,
536                 ptext (sLit "L0$") <> pprCLabel_asm lbl <> char ':',
537                     ptext (sLit "\tmflr r11"),
538                     ptext (sLit "\taddis r11,r11,ha16(L") <> pprCLabel_asm lbl
539                         <> ptext (sLit "$lazy_ptr-L0$") <> pprCLabel_asm lbl <> char ')',
540                     ptext (sLit "\tmtlr r0"),
541                     ptext (sLit "\tlwzu r12,lo16(L") <> pprCLabel_asm lbl
542                         <> ptext (sLit "$lazy_ptr-L0$") <> pprCLabel_asm lbl
543                         <> ptext (sLit ")(r11)"),
544                     ptext (sLit "\tmtctr r12"),
545                     ptext (sLit "\tbctr")
546             ]
547           $+$ vcat [
548                 ptext (sLit ".lazy_symbol_pointer"),
549                 ptext (sLit "L") <> pprCLabel_asm lbl <> ptext (sLit "$lazy_ptr:"),
550                 ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
551                 ptext (sLit "\t.long dyld_stub_binding_helper")]
552
553         | Just (SymbolPtr, lbl) <- dynamicLinkerLabelInfo importedLbl
554         = vcat [
555                 ptext (sLit ".non_lazy_symbol_pointer"),
556                 char 'L' <> pprCLabel_asm lbl <> ptext (sLit "$non_lazy_ptr:"),
557                 ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
558                 ptext (sLit "\t.long\t0")]
559
560         | otherwise 
561         = empty
562
563                 
564 pprImportedSymbol ArchX86 OSDarwin importedLbl
565         | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl
566         = case opt_PIC of
567            False ->
568             vcat [
569                 ptext (sLit ".symbol_stub"),
570                 ptext (sLit "L") <> pprCLabel_asm lbl <> ptext (sLit "$stub:"),
571                     ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
572                     ptext (sLit "\tjmp *L") <> pprCLabel_asm lbl
573                         <> ptext (sLit "$lazy_ptr"),
574                 ptext (sLit "L") <> pprCLabel_asm lbl
575                     <> ptext (sLit "$stub_binder:"),
576                     ptext (sLit "\tpushl $L") <> pprCLabel_asm lbl
577                         <> ptext (sLit "$lazy_ptr"),
578                     ptext (sLit "\tjmp dyld_stub_binding_helper")
579             ]
580            True ->
581             vcat [
582                 ptext (sLit ".section __TEXT,__picsymbolstub2,")
583                     <> ptext (sLit "symbol_stubs,pure_instructions,25"),
584                 ptext (sLit "L") <> pprCLabel_asm lbl <> ptext (sLit "$stub:"),
585                     ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
586                     ptext (sLit "\tcall ___i686.get_pc_thunk.ax"),
587                 ptext (sLit "1:"),
588                     ptext (sLit "\tmovl L") <> pprCLabel_asm lbl
589                         <> ptext (sLit "$lazy_ptr-1b(%eax),%edx"),
590                     ptext (sLit "\tjmp *%edx"),
591                 ptext (sLit "L") <> pprCLabel_asm lbl
592                     <> ptext (sLit "$stub_binder:"),
593                     ptext (sLit "\tlea L") <> pprCLabel_asm lbl
594                         <> ptext (sLit "$lazy_ptr-1b(%eax),%eax"),
595                     ptext (sLit "\tpushl %eax"),
596                     ptext (sLit "\tjmp dyld_stub_binding_helper")
597             ]
598           $+$ vcat [        ptext (sLit ".section __DATA, __la_sym_ptr")
599                     <> (if opt_PIC then int 2 else int 3)
600                     <> ptext (sLit ",lazy_symbol_pointers"),
601                 ptext (sLit "L") <> pprCLabel_asm lbl <> ptext (sLit "$lazy_ptr:"),
602                     ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
603                     ptext (sLit "\t.long L") <> pprCLabel_asm lbl
604                     <> ptext (sLit "$stub_binder")]
605
606         | Just (SymbolPtr, lbl) <- dynamicLinkerLabelInfo importedLbl
607         = vcat [
608                 ptext (sLit ".non_lazy_symbol_pointer"),
609                 char 'L' <> pprCLabel_asm lbl <> ptext (sLit "$non_lazy_ptr:"),
610                 ptext (sLit "\t.indirect_symbol") <+> pprCLabel_asm lbl,
611                 ptext (sLit "\t.long\t0")]
612
613         | otherwise 
614         = empty
615
616
617 pprImportedSymbol _ OSDarwin _
618         = empty
619         
620
621 -- ELF / Linux
622 --
623 -- In theory, we don't need to generate any stubs or symbol pointers
624 -- by hand for Linux.
625 --
626 -- Reality differs from this in two areas.
627 --
628 -- 1) If we just use a dynamically imported symbol directly in a read-only
629 --    section of the main executable (as GCC does), ld generates R_*_COPY
630 --    relocations, which are fundamentally incompatible with reversed info
631 --    tables. Therefore, we need a table of imported addresses in a writable
632 --    section.
633 --    The "official" GOT mechanism (label@got) isn't intended to be used
634 --    in position dependent code, so we have to create our own "fake GOT"
635 --    when not opt_PCI && not opt_Static.
636 --
637 -- 2) PowerPC Linux is just plain broken.
638 --    While it's theoretically possible to use GOT offsets larger
639 --    than 16 bit, the standard crt*.o files don't, which leads to
640 --    linker errors as soon as the GOT size exceeds 16 bit.
641 --    Also, the assembler doesn't support @gotoff labels.
642 --    In order to be able to use a larger GOT, we have to circumvent the
643 --    entire GOT mechanism and do it ourselves (this is also what GCC does).
644
645
646 -- When needImportedSymbols is defined,
647 -- the NCG will keep track of all DynamicLinkerLabels it uses
648 -- and output each of them using pprImportedSymbol.
649
650 pprImportedSymbol ArchPPC_64 OSLinux _
651         = empty
652
653 pprImportedSymbol _ OSLinux importedLbl
654         | Just (SymbolPtr, lbl) <- dynamicLinkerLabelInfo importedLbl
655         = let   symbolSize = case wordWidth of
656                      W32 -> sLit "\t.long"
657                      W64 -> sLit "\t.quad"
658                      _ -> panic "Unknown wordRep in pprImportedSymbol"
659
660           in vcat [
661                 ptext (sLit ".section \".got2\", \"aw\""),
662                 ptext (sLit ".LC_") <> pprCLabel_asm lbl <> char ':',
663                 ptext symbolSize <+> pprCLabel_asm lbl ]
664
665         -- PLT code stubs are generated automatically by the dynamic linker.
666         | otherwise = empty
667
668 pprImportedSymbol _ _ _
669         = panic "PIC.pprImportedSymbol: no match"
670
671 --------------------------------------------------------------------------------
672 -- Generate code to calculate the address that should be put in the
673 -- PIC base register.
674 -- This is called by MachCodeGen for every CmmProc that accessed the
675 -- PIC base register. It adds the appropriate instructions to the
676 -- top of the CmmProc.
677
678 -- It is assumed that the first NatCmmTop in the input list is a Proc
679 -- and the rest are CmmDatas.
680
681 -- Darwin is simple: just fetch the address of a local label.
682 -- The FETCHPC pseudo-instruction is expanded to multiple instructions
683 -- during pretty-printing so that we don't have to deal with the
684 -- local label:
685
686 -- PowerPC version:
687 --          bcl 20,31,1f.
688 --      1:  mflr picReg
689
690 -- i386 version:
691 --          call 1f
692 --      1:  popl %picReg
693
694
695
696 -- Get a pointer to our own fake GOT, which is defined on a per-module basis.
697 -- This is exactly how GCC does it, and it's quite horrible:
698 -- We first fetch the address of a local label (mkPicBaseLabel).
699 -- Then we add a 16-bit offset to that to get the address of a .long that we
700 -- define in .text space right next to the proc. This .long literal contains
701 -- the (32-bit) offset from our local label to our global offset table
702 -- (.LCTOC1 aka gotOffLabel).
703
704 initializePicBase_ppc 
705         :: Arch -> OS -> Reg 
706         -> [NatCmmTop PPC.Instr] 
707         -> NatM [NatCmmTop PPC.Instr]
708
709 initializePicBase_ppc ArchPPC OSLinux picReg
710     (CmmProc info lab params (ListGraph blocks) : statics)
711     = do
712         gotOffLabel <- getNewLabelNat
713         tmp <- getNewRegNat $ intSize wordWidth
714         let 
715             gotOffset = CmmData Text [
716                             CmmDataLabel gotOffLabel,
717                             CmmStaticLit (CmmLabelDiffOff gotLabel
718                                                           mkPicBaseLabel
719                                                           0)
720                         ]
721             offsetToOffset
722                         = PPC.ImmConstantDiff 
723                                 (PPC.ImmCLbl gotOffLabel)
724                                 (PPC.ImmCLbl mkPicBaseLabel)
725
726             BasicBlock bID insns 
727                         = head blocks
728
729             b' = BasicBlock bID (PPC.FETCHPC picReg
730                                : PPC.LD PPC.archWordSize tmp
731                                     (PPC.AddrRegImm picReg offsetToOffset)
732                                : PPC.ADD picReg picReg (PPC.RIReg tmp)
733                                : insns)
734
735         return (CmmProc info lab params (ListGraph (b' : tail blocks)) : gotOffset : statics)
736
737 initializePicBase_ppc ArchPPC OSDarwin picReg
738         (CmmProc info lab params (ListGraph blocks) : statics)
739         = return (CmmProc info lab params (ListGraph (b':tail blocks)) : statics)
740
741         where   BasicBlock bID insns = head blocks
742                 b' = BasicBlock bID (PPC.FETCHPC picReg : insns)
743
744
745 initializePicBase_ppc _ _ _ _
746         = panic "initializePicBase_ppc: not needed"
747
748
749 -- We cheat a bit here by defining a pseudo-instruction named FETCHGOT
750 -- which pretty-prints as:
751 --              call 1f
752 -- 1:           popl %picReg
753 --              addl __GLOBAL_OFFSET_TABLE__+.-1b, %picReg
754 -- (See PprMach.lhs)
755
756 initializePicBase_x86
757         :: Arch -> OS -> Reg 
758         -> [NatCmmTop X86.Instr] 
759         -> NatM [NatCmmTop X86.Instr]
760
761 initializePicBase_x86 ArchX86 OSLinux picReg 
762         (CmmProc info lab params (ListGraph blocks) : statics)
763     = return (CmmProc info lab params (ListGraph (b':tail blocks)) : statics)
764     where BasicBlock bID insns = head blocks
765           b' = BasicBlock bID (X86.FETCHGOT picReg : insns)
766
767 initializePicBase_x86 ArchX86 OSDarwin picReg
768         (CmmProc info lab params (ListGraph blocks) : statics)
769         = return (CmmProc info lab params (ListGraph (b':tail blocks)) : statics)
770
771         where   BasicBlock bID insns = head blocks
772                 b' = BasicBlock bID (X86.FETCHPC picReg : insns)
773
774 initializePicBase_x86 _ _ _ _
775         = panic "initializePicBase_x86: not needed"
776