switch MCSectionCOFF from a syntactic to semantic representation,

patch by Peter Housel!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103267 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-05-07 17:17:41 +00:00
parent 5fa680d397
commit eb40a0fd98
9 changed files with 277 additions and 120 deletions

View File

@ -161,13 +161,15 @@ public:
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
mutable void *UniquingMap;
const MCSection *DrectveSection;
public:
TargetLoweringObjectFileCOFF() : UniquingMap(0) {}
~TargetLoweringObjectFileCOFF();
TargetLoweringObjectFileCOFF() {}
~TargetLoweringObjectFileCOFF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getDrectveSection() const { return DrectveSection; }
virtual const MCSection *
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
@ -175,11 +177,6 @@ public:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
/// getCOFFSection - Return the MCSection for the specified COFF section.
/// FIXME: Switch this to a semantic view eventually.
const MCSection *getCOFFSection(StringRef Name, bool isDirective,
SectionKind K) const;
};
} // end namespace llvm

View File

@ -50,7 +50,7 @@ namespace llvm {
/// objects.
BumpPtrAllocator Allocator;
void *MachOUniquingMap, *ELFUniquingMap;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
public:
explicit MCContext(const MCAsmInfo &MAI);
~MCContext();
@ -97,6 +97,9 @@ namespace llvm {
const MCSection *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind,
bool IsExplicit = false);
const MCSection *getCOFFSection(StringRef Section, unsigned Flags,
SectionKind Kind);
/// @}

View File

@ -48,32 +48,6 @@ namespace llvm {
return false;
}
};
class MCSectionCOFF : public MCSection {
// The memory for this string is stored in the same MCContext as *this.
StringRef 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;
MCSectionCOFF(StringRef name, bool isDirective, SectionKind K)
: MCSection(K), Name(name), IsDirective(isDirective) {
}
public:
static MCSectionCOFF *Create(StringRef Name, bool IsDirective,
SectionKind K, MCContext &Ctx);
StringRef getName() const { return Name; }
bool isDirective() const { return IsDirective; }
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
};
} // end namespace llvm

View File

@ -0,0 +1,83 @@
//===- MCSectionCOFF.h - COFF 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 MCSectionCOFF class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTIONCOFF_H
#define LLVM_MC_MCSECTIONCOFF_H
#include "llvm/MC/MCSection.h"
namespace llvm {
/// MCSectionCOFF - This represents a section on Windows
class MCSectionCOFF : public MCSection {
// The memory for this string is stored in the same MCContext as *this.
StringRef SectionName;
/// Flags - This is the Characteristics field of a section, drawn
/// from the enums below.
unsigned Flags;
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned flags, SectionKind K)
: MCSection(K), SectionName(Section), Flags(flags) {
}
~MCSectionCOFF();
public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
/// should be printed before the section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
/// Valid section flags.
enum {
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
IMAGE_SCN_CNT_CODE = 0x00000020,
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
IMAGE_SCN_LNK_OTHER = 0x00000100,
IMAGE_SCN_LNK_INFO = 0x00000200,
IMAGE_SCN_LNK_REMOVE = 0x00000800,
IMAGE_SCN_LNK_COMDAT = 0x00001000,
IMAGE_SCN_MEM_FARDATA = 0x00008000,
IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
IMAGE_SCN_MEM_16BIT = 0x00020000,
IMAGE_SCN_MEM_LOCKED = 0x00040000,
IMAGE_SCN_MEM_PRELOAD = 0x00080000,
IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
IMAGE_SCN_MEM_SHARED = 0x10000000,
IMAGE_SCN_MEM_EXECUTE = 0x20000000,
IMAGE_SCN_MEM_READ = 0x40000000,
IMAGE_SCN_MEM_WRITE = 0x80000000
};
StringRef getSectionName() const { return SectionName; }
unsigned getFlags() const { return Flags; }
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
};
} // end namespace llvm
#endif

View File

@ -22,6 +22,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
@ -794,89 +795,147 @@ unsigned TargetLoweringObjectFileMachO::getTTypeEncoding() const {
// COFF
//===----------------------------------------------------------------------===//
typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
delete (COFFUniqueMapTy*)UniquingMap;
}
const MCSection *TargetLoweringObjectFileCOFF::
getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
// Create the map if it doesn't already exist.
if (UniquingMap == 0)
UniquingMap = new COFFUniqueMapTy();
COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
// Do the lookup, if we have a hit, return it.
const MCSectionCOFF *&Entry = Map[Name];
if (Entry) return Entry;
return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
}
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
if (UniquingMap != 0)
((COFFUniqueMapTy*)UniquingMap)->clear();
TargetLoweringObjectFile::Initialize(Ctx, TM);
TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
TextSection =
getContext().getCOFFSection(".text",
MCSectionCOFF::IMAGE_SCN_CNT_CODE |
MCSectionCOFF::IMAGE_SCN_MEM_EXECUTE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getText());
DataSection =
getContext().getCOFFSection(".data",
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ |
MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getDataRel());
ReadOnlySection =
getContext().getCOFFSection(".rdata",
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
StaticCtorSection =
getCOFFSection(".ctors", false, SectionKind::getDataRel());
getContext().getCOFFSection(".ctors",
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ |
MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getDataRel());
StaticDtorSection =
getCOFFSection(".dtors", false, SectionKind::getDataRel());
getContext().getCOFFSection(".dtors",
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ |
MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getDataRel());
// FIXME: We're emitting LSDA info into a readonly section on COFF, even
// though it contains relocatable pointers. In PIC mode, this is probably a
// big runtime hit for C++ apps. Either the contents of the LSDA need to be
// adjusted or this should be a data section.
LSDASection =
getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
getContext().getCOFFSection(".gcc_except_table",
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
EHFrameSection =
getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
getContext().getCOFFSection(".eh_frame",
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ |
MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getDataRel());
// Debug info.
// FIXME: Don't use 'directive' mode here.
DwarfAbbrevSection =
getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_abbrev",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfInfoSection =
getCOFFSection("\t.section\t.debug_info,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_info",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfLineSection =
getCOFFSection("\t.section\t.debug_line,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_line",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfFrameSection =
getCOFFSection("\t.section\t.debug_frame,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_frame",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfPubNamesSection =
getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_pubnames",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfPubTypesSection =
getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_pubtypes",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfStrSection =
getCOFFSection("\t.section\t.debug_str,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_str",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfLocSection =
getCOFFSection("\t.section\t.debug_loc,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_loc",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfARangesSection =
getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_aranges",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfRangesSection =
getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_ranges",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DwarfMacroInfoSection =
getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
true, SectionKind::getMetadata());
getContext().getCOFFSection(".debug_macinfo",
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
MCSectionCOFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
DrectveSection =
getContext().getCOFFSection(".drectve",
MCSectionCOFF::IMAGE_SCN_LNK_INFO,
SectionKind::getMetadata());
}
static unsigned
getCOFFSectionFlags(SectionKind K) {
unsigned Flags = 0;
if (!K.isMetadata())
Flags |= MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE;
else if (K.isText())
Flags |=
MCSectionCOFF::IMAGE_SCN_MEM_EXECUTE |
MCSectionCOFF::IMAGE_SCN_CNT_CODE;
else if (K.isReadOnly())
Flags |=
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ;
else if (K.isWriteable())
Flags |=
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ |
MCSectionCOFF::IMAGE_SCN_MEM_WRITE;
return Flags;
}
const MCSection *TargetLoweringObjectFileCOFF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
return getCOFFSection(GV->getSection(), false, Kind);
return getContext().getCOFFSection(GV->getSection(),
getCOFFSectionFlags(Kind),
Kind);
}
static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
@ -900,7 +959,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
MCSymbol *Sym = Mang->getSymbol(GV);
Name.append(Sym->getName().begin(), Sym->getName().end());
return getCOFFSection(Name.str(), false, Kind);
return getContext().getCOFFSection(Name.str(),
getCOFFSectionFlags(Kind),
Kind);
}
if (Kind.isText())

View File

@ -11,6 +11,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
@ -18,11 +19,13 @@ using namespace llvm;
typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) {
MachOUniquingMap = 0;
ELFUniquingMap = 0;
COFFUniquingMap = 0;
}
MCContext::~MCContext() {
@ -32,6 +35,7 @@ MCContext::~MCContext() {
// If we have the MachO uniquing map, free it.
delete (MachOUniqueMapTy*)MachOUniquingMap;
delete (ELFUniqueMapTy*)ELFUniquingMap;
delete (COFFUniqueMapTy*)COFFUniquingMap;
}
//===----------------------------------------------------------------------===//
@ -122,4 +126,19 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags,
return Result;
}
const MCSection *MCContext::
getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) {
if (COFFUniquingMap == 0)
COFFUniquingMap = new COFFUniqueMapTy();
COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
// Do the lookup, if we have a hit, return it.
StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
if (Entry.getValue()) return Entry.getValue();
MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), Flags,
Kind);
Entry.setValue(Result);
return Result;
}

View File

@ -20,30 +20,3 @@ using namespace llvm;
MCSection::~MCSection() {
}
//===----------------------------------------------------------------------===//
// MCSectionCOFF
//===----------------------------------------------------------------------===//
MCSectionCOFF *MCSectionCOFF::
Create(StringRef Name, bool IsDirective, SectionKind K, MCContext &Ctx) {
char *NameCopy = static_cast<char*>(
Ctx.Allocate(Name.size(), /*Alignment=*/1));
memcpy(NameCopy, Name.data(), Name.size());
return new (Ctx) MCSectionCOFF(StringRef(NameCopy, Name.size()),
IsDirective, K);
}
void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
if (isDirective()) {
OS << getName() << '\n';
return;
}
OS << "\t.section\t" << getName() << ",\"";
if (getKind().isText())
OS << 'x';
if (getKind().isWriteable())
OS << 'w';
OS << "\"\n";
}

49
lib/MC/MCSectionCOFF.cpp Normal file
View File

@ -0,0 +1,49 @@
//===- lib/MC/MCSectionCOFF.cpp - COFF 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/MCSectionCOFF.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
MCSectionCOFF::~MCSectionCOFF() {} // anchor.
// ShouldOmitSectionDirective - Decides whether a '.section' directive
// should be printed before the section name
bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
// FIXME: Does .section .bss/.data/.text work everywhere??
if (Name == ".text" || Name == ".data" || Name == ".bss")
return true;
return false;
}
void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName() << '\n';
return;
}
OS << "\t.section\t" << getSectionName() << ",\"";
if (getKind().isText())
OS << 'x';
if (getKind().isWriteable())
OS << 'w';
else
OS << 'r';
if (getFlags() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE)
OS << 'n';
OS << "\"\n";
}

View File

@ -598,9 +598,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// Output linker support code for dllexported globals on windows.
if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
OutStreamer.SwitchSection(TLOFCOFF.getCOFFSection(".section .drectve",
true,
SectionKind::getMetadata()));
OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());
for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i)
OutStreamer.EmitRawText("\t.ascii \" -export:" +
Twine(DLLExportedGlobals[i]->getName()) +