Emit a symbol table entry for each function we output to the ELF file. This
authorChris Lattner <sabre@nondot.org>
Mon, 11 Jul 2005 06:17:35 +0000 (06:17 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 11 Jul 2005 06:17:35 +0000 (06:17 +0000)
allows objdump to know which function we are emitting to:

00000000 <foo>:     <----
   0:   b8 01 00 00 00          mov    $0x1,%eax
   5:   03 44 24 04             add    0x4(%esp,1),%eax
   9:   c3                      ret

... and allows .o files to be useful for linking :)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22378 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ELFWriter.cpp

index 96668e29ecb3bb162eb51cf50a3aad3c34e9ebf7..2f2eec0ec20daae2e2cd952c5519e7da28d02b1b 100644 (file)
@@ -67,7 +67,37 @@ namespace llvm {
 
       FnStart = OutputBuffer.size();
     }
-    void finishFunction(MachineFunction &F) {}
+    void finishFunction(MachineFunction &F) {
+      // We now know the size of the function, add a symbol to represent it.
+      ELFWriter::ELFSym FnSym(F.getFunction());
+
+      // Figure out the binding (linkage) of the symbol.
+      switch (F.getFunction()->getLinkage()) {
+      default:
+        // appending linkage is illegal for functions.
+        assert(0 && "Unknown linkage type!");
+      case GlobalValue::ExternalLinkage:
+        FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
+        break;
+      case GlobalValue::LinkOnceLinkage:
+      case GlobalValue::WeakLinkage:
+        FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
+        break;
+      case GlobalValue::InternalLinkage:
+        FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
+        break;
+      }
+
+      FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
+      FnSym.SectionIdx = EW.SectionList.size()-1;  // .text section.
+      // Value = Offset from start of .text
+      FnSym.Value = FnStart - EW.SectionList.back().Offset;
+      FnSym.Size = OutputBuffer.size()-FnStart;
+
+      // Finally, add it to the symtab.
+      EW.SymbolTable.push_back(FnSym);
+    }
+
     void emitConstantPool(MachineConstantPool *MCP) {
       if (MCP->isEmpty()) return;
       assert(0 && "unimp");