1 //===-- ELFTargetAsmInfo.cpp - ELF asm properties ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines target asm properties related what form asm statements
11 // should take in general on ELF-based targets
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Constants.h"
16 #include "llvm/DerivedTypes.h"
17 #include "llvm/Function.h"
18 #include "llvm/GlobalVariable.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/CodeGen/MachineConstantPool.h"
21 #include "llvm/Target/ELFTargetAsmInfo.h"
22 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Target/TargetData.h"
27 ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine
&TM
)
30 BSSSection_
= getUnnamedSection("\t.bss",
31 SectionFlags::Writeable
| SectionFlags::BSS
);
32 ReadOnlySection
= getNamedSection("\t.rodata", SectionFlags::None
);
33 TLSDataSection
= getNamedSection("\t.tdata",
34 SectionFlags::Writeable
| SectionFlags::TLS
);
35 TLSBSSSection
= getNamedSection("\t.tbss",
36 SectionFlags::Writeable
| SectionFlags::TLS
| SectionFlags::BSS
);
38 DataRelSection
= getNamedSection("\t.data.rel", SectionFlags::Writeable
);
39 DataRelLocalSection
= getNamedSection("\t.data.rel.local",
40 SectionFlags::Writeable
);
41 DataRelROSection
= getNamedSection("\t.data.rel.ro",
42 SectionFlags::Writeable
);
43 DataRelROLocalSection
= getNamedSection("\t.data.rel.ro.local",
44 SectionFlags::Writeable
);
48 ELFTargetAsmInfo::SectionKindForGlobal(const GlobalValue
*GV
) const {
49 SectionKind::Kind Kind
= TargetAsmInfo::SectionKindForGlobal(GV
);
51 if (Kind
!= SectionKind::Data
)
54 // Decide, whether we need data.rel stuff
55 const GlobalVariable
* GVar
= dyn_cast
<GlobalVariable
>(GV
);
56 if (GVar
->hasInitializer()) {
57 Constant
*C
= GVar
->getInitializer();
58 bool isConstant
= GVar
->isConstant();
59 unsigned Reloc
= RelocBehaviour();
60 if (Reloc
!= Reloc::None
&& C
->ContainsRelocations(Reloc
))
61 return (C
->ContainsRelocations(Reloc::Global
) ?
63 SectionKind::DataRelRO
: SectionKind::DataRel
) :
65 SectionKind::DataRelROLocal
: SectionKind::DataRelLocal
));
72 ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue
*GV
) const {
73 SectionKind::Kind Kind
= SectionKindForGlobal(GV
);
75 if (const Function
*F
= dyn_cast
<Function
>(GV
)) {
76 switch (F
->getLinkage()) {
77 default: assert(0 && "Unknown linkage type!");
78 case Function::PrivateLinkage
:
79 case Function::InternalLinkage
:
80 case Function::DLLExportLinkage
:
81 case Function::ExternalLinkage
:
83 case Function::WeakAnyLinkage
:
84 case Function::WeakODRLinkage
:
85 case Function::LinkOnceAnyLinkage
:
86 case Function::LinkOnceODRLinkage
:
87 std::string Name
= UniqueSectionForGlobal(GV
, Kind
);
88 unsigned Flags
= SectionFlagsForGlobal(GV
, Name
.c_str());
89 return getNamedSection(Name
.c_str(), Flags
);
91 } else if (const GlobalVariable
*GVar
= dyn_cast
<GlobalVariable
>(GV
)) {
92 if (GVar
->isWeakForLinker()) {
93 std::string Name
= UniqueSectionForGlobal(GVar
, Kind
);
94 unsigned Flags
= SectionFlagsForGlobal(GVar
, Name
.c_str());
95 return getNamedSection(Name
.c_str(), Flags
);
98 case SectionKind::Data
:
99 case SectionKind::SmallData
:
101 case SectionKind::DataRel
:
102 return DataRelSection
;
103 case SectionKind::DataRelLocal
:
104 return DataRelLocalSection
;
105 case SectionKind::DataRelRO
:
106 return DataRelROSection
;
107 case SectionKind::DataRelROLocal
:
108 return DataRelROLocalSection
;
109 case SectionKind::BSS
:
110 case SectionKind::SmallBSS
:
111 // ELF targets usually have BSS sections
112 return getBSSSection_();
113 case SectionKind::ROData
:
114 case SectionKind::SmallROData
:
115 return getReadOnlySection();
116 case SectionKind::RODataMergeStr
:
117 return MergeableStringSection(GVar
);
118 case SectionKind::RODataMergeConst
:
119 return MergeableConstSection(GVar
);
120 case SectionKind::ThreadData
:
121 // ELF targets usually support TLS stuff
122 return TLSDataSection
;
123 case SectionKind::ThreadBSS
:
124 return TLSBSSSection
;
126 assert(0 && "Unsuported section kind for global");
130 assert(0 && "Unsupported global");
136 ELFTargetAsmInfo::SelectSectionForMachineConst(const Type
*Ty
) const {
137 // FIXME: Support data.rel stuff someday
138 return MergeableConstSection(Ty
);
142 ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable
*GV
) const {
143 Constant
*C
= GV
->getInitializer();
144 return MergeableConstSection(C
->getType());
147 inline const Section
*
148 ELFTargetAsmInfo::MergeableConstSection(const Type
*Ty
) const {
149 const TargetData
*TD
= TM
.getTargetData();
151 // FIXME: string here is temporary, until stuff will fully land in.
152 // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's
153 // currently directly used by asmprinter.
154 unsigned Size
= TD
->getTypeAllocSize(Ty
);
155 if (Size
== 4 || Size
== 8 || Size
== 16) {
156 std::string Name
= ".rodata.cst" + utostr(Size
);
158 return getNamedSection(Name
.c_str(),
159 SectionFlags::setEntitySize(SectionFlags::Mergeable
,
163 return getReadOnlySection();
167 ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable
*GV
) const {
168 const TargetData
*TD
= TM
.getTargetData();
169 Constant
*C
= cast
<GlobalVariable
>(GV
)->getInitializer();
170 const Type
*Ty
= cast
<ArrayType
>(C
->getType())->getElementType();
172 unsigned Size
= TD
->getTypeAllocSize(Ty
);
174 assert(getCStringSection() && "Should have string section prefix");
176 // We also need alignment here
177 unsigned Align
= TD
->getPrefTypeAlignment(Ty
);
181 std::string Name
= getCStringSection() + utostr(Size
) + '.' + utostr(Align
);
182 unsigned Flags
= SectionFlags::setEntitySize(SectionFlags::Mergeable
|
183 SectionFlags::Strings
,
185 return getNamedSection(Name
.c_str(), Flags
);
188 return getReadOnlySection();
191 std::string
ELFTargetAsmInfo::printSectionFlags(unsigned flags
) const {
192 std::string Flags
= ",\"";
194 if (!(flags
& SectionFlags::Debug
))
196 if (flags
& SectionFlags::Code
)
198 if (flags
& SectionFlags::Writeable
)
200 if (flags
& SectionFlags::Mergeable
)
202 if (flags
& SectionFlags::Strings
)
204 if (flags
& SectionFlags::TLS
)
206 if (flags
& SectionFlags::Small
)
211 // If comment string is '@', e.g. as on ARM - use '%' instead
212 if (strcmp(CommentString
, "@") == 0)
217 // FIXME: There can be exceptions here
218 if (flags
& SectionFlags::BSS
)
223 if (unsigned entitySize
= SectionFlags::getEntitySize(flags
))
224 Flags
+= "," + utostr(entitySize
);