[llvm-commits] CVS: llvm/lib/CodeGen/ELFWriter.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Jul 7 22:47:11 PDT 2005



Changes in directory llvm/lib/CodeGen:

ELFWriter.cpp updated: 1.2 -> 1.3
---
Log message:

Add support for emitting a .data section and .bss section.
Add support for emitting external and .bss symbols.


---
Diffs of the changes:  (+67 -22)

 ELFWriter.cpp |   89 +++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 67 insertions(+), 22 deletions(-)


Index: llvm/lib/CodeGen/ELFWriter.cpp
diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.2 llvm/lib/CodeGen/ELFWriter.cpp:1.3
--- llvm/lib/CodeGen/ELFWriter.cpp:1.2	Thu Jul  7 02:02:20 2005
+++ llvm/lib/CodeGen/ELFWriter.cpp	Fri Jul  8 00:47:00 2005
@@ -96,9 +96,22 @@
 
 void ELFWriter::EmitGlobal(GlobalVariable *GV, ELFSection &DataSection,
                            ELFSection &BSSSection) {
-  // If this is an external global, emit it...
-  assert(GV->hasInitializer() && "FIXME: unimp");
+  // If this is an external global, emit it now.  TODO: Note that it would be
+  // better to ignore the symbol here and only add it to the symbol table if
+  // referenced.
+  if (!GV->hasInitializer()) {
+    ELFSym ExternalSym(GV);
+    ExternalSym.SetBind(ELFSym::STB_GLOBAL);
+    ExternalSym.SetType(ELFSym::STT_NOTYPE);
+    ExternalSym.SectionIdx = ELFSection::SHN_UNDEF;
+    SymbolTable.push_back(ExternalSym);
+    return;
+  }
   
+  const Type *GVType = (const Type*)GV->getType();
+  unsigned Align = TM.getTargetData().getTypeAlignment(GVType);
+  unsigned Size  = TM.getTargetData().getTypeSize(GVType);
+
   // If this global has a zero initializer, it is part of the .bss or common
   // section.
   if (GV->getInitializer()->isNullValue()) {
@@ -108,9 +121,8 @@
     if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
       ELFSym CommonSym(GV);
       // Value for common symbols is the alignment required.
-      const Type *GVType = (const Type*)GV->getType();
-      CommonSym.Value = TM.getTargetData().getTypeAlignment(GVType);
-      CommonSym.Size  = TM.getTargetData().getTypeSize(GVType);
+      CommonSym.Value = Align;
+      CommonSym.Size  = Size;
       CommonSym.SetBind(ELFSym::STB_GLOBAL);
       CommonSym.SetType(ELFSym::STT_OBJECT);
       // TODO SOMEDAY: add ELF visibility.
@@ -119,7 +131,40 @@
       return;
     }
 
-    // FIXME: Implement the .bss section.
+    // Otherwise, this symbol is part of the .bss section.  Emit it now.
+
+    // Handle alignment.  Ensure section is aligned at least as much as required
+    // by this symbol.
+    BSSSection.Align = std::max(BSSSection.Align, Align);
+
+    // Within the section, emit enough virtual padding to get us to an alignment
+    // boundary.
+    if (Align)
+      BSSSection.Size = (BSSSection.Size + Align - 1) & ~(Align-1);
+
+    ELFSym BSSSym(GV);
+    BSSSym.Value = BSSSection.Size;
+    BSSSym.Size = Size;
+    BSSSym.SetType(ELFSym::STT_OBJECT);
+
+    switch (GV->getLinkage()) {
+    default:  // weak/linkonce handled above
+      assert(0 && "Unexpected linkage type!");
+    case GlobalValue::AppendingLinkage:  // FIXME: This should be improved!
+    case GlobalValue::ExternalLinkage:
+      BSSSym.SetBind(ELFSym::STB_GLOBAL);
+      break;
+    case GlobalValue::InternalLinkage:
+      BSSSym.SetBind(ELFSym::STB_LOCAL);
+      break;
+    }
+
+    // Set the idx of the .bss section
+    BSSSym.SectionIdx = &BSSSection-&SectionList[0];
+    SymbolTable.push_back(BSSSym);
+
+    // Reserve space in the .bss section for this symbol.
+    BSSSection.Size += Size;
     return;
   }
 
@@ -143,26 +188,26 @@
 
   // Okay, the ELF header and .text sections have been completed, build the
   // .data, .bss, and "common" sections next.
-  ELFSection DataSection(".data", OutputBuffer.size());
-  ELFSection BSSSection (".bss");
+  SectionList.push_back(ELFSection(".data", OutputBuffer.size()));
+  SectionList.push_back(ELFSection(".bss"));
+  ELFSection &DataSection = *(SectionList.end()-2);
+  ELFSection &BSSSection = SectionList.back();
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I)
     EmitGlobal(I, DataSection, BSSSection);
 
-  // If the .data section is nonempty, add it to our list.
-  if (DataSection.Size) {
-    DataSection.Align = 4;   // FIXME: Compute!
-    // FIXME: Set the right flags and stuff.
-    SectionList.push_back(DataSection);
-  }
-
-  // If the .bss section is nonempty, add it to our list.
-  if (BSSSection.Size) {
-    BSSSection.Offset = OutputBuffer.size();
-    BSSSection.Align = 4;  // FIXME: Compute!
-    // FIXME: Set the right flags and stuff.
-    SectionList.push_back(BSSSection);
-  }
+  // Finish up the data section.
+  DataSection.Type  = ELFSection::SHT_PROGBITS;
+  DataSection.Flags = ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC;
+
+  // The BSS Section logically starts at the end of the Data Section (adjusted
+  // to the required alignment of the BSSSection).
+  BSSSection.Offset = DataSection.Offset+DataSection.Size;
+  BSSSection.Type   = ELFSection::SHT_NOBITS; 
+  BSSSection.Flags  = ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC;
+  if (BSSSection.Align)
+    BSSSection.Offset = (BSSSection.Offset+BSSSection.Align-1) &
+                        ~(BSSSection.Align-1);
 
   // Emit the symbol table now, if non-empty.
   EmitSymbolTable();






More information about the llvm-commits mailing list