[llvm-commits] [llvm] r117849 - in /llvm/trunk: include/llvm/Support/ELF.h lib/MC/ELFObjectWriter.cpp

Rafael Espindola rafael.espindola at gmail.com
Sat Oct 30 17:16:26 PDT 2010


Author: rafael
Date: Sat Oct 30 19:16:26 2010
New Revision: 117849

URL: http://llvm.org/viewvc/llvm-project?rev=117849&view=rev
Log:
Add support for files with more than 65280 sections. No testcase since
it would be a bit too big :-)

Modified:
    llvm/trunk/include/llvm/Support/ELF.h
    llvm/trunk/lib/MC/ELFObjectWriter.cpp

Modified: llvm/trunk/include/llvm/Support/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELF.h?rev=117849&r1=117848&r2=117849&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ELF.h (original)
+++ llvm/trunk/include/llvm/Support/ELF.h Sat Oct 30 19:16:26 2010
@@ -299,6 +299,7 @@
   SHN_HIPROC    = 0xff1f, // Highest processor-specific index
   SHN_ABS       = 0xfff1, // Symbol has absolute value; does not need relocation
   SHN_COMMON    = 0xfff2, // FORTRAN COMMON or C external global variables
+  SHN_XINDEX    = 0xffff, // Mark that the index is >= SHN_LORESERVE
   SHN_HIRESERVE = 0xffff  // Highest reserved index
 };
 

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=117849&r1=117848&r2=117849&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sat Oct 30 19:16:26 2010
@@ -164,6 +164,8 @@
 
     bool NeedsGOT;
 
+    bool NeedsSymtabShndx;
+
     ELFObjectWriter *Writer;
 
     raw_ostream &OS;
@@ -180,6 +182,8 @@
     unsigned LastLocalSymbolIndex;
     // This holds the .strtab section index.
     unsigned StringTableIndex;
+    // This holds the .symtab section index.
+    unsigned SymbolTableIndex;
 
     unsigned ShstrtabIndex;
 
@@ -187,7 +191,8 @@
     ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit,
                         uint16_t _EMachine, bool _HasRelAddend,
                         Triple::OSType _OSType)
-      : NeedsGOT(false), Writer(_Writer), OS(Writer->getStream()),
+      : NeedsGOT(false), NeedsSymtabShndx(false), Writer(_Writer),
+        OS(Writer->getStream()),
         Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend),
         OSType(_OSType), EMachine(_EMachine) {
     }
@@ -265,14 +270,18 @@
 
     void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections);
 
-    void WriteSymbolEntry(MCDataFragment *F, uint64_t name, uint8_t info,
+    void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
+                          uint64_t name, uint8_t info,
                           uint64_t value, uint64_t size,
-                          uint8_t other, uint16_t shndx);
+                          uint8_t other, uint32_t shndx,
+                          bool Reserved);
 
-    void WriteSymbol(MCDataFragment *F, ELFSymbolData &MSD,
+    void WriteSymbol(MCDataFragment *SymtabF,  MCDataFragment *ShndxF,
+                     ELFSymbolData &MSD,
                      const MCAsmLayout &Layout);
 
-    void WriteSymbolTable(MCDataFragment *F, const MCAssembler &Asm,
+    void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
+                          const MCAssembler &Asm,
                           const MCAsmLayout &Layout,
                           unsigned NumRegularSections);
 
@@ -377,56 +386,82 @@
   Write16(Is64Bit ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
 
   // e_shnum     = # of section header ents
-  Write16(NumberOfSections);
+  if (NumberOfSections >= ELF::SHN_LORESERVE)
+    Write16(0);
+  else
+    Write16(NumberOfSections);
 
   // e_shstrndx  = Section # of '.shstrtab'
-  Write16(ShstrtabIndex);
+  if (NumberOfSections >= ELF::SHN_LORESERVE)
+    Write16(ELF::SHN_XINDEX);
+  else
+    Write16(ShstrtabIndex);
 }
 
-void ELFObjectWriterImpl::WriteSymbolEntry(MCDataFragment *F, uint64_t name,
+void ELFObjectWriterImpl::WriteSymbolEntry(MCDataFragment *SymtabF,
+                                           MCDataFragment *ShndxF,
+                                           uint64_t name,
                                            uint8_t info, uint64_t value,
                                            uint64_t size, uint8_t other,
-                                           uint16_t shndx) {
+                                           uint32_t shndx,
+                                           bool Reserved) {
+  if (ShndxF) {
+    char buf[4];
+    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
+      String32(buf, shndx);
+    else
+      String32(buf, 0);
+    ShndxF->getContents() += StringRef(buf, 4);
+  }
+
   if (Is64Bit) {
     char buf[8];
 
     String32(buf, name);
-    F->getContents() += StringRef(buf, 4); // st_name
+    SymtabF->getContents() += StringRef(buf, 4); // st_name
 
     String8(buf, info);
-    F->getContents() += StringRef(buf, 1);  // st_info
+    SymtabF->getContents() += StringRef(buf, 1);  // st_info
 
     String8(buf, other);
-    F->getContents() += StringRef(buf, 1); // st_other
+    SymtabF->getContents() += StringRef(buf, 1); // st_other
+
+    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
+      String16(buf, ELF::SHN_XINDEX);
+    else
+      String16(buf, shndx);
 
-    String16(buf, shndx);
-    F->getContents() += StringRef(buf, 2); // st_shndx
+    SymtabF->getContents() += StringRef(buf, 2); // st_shndx
 
     String64(buf, value);
-    F->getContents() += StringRef(buf, 8); // st_value
+    SymtabF->getContents() += StringRef(buf, 8); // st_value
 
     String64(buf, size);
-    F->getContents() += StringRef(buf, 8);  // st_size
+    SymtabF->getContents() += StringRef(buf, 8);  // st_size
   } else {
     char buf[4];
 
     String32(buf, name);
-    F->getContents() += StringRef(buf, 4);  // st_name
+    SymtabF->getContents() += StringRef(buf, 4);  // st_name
 
     String32(buf, value);
-    F->getContents() += StringRef(buf, 4); // st_value
+    SymtabF->getContents() += StringRef(buf, 4); // st_value
 
     String32(buf, size);
-    F->getContents() += StringRef(buf, 4);  // st_size
+    SymtabF->getContents() += StringRef(buf, 4);  // st_size
 
     String8(buf, info);
-    F->getContents() += StringRef(buf, 1);  // st_info
+    SymtabF->getContents() += StringRef(buf, 1);  // st_info
 
     String8(buf, other);
-    F->getContents() += StringRef(buf, 1); // st_other
+    SymtabF->getContents() += StringRef(buf, 1); // st_other
+
+    if (shndx >= ELF::SHN_LORESERVE && !Reserved)
+      String16(buf, ELF::SHN_XINDEX);
+    else
+      String16(buf, shndx);
 
-    String16(buf, shndx);
-    F->getContents() += StringRef(buf, 2); // st_shndx
+    SymtabF->getContents() += StringRef(buf, 2); // st_shndx
   }
 }
 
@@ -503,12 +538,17 @@
   }
 }
 
-void ELFObjectWriterImpl::WriteSymbol(MCDataFragment *F, ELFSymbolData &MSD,
+void ELFObjectWriterImpl::WriteSymbol(MCDataFragment *SymtabF,
+                                      MCDataFragment *ShndxF,
+                                      ELFSymbolData &MSD,
                                       const MCAsmLayout &Layout) {
   MCSymbolData &OrigData = *MSD.SymbolData;
   MCSymbolData &Data =
     Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol()));
 
+  bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
+    Data.getSymbol().isVariable();
+
   uint8_t Binding = GetBinding(OrigData);
   uint8_t Visibility = GetVisibility(OrigData);
   uint8_t Type = GetType(Data);
@@ -541,11 +581,12 @@
   }
 
   // Write out the symbol table entry
-  WriteSymbolEntry(F, MSD.StringIndex, Info, Value,
-                   Size, Other, MSD.SectionIndex);
+  WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
+                   Size, Other, MSD.SectionIndex, IsReserved);
 }
 
-void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *F,
+void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *SymtabF,
+                                           MCDataFragment *ShndxF,
                                            const MCAssembler &Asm,
                                            const MCAsmLayout &Layout,
                                            unsigned NumRegularSections) {
@@ -556,14 +597,13 @@
   // FIXME: Make sure the start of the symbol table is aligned.
 
   // The first entry is the undefined symbol entry.
-  unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
-  F->getContents().append(EntrySize, '\x00');
+  WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
 
   // Write the symbol table entries.
   LastLocalSymbolIndex = LocalSymbolData.size() + 1;
   for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
     ELFSymbolData &MSD = LocalSymbolData[i];
-    WriteSymbol(F, MSD, Layout);
+    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
   }
 
   // Write out a symbol table entry for each regular section.
@@ -576,7 +616,8 @@
     // the relocations messed up
     if (Section.getType() == ELF::SHT_RELA || Section.getType() == ELF::SHT_REL)
       continue;
-    WriteSymbolEntry(F, 0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT, Index);
+    WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
+                     ELF::STV_DEFAULT, Index, false);
     LastLocalSymbolIndex++;
   }
 
@@ -586,7 +627,7 @@
     assert(((Data.getFlags() & ELF_STB_Global) ||
             (Data.getFlags() & ELF_STB_Weak)) &&
            "External symbol requires STB_GLOBAL or STB_WEAK flag");
-    WriteSymbol(F, MSD, Layout);
+    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
     if (GetBinding(Data) == ELF::STB_LOCAL)
       LastLocalSymbolIndex++;
   }
@@ -594,7 +635,7 @@
   for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
     ELFSymbolData &MSD = UndefinedSymbolData[i];
     MCSymbolData &Data = *MSD.SymbolData;
-    WriteSymbol(F, MSD, Layout);
+    WriteSymbol(SymtabF, ShndxF, MSD, Layout);
     if (GetBinding(Data) == ELF::STB_LOCAL)
       LastLocalSymbolIndex++;
   }
@@ -940,6 +981,8 @@
       MSD.SectionIndex = ELF::SHN_UNDEF;
     } else {
       MSD.SectionIndex = SectionIndexMap.lookup(&RefSymbol.getSection());
+      if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
+        NeedsSymtabShndx = true;
       assert(MSD.SectionIndex && "Invalid section index!");
     }
 
@@ -1093,24 +1136,35 @@
   MCContext &Ctx = Asm.getContext();
   MCDataFragment *F;
 
-  const MCSection *SymtabSection;
   unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
 
   unsigned NumRegularSections = Asm.size();
 
   // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
-  const MCSection *ShstrtabSection;
-  ShstrtabSection = Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
-                                      SectionKind::getReadOnly(), false);
+  const MCSection *ShstrtabSection =
+    Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0,
+                      SectionKind::getReadOnly(), false);
   MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
   ShstrtabSD.setAlignment(1);
   ShstrtabIndex = Asm.size();
 
-  SymtabSection = Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
-                                    SectionKind::getReadOnly(),
-                                    false, EntrySize);
+  const MCSection *SymtabSection =
+    Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
+                      SectionKind::getReadOnly(),
+                      false, EntrySize);
   MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
   SymtabSD.setAlignment(Is64Bit ? 8 : 4);
+  SymbolTableIndex = Asm.size();
+
+  MCSectionData *SymtabShndxSD = NULL;
+
+  if (NeedsSymtabShndx) {
+    const MCSection *SymtabShndxSection =
+      Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
+                        SectionKind::getReadOnly(), false, 4);
+    SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
+    SymtabShndxSD->setAlignment(4);
+  }
 
   const MCSection *StrtabSection;
   StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
@@ -1123,7 +1177,12 @@
 
   // Symbol table
   F = new MCDataFragment(&SymtabSD);
-  WriteSymbolTable(F, Asm, Layout, NumRegularSections);
+  MCDataFragment *ShndxF = NULL;
+  if (NeedsSymtabShndx) {
+    ShndxF = new MCDataFragment(SymtabShndxSD);
+    Asm.AddSectionToTheEnd(*Writer, *SymtabShndxSD, Layout);
+  }
+  WriteSymbolTable(F, ShndxF, Asm, Layout, NumRegularSections);
   Asm.AddSectionToTheEnd(*Writer, SymtabSD, Layout);
 
   F = new MCDataFragment(&StrtabSD);
@@ -1255,7 +1314,11 @@
   // Should we align the section header table?
   //
   // Null section first.
-  WriteSecHdrEntry(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  uint64_t FirstSectionSize =
+    NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
+  uint32_t FirstSectionLink =
+    ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
+  WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
 
   for (MCAssembler::const_iterator it = Asm.begin(),
          ie = Asm.end(); it != ie; ++it) {
@@ -1300,6 +1363,10 @@
       sh_info = LastLocalSymbolIndex;
       break;
 
+    case ELF::SHT_SYMTAB_SHNDX:
+      sh_link = SymbolTableIndex;
+      break;
+
     case ELF::SHT_PROGBITS:
     case ELF::SHT_STRTAB:
     case ELF::SHT_NOBITS:





More information about the llvm-commits mailing list