mirror of
https://github.com/RPCSX/llvm.git
synced 2025-03-01 09:26:22 +00:00
add COFF support for COMDAT sections, patch by Nathan Jeffords!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103304 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9c00487dc3
commit
6e5ce287b0
@ -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);
|
||||
}
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user