diff options
| -rw-r--r-- | llvm/lib/CodeGen/ELF.h | 38 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFCodeEmitter.cpp | 41 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFCodeEmitter.h | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFWriter.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFWriter.h | 19 | 
5 files changed, 63 insertions, 67 deletions
diff --git a/llvm/lib/CodeGen/ELF.h b/llvm/lib/CodeGen/ELF.h index 8d92373b713..7e983a4d051 100644 --- a/llvm/lib/CodeGen/ELF.h +++ b/llvm/lib/CodeGen/ELF.h @@ -20,14 +20,12 @@  #ifndef CODEGEN_ELF_H  #define CODEGEN_ELF_H -#include "llvm/GlobalVariable.h"  #include "llvm/CodeGen/BinaryObject.h"  #include "llvm/CodeGen/MachineRelocation.h"  #include "llvm/Support/DataTypes.h" -#include <cstring>  namespace llvm { -  class BinaryObject; +  class GlobalValue;    // Identification Indexes    enum { @@ -172,41 +170,25 @@ namespace llvm {                                      IsConstant(false), NameIdx(0), Value(0),                                      Size(0), Info(0), Other(STV_DEFAULT),                                      SectionIdx(ELFSection::SHN_UNDEF), -                                    SymTabIdx(0) { -      if (!GV) -        return; - -      switch (GV->getVisibility()) { -      default: -        assert(0 && "unknown visibility type"); -      case GlobalValue::DefaultVisibility: -        Other = STV_DEFAULT; -        break; -      case GlobalValue::HiddenVisibility: -        Other = STV_HIDDEN; -        break; -      case GlobalValue::ProtectedVisibility: -        Other = STV_PROTECTED; -        break; -      } -    } - -    unsigned getBind() { -      return (Info >> 4) & 0xf; -    } +                                    SymTabIdx(0) {} -    unsigned getType() { -      return Info & 0xf; -    } +    unsigned getBind() { return (Info >> 4) & 0xf; } +    unsigned getType() { return Info & 0xf; }      void setBind(unsigned X) {        assert(X == (X & 0xF) && "Bind value out of range!");        Info = (Info & 0x0F) | (X << 4);      } +      void setType(unsigned X) {        assert(X == (X & 0xF) && "Type value out of range!");        Info = (Info & 0xF0) | X;      } + +    void setVisibility(unsigned V) { +      assert(V == (V & 0x3) && "Type value out of range!"); +      Other = V; +    }    };    /// ELFRelocation - This class contains all the information necessary to diff --git a/llvm/lib/CodeGen/ELFCodeEmitter.cpp b/llvm/lib/CodeGen/ELFCodeEmitter.cpp index 623507a9589..57b75a37f23 100644 --- a/llvm/lib/CodeGen/ELFCodeEmitter.cpp +++ b/llvm/lib/CodeGen/ELFCodeEmitter.cpp @@ -9,6 +9,8 @@  #define DEBUG_TYPE "elfce" +#include "ELF.h" +#include "ELFWriter.h"  #include "ELFCodeEmitter.h"  #include "llvm/Constants.h"  #include "llvm/DerivedTypes.h" @@ -16,8 +18,10 @@  #include "llvm/CodeGen/BinaryObject.h"  #include "llvm/CodeGen/MachineConstantPool.h"  #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineRelocation.h"  #include "llvm/Target/TargetData.h"  #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetAsmInfo.h"  #include "llvm/Support/Debug.h"  //===----------------------------------------------------------------------===// @@ -67,42 +71,27 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) {  /// finishFunction - This callback is invoked after the function is completely  /// finished.  bool ELFCodeEmitter::finishFunction(MachineFunction &MF) { -  // Add a symbol to represent the function. -  ELFSym FnSym(MF.getFunction()); -    // Update Section Size    ES->Size = CurBufferPtr - BufferBegin; -  // Set the symbol type as a function +  // Add a symbol to represent the function. +  const Function *F = MF.getFunction(); +  ELFSym FnSym(F);    FnSym.setType(ELFSym::STT_FUNC); +  FnSym.setBind(EW.getGlobalELFLinkage(F)); +  FnSym.setVisibility(EW.getGlobalELFVisibility(F));    FnSym.SectionIdx = ES->SectionIdx;    FnSym.Size = CurBufferPtr-FnStartPtr;    // Offset from start of Section    FnSym.Value = FnStartPtr-BufferBegin; -  // Figure out the binding (linkage) of the symbol. -  switch (MF.getFunction()->getLinkage()) { -  default: -    // appending linkage is illegal for functions. -    assert(0 && "Unknown linkage type!"); -  case GlobalValue::ExternalLinkage: -    FnSym.setBind(ELFSym::STB_GLOBAL); -    EW.SymbolList.push_back(FnSym); -    break; -  case GlobalValue::LinkOnceAnyLinkage: -  case GlobalValue::LinkOnceODRLinkage: -  case GlobalValue::WeakAnyLinkage: -  case GlobalValue::WeakODRLinkage: -    FnSym.setBind(ELFSym::STB_WEAK); -    EW.SymbolList.push_back(FnSym); -    break; -  case GlobalValue::PrivateLinkage: -    assert (0 && "PrivateLinkage should not be in the symbol table."); -  case GlobalValue::InternalLinkage: -    FnSym.setBind(ELFSym::STB_LOCAL); -    EW.SymbolList.push_front(FnSym); -    break; +  // Locals should go on the symbol list front +  if (!F->hasPrivateLinkage()) { +    if (FnSym.getBind() == ELFSym::STB_LOCAL) +      EW.SymbolList.push_front(FnSym); +    else +      EW.SymbolList.push_back(FnSym);    }    // Emit constant pool to appropriate section(s) diff --git a/llvm/lib/CodeGen/ELFCodeEmitter.h b/llvm/lib/CodeGen/ELFCodeEmitter.h index c309ef75971..e3d36184748 100644 --- a/llvm/lib/CodeGen/ELFCodeEmitter.h +++ b/llvm/lib/CodeGen/ELFCodeEmitter.h @@ -10,11 +10,12 @@  #ifndef ELFCODEEMITTER_H  #define ELFCODEEMITTER_H -#include "ELFWriter.h"  #include "llvm/CodeGen/MachineCodeEmitter.h"  #include <vector>  namespace llvm { +  class ELFWriter; +  class ELFSection;    /// ELFCodeEmitter - This class is used by the ELFWriter to     /// emit the code for functions to the ELF file. diff --git a/llvm/lib/CodeGen/ELFWriter.cpp b/llvm/lib/CodeGen/ELFWriter.cpp index 041defa5236..d74e826f92e 100644 --- a/llvm/lib/CodeGen/ELFWriter.cpp +++ b/llvm/lib/CodeGen/ELFWriter.cpp @@ -30,9 +30,9 @@  #define DEBUG_TYPE "elfwriter" +#include "ELF.h"  #include "ELFWriter.h"  #include "ELFCodeEmitter.h" -#include "ELF.h"  #include "llvm/Constants.h"  #include "llvm/Module.h"  #include "llvm/PassManager.h" @@ -41,14 +41,14 @@  #include "llvm/CodeGen/FileWriters.h"  #include "llvm/CodeGen/MachineCodeEmitter.h"  #include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Target/TargetAsmInfo.h"  #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetELFWriterInfo.h"  #include "llvm/Target/TargetMachine.h"  #include "llvm/Support/Mangler.h"  #include "llvm/Support/Streams.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Support/Debug.h" -#include <list>  using namespace llvm;  char ELFWriter::ID = 0; @@ -141,7 +141,22 @@ bool ELFWriter::doInitialization(Module &M) {    return false;  } -unsigned ELFWriter::getGlobalELFLinkage(const GlobalVariable *GV) { +unsigned ELFWriter::getGlobalELFVisibility(const GlobalValue *GV) { +  switch (GV->getVisibility()) { +  default: +    assert(0 && "unknown visibility type"); +  case GlobalValue::DefaultVisibility: +    return ELFSym::STV_DEFAULT; +  case GlobalValue::HiddenVisibility: +    return ELFSym::STV_HIDDEN; +  case GlobalValue::ProtectedVisibility: +    return ELFSym::STV_PROTECTED; +  } + +  return 0; +} + +unsigned ELFWriter::getGlobalELFLinkage(const GlobalValue *GV) {    if (GV->hasInternalLinkage())      return ELFSym::STB_LOCAL; @@ -213,6 +228,7 @@ void ELFWriter::EmitFunctionDeclaration(const Function *F) {    ELFSym GblSym(F);    GblSym.setBind(ELFSym::STB_GLOBAL);    GblSym.setType(ELFSym::STT_NOTYPE); +  GblSym.setVisibility(ELFSym::STV_DEFAULT);    GblSym.SectionIdx = ELFSection::SHN_UNDEF;    SymbolList.push_back(GblSym);  } @@ -222,6 +238,7 @@ void ELFWriter::EmitGlobalVar(const GlobalVariable *GV) {    unsigned Align=0, Size=0;    ELFSym GblSym(GV);    GblSym.setBind(SymBind); +  GblSym.setVisibility(getGlobalELFVisibility(GV));    if (GV->hasInitializer()) {      GblSym.setType(ELFSym::STT_OBJECT); @@ -402,6 +419,7 @@ bool ELFWriter::doFinalization(Module &M) {      SectionSym.Size = 0;      SectionSym.setBind(ELFSym::STB_LOCAL);      SectionSym.setType(ELFSym::STT_SECTION); +    SectionSym.setVisibility(ELFSym::STV_DEFAULT);      // Local symbols go in the list front      SymbolList.push_front(SectionSym); @@ -443,7 +461,8 @@ void ELFWriter::EmitRelocations() {      // Get the relocation section for section 'I'      bool HasRelA = TEW->hasRelocationAddend(); -    ELFSection &RelSec = getRelocSection(I->getName(), HasRelA); +    ELFSection &RelSec = getRelocSection(I->getName(), HasRelA, +                                         TEW->getPrefELFAlignment());      // 'Link' - Section hdr idx of the associated symbol table      // 'Info' - Section hdr idx of the section to which the relocation applies diff --git a/llvm/lib/CodeGen/ELFWriter.h b/llvm/lib/CodeGen/ELFWriter.h index e0e71d01fa5..950af90035b 100644 --- a/llvm/lib/CodeGen/ELFWriter.h +++ b/llvm/lib/CodeGen/ELFWriter.h @@ -16,21 +16,23 @@  #include "llvm/ADT/SetVector.h"  #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Support/Debug.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetELFWriterInfo.h" -#include "ELF.h"  #include <list>  #include <map>  namespace llvm {    class BinaryObject; +  class Constant;    class ConstantStruct;    class ELFCodeEmitter;    class GlobalVariable;    class Mangler;    class MachineCodeEmitter; +  class TargetAsmInfo; +  class TargetELFWriterInfo;    class raw_ostream; +  class ELFSection; +  class ELFSym; +  class ELFRelocation;    /// ELFWriter - This class implements the common target-independent code for    /// writing ELF files.  Targets should derive a class from this to @@ -155,14 +157,14 @@ namespace llvm {      /// Return the relocation section of section 'S'. 'RelA' is true      /// if the relocation section contains entries with addends. -    ELFSection &getRelocSection(std::string SName, bool RelA) { +    ELFSection &getRelocSection(std::string SName, bool RelA, unsigned Align) {        std::string RelSName(".rel");        unsigned SHdrTy = RelA ? ELFSection::SHT_RELA : ELFSection::SHT_REL;        if (RelA) RelSName.append("a");        RelSName.append(SName); -      return getSection(RelSName, SHdrTy, 0, TEW->getPrefELFAlignment()); +      return getSection(RelSName, SHdrTy, 0, Align);      }      ELFSection &getNonExecStackSection() { @@ -195,6 +197,10 @@ namespace llvm {        return getSection("", ELFSection::SHT_NULL, 0);      } +    // Helpers for obtaining ELF specific Linkage and Visibility info. +    unsigned getGlobalELFLinkage(const GlobalValue *GV); +    unsigned getGlobalELFVisibility(const GlobalValue *GV); +      // As we complete the ELF file, we need to update fields in the ELF header      // (e.g. the location of the section table).  These members keep track of      // the offset in ELFHeader of these various pieces to update and other @@ -209,7 +215,6 @@ namespace llvm {      void EmitGlobalConstant(const Constant *C, ELFSection &GblS);      void EmitGlobalConstantStruct(const ConstantStruct *CVS,                                    ELFSection &GblS); -    unsigned getGlobalELFLinkage(const GlobalVariable *GV);      ELFSection &getGlobalSymELFSection(const GlobalVariable *GV, ELFSym &Sym);      void EmitRelocations();      void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA);  | 

