diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFCodeEmitter.cpp | 94 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFCodeEmitter.h | 87 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFWriter.cpp | 142 | 
4 files changed, 184 insertions, 140 deletions
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index 89aebd82a12..ff917a72f0c 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -3,6 +3,7 @@ add_llvm_library(LLVMCodeGen    CodePlacementOpt.cpp    DeadMachineInstructionElim.cpp    DwarfEHPrepare.cpp +  ELFCodeEmitter.cpp    ELFWriter.cpp    GCMetadata.cpp    GCMetadataPrinter.cpp diff --git a/llvm/lib/CodeGen/ELFCodeEmitter.cpp b/llvm/lib/CodeGen/ELFCodeEmitter.cpp new file mode 100644 index 00000000000..0a0245f3dd5 --- /dev/null +++ b/llvm/lib/CodeGen/ELFCodeEmitter.cpp @@ -0,0 +1,94 @@ +//===-- lib/CodeGen/ELFCodeEmitter.cpp ------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ELFCodeEmitter.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Support/OutputBuffer.h" + +//===----------------------------------------------------------------------===// +//                       ELFCodeEmitter Implementation +//===----------------------------------------------------------------------===// + +namespace llvm { + +/// startFunction - This callback is invoked when a new machine function is +/// about to be emitted. +void ELFCodeEmitter::startFunction(MachineFunction &F) { +  // Align the output buffer to the appropriate alignment. +  unsigned Align = 16;   // FIXME: GENERICIZE!! +  // Get the ELF Section that this function belongs in. +  ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS, +                      ELFWriter::ELFSection::SHF_EXECINSTR | +                      ELFWriter::ELFSection::SHF_ALLOC); +  OutBuffer = &ES->SectionData; +  cerr << "FIXME: This code needs to be updated for changes in the " +       << "CodeEmitter interfaces.  In particular, this should set " +       << "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!"; +  abort(); + +  // Upgrade the section alignment if required. +  if (ES->Align < Align) ES->Align = Align; + +  // Add padding zeros to the end of the buffer to make sure that the +  // function will start on the correct byte alignment within the section. +  OutputBuffer OB(*OutBuffer, +                  TM.getTargetData()->getPointerSizeInBits() == 64, +                  TM.getTargetData()->isLittleEndian()); +  OB.align(Align); +  FnStart = OutBuffer->size(); +} + +/// finishFunction - This callback is invoked after the function is completely +/// finished. +bool ELFCodeEmitter::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::LinkOnceAnyLinkage: +  case GlobalValue::LinkOnceODRLinkage: +  case GlobalValue::WeakAnyLinkage: +  case GlobalValue::WeakODRLinkage: +    FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK); +    break; +  case GlobalValue::PrivateLinkage: +    assert (0 && "PrivateLinkage should not be in the symbol table."); +  case GlobalValue::InternalLinkage: +    FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL); +    break; +  } + +  ES->Size = OutBuffer->size(); + +  FnSym.SetType(ELFWriter::ELFSym::STT_FUNC); +  FnSym.SectionIdx = ES->SectionIdx; +  FnSym.Value = FnStart;   // Value = Offset from start of Section. +  FnSym.Size = OutBuffer->size()-FnStart; + +  // Finally, add it to the symtab. +  EW.SymbolTable.push_back(FnSym); +  return false; +} + +} // end namespace llvm diff --git a/llvm/lib/CodeGen/ELFCodeEmitter.h b/llvm/lib/CodeGen/ELFCodeEmitter.h new file mode 100644 index 00000000000..11ebcc871da --- /dev/null +++ b/llvm/lib/CodeGen/ELFCodeEmitter.h @@ -0,0 +1,87 @@ +//===-- lib/CodeGen/ELFCodeEmitter.h ----------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef ELFCODEEMITTER_H +#define ELFCODEEMITTER_H + +#include "ELFWriter.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" +#include <vector> + +namespace llvm { + +  /// ELFCodeEmitter - This class is used by the ELFWriter to  +  /// emit the code for functions to the ELF file. +  class ELFCodeEmitter : public MachineCodeEmitter { +    ELFWriter &EW; +    TargetMachine &TM; +    ELFWriter::ELFSection *ES;  // Section to write to. +    std::vector<unsigned char> *OutBuffer; +    size_t FnStart; +  public: +    explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {} + +    void startFunction(MachineFunction &F); +    bool finishFunction(MachineFunction &F); + +    void addRelocation(const MachineRelocation &MR) { +      assert(0 && "relo not handled yet!"); +    } + +    virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { +    } + +    virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { +      assert(0 && "CP not implementated yet!"); +      return 0; +    } +    virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const { +      assert(0 && "JT not implementated yet!"); +      return 0; +    } + +    virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { +      assert(0 && "JT not implementated yet!"); +      return 0; +    } + +    virtual uintptr_t getLabelAddress(uint64_t Label) const { +      assert(0 && "Label address not implementated yet!"); +      abort(); +      return 0; +    } + +    virtual void emitLabel(uint64_t LabelID) { +      assert(0 && "emit Label not implementated yet!"); +      abort(); +    } + +    virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { } + +    /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE! +    void startGVStub(const GlobalValue* F, unsigned StubSize, +                     unsigned Alignment = 1) { +      assert(0 && "JIT specific function called!"); +      abort(); +    } +    void startGVStub(const GlobalValue* F,  void *Buffer, unsigned StubSize) { +      assert(0 && "JIT specific function called!"); +      abort(); +    } +    void *finishGVStub(const GlobalValue *F) { +      assert(0 && "JIT specific function called!"); +      abort(); +      return 0; +    } +};  // end class ELFCodeEmitter + +} // end namespace llvm + +#endif + diff --git a/llvm/lib/CodeGen/ELFWriter.cpp b/llvm/lib/CodeGen/ELFWriter.cpp index 7cc11623524..be8edce08d7 100644 --- a/llvm/lib/CodeGen/ELFWriter.cpp +++ b/llvm/lib/CodeGen/ELFWriter.cpp @@ -32,6 +32,7 @@  //===----------------------------------------------------------------------===//  #include "ELFWriter.h" +#include "ELFCodeEmitter.h"  #include "llvm/Module.h"  #include "llvm/PassManager.h"  #include "llvm/DerivedTypes.h" @@ -61,149 +62,10 @@ MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,  }  //===----------------------------------------------------------------------===// -//                       ELFCodeEmitter Implementation -//===----------------------------------------------------------------------===// - -namespace llvm { -  /// ELFCodeEmitter - This class is used by the ELFWriter to emit the code for -  /// functions to the ELF file. -  class ELFCodeEmitter : public MachineCodeEmitter { -    ELFWriter &EW; -    TargetMachine &TM; -    ELFWriter::ELFSection *ES;  // Section to write to. -    std::vector<unsigned char> *OutBuffer; -    size_t FnStart; -  public: -    explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {} - -    void startFunction(MachineFunction &F); -    bool finishFunction(MachineFunction &F); - -    void addRelocation(const MachineRelocation &MR) { -      assert(0 && "relo not handled yet!"); -    } -     -    virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { -    } - -    virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { -      assert(0 && "CP not implementated yet!"); -      return 0; -    } -    virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const { -      assert(0 && "JT not implementated yet!"); -      return 0; -    } - -    virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { -      assert(0 && "JT not implementated yet!"); -      return 0; -    } - -    virtual uintptr_t getLabelAddress(uint64_t Label) const { -      assert(0 && "Label address not implementated yet!"); -      abort(); -      return 0; -    } - -    virtual void emitLabel(uint64_t LabelID) { -      assert(0 && "emit Label not implementated yet!"); -      abort(); -    } - - -    virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { } - - -    /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE! -    void startGVStub(const GlobalValue* F, unsigned StubSize, -                     unsigned Alignment = 1) { -      assert(0 && "JIT specific function called!"); -      abort(); -    } -    void startGVStub(const GlobalValue* F,  void *Buffer, unsigned StubSize) { -      assert(0 && "JIT specific function called!"); -      abort(); -    } -    void *finishGVStub(const GlobalValue *F) { -      assert(0 && "JIT specific function called!"); -      abort(); -      return 0; -    } -  }; -} - -/// startFunction - This callback is invoked when a new machine function is -/// about to be emitted. -void ELFCodeEmitter::startFunction(MachineFunction &F) { -  // Align the output buffer to the appropriate alignment. -  unsigned Align = 16;   // FIXME: GENERICIZE!! -  // Get the ELF Section that this function belongs in. -  ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS, -                      ELFWriter::ELFSection::SHF_EXECINSTR | -                      ELFWriter::ELFSection::SHF_ALLOC); -  OutBuffer = &ES->SectionData; -  cerr << "FIXME: This code needs to be updated for changes in the " -       << "CodeEmitter interfaces.  In particular, this should set " -       << "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!"; -  abort(); - -  // Upgrade the section alignment if required. -  if (ES->Align < Align) ES->Align = Align; - -  // Add padding zeros to the end of the buffer to make sure that the -  // function will start on the correct byte alignment within the section. -  OutputBuffer OB(*OutBuffer, -                  TM.getTargetData()->getPointerSizeInBits() == 64, -                  TM.getTargetData()->isLittleEndian()); -  OB.align(Align); -  FnStart = OutBuffer->size(); -} - -/// finishFunction - This callback is invoked after the function is completely -/// finished. -bool ELFCodeEmitter::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::LinkOnceAnyLinkage: -  case GlobalValue::LinkOnceODRLinkage: -  case GlobalValue::WeakAnyLinkage: -  case GlobalValue::WeakODRLinkage: -    FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK); -    break; -  case GlobalValue::PrivateLinkage: -    assert (0 && "PrivateLinkage should not be in the symbol table."); -  case GlobalValue::InternalLinkage: -    FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL); -    break; -  } - -  ES->Size = OutBuffer->size(); - -  FnSym.SetType(ELFWriter::ELFSym::STT_FUNC); -  FnSym.SectionIdx = ES->SectionIdx; -  FnSym.Value = FnStart;   // Value = Offset from start of Section. -  FnSym.Size = OutBuffer->size()-FnStart; - -  // Finally, add it to the symtab. -  EW.SymbolTable.push_back(FnSym); -  return false; -} - -//===----------------------------------------------------------------------===//  //                          ELFWriter Implementation  //===----------------------------------------------------------------------===// -ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)  +ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)    : MachineFunctionPass(&ID), O(o), TM(tm) {    e_flags = 0;    // e_flags defaults to 0, no flags.  | 

