Revert "Batch merge"
[ghc.git] / rts / linker / Elf.c
index 0a7ffae..9ea10d4 100644 (file)
@@ -169,8 +169,6 @@ get_shndx_table(Elf_Ehdr* ehdr)
 void
 ocInit_ELF(ObjectCode * oc)
 {
-    ocDeinit_ELF(oc);
-
     oc->info = (struct ObjectCodeFormatInfo*)stgCallocBytes(
             1, sizeof *oc->info,
             "ocInit_Elf(ObjectCodeFormatInfo)");
@@ -320,7 +318,6 @@ ocDeinit_ELF(ObjectCode * oc)
         }
 
         stgFree(oc->info);
-        oc->info = NULL;
     }
 }
 
@@ -579,7 +576,7 @@ ocVerifyImage_ELF ( ObjectCode* oc )
 /* Figure out what kind of section it is.  Logic derived from
    Figure 1.14 ("Special Sections") of the ELF document
    ("Portable Formats Specification, Version 1.1"). */
-static SectionKind getSectionKind_ELF( Elf_Shdr *hdr, int *is_bss )
+static int getSectionKind_ELF( Elf_Shdr *hdr, int *is_bss )
 {
     *is_bss = false;
 
@@ -681,31 +678,23 @@ ocGetNames_ELF ( ObjectCode* oc )
       StgWord mapped_size = 0, mapped_offset = 0;
       StgWord size = shdr[i].sh_size;
       StgWord offset = shdr[i].sh_offset;
-      StgWord align = shdr[i].sh_addralign;
 
       if (is_bss && size > 0) {
          /* This is a non-empty .bss section.  Allocate zeroed space for
             it, and set its .sh_offset field such that
             ehdrC + .sh_offset == addr_of_zeroed_space.  */
-#if defined(NEED_GOT) || RTS_LINKER_USE_MMAP
-          if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
-              /* The space for bss sections is already preallocated */
-              ASSERT(oc->bssBegin != NULL);
-              alloc = SECTION_NOMEM;
-              start =
-                oc->image + roundUpToAlign(oc->bssBegin - oc->image, align);
-              oc->bssBegin = (char*)start + size;
-              ASSERT(oc->bssBegin <= oc->bssEnd);
-          } else {
-              /* Use mmapForLinker to allocate .bss, otherwise the malloced
-               * address might be out of range for sections that are mmaped.
-               */
-              alloc = SECTION_MMAP;
-              start = mmapForLinker(size, MAP_ANONYMOUS, -1, 0);
-              mapped_start = start;
-              mapped_offset = 0;
-              mapped_size = roundUpToPage(size);
-          }
+#if defined(NEED_GOT)
+          /* always use mmap if we use GOT slots.  Otherwise the malloced
+           * address might be out of range for sections that are mmaped.
+           */
+          alloc = SECTION_MMAP;
+          start = mmap(NULL, size,
+                       PROT_READ | PROT_WRITE | PROT_EXEC,
+                       MAP_ANON | MAP_PRIVATE,
+                       -1, 0);
+          mapped_start = start;
+          mapped_offset = 0;
+          mapped_size = roundUpToPage(size);
 #else
           alloc = SECTION_MALLOC;
           start = stgCallocBytes(1, size, "ocGetNames_ELF(BSS)");
@@ -765,7 +754,7 @@ ocGetNames_ELF ( ObjectCode* oc )
           start = mem;
           mapped_start = mem;
 #else
-          if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
+          if (USE_CONTIGUOUS_MMAP) {
               // already mapped.
               start = oc->image + offset;
               alloc = SECTION_NOMEM;
@@ -827,7 +816,7 @@ ocGetNames_ELF ( ObjectCode* oc )
           oc->n_symbols += symTab->n_symbols;
       }
 
-      oc->symbols = stgCallocBytes(oc->n_symbols, sizeof(SymbolName*),
+      oc->symbols = stgCallocBytes(oc->n_symbols, sizeof(Symbol_t),
                                    "ocGetNames_ELF(oc->symbols)");
       // Note calloc: if we fail partway through initializing symbols, we need
       // to undo the additions to the symbol table so far. We know which ones
@@ -938,7 +927,8 @@ ocGetNames_ELF ( ObjectCode* oc )
                            ) {
                            goto fail;
                        }
-                       oc->symbols[curSymbol++] = nm;
+                       oc->symbols[curSymbol++].name = nm;
+                       oc->symbols[curSymbol].addr = symbol->addr;
                    }
                } else {
                    /* Skip. */
@@ -1547,7 +1537,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 
          case R_PPC_PLTREL24:
             value -= 0x8000; /* See Note [.LCTOC1 in PPC PIC code] */
-            /* fallthrough */
+            FALLTHROUGH;
          case R_PPC_REL24:
             delta = value - P;
 
@@ -1595,6 +1585,9 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 
       case COMPAT_R_X86_64_PC32:
       {
+#if defined(ALWAYS_PIC)
+          barf("R_X86_64_PC32 relocation, but ALWAYS_PIC.");
+#else
           StgInt64 off = value - P;
           if (off != (Elf64_Sword)off && X86_64_ELF_NONPIC_HACK) {
               StgInt64 pltAddress =
@@ -1611,6 +1604,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           }
           Elf64_Sword payload = off;
           memcpy((void*)P, &payload, sizeof(payload));
+#endif
           break;
       }
 
@@ -1623,6 +1617,9 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 
       case COMPAT_R_X86_64_32:
       {
+#if defined(ALWAYS_PIC)
+          barf("R_X86_64_32 relocation, but ALWAYS_PIC.");
+#else
           if (value != (Elf64_Word)value && X86_64_ELF_NONPIC_HACK) {
               StgInt64 pltAddress =
                   (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
@@ -1638,11 +1635,15 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           }
           Elf64_Word payload = value;
           memcpy((void*)P, &payload, sizeof(payload));
+#endif
           break;
       }
 
       case COMPAT_R_X86_64_32S:
       {
+#if defined(ALWAYS_PIC)
+          barf("R_X86_64_32S relocation, but ALWAYS_PIC.");
+#else
           if ((StgInt64)value != (Elf64_Sword)value && X86_64_ELF_NONPIC_HACK) {
               StgInt64 pltAddress =
                   (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
@@ -1658,6 +1659,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           }
           Elf64_Sword payload = value;
           memcpy((void*)P, &payload, sizeof(payload));
+#endif
           break;
       }
       case COMPAT_R_X86_64_REX_GOTPCRELX:
@@ -1679,6 +1681,9 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 #if defined(dragonfly_HOST_OS)
       case COMPAT_R_X86_64_GOTTPOFF:
       {
+#if defined(ALWAYS_PIC)
+          barf("R_X86_64_GOTTPOFF relocation, but ALWAYS_PIC.");
+#else
         /* determine the offset of S to the current thread's tls
            area
            XXX: Move this to the beginning of function */
@@ -1696,12 +1701,16 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           }
           Elf64_SWord payload = off;
           memcpy((void*)P, &payload, sizeof(payload));
+#endif
           break;
       }
 #endif
 
       case COMPAT_R_X86_64_PLT32:
       {
+#if defined(ALWAYS_PIC)
+          barf("R_X86_64_PLT32 relocation, but ALWAYS_PIC.");
+#else
           StgInt64 off = value - P;
           if (off != (Elf64_Sword)off) {
               StgInt64 pltAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
@@ -1716,6 +1725,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           }
           Elf64_Sword payload = off;
           memcpy((void*)P, &payload, sizeof(payload));
+#endif
           break;
       }
 #endif
@@ -1881,27 +1891,22 @@ int ocRunInit_ELF( ObjectCode *oc )
 
 #if defined(NEED_SYMBOL_EXTRAS)
 
-int ocAllocateExtras_ELF( ObjectCode *oc )
+int ocAllocateSymbolExtras_ELF( ObjectCode *oc )
 {
-  Elf_Ehdr *ehdr = (Elf_Ehdr *) oc->image;
-  Elf_Shdr* shdr = (Elf_Shdr *) ( ((char *)oc->image) + ehdr->e_shoff );
-  Elf_Shdr* symtab = NULL;
-  Elf_Word shnum = elf_shnum(ehdr);
-  int bssSize = 0;
-
-  for (Elf_Word i = 0; i < shnum; ++i) {
-    if(shdr[i].sh_type == SHT_SYMTAB) {
-      symtab = &shdr[i];
-    } else {
-      int isBss = 0;
-      getSectionKind_ELF(&shdr[i], &isBss);
-      if (isBss && shdr[i].sh_size > 0) {
-        bssSize += roundUpToAlign(shdr[i].sh_size, shdr[i].sh_addralign);
-      }
-    }
-  }
+  Elf_Ehdr *ehdr;
+  Elf_Shdr* shdr;
+  Elf_Word i, shnum;
+
+  ehdr = (Elf_Ehdr *) oc->image;
+  shdr = (Elf_Shdr *) ( ((char *)oc->image) + ehdr->e_shoff );
+
+  shnum = elf_shnum(ehdr);
+
+  for( i = 0; i < shnum; i++ )
+    if( shdr[i].sh_type == SHT_SYMTAB )
+      break;
 
-  if (symtab == NULL)
+  if( i == shnum )
   {
     // Not having a symbol table is not in principle a problem.
     // When an object file has no symbols then the 'strip' program
@@ -1911,15 +1916,15 @@ int ocAllocateExtras_ELF( ObjectCode *oc )
     return 1;
   }
 
-  if( symtab->sh_entsize != sizeof( Elf_Sym ) )
+  if( shdr[i].sh_entsize != sizeof( Elf_Sym ) )
   {
     errorBelch( "The entry size (%d) of the symtab isn't %d\n",
-      (int) symtab->sh_entsize, (int) sizeof( Elf_Sym ) );
+      (int) shdr[i].sh_entsize, (int) sizeof( Elf_Sym ) );
 
     return 0;
   }
 
-  return ocAllocateExtras(oc, symtab->sh_size / sizeof( Elf_Sym ), 0, bssSize);
+  return ocAllocateSymbolExtras( oc, shdr[i].sh_size / sizeof( Elf_Sym ), 0 );
 }
 
 #endif /* NEED_SYMBOL_EXTRAS */