mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-25 21:16:19 +00:00
Properly handle linkonce stuff
llvm-svn: 53296
This commit is contained in:
parent
782a69505d
commit
ca271dd426
@ -56,11 +56,6 @@ namespace llvm {
|
||||
};
|
||||
}
|
||||
|
||||
struct SectionInfo {
|
||||
SectionKind::Kind kind;
|
||||
SectionFlags::Flags flags;
|
||||
};
|
||||
|
||||
class TargetMachine;
|
||||
class CallInst;
|
||||
class GlobalValue;
|
||||
@ -476,6 +471,9 @@ namespace llvm {
|
||||
/// global with all necessary flags and marks.
|
||||
virtual std::string SectionForGlobal(const GlobalValue *GV) const;
|
||||
|
||||
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
|
||||
SectionKind::Kind kind) const;
|
||||
|
||||
// Accessors.
|
||||
//
|
||||
const char *getTextSection() const {
|
||||
|
@ -266,3 +266,26 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
|
||||
|
||||
return getDataSection();
|
||||
}
|
||||
|
||||
std::string
|
||||
TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
|
||||
SectionKind::Kind kind) const {
|
||||
switch (kind) {
|
||||
case SectionKind::Text:
|
||||
return ".llvm.linkonce.t." + GV->getName();
|
||||
case SectionKind::Data:
|
||||
return ".llvm.linkonce.d." + GV->getName();
|
||||
case SectionKind::BSS:
|
||||
return ".llvm.linkonce.b." + GV->getName();
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeConst:
|
||||
case SectionKind::RODataMergeStr:
|
||||
return ".llvm.linkonce.r." + GV->getName();
|
||||
case SectionKind::ThreadData:
|
||||
return ".llvm.linkonce.td." + GV->getName();
|
||||
case SectionKind::ThreadBSS:
|
||||
return ".llvm.linkonce.tb." + GV->getName();
|
||||
default:
|
||||
assert(0 && "Unknown section kind");
|
||||
}
|
||||
}
|
||||
|
@ -375,6 +375,41 @@ unsigned X86TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
|
||||
}
|
||||
}
|
||||
|
||||
std::string X86TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
|
||||
SectionKind::Kind kind) const {
|
||||
const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
|
||||
|
||||
switch (Subtarget->TargetType) {
|
||||
case X86Subtarget::isDarwin:
|
||||
if (kind == SectionKind::Text)
|
||||
return "__TEXT,__textcoal_nt,coalesced,pure_instructions";
|
||||
else
|
||||
return "__DATA,__datacoal_nt,coalesced";
|
||||
case X86Subtarget::isCygwin:
|
||||
case X86Subtarget::isMingw:
|
||||
switch (kind) {
|
||||
case SectionKind::Text:
|
||||
return ".text$linkonce" + GV->getName();
|
||||
case SectionKind::Data:
|
||||
case SectionKind::BSS:
|
||||
case SectionKind::ThreadData:
|
||||
case SectionKind::ThreadBSS:
|
||||
return ".data$linkonce" + GV->getName();
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeConst:
|
||||
case SectionKind::RODataMergeStr:
|
||||
return ".rdata$linkonce" + GV->getName();
|
||||
default:
|
||||
assert(0 && "Unknown section kind");
|
||||
}
|
||||
case X86Subtarget::isELF:
|
||||
return TargetAsmInfo::UniqueSectionForGlobal(GV, kind);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string X86TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
|
||||
const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
|
||||
SectionKind::Kind kind = SectionKindForGlobal(GV);
|
||||
@ -383,41 +418,58 @@ std::string X86TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
|
||||
|
||||
// FIXME: Should we use some hashing based on section name and just check
|
||||
// flags?
|
||||
// FIXME: It seems, that Darwin uses much more sections.
|
||||
|
||||
// Select section name
|
||||
if (const Function *F = dyn_cast<Function>(GV)) {
|
||||
// Implement here
|
||||
} else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
|
||||
if (GVar->hasSection()) {
|
||||
// Honour section already set, if any
|
||||
Name = GVar->getSection();
|
||||
} else {
|
||||
// Use default section depending on the 'type' of global
|
||||
// FIXME: Handle linkonce stuff
|
||||
switch (kind) {
|
||||
case SectionKind::Data:
|
||||
Name = DataSection;
|
||||
if (GV->hasSection()) {
|
||||
// Honour section already set, if any
|
||||
Name = GV->getSection();
|
||||
} else {
|
||||
// Use default section depending on the 'type' of global
|
||||
if (const Function *F = dyn_cast<Function>(GV)) {
|
||||
switch (F->getLinkage()) {
|
||||
default: assert(0 && "Unknown linkage type!");
|
||||
case Function::InternalLinkage:
|
||||
case Function::DLLExportLinkage:
|
||||
case Function::ExternalLinkage:
|
||||
Name = TextSection;
|
||||
break;
|
||||
case SectionKind::BSS:
|
||||
Name = (BSSSection ? BSSSection : DataSection);
|
||||
case Function::WeakLinkage:
|
||||
case Function::LinkOnceLinkage:
|
||||
Name = UniqueSectionForGlobal(F, kind);
|
||||
break;
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeStr:
|
||||
case SectionKind::RODataMergeConst:
|
||||
// FIXME: Temporary
|
||||
Name = DataSection;
|
||||
break;
|
||||
case SectionKind::ThreadData:
|
||||
Name = (TLSDataSection ? TLSDataSection : DataSection);
|
||||
break;
|
||||
case SectionKind::ThreadBSS:
|
||||
Name = (TLSBSSSection ? TLSBSSSection : DataSection);
|
||||
default:
|
||||
assert(0 && "Unsuported section kind for global");
|
||||
}
|
||||
}
|
||||
} else
|
||||
assert(0 && "Unsupported global");
|
||||
} else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
|
||||
if (GVar->hasCommonLinkage() ||
|
||||
GVar->hasLinkOnceLinkage() ||
|
||||
GVar->hasWeakLinkage())
|
||||
Name = UniqueSectionForGlobal(GVar, kind);
|
||||
else {
|
||||
switch (kind) {
|
||||
case SectionKind::Data:
|
||||
Name = DataSection;
|
||||
break;
|
||||
case SectionKind::BSS:
|
||||
Name = (BSSSection ? BSSSection : DataSection);
|
||||
break;
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeStr:
|
||||
case SectionKind::RODataMergeConst:
|
||||
// FIXME: Temporary
|
||||
Name = DataSection;
|
||||
break;
|
||||
case SectionKind::ThreadData:
|
||||
Name = (TLSDataSection ? TLSDataSection : DataSection);
|
||||
break;
|
||||
case SectionKind::ThreadBSS:
|
||||
Name = (TLSBSSSection ? TLSBSSSection : DataSection);
|
||||
default:
|
||||
assert(0 && "Unsuported section kind for global");
|
||||
}
|
||||
}
|
||||
} else
|
||||
assert(0 && "Unsupported global");
|
||||
}
|
||||
|
||||
// Add all special flags, etc
|
||||
switch (Subtarget->TargetType) {
|
||||
|
@ -28,6 +28,8 @@ namespace llvm {
|
||||
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
|
||||
bool Global) const;
|
||||
virtual std::string SectionForGlobal(const GlobalValue *GV) const;
|
||||
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
|
||||
SectionKind::Kind kind) const;
|
||||
|
||||
private:
|
||||
const X86TargetMachine* X86TM;
|
||||
|
Loading…
Reference in New Issue
Block a user