[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / rts / Linker.c
index a9d3089..e6e82aa 100644 (file)
@@ -22,8 +22,8 @@
 #include "Linker.h"
 #include "LinkerInternals.h"
 #include "RtsUtils.h"
-#include "StoragePriv.h"
 #include "Schedule.h"
+#include "Storage.h"
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -312,12 +312,34 @@ typedef struct _RtsSymbolVal {
 # define MAIN_CAP_SYM
 #endif
 
+#ifdef TABLES_NEXT_TO_CODE
+#define RTS_RET_SYMBOLS /* nothing */
+#else
+#define RTS_RET_SYMBOLS                        \
+      SymX(stg_enter_ret)                      \
+      SymX(stg_gc_fun_ret)                     \
+      SymX(stg_ap_0_ret)                       \
+      SymX(stg_ap_v_ret)                       \
+      SymX(stg_ap_f_ret)                       \
+      SymX(stg_ap_d_ret)                       \
+      SymX(stg_ap_l_ret)                       \
+      SymX(stg_ap_n_ret)                       \
+      SymX(stg_ap_p_ret)                       \
+      SymX(stg_ap_pv_ret)                      \
+      SymX(stg_ap_pp_ret)                      \
+      SymX(stg_ap_ppv_ret)                     \
+      SymX(stg_ap_ppp_ret)                     \
+      SymX(stg_ap_pppv_ret)                    \
+      SymX(stg_ap_pppp_ret)                    \
+      SymX(stg_ap_ppppp_ret)                   \
+      SymX(stg_ap_pppppp_ret)
+#endif
+
 #define RTS_SYMBOLS                            \
       Maybe_ForeignObj                         \
       Maybe_Stable_Names                       \
       Sym(StgReturn)                           \
       SymX(stg_enter_info)                     \
-      SymX(stg_enter_ret)                      \
       SymX(stg_gc_void_info)                   \
       SymX(__stg_gc_enter_1)                   \
       SymX(stg_gc_noregs)                      \
@@ -333,7 +355,6 @@ typedef struct _RtsSymbolVal {
       SymX(stg_gc_l1)                          \
       SymX(__stg_gc_fun)                       \
       SymX(stg_gc_fun_info)                    \
-      SymX(stg_gc_fun_ret)                     \
       SymX(stg_gc_gen)                         \
       SymX(stg_gc_gen_info)                    \
       SymX(stg_gc_gen_hp)                      \
@@ -504,25 +525,10 @@ typedef struct _RtsSymbolVal {
       SymX(stg_ap_pp_info)                     \
       SymX(stg_ap_ppv_info)                    \
       SymX(stg_ap_ppp_info)                    \
+      SymX(stg_ap_pppv_info)                   \
       SymX(stg_ap_pppp_info)                   \
       SymX(stg_ap_ppppp_info)                  \
       SymX(stg_ap_pppppp_info)                 \
-      SymX(stg_ap_ppppppp_info)                        \
-      SymX(stg_ap_0_ret)                       \
-      SymX(stg_ap_v_ret)                       \
-      SymX(stg_ap_f_ret)                       \
-      SymX(stg_ap_d_ret)                       \
-      SymX(stg_ap_l_ret)                       \
-      SymX(stg_ap_n_ret)                       \
-      SymX(stg_ap_p_ret)                       \
-      SymX(stg_ap_pv_ret)                      \
-      SymX(stg_ap_pp_ret)                      \
-      SymX(stg_ap_ppv_ret)                     \
-      SymX(stg_ap_ppp_ret)                     \
-      SymX(stg_ap_pppp_ret)                    \
-      SymX(stg_ap_ppppp_ret)                   \
-      SymX(stg_ap_pppppp_ret)                  \
-      SymX(stg_ap_ppppppp_ret)                 \
       SymX(stg_ap_1_upd_info)                  \
       SymX(stg_ap_2_upd_info)                  \
       SymX(stg_ap_3_upd_info)                  \
@@ -530,7 +536,6 @@ typedef struct _RtsSymbolVal {
       SymX(stg_ap_5_upd_info)                  \
       SymX(stg_ap_6_upd_info)                  \
       SymX(stg_ap_7_upd_info)                  \
-      SymX(stg_ap_8_upd_info)                  \
       SymX(stg_exit)                           \
       SymX(stg_sel_0_upd_info)                 \
       SymX(stg_sel_10_upd_info)                        \
@@ -608,6 +613,7 @@ typedef struct _RtsSymbolVal {
 #define SymX(vvv) /**/
 #define SymX_redirect(vvv,xxx) /**/
 RTS_SYMBOLS
+RTS_RET_SYMBOLS
 RTS_LONG_LONG_SYMS
 RTS_POSIX_ONLY_SYMBOLS
 RTS_MINGW_ONLY_SYMBOLS
@@ -3247,7 +3253,45 @@ static int relocateSection(
                              - relocateAddress(oc, nSections, sections, pair->r_value));
                        i++;
                    }
-                   else
+                   else if(scat->r_type == PPC_RELOC_HI16
+                         || scat->r_type == PPC_RELOC_LO16
+                         || scat->r_type == PPC_RELOC_HA16
+                         || scat->r_type == PPC_RELOC_LO14)
+                    {   // these are generated by label+offset things
+                       struct relocation_info *pair = &relocs[i+1];
+                        if((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR)
+                           barf("Invalid Mach-O file: "
+                                "PPC_RELOC_* not followed by PPC_RELOC_PAIR");
+                        
+                        if(scat->r_type == PPC_RELOC_LO16)
+                        {
+                            word = ((unsigned short*) wordPtr)[1];
+                            word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
+                        }
+                        else if(scat->r_type == PPC_RELOC_LO14)
+                        {
+                            barf("Unsupported Relocation: PPC_RELOC_LO14");
+                            word = ((unsigned short*) wordPtr)[1] & 0xFFFC;
+                            word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
+                        }
+                        else if(scat->r_type == PPC_RELOC_HI16)
+                        {
+                            word = ((unsigned short*) wordPtr)[1] << 16;
+                            word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
+                        }
+                        else if(scat->r_type == PPC_RELOC_HA16)
+                        {
+                            word = ((unsigned short*) wordPtr)[1] << 16;
+                            word += ((short)relocs[i+1].r_address & (short)0xFFFF);
+                        }
+                       
+                        
+                        word += (unsigned long) relocateAddress(oc, nSections, sections, scat->r_value)
+                                                - scat->r_value;
+                        
+                        i++;
+                    }
+                    else
                        continue;  // ignore the others
 
                     if(scat->r_type == GENERIC_RELOC_VANILLA
@@ -3255,15 +3299,15 @@ static int relocateSection(
                     {
                         *wordPtr = word;
                     }
-                    else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF)
+                    else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16)
                     {
                         ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
                     }
-                    else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF)
+                    else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16)
                     {
                         ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
                     }
-                    else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF)
+                    else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF || scat->r_type == PPC_RELOC_HA16)
                     {
                         ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
                             + ((word & (1<<15)) ? 1 : 0);
@@ -3327,15 +3371,17 @@ static int relocateSection(
                {
                    struct nlist *symbol = &nlist[reloc->r_symbolnum];
                    char *nm = image + symLC->stroff + symbol->n_un.n_strx;
-                   word = (unsigned long) (lookupSymbol(nm));
-                   if(!word)
+                   unsigned long symbolAddress = (unsigned long) (lookupSymbol(nm));
+                   if(!symbolAddress)
                    {
                        belch("\nunknown symbol `%s'", nm);
                        return 0;
                    }
 
                    if(reloc->r_pcrel)
-                    {
+                    {  
+                        ASSERT(word == 0);
+                        word = symbolAddress;
                         jumpIsland = (long) makeJumpIsland(oc,reloc->r_symbolnum,(void*)word);
                        word -= ((long)image) + sect->offset + reloc->r_address;
                         if(jumpIsland != 0)
@@ -3344,6 +3390,10 @@ static int relocateSection(
                                 - (((long)image) + sect->offset + reloc->r_address);
                         }
                     }
+                    else
+                    {
+                        word += symbolAddress;
+                    }
                }
 
                if(reloc->r_type == GENERIC_RELOC_VANILLA)