blob: cefcb5d21c1654647eb2f27717f2f25deaeb3d41 [file] [log] [blame]
asle0d0f482008-07-19 13:14:11 +00001//===-- ELFTargetAsmInfo.cpp - ELF asm properties ---------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines target asm properties related what form asm statements
11// should take in general on ELF-based targets
12//
13//===----------------------------------------------------------------------===//
14
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"
Anton Korobeynikovfc54db12008-08-07 09:50:34 +000020#include "llvm/CodeGen/MachineConstantPool.h"
Edwin Török675d5622009-07-11 20:10:48 +000021#include "llvm/Support/ErrorHandling.h"
asle0d0f482008-07-19 13:14:11 +000022#include "llvm/Target/ELFTargetAsmInfo.h"
23#include "llvm/Target/TargetMachine.h"
24#include "llvm/Target/TargetData.h"
asle0d0f482008-07-19 13:14:11 +000025using namespace llvm;
26
Dan Gohmana004d7b2008-11-03 18:22:42 +000027ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
28 : TargetAsmInfo(TM) {
asle0d0f482008-07-19 13:14:11 +000029
Chris Lattnerd8310522009-07-27 05:32:16 +000030 ReadOnlySection = getNamedSection("\t.rodata", SectionKind::ReadOnly);
31 TLSDataSection = getNamedSection("\t.tdata", SectionKind::ThreadData);
32 TLSBSSSection = getNamedSection("\t.tbss", SectionKind::ThreadBSS);
asle0d0f482008-07-19 13:14:11 +000033
Chris Lattnerd8310522009-07-27 05:32:16 +000034 DataRelSection = getNamedSection("\t.data.rel", SectionKind::DataRel);
Anton Korobeynikov8a4fbe42009-03-30 15:27:03 +000035 DataRelLocalSection = getNamedSection("\t.data.rel.local",
Chris Lattnerd8310522009-07-27 05:32:16 +000036 SectionKind::DataRelLocal);
Anton Korobeynikov8a4fbe42009-03-30 15:27:03 +000037 DataRelROSection = getNamedSection("\t.data.rel.ro",
Chris Lattnerd8310522009-07-27 05:32:16 +000038 SectionKind::ReadOnlyWithRel);
Anton Korobeynikov8a4fbe42009-03-30 15:27:03 +000039 DataRelROLocalSection = getNamedSection("\t.data.rel.ro.local",
Chris Lattnerd8310522009-07-27 05:32:16 +000040 SectionKind::ReadOnlyWithRelLocal);
Chris Lattner52954842009-07-26 06:16:11 +000041
Chris Lattner1c379242009-07-26 06:48:26 +000042 MergeableConst4Section = getNamedSection(".rodata.cst4",
Chris Lattnerd8310522009-07-27 05:32:16 +000043 SectionKind::MergeableConst4);
Chris Lattner1c379242009-07-26 06:48:26 +000044 MergeableConst8Section = getNamedSection(".rodata.cst8",
Chris Lattnerd8310522009-07-27 05:32:16 +000045 SectionKind::MergeableConst8);
Chris Lattner1c379242009-07-26 06:48:26 +000046 MergeableConst16Section = getNamedSection(".rodata.cst16",
Chris Lattnerd8310522009-07-27 05:32:16 +000047 SectionKind::MergeableConst16);
asle0d0f482008-07-19 13:14:11 +000048}
49
Anton Korobeynikovb3882b62009-03-30 15:27:43 +000050
asle0d0f482008-07-19 13:14:11 +000051const Section*
Chris Lattnerbb0c9bf2009-07-24 18:42:53 +000052ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
Chris Lattnercc195212009-07-25 23:21:55 +000053 SectionKind Kind) const {
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +000054 if (Kind.isText()) return TextSection;
Chris Lattner1c379242009-07-26 06:48:26 +000055 if (Kind.isMergeableCString())
Chris Lattner3a2a55a2009-07-26 03:06:11 +000056 return MergeableStringSection(cast<GlobalVariable>(GV));
Chris Lattner2a7dd7d2009-07-26 06:11:33 +000057
Chris Lattner1c379242009-07-26 06:48:26 +000058 if (Kind.isMergeableConst()) {
59 if (Kind.isMergeableConst4())
60 return MergeableConst4Section;
61 if (Kind.isMergeableConst8())
62 return MergeableConst8Section;
63 if (Kind.isMergeableConst16())
64 return MergeableConst16Section;
Chris Lattner52954842009-07-26 06:16:11 +000065 return ReadOnlySection; // .const
Chris Lattnera06e19b2009-07-24 05:01:55 +000066 }
Chris Lattner52954842009-07-26 06:16:11 +000067
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +000068 if (Kind.isReadOnly()) return getReadOnlySection();
69
70
71 if (Kind.isThreadData()) return TLSDataSection;
72 if (Kind.isThreadBSS()) return TLSBSSSection;
73
74 if (Kind.isBSS()) return getBSSSection_();
75
76
77 if (Kind.isDataNoRel()) return DataSection;
78 if (Kind.isDataRelLocal()) return DataRelLocalSection;
79 if (Kind.isDataRel()) return DataRelSection;
80 if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
81
82 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
83 return DataRelROSection;
asle0d0f482008-07-19 13:14:11 +000084}
85
Chris Lattner1c379242009-07-26 06:48:26 +000086/// getSectionForMergeableConstant - Given a Mergeable constant with the
Chris Lattner680c6f62009-07-22 00:28:43 +000087/// specified size and relocation information, return a section that it
88/// should be placed in.
89const Section *
Chris Lattner1c379242009-07-26 06:48:26 +000090ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
Chris Lattnerfc60ba12009-07-26 06:26:55 +000091 return SelectSectionForGlobal(0, Kind);
Anton Korobeynikovfc54db12008-08-07 09:50:34 +000092}
93
Chris Lattnerdfd15982009-07-24 17:02:17 +000094/// getFlagsForNamedSection - If this target wants to be able to infer
95/// section flags based on the name of the section specified for a global
96/// variable, it can implement this.
Chris Lattnerd8310522009-07-27 05:32:16 +000097SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
98 SectionKind::Kind K) const {
99 if (Name[0] != '.') return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000100
101 // Some lame default implementation based on some magic section names.
102 if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
103 strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
104 strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
105 strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
Chris Lattnerd8310522009-07-27 05:32:16 +0000106 return SectionKind::BSS;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000107
Chris Lattnerd8310522009-07-27 05:32:16 +0000108 if (strcmp(Name, ".tdata") == 0 ||
109 strncmp(Name, ".tdata.", 7) == 0 ||
110 strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
111 strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
112 return SectionKind::ThreadData;
113
114 if (strcmp(Name, ".tbss") == 0 ||
115 strncmp(Name, ".tbss.", 6) == 0 ||
116 strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
117 strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
118 return SectionKind::ThreadBSS;
119
120 return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000121}
122
Chris Lattner4c530ee2009-07-25 18:57:34 +0000123const char *
Chris Lattnercc195212009-07-25 23:21:55 +0000124ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +0000125 if (Kind.isText()) return ".gnu.linkonce.t.";
126 if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
127
128 if (Kind.isThreadData()) return ".gnu.linkonce.td.";
129 if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
130
131 if (Kind.isBSS()) return ".gnu.linkonce.b.";
132 if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
133 if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
134 if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
135 if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
136
137 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
138 return ".gnu.linkonce.d.rel.ro.";
Chris Lattner4c530ee2009-07-25 18:57:34 +0000139}
140
141
142
Anton Korobeynikovfc54db12008-08-07 09:50:34 +0000143const Section*
asle0d0f482008-07-19 13:14:11 +0000144ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
Dan Gohmana004d7b2008-11-03 18:22:42 +0000145 const TargetData *TD = TM.getTargetData();
asle0d0f482008-07-19 13:14:11 +0000146 Constant *C = cast<GlobalVariable>(GV)->getInitializer();
asl4eeee012009-01-27 22:29:24 +0000147 const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
asle0d0f482008-07-19 13:14:11 +0000148
Duncan Sandsec4f97d2009-05-09 07:06:46 +0000149 unsigned Size = TD->getTypeAllocSize(Ty);
asle0d0f482008-07-19 13:14:11 +0000150 if (Size <= 16) {
Anton Korobeynikovfb4bf862008-08-07 09:54:40 +0000151 assert(getCStringSection() && "Should have string section prefix");
152
Chris Lattnerd8310522009-07-27 05:32:16 +0000153 // We also need alignment here.
154 // FIXME: this is getting the alignment of the character, not the alignment
155 // of the string!!
Anton Korobeynikov6fbf6d52008-07-21 18:29:23 +0000156 unsigned Align = TD->getPrefTypeAlignment(Ty);
asle0d0f482008-07-19 13:14:11 +0000157 if (Align < Size)
158 Align = Size;
159
160 std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align);
Chris Lattnerd8310522009-07-27 05:32:16 +0000161 return getNamedSection(Name.c_str(), SectionKind::MergeableCString);
asle0d0f482008-07-19 13:14:11 +0000162 }
163
Anton Korobeynikov4d433222008-09-24 22:20:27 +0000164 return getReadOnlySection();
asle0d0f482008-07-19 13:14:11 +0000165}
166
Chris Lattnerd8310522009-07-27 05:32:16 +0000167void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
168 SmallVectorImpl<char> &Str) const {
Chris Lattner94d8a762009-07-26 07:33:58 +0000169 Str.push_back(',');
170 Str.push_back('"');
171
Chris Lattnerd8310522009-07-27 05:32:16 +0000172 if (!Kind.isMetadata())
Chris Lattner94d8a762009-07-26 07:33:58 +0000173 Str.push_back('a');
Chris Lattnerd8310522009-07-27 05:32:16 +0000174 if (Kind.isText())
Chris Lattner94d8a762009-07-26 07:33:58 +0000175 Str.push_back('x');
Chris Lattnerd8310522009-07-27 05:32:16 +0000176 if (Kind.isWriteable())
Chris Lattner94d8a762009-07-26 07:33:58 +0000177 Str.push_back('w');
Chris Lattnerd8310522009-07-27 05:32:16 +0000178 if (Kind.isMergeableConst() || Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +0000179 Str.push_back('M');
Chris Lattnerd8310522009-07-27 05:32:16 +0000180 if (Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +0000181 Str.push_back('S');
Chris Lattnerd8310522009-07-27 05:32:16 +0000182 if (Kind.isThreadLocal())
Chris Lattner94d8a762009-07-26 07:33:58 +0000183 Str.push_back('T');
asle0d0f482008-07-19 13:14:11 +0000184
Chris Lattner94d8a762009-07-26 07:33:58 +0000185 Str.push_back('"');
186 Str.push_back(',');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000187
188 // If comment string is '@', e.g. as on ARM - use '%' instead
189 if (strcmp(CommentString, "@") == 0)
Chris Lattner94d8a762009-07-26 07:33:58 +0000190 Str.push_back('%');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000191 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000192 Str.push_back('@');
asle0d0f482008-07-19 13:14:11 +0000193
Chris Lattner94d8a762009-07-26 07:33:58 +0000194 const char *KindStr;
Chris Lattnerd8310522009-07-27 05:32:16 +0000195 if (Kind.isBSS())
Chris Lattner94d8a762009-07-26 07:33:58 +0000196 KindStr = "nobits";
asle0d0f482008-07-19 13:14:11 +0000197 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000198 KindStr = "progbits";
199
200 Str.append(KindStr, KindStr+strlen(KindStr));
asle0d0f482008-07-19 13:14:11 +0000201
Chris Lattnerd8310522009-07-27 05:32:16 +0000202 if (Kind.isMergeableCString()) {
203 // TODO: Eventually handle multiple byte character strings. For now, all
204 // mergable C strings are single byte.
Chris Lattner94d8a762009-07-26 07:33:58 +0000205 Str.push_back(',');
Chris Lattnerd8310522009-07-27 05:32:16 +0000206 Str.push_back('1');
207 } else if (Kind.isMergeableConst4()) {
208 Str.push_back(',');
209 Str.push_back('4');
210 } else if (Kind.isMergeableConst8()) {
211 Str.push_back(',');
212 Str.push_back('8');
213 } else if (Kind.isMergeableConst16()) {
214 Str.push_back(',');
215 Str.push_back('1');
216 Str.push_back('6');
Chris Lattner94d8a762009-07-26 07:33:58 +0000217 }
asle0d0f482008-07-19 13:14:11 +0000218}