1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

add COFF support for COMDAT sections, patch by Nathan Jeffords!

llvm-svn: 103304
This commit is contained in:
Chris Lattner 2010-05-07 21:49:09 +00:00
parent e7333c8318
commit e72e3e9c12
5 changed files with 65 additions and 17 deletions

View File

@ -98,8 +98,14 @@ namespace llvm {
unsigned Flags, SectionKind Kind,
bool IsExplicit = false);
const MCSection *getCOFFSection(StringRef Section, unsigned Flags,
SectionKind Kind);
const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
int Selection, SectionKind Kind);
const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind) {
return getCOFFSection (Section, Characteristics, 0, Kind);
}
/// @}

View File

@ -23,14 +23,22 @@ namespace llvm {
// 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;
/// Characteristics - This is the Characteristics field of a section,
// drawn from the enums below.
unsigned Characteristics;
/// Selection - This is the Selection field for the section symbol, if
/// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
int Selection;
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned flags, SectionKind K)
: MCSection(K), SectionName(Section), Flags(flags) {
MCSectionCOFF(StringRef Section, unsigned Characteristics,
int Selection, SectionKind K)
: MCSection(K), SectionName(Section), Characteristics(Characteristics),
Selection (Selection) {
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
~MCSectionCOFF();
@ -39,6 +47,13 @@ namespace llvm {
/// should be printed before the section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
//FIXME: all COFF enumerations/flags should be standardized into one place...
// Target/X86COFF.h doesn't seem right as COFF can be used for other targets,
// MC/WinCOFF.h maybe right as it isn't target or entity specific, and it is
// pretty low on the dependancy graph (is there any need to support non
// windows COFF?)
// here is good for section stuff, but others should go elsewhere
/// Valid section flags.
enum {
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
@ -54,6 +69,7 @@ namespace llvm {
IMAGE_SCN_MEM_16BIT = 0x00020000,
IMAGE_SCN_MEM_LOCKED = 0x00040000,
IMAGE_SCN_MEM_PRELOAD = 0x00080000,
/* these are handled elsewhere
IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
@ -61,6 +77,7 @@ namespace llvm {
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,
@ -71,8 +88,18 @@ namespace llvm {
IMAGE_SCN_MEM_WRITE = 0x80000000
};
enum {
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
IMAGE_COMDAT_SELECT_ANY,
IMAGE_COMDAT_SELECT_SAME_SIZE,
IMAGE_COMDAT_SELECT_EXACT_MATCH,
IMAGE_COMDAT_SELECT_ASSOCIATIVE,
IMAGE_COMDAT_SELECT_LARGEST
};
StringRef getSectionName() const { return SectionName; }
unsigned getFlags() const { return Flags; }
unsigned getCharacteristics() const { return Characteristics; }
int getSelection () const { return Selection; }
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;

View File

@ -912,11 +912,17 @@ getCOFFSectionFlags(SectionKind K) {
unsigned Flags = 0;
if (!K.isMetadata())
Flags |= MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE;
Flags |=
MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE;
else if (K.isText())
Flags |=
MCSectionCOFF::IMAGE_SCN_MEM_EXECUTE |
MCSectionCOFF::IMAGE_SCN_CNT_CODE;
else if (K.isBSS ())
Flags |=
MCSectionCOFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
MCSectionCOFF::IMAGE_SCN_MEM_READ |
MCSectionCOFF::IMAGE_SCN_MEM_WRITE;
else if (K.isReadOnly())
Flags |=
MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@ -941,6 +947,8 @@ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
if (Kind.isText())
return ".text$linkonce";
if (Kind.isBSS ())
return ".bss$linkonce";
if (Kind.isWriteable())
return ".data$linkonce";
return ".rdata$linkonce";
@ -959,9 +967,13 @@ 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 getContext().getCOFFSection(Name.str(),
getCOFFSectionFlags(Kind),
Kind);
unsigned Characteristics = getCOFFSectionFlags(Kind);
Characteristics |= MCSectionCOFF::IMAGE_SCN_LNK_COMDAT;
return getContext().getCOFFSection(Name.str(), Characteristics,
MCSectionCOFF::IMAGE_COMDAT_SELECT_EXACT_MATCH, Kind);
}
if (Kind.isText())

View File

@ -126,8 +126,10 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags,
return Result;
}
const MCSection *MCContext::
getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) {
const MCSection *MCContext::getCOFFSection(StringRef Section,
unsigned Characteristics,
int Selection,
SectionKind Kind) {
if (COFFUniquingMap == 0)
COFFUniquingMap = new COFFUniqueMapTy();
COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
@ -136,8 +138,9 @@ getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) {
StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
if (Entry.getValue()) return Entry.getValue();
MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), Flags,
Kind);
MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
Characteristics,
Selection, Kind);
Entry.setValue(Result);
return Result;

View File

@ -43,7 +43,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << 'w';
else
OS << 'r';
if (getFlags() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE)
if (getCharacteristics() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE)
OS << 'n';
OS << "\"\n";
}