[project @ 2001-09-12 14:53:39 by sewardj]
[ghc-hetmet.git] / ghc / rts / Linker.c
index 271aa4b..d733257 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.63 2001/09/04 16:33:04 sewardj Exp $
+ * $Id: Linker.c,v 1.67 2001/09/12 14:53:39 sewardj Exp $
  *
  * (c) The GHC Team, 2000, 2001
  *
@@ -287,7 +287,7 @@ typedef struct _RtsSymbolVal {
       Sym(StgReturn)                           \
       Sym(init_stack)                          \
       SymX(cmp_thread)                         \
-      Sym(__init_PrelGHC)                      \
+      Sym(__stginit_PrelGHC)                   \
       SymX(freeHaskellFunctionPtr)             \
       SymX(OnExitHook)                         \
       SymX(ErrorHdrHook)                       \
@@ -1699,11 +1699,7 @@ ocGetNames_ELF ( ObjectCode* oc )
    }
 
    k = 0;
-   oc->n_sections = ehdr->e_shnum;
-   oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section), 
-                                  "ocGetNames_ELF(oc->sections)" );
-
-   for (i = 0; i < oc->n_sections; i++) {
+   for (i = 0; i < ehdr->e_shnum; i++) {
 
       /* make a section entry for relevant sections */
       SectionKind kind = SECTIONKIND_OTHER;
@@ -1721,22 +1717,17 @@ ocGetNames_ELF ( ObjectCode* oc )
             it, and set its .sh_offset field such that 
             ehdrC + .sh_offset == addr_of_zeroed_space.  */
          char* zspace = stgCallocBytes(1, shdr[i].sh_size, 
-                                       "ocGetNames_ELF(anonymous bss)");
+                                       "ocGetNames_ELF(BSS)");
          shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC);
-         /* We don't prod BSS sections, hence the following isn't
-            necessary:
-               addProddableBlock(oc, zspace, shdr[i].sh_size);
-         */
-         /*
+        /*         
          fprintf(stderr, "BSS section at 0x%x, size %d\n", 
                          zspace, shdr[i].sh_size);
-         */
+        */
       }
 
       /* fill in the section info */
-      oc->sections[i].start = ehdrC + shdr[i].sh_offset;
-      oc->sections[i].end   = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
-      oc->sections[i].kind  = kind;
+      addSection(oc, kind, ehdrC + shdr[i].sh_offset, 
+                     ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
       if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0)
          addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size);
 
@@ -1751,6 +1742,26 @@ ocGetNames_ELF ( ObjectCode* oc )
                                    "ocGetNames_ELF(oc->symbols)");
 
       for (j = 0; j < nent; j++) {
+
+         char  isLocal = FALSE; /* avoids uninit-var warning */
+         char* ad      = NULL;
+         char* nm      = strtab + stab[j].st_name;
+         int   secno   = stab[j].st_shndx;
+
+        /* Figure out if we want to add it; if so, set ad to its
+            address.  Otherwise leave ad == NULL. */
+
+         if (secno == SHN_COMMON) {
+            isLocal = FALSE;
+            ad = stgCallocBytes(1, stab[j].st_size, "ocGetNames_ELF(COMMON)");
+           /*
+            fprintf(stderr, "COMMON symbol, size %d name %s\n", 
+                            stab[j].st_size, nm);
+           */
+           /* Pointless to do addProddableBlock() for this area,
+               since the linker should never poke around in it. */
+        }
+         else
          if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
                 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
               )
@@ -1765,33 +1776,39 @@ ocGetNames_ELF ( ObjectCode* oc )
                 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE 
               )
             ) {
-            char* nm;
-            char* ad; 
-           int secno = stab[j].st_shndx;
            /* Section 0 is the undefined section, hence > and not >=. */
             ASSERT(secno > 0 && secno < ehdr->e_shnum);
-            nm = strtab + stab[j].st_name;
-            /*
+           /*            
             if (shdr[secno].sh_type == SHT_NOBITS) {
-               fprintf(stderr, "bss symbol, size %d off %d name %s\n", 
-               stab[j].st_size, stab[j].st_value, nm);
+               fprintf(stderr, "   BSS symbol, size %d off %d name %s\n", 
+                               stab[j].st_size, stab[j].st_value, nm);
             }
             */
             ad = ehdrC + shdr[ secno ].sh_offset + stab[j].st_value;
-            ASSERT(nm != NULL);
-            ASSERT(ad != NULL);
-           oc->symbols[j] = nm;
             if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
                IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p  %s %s",
                                       ad, oc->fileName, nm ));
-               insertStrHashTable(oc->lochash, nm, ad);
+               isLocal = TRUE;
             } else {
                IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p  %s %s",
                                       ad, oc->fileName, nm ));
-               insertStrHashTable(symhash, nm, ad);
+               isLocal = FALSE;
             }
          }
-         else {
+
+         /* And the decision is ... */
+
+         if (ad != NULL) {
+            ASSERT(nm != NULL);
+           oc->symbols[j] = nm;
+            /* Acquire! */
+            if (isLocal) {
+               insertStrHashTable(oc->lochash, nm, ad);
+            } else {
+               insertStrHashTable(symhash, nm, ad);
+            }
+         } else {
+            /* Skip. */
             IF_DEBUG(linker,belch( "skipping `%s'", 
                                    strtab + stab[j].st_name ));
             /*
@@ -1805,6 +1822,7 @@ ocGetNames_ELF ( ObjectCode* oc )
             */
             oc->symbols[j] = NULL;
          }
+
       }
    }
 
@@ -1906,7 +1924,6 @@ do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
       Elf32_Addr  offset = rtab[j].r_offset;
       Elf32_Word  info   = rtab[j].r_info;
       Elf32_Sword addend = rtab[j].r_addend;
-
       Elf32_Addr  P  = ((Elf32_Addr)targ) + offset;
       Elf32_Addr  A  = addend;
       Elf32_Addr  S;
@@ -1949,7 +1966,7 @@ do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
       }
       IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p   S = %p   A = %p\n",
                                         (void*)P, (void*)S, (void*)A )); 
-      checkProddableBlock ( oc, P );
+      checkProddableBlock ( oc, (void*)P );
       switch (ELF32_R_TYPE(info)) {
 #        if defined(sparc_TARGET_ARCH)
          case R_SPARC_WDISP30: