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:
Bruno Cardoso Lopes 2009-08-13 05:07:35 +00:00
parent 5c2764b3e9
commit 607cd3b63a
11 changed files with 512 additions and 197 deletions

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -4,6 +4,7 @@ add_llvm_library(LLVMMC
MCAsmStreamer.cpp
MCContext.cpp
MCSection.cpp
MCSectionELF.cpp
MCSectionMachO.cpp
MCStreamer.cpp
TargetAsmParser.cpp

View File

@ -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
//===----------------------------------------------------------------------===//

View File

@ -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';
}

View File

@ -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());
}
}

View File

@ -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()) {

View File

@ -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());
}

View File

@ -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