[project @ 2004-12-02 23:39:13 by wolfgang]
[ghc-hetmet.git] / ghc / rts / Linker.c
index 7924913..ef5697a 100644 (file)
@@ -296,6 +296,7 @@ typedef struct _RtsSymbolVal {
       SymX(log)                                 \
       SymX(sqrt)                                \
       SymX(memcpy)                              \
+      SymX(stg_InstallConsoleEvent)             \
       Sym(mktime)                               \
       Sym(_imp___timezone)                      \
       Sym(_imp___tzname)                        \
@@ -388,9 +389,12 @@ typedef struct _RtsSymbolVal {
       SymX(__int_encodeDouble)                 \
       SymX(__int_encodeFloat)                  \
       SymX(andIntegerzh_fast)                  \
+      SymX(atomicallyzh_fast)                  \
       SymX(barf)                               \
       SymX(blockAsyncExceptionszh_fast)                \
       SymX(catchzh_fast)                       \
+      SymX(catchRetryzh_fast)                  \
+      SymX(catchSTMzh_fast)                    \
       SymX(closure_flags)                       \
       SymX(cmp_thread)                         \
       SymX(cmpIntegerzh_fast)                  \
@@ -414,6 +418,7 @@ typedef struct _RtsSymbolVal {
       SymX(gcdIntegerIntzh_fast)               \
       SymX(gcdIntzh_fast)                      \
       SymX(genSymZh)                           \
+      SymX(genericRaise)                       \
       SymX(getProgArgv)                                \
       SymX(getStablePtr)                       \
       SymX(initLinker)                         \
@@ -444,6 +449,7 @@ typedef struct _RtsSymbolVal {
       SymX_redirect(newCAF, newDynCAF)         \
       SymX(newMVarzh_fast)                     \
       SymX(newMutVarzh_fast)                   \
+      SymX(newTVarzh_fast)                     \
       SymX(atomicModifyMutVarzh_fast)          \
       SymX(newPinnedByteArrayzh_fast)          \
       SymX(orIntegerzh_fast)                   \
@@ -457,10 +463,12 @@ typedef struct _RtsSymbolVal {
       SymX(quotRemIntegerzh_fast)              \
       SymX(raisezh_fast)                       \
       SymX(raiseIOzh_fast)                     \
+      SymX(readTVarzh_fast)                    \
       SymX(remIntegerzh_fast)                  \
       SymX(resetNonBlockingFd)                 \
       SymX(resumeThread)                       \
       SymX(resolveObjs)                         \
+      SymX(retryzh_fast)                        \
       SymX(rts_apply)                          \
       SymX(rts_checkSchedStatus)               \
       SymX(rts_eval)                           \
@@ -570,6 +578,7 @@ typedef struct _RtsSymbolVal {
       SymX(waitReadzh_fast)                    \
       SymX(waitWritezh_fast)                   \
       SymX(word2Integerzh_fast)                        \
+      SymX(writeTVarzh_fast)                   \
       SymX(xorIntegerzh_fast)                  \
       SymX(yieldzh_fast)
 
@@ -3258,20 +3267,42 @@ static int ocAllocateJumpIslands_MachO(ObjectCode* oc)
     unsigned i;
 
     for( i = 0; i < header->ncmds; i++ )
-    {
-        if( lc->cmd == LC_DYSYMTAB )
+    {   
+        if( lc->cmd == LC_SYMTAB )
         {
-            struct dysymtab_command *dsymLC = (struct dysymtab_command *) lc;
-
-            if( !ocAllocateJumpIslands( oc, dsymLC->nundefsym,
-                                            dsymLC->iundefsym ) )
-              return 0;
+                // Find out the first and last undefined external
+                // symbol, so we don't have to allocate too many
+                // jump islands.
+            struct symtab_command *symLC = (struct symtab_command *) lc;
+            int min = symLC->nsyms, max = 0;
+            struct nlist *nlist =
+                symLC ? (struct nlist*) ((char*) oc->image + symLC->symoff)
+                      : NULL;
+            for(i=0;i<symLC->nsyms;i++)
+            {
+                if(nlist[i].n_type & N_STAB)
+                    ;
+                else if(nlist[i].n_type & N_EXT)
+                {
+                    if((nlist[i].n_type & N_TYPE) == N_UNDF
+                        && (nlist[i].n_value == 0))
+                    {
+                        if(i < min)
+                            min = i;
+                        if(i > max)
+                            max = i;
+                    }
+                }
+            }
+            if(max >= min)
+                return ocAllocateJumpIslands(oc, max - min + 1, min);
 
-            break;  // there can be only one LC_DSYMTAB
+            break;
         }
+        
         lc = (struct load_command *) ( ((char *)lc) + lc->cmdsize );
     }
-    return 1;
+    return ocAllocateJumpIslands(oc,0,0);
 }
 
 static int ocVerifyImage_MachO(ObjectCode* oc)
@@ -3372,7 +3403,12 @@ static int relocateSection(
                    // Step 1: Figure out what the relocated value should be
                    if(scat->r_type == GENERIC_RELOC_VANILLA)
                    {
-                       word = scat->r_value + sect->offset + ((long) image);
+                        word = *wordPtr + (unsigned long) relocateAddress(
+                                                                oc,
+                                                                nSections,
+                                                                sections,
+                                                                scat->r_value)
+                                        - scat->r_value;
                    }
                    else if(scat->r_type == PPC_RELOC_SECTDIFF
                        || scat->r_type == PPC_RELOC_LO16_SECTDIFF
@@ -3564,9 +3600,11 @@ static int relocateSection(
                         // The branch offset is too large.
                         // Therefore, we try to use a jump island.
                         if(jumpIsland == 0)
+                        {
                             barf("unconditional relative branch out of range: "
                                  "no jump island available");
-
+                        }
+                        
                         word = offsetToJumpIsland;
                         if((long)word > (long)0x01FFFFFF || (long)word < (long)0xFFE00000)
                             barf("unconditional relative branch out of range: "
@@ -3592,7 +3630,6 @@ static int ocGetNames_MachO(ObjectCode* oc)
     struct segment_command *segLC = NULL;
     struct section *sections;
     struct symtab_command *symLC = NULL;
-    struct dysymtab_command *dsymLC = NULL;
     struct nlist *nlist;
     unsigned long commonSize = 0;
     char    *commonStorage = NULL;
@@ -3604,13 +3641,12 @@ static int ocGetNames_MachO(ObjectCode* oc)
            segLC = (struct segment_command*) lc;
        else if(lc->cmd == LC_SYMTAB)
            symLC = (struct symtab_command*) lc;
-       else if(lc->cmd == LC_DYSYMTAB)
-           dsymLC = (struct dysymtab_command*) lc;
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
 
     sections = (struct section*) (segLC+1);
-    nlist = (struct nlist*) (image + symLC->symoff);
+    nlist = symLC ? (struct nlist*) (image + symLC->symoff)
+                  : NULL;
 
     for(i=0;i<segLC->nsects;i++)
     {
@@ -3648,68 +3684,81 @@ static int ocGetNames_MachO(ObjectCode* oc)
 
        // count external symbols defined here
     oc->n_symbols = 0;
-    for(i=dsymLC->iextdefsym;i<dsymLC->iextdefsym+dsymLC->nextdefsym;i++)
-    {
-       if((nlist[i].n_type & N_TYPE) == N_SECT)
-           oc->n_symbols++;
-    }
-    for(i=0;i<symLC->nsyms;i++)
+    if(symLC)
     {
-       if((nlist[i].n_type & N_TYPE) == N_UNDF
-               && (nlist[i].n_type & N_EXT) && (nlist[i].n_value != 0))
-       {
-           commonSize += nlist[i].n_value;
-           oc->n_symbols++;
-       }
+        for(i=0;i<symLC->nsyms;i++)
+        {
+            if(nlist[i].n_type & N_STAB)
+                ;
+            else if(nlist[i].n_type & N_EXT)
+            {
+                if((nlist[i].n_type & N_TYPE) == N_UNDF
+                    && (nlist[i].n_value != 0))
+                {
+                    commonSize += nlist[i].n_value;
+                    oc->n_symbols++;
+                }
+                else if((nlist[i].n_type & N_TYPE) == N_SECT)
+                    oc->n_symbols++;
+            }
+        }
     }
     oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
                                   "ocGetNames_MachO(oc->symbols)");
 
-       // insert symbols into hash table
-    for(i=dsymLC->iextdefsym,curSymbol=0;i<dsymLC->iextdefsym+dsymLC->nextdefsym;i++)
-    {
-       if((nlist[i].n_type & N_TYPE) == N_SECT)
-       {
-           char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
-           ghciInsertStrHashTable(oc->fileName, symhash, nm, image +
-               sections[nlist[i].n_sect-1].offset
-               - sections[nlist[i].n_sect-1].addr
-               + nlist[i].n_value);
-           oc->symbols[curSymbol++] = nm;
-       }
-    }
-
-       // insert local symbols into lochash
-    for(i=dsymLC->ilocalsym;i<dsymLC->ilocalsym+dsymLC->nlocalsym;i++)
+    if(symLC)
     {
-       if((nlist[i].n_type & N_TYPE) == N_SECT)
-       {
-           char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
-           ghciInsertStrHashTable(oc->fileName, oc->lochash, nm, image +
-               sections[nlist[i].n_sect-1].offset
-               - sections[nlist[i].n_sect-1].addr
-               + nlist[i].n_value);
-       }
+        curSymbol = 0;
+        for(i=0;i<symLC->nsyms;i++)
+        {
+            if(nlist[i].n_type & N_STAB)
+                ;
+            else if((nlist[i].n_type & N_TYPE) == N_SECT)
+            {
+                if(nlist[i].n_type & N_EXT)
+                {
+                    char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
+                    ghciInsertStrHashTable(oc->fileName, symhash, nm,
+                                            image
+                                            + sections[nlist[i].n_sect-1].offset
+                                            - sections[nlist[i].n_sect-1].addr
+                                            + nlist[i].n_value);
+                    oc->symbols[curSymbol++] = nm;
+                }
+                else
+                {
+                    char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
+                    ghciInsertStrHashTable(oc->fileName, oc->lochash, nm,
+                                            image
+                                            + sections[nlist[i].n_sect-1].offset
+                                            - sections[nlist[i].n_sect-1].addr
+                                            + nlist[i].n_value);
+                }
+            }
+        }
     }
 
-
     commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
     commonCounter = (unsigned long)commonStorage;
-    for(i=0;i<symLC->nsyms;i++)
+    if(symLC)
     {
-       if((nlist[i].n_type & N_TYPE) == N_UNDF
-               && (nlist[i].n_type & N_EXT) && (nlist[i].n_value != 0))
-       {
-           char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
-           unsigned long sz = nlist[i].n_value;
+        for(i=0;i<symLC->nsyms;i++)
+        {
+           if((nlist[i].n_type & N_TYPE) == N_UNDF
+                   && (nlist[i].n_type & N_EXT) && (nlist[i].n_value != 0))
+           {
+               char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
+               unsigned long sz = nlist[i].n_value;
 
-           nlist[i].n_value = commonCounter;
+               nlist[i].n_value = commonCounter;
 
-           ghciInsertStrHashTable(oc->fileName, symhash, nm, (void*)commonCounter);
-           oc->symbols[curSymbol++] = nm;
+               ghciInsertStrHashTable(oc->fileName, symhash, nm,
+                                      (void*)commonCounter);
+               oc->symbols[curSymbol++] = nm;
 
-           commonCounter += sz;
-       }
+               commonCounter += sz;
+           }
+        }
     }
     return 1;
 }
@@ -3725,7 +3774,6 @@ static int ocResolve_MachO(ObjectCode* oc)
     struct symtab_command *symLC = NULL;
     struct dysymtab_command *dsymLC = NULL;
     struct nlist *nlist;
-    unsigned long *indirectSyms;
 
     for(i=0;i<header->ncmds;i++)
     {
@@ -3739,7 +3787,8 @@ static int ocResolve_MachO(ObjectCode* oc)
     }
 
     sections = (struct section*) (segLC+1);
-    nlist = (struct nlist*) (image + symLC->symoff);
+    nlist = symLC ? (struct nlist*) (image + symLC->symoff)
+                  : NULL;
 
     for(i=0;i<segLC->nsects;i++)
     {
@@ -3749,15 +3798,19 @@ static int ocResolve_MachO(ObjectCode* oc)
            nl_ptrs = &sections[i];
     }
 
-    indirectSyms = (unsigned long*) (image + dsymLC->indirectsymoff);
-
-    if(la_ptrs)
-       if(!resolveImports(oc,image,symLC,la_ptrs,indirectSyms,nlist))
-           return 0;
-    if(nl_ptrs)
-       if(!resolveImports(oc,image,symLC,nl_ptrs,indirectSyms,nlist))
-           return 0;
-
+    if(dsymLC)
+    {
+        unsigned long *indirectSyms
+            = (unsigned long*) (image + dsymLC->indirectsymoff);
+
+        if(la_ptrs)
+            if(!resolveImports(oc,image,symLC,la_ptrs,indirectSyms,nlist))
+                return 0;
+        if(nl_ptrs)
+            if(!resolveImports(oc,image,symLC,nl_ptrs,indirectSyms,nlist))
+                return 0;
+    }
+    
     for(i=0;i<segLC->nsects;i++)
     {
        if(!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,&sections[i]))
@@ -3786,14 +3839,24 @@ static int ocResolve_MachO(ObjectCode* oc)
 
 static void machoInitSymbolsWithoutUnderscore()
 {
-    void *p;
+    extern void* symbolsWithoutUnderscore[];
+    void **p = symbolsWithoutUnderscore;
+    __asm__ volatile(".data\n_symbolsWithoutUnderscore:");
 
 #undef Sym
-#define Sym(x)                                         \
-    __asm__ ("lis %0,hi16(" #x ")\n\tori %0,%0,lo16(" #x ")" : "=r" (p));      \
-    ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, p);
+#define Sym(x)  \
+    __asm__ volatile(".long " # x);
 
     RTS_MACHO_NOUNDERLINE_SYMBOLS
 
+    __asm__ volatile(".text");
+    
+#undef Sym
+#define Sym(x)  \
+    ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, *p++);
+    
+    RTS_MACHO_NOUNDERLINE_SYMBOLS
+    
+#undef Sym
 }
 #endif