forked from OSchip/llvm-project
Change MCSectionELF to represent a section semantically instead of
syntactically as a string, very similiar to what Chris did with MachO. The parsing support and validation is not introduced yet. llvm-svn: 78890
This commit is contained in:
parent
5c2764b3e9
commit
607cd3b63a
|
@ -41,33 +41,6 @@ namespace llvm {
|
|||
raw_ostream &OS) const = 0;
|
||||
};
|
||||
|
||||
|
||||
class MCSectionELF : public MCSection {
|
||||
std::string Name;
|
||||
|
||||
/// IsDirective - This is true if the section name is a directive, not
|
||||
/// something that should be printed with ".section".
|
||||
///
|
||||
/// FIXME: This is a hack. Switch to a semantic view of the section instead
|
||||
/// of a syntactic one.
|
||||
bool IsDirective;
|
||||
|
||||
MCSectionELF(const StringRef &name, bool isDirective, SectionKind K)
|
||||
: MCSection(K), Name(name), IsDirective(isDirective) {
|
||||
}
|
||||
public:
|
||||
|
||||
static MCSectionELF *Create(const StringRef &Name, bool IsDirective,
|
||||
SectionKind K, MCContext &Ctx);
|
||||
|
||||
const std::string &getName() const { return Name; }
|
||||
bool isDirective() const { return IsDirective; }
|
||||
|
||||
|
||||
virtual void PrintSwitchToSection(const TargetAsmInfo &TAI,
|
||||
raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
class MCSectionCOFF : public MCSection {
|
||||
std::string Name;
|
||||
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the MCSectionELF class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCSECTIONELF_H
|
||||
#define LLVM_MC_MCSECTIONELF_H
|
||||
|
||||
#include "llvm/MC/MCSection.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// MCSectionELF - This represents a section on linux, lots of unix variants
|
||||
/// and some bare metal systems.
|
||||
class MCSectionELF : public MCSection {
|
||||
std::string SectionName;
|
||||
|
||||
/// Type - This is the sh_type field of a section, drawn from the enums below.
|
||||
unsigned Type;
|
||||
|
||||
/// Flags - This is the sh_flags field of a section, drawn from the enums.
|
||||
/// below.
|
||||
unsigned Flags;
|
||||
|
||||
/// HasCrazyBSS - PPC/Linux doesn't support the .bss directive, it
|
||||
/// needs .section .bss. TODO: replace this with a TAI method.
|
||||
bool HasCrazyBSS;
|
||||
|
||||
/// IsExplicit - Indicates that this section comes from globals with an
|
||||
/// explicit section specfied.
|
||||
bool IsExplicit;
|
||||
|
||||
MCSectionELF(const StringRef &Section, unsigned T, unsigned F,
|
||||
SectionKind K, bool hasCrazyBSS, bool isExplicit)
|
||||
: MCSection(K), SectionName(Section.str()), Type(T), Flags(F),
|
||||
HasCrazyBSS(hasCrazyBSS), IsExplicit(isExplicit) {}
|
||||
public:
|
||||
|
||||
static MCSectionELF *Create(const StringRef &Section, unsigned Type,
|
||||
unsigned Flags, SectionKind K,
|
||||
bool hasCrazyBSS, bool isExplicit,
|
||||
MCContext &Ctx);
|
||||
|
||||
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
|
||||
/// should be printed before the section name
|
||||
bool ShouldOmitSectionDirective(const char *Name) const;
|
||||
|
||||
/// ShouldPrintSectionType - Only prints the section type if supported
|
||||
bool ShouldPrintSectionType(unsigned Ty) const;
|
||||
|
||||
/// These are the section type and flags fields. An ELF section can have
|
||||
/// only one Type, but can have more than one of the flags specified.
|
||||
///
|
||||
/// Valid section types.
|
||||
enum {
|
||||
// This value marks the section header as inactive.
|
||||
SHT_NULL = 0x00U,
|
||||
|
||||
// Holds information defined by the program, with custom format and meaning.
|
||||
SHT_PROGBITS = 0x01U,
|
||||
|
||||
// This section holds a symbol table.
|
||||
SHT_SYMTAB = 0x02U,
|
||||
|
||||
// The section holds a string table.
|
||||
SHT_STRTAB = 0x03U,
|
||||
|
||||
// The section holds relocation entries with explicit addends.
|
||||
SHT_RELA = 0x04U,
|
||||
|
||||
// The section holds a symbol hash table.
|
||||
SHT_HASH = 0x05U,
|
||||
|
||||
// Information for dynamic linking.
|
||||
SHT_DYNAMIC = 0x06U,
|
||||
|
||||
// The section holds information that marks the file in some way.
|
||||
SHT_NOTE = 0x07U,
|
||||
|
||||
// A section of this type occupies no space in the file.
|
||||
SHT_NOBITS = 0x08U,
|
||||
|
||||
// The section holds relocation entries without explicit addends.
|
||||
SHT_REL = 0x09U,
|
||||
|
||||
// This section type is reserved but has unspecified semantics.
|
||||
SHT_SHLIB = 0x0aU,
|
||||
|
||||
// This section holds a symbol table.
|
||||
SHT_DYNSYM = 0x0bU,
|
||||
|
||||
// This section contains an array of pointers to initialization functions.
|
||||
SHT_INIT_ARRAY = 0x0eU,
|
||||
|
||||
// This section contains an array of pointers to termination functions.
|
||||
SHT_FINI_ARRAY = 0x0fU,
|
||||
|
||||
// This section contains an array of pointers to functions that are invoked
|
||||
// before all other initialization functions.
|
||||
SHT_PREINIT_ARRAY = 0x10U,
|
||||
|
||||
// A section group is a set of sections that are related and that must be
|
||||
// treated specially by the linker.
|
||||
SHT_GROUP = 0x11U,
|
||||
|
||||
// This section is associated with a section of type SHT_SYMTAB, when the
|
||||
// referenced symbol table contain the escape value SHN_XINDEX
|
||||
SHT_SYMTAB_SHNDX = 0x12U,
|
||||
|
||||
LAST_KNOWN_SECTION_TYPE = SHT_SYMTAB_SHNDX
|
||||
};
|
||||
|
||||
/// Valid section flags.
|
||||
enum {
|
||||
// The section contains data that should be writable.
|
||||
SHF_WRITE = 0x1U,
|
||||
|
||||
// The section occupies memory during execution.
|
||||
SHF_ALLOC = 0x2U,
|
||||
|
||||
// The section contains executable machine instructions.
|
||||
SHF_EXECINSTR = 0x4U,
|
||||
|
||||
// The data in the section may be merged to eliminate duplication.
|
||||
SHF_MERGE = 0x10U,
|
||||
|
||||
// Elements in the section consist of null-terminated character strings.
|
||||
SHF_STRINGS = 0x20U,
|
||||
|
||||
// A field in this section holds a section header table index.
|
||||
SHF_INFO_LINK = 0x40U,
|
||||
|
||||
// Adds special ordering requirements for link editors.
|
||||
SHF_LINK_ORDER = 0x80U,
|
||||
|
||||
// This section requires special OS-specific processing to avoid incorrect
|
||||
// behavior.
|
||||
SHF_OS_NONCONFORMING = 0x100U,
|
||||
|
||||
// This section is a member of a section group.
|
||||
SHF_GROUP = 0x200U,
|
||||
|
||||
// This section holds Thread-Local Storage.
|
||||
SHF_TLS = 0x400U
|
||||
};
|
||||
|
||||
StringRef getSectionName() const {
|
||||
return StringRef(SectionName);
|
||||
}
|
||||
|
||||
unsigned getType() const { return Type; }
|
||||
unsigned getFlags() const { return Flags; }
|
||||
|
||||
virtual void PrintSwitchToSection(const TargetAsmInfo &TAI,
|
||||
raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -204,8 +204,9 @@ protected:
|
|||
const MCSection *MergeableConst16Section;
|
||||
|
||||
protected:
|
||||
const MCSection *getELFSection(const char *Name, bool isDirective,
|
||||
SectionKind Kind) const;
|
||||
const MCSection *getELFSection(StringRef Section, unsigned Type,
|
||||
unsigned Flags, SectionKind Kind,
|
||||
bool IsExplicit = false) const;
|
||||
public:
|
||||
TargetLoweringObjectFileELF(// FIXME: REMOVE AFTER UNIQUING IS FIXED.
|
||||
bool hasCrazyBSS = false)
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "llvm/CodeGen/MachineCodeEmitter.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCSection.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/Target/TargetAsmInfo.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetELFWriterInfo.h"
|
||||
|
@ -178,30 +178,32 @@ void ELFWriter::addExternalSymbol(const char *External) {
|
|||
|
||||
// getCtorSection - Get the static constructor section
|
||||
ELFSection &ELFWriter::getCtorSection() {
|
||||
const MCSection *Ctor = TLOF.getStaticCtorSection();
|
||||
return getSection(((MCSectionELF*)Ctor)->getName(), ELFSection::SHT_PROGBITS,
|
||||
const MCSectionELF *Ctor = (const MCSectionELF *)TLOF.getStaticCtorSection();
|
||||
return getSection(Ctor->getSectionName(), ELFSection::SHT_PROGBITS,
|
||||
getElfSectionFlags(Ctor->getKind()));
|
||||
}
|
||||
|
||||
// getDtorSection - Get the static destructor section
|
||||
ELFSection &ELFWriter::getDtorSection() {
|
||||
const MCSection *Dtor = TLOF.getStaticDtorSection();
|
||||
return getSection(((MCSectionELF*)Dtor)->getName(), ELFSection::SHT_PROGBITS,
|
||||
const MCSectionELF *Dtor = (const MCSectionELF *)TLOF.getStaticDtorSection();
|
||||
return getSection(Dtor->getSectionName(), ELFSection::SHT_PROGBITS,
|
||||
getElfSectionFlags(Dtor->getKind()));
|
||||
}
|
||||
|
||||
// getTextSection - Get the text section for the specified function
|
||||
ELFSection &ELFWriter::getTextSection(Function *F) {
|
||||
const MCSection *Text = TLOF.SectionForGlobal(F, Mang, TM);
|
||||
return getSection(((MCSectionELF*)Text)->getName(), ELFSection::SHT_PROGBITS,
|
||||
const MCSectionELF *Text =
|
||||
(const MCSectionELF *)TLOF.SectionForGlobal(F, Mang, TM);
|
||||
return getSection(Text->getSectionName(), ELFSection::SHT_PROGBITS,
|
||||
getElfSectionFlags(Text->getKind()));
|
||||
}
|
||||
|
||||
// getJumpTableSection - Get a read only section for constants when
|
||||
// emitting jump tables. TODO: add PIC support
|
||||
ELFSection &ELFWriter::getJumpTableSection() {
|
||||
const MCSection *JT = TLOF.getSectionForConstant(SectionKind::getReadOnly());
|
||||
return getSection(((MCSectionELF*)JT)->getName(),
|
||||
const MCSectionELF *JT =
|
||||
(const MCSectionELF *)TLOF.getSectionForConstant(SectionKind::getReadOnly());
|
||||
return getSection(JT->getSectionName(),
|
||||
ELFSection::SHT_PROGBITS,
|
||||
getElfSectionFlags(JT->getKind()),
|
||||
TM.getTargetData()->getPointerABIAlignment());
|
||||
|
@ -226,8 +228,9 @@ ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) {
|
|||
}
|
||||
}
|
||||
|
||||
const MCSection *CPSect = TLOF.getSectionForConstant(Kind);
|
||||
return getSection(((MCSectionELF*)CPSect)->getName(),
|
||||
const MCSectionELF *CPSect =
|
||||
(const MCSectionELF *)TLOF.getSectionForConstant(Kind);
|
||||
return getSection(CPSect->getSectionName(),
|
||||
ELFSection::SHT_PROGBITS,
|
||||
getElfSectionFlags(Kind),
|
||||
CPE.getAlignment());
|
||||
|
@ -358,8 +361,9 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||
return;
|
||||
|
||||
// Get the ELF section where this global belongs from TLOF
|
||||
const MCSection *S = TLOF.SectionForGlobal(GV, Mang, TM);
|
||||
SectionKind Kind = ((MCSectionELF*)S)->getKind();
|
||||
const MCSectionELF *S =
|
||||
(const MCSectionELF *)TLOF.SectionForGlobal(GV, Mang, TM);
|
||||
SectionKind Kind = S->getKind();
|
||||
unsigned SectionFlags = getElfSectionFlags(Kind);
|
||||
|
||||
// The symbol align should update the section alignment if needed
|
||||
|
@ -370,7 +374,7 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||
|
||||
if (isELFCommonSym(GVar)) {
|
||||
GblSym->SectionIdx = ELFSection::SHN_COMMON;
|
||||
getSection(((MCSectionELF*)S)->getName(),
|
||||
getSection(S->getSectionName(),
|
||||
ELFSection::SHT_NOBITS, SectionFlags, 1);
|
||||
|
||||
// A new linkonce section is created for each global in the
|
||||
|
@ -380,7 +384,7 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||
|
||||
} else if (isELFBssSym(GVar, Kind)) {
|
||||
ELFSection &ES =
|
||||
getSection(((MCSectionELF*)S)->getName(), ELFSection::SHT_NOBITS,
|
||||
getSection(S->getSectionName(), ELFSection::SHT_NOBITS,
|
||||
SectionFlags);
|
||||
GblSym->SectionIdx = ES.SectionIdx;
|
||||
|
||||
|
@ -396,7 +400,7 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||
|
||||
} else { // The symbol must go to some kind of data section
|
||||
ELFSection &ES =
|
||||
getSection(((MCSectionELF*)S)->getName(), ELFSection::SHT_PROGBITS,
|
||||
getSection(S->getSectionName(), ELFSection::SHT_PROGBITS,
|
||||
SectionFlags);
|
||||
GblSym->SectionIdx = ES.SectionIdx;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ add_llvm_library(LLVMMC
|
|||
MCAsmStreamer.cpp
|
||||
MCContext.cpp
|
||||
MCSection.cpp
|
||||
MCSectionELF.cpp
|
||||
MCSectionMachO.cpp
|
||||
MCStreamer.cpp
|
||||
TargetAsmParser.cpp
|
||||
|
|
|
@ -20,91 +20,6 @@ using namespace llvm;
|
|||
MCSection::~MCSection() {
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MCSectionELF
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MCSectionELF *MCSectionELF::
|
||||
Create(const StringRef &Name, bool IsDirective, SectionKind K, MCContext &Ctx) {
|
||||
return new (Ctx) MCSectionELF(Name, IsDirective, K);
|
||||
}
|
||||
|
||||
void MCSectionELF::PrintSwitchToSection(const TargetAsmInfo &TAI,
|
||||
raw_ostream &OS) const {
|
||||
if (isDirective()) {
|
||||
OS << getName() << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
OS << "\t.section\t" << getName();
|
||||
|
||||
// Handle the weird solaris syntax if desired.
|
||||
if (TAI.usesSunStyleELFSectionSwitchSyntax() &&
|
||||
!getKind().isMergeableConst() && !getKind().isMergeableCString()) {
|
||||
if (!getKind().isMetadata())
|
||||
OS << ",#alloc";
|
||||
if (getKind().isText())
|
||||
OS << ",#execinstr";
|
||||
if (getKind().isWriteable())
|
||||
OS << ",#write";
|
||||
if (getKind().isThreadLocal())
|
||||
OS << ",#tls";
|
||||
} else {
|
||||
OS << ",\"";
|
||||
|
||||
if (!getKind().isMetadata())
|
||||
OS << 'a';
|
||||
if (getKind().isText())
|
||||
OS << 'x';
|
||||
if (getKind().isWriteable())
|
||||
OS << 'w';
|
||||
if (getKind().isMergeable1ByteCString() ||
|
||||
getKind().isMergeable2ByteCString() ||
|
||||
getKind().isMergeable4ByteCString() ||
|
||||
getKind().isMergeableConst4() ||
|
||||
getKind().isMergeableConst8() ||
|
||||
getKind().isMergeableConst16())
|
||||
OS << 'M';
|
||||
if (getKind().isMergeable1ByteCString() ||
|
||||
getKind().isMergeable2ByteCString() ||
|
||||
getKind().isMergeable4ByteCString())
|
||||
OS << 'S';
|
||||
if (getKind().isThreadLocal())
|
||||
OS << 'T';
|
||||
|
||||
OS << "\",";
|
||||
|
||||
// If comment string is '@', e.g. as on ARM - use '%' instead
|
||||
if (TAI.getCommentString()[0] == '@')
|
||||
OS << '%';
|
||||
else
|
||||
OS << '@';
|
||||
|
||||
if (getKind().isBSS() || getKind().isThreadBSS())
|
||||
OS << "nobits";
|
||||
else
|
||||
OS << "progbits";
|
||||
|
||||
if (getKind().isMergeable1ByteCString()) {
|
||||
OS << ",1";
|
||||
} else if (getKind().isMergeable2ByteCString()) {
|
||||
OS << ",2";
|
||||
} else if (getKind().isMergeable4ByteCString()) {
|
||||
OS << ",4";
|
||||
} else if (getKind().isMergeableConst4()) {
|
||||
OS << ",4";
|
||||
} else if (getKind().isMergeableConst8()) {
|
||||
OS << ",8";
|
||||
} else if (getKind().isMergeableConst16()) {
|
||||
OS << ",16";
|
||||
}
|
||||
}
|
||||
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MCSectionCOFF
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
//===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetAsmInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
MCSectionELF *MCSectionELF::
|
||||
Create(const StringRef &Section, unsigned Type, unsigned Flags,
|
||||
SectionKind K, bool hasCrazyBSS, bool isExplicit, MCContext &Ctx) {
|
||||
return new
|
||||
(Ctx) MCSectionELF(Section, Type, Flags, K, hasCrazyBSS, isExplicit);
|
||||
}
|
||||
|
||||
// ShouldOmitSectionDirective - Decides whether a '.section' directive
|
||||
// should be printed before the section name
|
||||
bool MCSectionELF::ShouldOmitSectionDirective(const char *Name) const {
|
||||
|
||||
// PPC/Linux doesn't support the .bss directive, it needs .section .bss.
|
||||
// FIXME: Does .section .bss/.data/.text work everywhere??
|
||||
if ((!HasCrazyBSS && strncmp(Name, ".bss", 4) == 0) ||
|
||||
strncmp(Name, ".text", 5) == 0 ||
|
||||
strncmp(Name, ".data", 5) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ShouldPrintSectionType - Only prints the section type if supported
|
||||
bool MCSectionELF::ShouldPrintSectionType(unsigned Ty) const {
|
||||
|
||||
if (IsExplicit && !(Ty == SHT_NOBITS || Ty == SHT_PROGBITS))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MCSectionELF::PrintSwitchToSection(const TargetAsmInfo &TAI,
|
||||
raw_ostream &OS) const {
|
||||
|
||||
if (ShouldOmitSectionDirective(SectionName.c_str())) {
|
||||
OS << '\t' << getSectionName() << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
OS << "\t.section\t" << getSectionName();
|
||||
|
||||
// Handle the weird solaris syntax if desired.
|
||||
if (TAI.usesSunStyleELFSectionSwitchSyntax() &&
|
||||
!(Flags & MCSectionELF::SHF_MERGE)) {
|
||||
if (Flags & MCSectionELF::SHF_ALLOC)
|
||||
OS << ",#alloc";
|
||||
if (Flags & MCSectionELF::SHF_EXECINSTR)
|
||||
OS << ",#execinstr";
|
||||
if (Flags & MCSectionELF::SHF_WRITE)
|
||||
OS << ",#write";
|
||||
if (Flags & MCSectionELF::SHF_TLS)
|
||||
OS << ",#tls";
|
||||
} else {
|
||||
OS << ",\"";
|
||||
|
||||
if (Flags & MCSectionELF::SHF_ALLOC)
|
||||
OS << 'a';
|
||||
if (Flags & MCSectionELF::SHF_EXECINSTR)
|
||||
OS << 'x';
|
||||
if (Flags & MCSectionELF::SHF_WRITE)
|
||||
OS << 'w';
|
||||
if (Flags & MCSectionELF::SHF_MERGE)
|
||||
OS << 'M';
|
||||
if (Flags & MCSectionELF::SHF_STRINGS)
|
||||
OS << 'S';
|
||||
if (Flags & MCSectionELF::SHF_TLS)
|
||||
OS << 'T';
|
||||
|
||||
OS << '"';
|
||||
|
||||
if (ShouldPrintSectionType(Type)) {
|
||||
OS << ',';
|
||||
|
||||
// If comment string is '@', e.g. as on ARM - use '%' instead
|
||||
if (TAI.getCommentString()[0] == '@')
|
||||
OS << '%';
|
||||
else
|
||||
OS << '@';
|
||||
|
||||
if (Type == MCSectionELF::SHT_INIT_ARRAY)
|
||||
OS << "init_array";
|
||||
else if (Type == MCSectionELF::SHT_FINI_ARRAY)
|
||||
OS << "fini_array";
|
||||
else if (Type == MCSectionELF::SHT_PREINIT_ARRAY)
|
||||
OS << "preinit_array";
|
||||
else if (Type == MCSectionELF::SHT_NOBITS)
|
||||
OS << "nobits";
|
||||
else if (Type == MCSectionELF::SHT_PROGBITS)
|
||||
OS << "progbits";
|
||||
|
||||
if (getKind().isMergeable1ByteCString()) {
|
||||
OS << ",1";
|
||||
} else if (getKind().isMergeable2ByteCString()) {
|
||||
OS << ",2";
|
||||
} else if (getKind().isMergeable4ByteCString() ||
|
||||
getKind().isMergeableConst4()) {
|
||||
OS << ",4";
|
||||
} else if (getKind().isMergeableConst8()) {
|
||||
OS << ",8";
|
||||
} else if (getKind().isMergeableConst16()) {
|
||||
OS << ",16";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OS << '\n';
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#define LLVM_TARGET_ARM_TARGETOBJECTFILE_H
|
||||
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -21,14 +22,14 @@ namespace llvm {
|
|||
void Initialize(MCContext &Ctx, const TargetMachine &TM) {
|
||||
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
|
||||
|
||||
// FIXME: Add new attribute/flag to MCSection for init_array/fini_array.
|
||||
// That will allow not treating these as "directives".
|
||||
if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
|
||||
StaticCtorSection =
|
||||
getELFSection("\t.section .init_array,\"aw\",%init_array", true,
|
||||
getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
|
||||
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getDataRel());
|
||||
StaticDtorSection =
|
||||
getELFSection("\t.section .fini_array,\"aw\",%fini_array", true,
|
||||
getELFSection(".fini_array", MCSectionELF::SHT_FINI_ARRAY,
|
||||
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getDataRel());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCSectionMachO.h"
|
||||
#include "llvm/Target/TargetAsmInfo.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
|
@ -288,64 +288,98 @@ TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() {
|
|||
}
|
||||
|
||||
const MCSection *TargetLoweringObjectFileELF::
|
||||
getELFSection(const char *Name, bool isDirective, SectionKind Kind) const {
|
||||
// Create the map if it doesn't already exist.
|
||||
getELFSection(StringRef Section, unsigned Type, unsigned Flags,
|
||||
SectionKind Kind, bool IsExplicit) const {
|
||||
if (UniquingMap == 0)
|
||||
UniquingMap = new ELFUniqueMapTy();
|
||||
ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap;
|
||||
|
||||
// Do the lookup, if we have a hit, return it.
|
||||
const MCSectionELF *&Entry = Map[Name];
|
||||
const MCSectionELF *&Entry = Map[Section];
|
||||
if (Entry) return Entry;
|
||||
|
||||
return Entry = MCSectionELF::Create(Name, isDirective, Kind, getContext());
|
||||
return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, HasCrazyBSS,
|
||||
IsExplicit, getContext());
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
|
||||
const TargetMachine &TM) {
|
||||
TargetLoweringObjectFile::Initialize(Ctx, TM);
|
||||
if (!HasCrazyBSS)
|
||||
BSSSection = getELFSection("\t.bss", true, SectionKind::getBSS());
|
||||
else
|
||||
// PPC/Linux doesn't support the .bss directive, it needs .section .bss.
|
||||
// FIXME: Does .section .bss work everywhere??
|
||||
// FIXME2: this should just be handle by the section printer. We should get
|
||||
// away from syntactic view of the sections and MCSection should just be a
|
||||
// semantic view.
|
||||
BSSSection = getELFSection("\t.bss", false, SectionKind::getBSS());
|
||||
|
||||
BSSSection =
|
||||
getELFSection(".bss", MCSectionELF::SHT_NOBITS,
|
||||
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getBSS());
|
||||
|
||||
TextSection = getELFSection("\t.text", true, SectionKind::getText());
|
||||
DataSection = getELFSection("\t.data", true, SectionKind::getDataRel());
|
||||
ReadOnlySection =
|
||||
getELFSection("\t.rodata", false, SectionKind::getReadOnly());
|
||||
TLSDataSection =
|
||||
getELFSection("\t.tdata", false, SectionKind::getThreadData());
|
||||
TextSection =
|
||||
getELFSection(".text", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getText());
|
||||
|
||||
DataSection =
|
||||
getELFSection(".data", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getDataRel());
|
||||
|
||||
ReadOnlySection =
|
||||
getELFSection(".rodata", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getReadOnly());
|
||||
|
||||
TLSDataSection =
|
||||
getELFSection(".tdata", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
|
||||
MCSectionELF::SHF_WRITE, SectionKind::getThreadData());
|
||||
|
||||
TLSBSSSection = getELFSection("\t.tbss", false,
|
||||
SectionKind::getThreadBSS());
|
||||
TLSBSSSection =
|
||||
getELFSection(".tbss", MCSectionELF::SHT_NOBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
|
||||
MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS());
|
||||
|
||||
DataRelSection = getELFSection("\t.data.rel", false,
|
||||
SectionKind::getDataRel());
|
||||
DataRelLocalSection = getELFSection("\t.data.rel.local", false,
|
||||
SectionKind::getDataRelLocal());
|
||||
DataRelROSection = getELFSection("\t.data.rel.ro", false,
|
||||
SectionKind::getReadOnlyWithRel());
|
||||
DataRelROLocalSection =
|
||||
getELFSection("\t.data.rel.ro.local", false,
|
||||
SectionKind::getReadOnlyWithRelLocal());
|
||||
DataRelSection =
|
||||
getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getDataRel());
|
||||
|
||||
DataRelLocalSection =
|
||||
getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getDataRelLocal());
|
||||
|
||||
DataRelROSection =
|
||||
getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getReadOnlyWithRel());
|
||||
|
||||
DataRelROLocalSection =
|
||||
getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getReadOnlyWithRelLocal());
|
||||
|
||||
MergeableConst4Section = getELFSection(".rodata.cst4", false,
|
||||
SectionKind::getMergeableConst4());
|
||||
MergeableConst8Section = getELFSection(".rodata.cst8", false,
|
||||
SectionKind::getMergeableConst8());
|
||||
MergeableConst16Section = getELFSection(".rodata.cst16", false,
|
||||
SectionKind::getMergeableConst16());
|
||||
MergeableConst4Section =
|
||||
getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
|
||||
SectionKind::getMergeableConst4());
|
||||
|
||||
MergeableConst8Section =
|
||||
getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
|
||||
SectionKind::getMergeableConst8());
|
||||
|
||||
MergeableConst16Section =
|
||||
getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
|
||||
SectionKind::getMergeableConst16());
|
||||
|
||||
StaticCtorSection =
|
||||
getELFSection(".ctors", false, SectionKind::getDataRel());
|
||||
getELFSection(".ctors", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getDataRel());
|
||||
|
||||
StaticDtorSection =
|
||||
getELFSection(".dtors", false, SectionKind::getDataRel());
|
||||
getELFSection(".dtors", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getDataRel());
|
||||
|
||||
// Exception Handling Sections.
|
||||
|
||||
|
@ -354,33 +388,46 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
|
|||
// runtime hit for C++ apps. Either the contents of the LSDA need to be
|
||||
// adjusted or this should be a data section.
|
||||
LSDASection =
|
||||
getELFSection(".gcc_except_table", false, SectionKind::getReadOnly());
|
||||
getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
|
||||
EHFrameSection =
|
||||
getELFSection(".eh_frame", false, SectionKind::getDataRel());
|
||||
getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC, SectionKind::getDataRel());
|
||||
|
||||
// Debug Info Sections.
|
||||
DwarfAbbrevSection =
|
||||
getELFSection(".debug_abbrev", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfInfoSection =
|
||||
getELFSection(".debug_info", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfLineSection =
|
||||
getELFSection(".debug_line", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfFrameSection =
|
||||
getELFSection(".debug_frame", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfPubNamesSection =
|
||||
getELFSection(".debug_pubnames", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfPubTypesSection =
|
||||
getELFSection(".debug_pubtypes", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfStrSection =
|
||||
getELFSection(".debug_str", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfLocSection =
|
||||
getELFSection(".debug_loc", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfARangesSection =
|
||||
getELFSection(".debug_aranges", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfRangesSection =
|
||||
getELFSection(".debug_ranges", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
DwarfMacroInfoSection =
|
||||
getELFSection(".debug_macinfo", false, SectionKind::getMetadata());
|
||||
getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0,
|
||||
SectionKind::getMetadata());
|
||||
}
|
||||
|
||||
|
||||
|
@ -410,13 +457,62 @@ getELFKindForNamedSection(const char *Name, SectionKind K) {
|
|||
return K;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
getELFSectionType(const char *Name, SectionKind K) {
|
||||
|
||||
if (strncmp(Name, ".init_array", 11) == 0)
|
||||
return MCSectionELF::SHT_INIT_ARRAY;
|
||||
|
||||
if (strncmp(Name, ".fini_array", 11) == 0)
|
||||
return MCSectionELF::SHT_FINI_ARRAY;
|
||||
|
||||
if (strncmp(Name, ".preinit_array", 14) == 0)
|
||||
return MCSectionELF::SHT_PREINIT_ARRAY;
|
||||
|
||||
if (K.isBSS() || K.isThreadBSS())
|
||||
return MCSectionELF::SHT_NOBITS;
|
||||
|
||||
return MCSectionELF::SHT_PROGBITS;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
getELFSectionFlags(SectionKind K) {
|
||||
unsigned Flags = 0;
|
||||
|
||||
if (!K.isMetadata())
|
||||
Flags |= MCSectionELF::SHF_ALLOC;
|
||||
|
||||
if (K.isWriteable())
|
||||
Flags |= MCSectionELF::SHF_WRITE;
|
||||
|
||||
if (K.isThreadLocal())
|
||||
Flags |= MCSectionELF::SHF_TLS;
|
||||
|
||||
// K.isMergeableConst() is left out to honour PR4650
|
||||
if (K.isMergeableCString() || K.isMergeableConst4() ||
|
||||
K.isMergeableConst8() || K.isMergeableConst16())
|
||||
Flags |= MCSectionELF::SHF_MERGE;
|
||||
|
||||
if (K.isMergeableCString())
|
||||
Flags |= MCSectionELF::SHF_STRINGS;
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
|
||||
const MCSection *TargetLoweringObjectFileELF::
|
||||
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||
Mangler *Mang, const TargetMachine &TM) const {
|
||||
const char *SectionName = GV->getSection().c_str();
|
||||
|
||||
// Infer section flags from the section name if we can.
|
||||
Kind = getELFKindForNamedSection(GV->getSection().c_str(), Kind);
|
||||
Kind = getELFKindForNamedSection(SectionName, Kind);
|
||||
|
||||
return getELFSection(GV->getSection().c_str(), false, Kind);
|
||||
return getELFSection(SectionName,
|
||||
getELFSectionType(SectionName, Kind),
|
||||
getELFSectionFlags(Kind), Kind, true);
|
||||
}
|
||||
|
||||
static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
|
||||
|
@ -445,7 +541,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
|||
if (GV->isWeakForLinker()) {
|
||||
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
|
||||
std::string Name = Mang->makeNameProper(GV->getNameStr());
|
||||
return getELFSection((Prefix+Name).c_str(), false, Kind);
|
||||
|
||||
return getELFSection((Prefix+Name).c_str(),
|
||||
getELFSectionType((Prefix+Name).c_str(), Kind),
|
||||
getELFSectionFlags(Kind),
|
||||
Kind);
|
||||
}
|
||||
|
||||
if (Kind.isText()) return TextSection;
|
||||
|
@ -470,7 +570,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
|||
|
||||
|
||||
std::string Name = SizeSpec + utostr(Align);
|
||||
return getELFSection(Name.c_str(), false, Kind);
|
||||
return getELFSection(Name.c_str(), MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC |
|
||||
MCSectionELF::SHF_MERGE |
|
||||
MCSectionELF::SHF_STRINGS,
|
||||
Kind);
|
||||
}
|
||||
|
||||
if (Kind.isMergeableConst()) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "XCoreTargetObjectFile.h"
|
||||
#include "XCoreSubtarget.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -16,9 +17,12 @@ using namespace llvm;
|
|||
void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
||||
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
|
||||
|
||||
TextSection = getELFSection("\t.text", true, SectionKind::getText());
|
||||
DataSection = getELFSection("\t.dp.data", false, SectionKind::getDataRel());
|
||||
BSSSection = getELFSection("\t.dp.bss", false, SectionKind::getBSS());
|
||||
DataSection = getELFSection(".dp.data", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getDataRel());
|
||||
BSSSection = getELFSection(".dp.bss", MCSectionELF::SHT_NOBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getBSS());
|
||||
|
||||
// TLS globals are lowered in the backend to arrays indexed by the current
|
||||
// thread id. After lowering they require no special handling by the linker
|
||||
|
@ -28,9 +32,12 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
|||
|
||||
if (TM.getSubtarget<XCoreSubtarget>().isXS1A())
|
||||
// FIXME: Why is this writable ("datarel")???
|
||||
ReadOnlySection = getELFSection("\t.dp.rodata", false,
|
||||
SectionKind::getDataRel());
|
||||
ReadOnlySection =
|
||||
getELFSection(".dp.rodata", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
|
||||
SectionKind::getDataRel());
|
||||
else
|
||||
ReadOnlySection = getELFSection("\t.cp.rodata", false,
|
||||
SectionKind::getReadOnly());
|
||||
ReadOnlySection =
|
||||
getELFSection(".cp.rodata", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
; RUN: llvm-as < %s | llc -mtriple=i386-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX
|
||||
|
||||
declare i32 @foo()
|
||||
@G0 = global i32 ()* @foo, section ".init_array"
|
||||
|
||||
; LINUX: .section .init_array,"aw"
|
||||
; LINUX: .globl G0
|
||||
|
||||
@G1 = global i32 ()* @foo, section ".fini_array"
|
||||
|
||||
; LINUX: .section .fini_array,"aw"
|
||||
; LINUX: .globl G1
|
||||
|
||||
@G2 = global i32 ()* @foo, section ".preinit_array"
|
||||
|
||||
; LINUX: .section .preinit_array,"aw"
|
||||
; LINUX: .globl G2
|
||||
|
Loading…
Reference in New Issue