blob: 556b494185ed70d02c8e450fcf9697c8cf54985f [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
asle0d0f482008-07-19 13:14:11 +000015#include "llvm/Target/ELFTargetAsmInfo.h"
Chris Lattner000f7232009-07-27 19:14:14 +000016#include "llvm/ADT/SmallVector.h"
asle0d0f482008-07-19 13:14:11 +000017using namespace llvm;
18
Dan Gohmana004d7b2008-11-03 18:22:42 +000019ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
20 : TargetAsmInfo(TM) {
Chris Lattner60c128a2009-07-27 16:20:58 +000021
22 TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
23 DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
Chris Lattner64630562009-07-27 06:17:14 +000024 ReadOnlySection =
25 getOrCreateSection("\t.rodata", false, SectionKind::ReadOnly);
26 TLSDataSection =
27 getOrCreateSection("\t.tdata", false, SectionKind::ThreadData);
28 TLSBSSSection = getOrCreateSection("\t.tbss", false, SectionKind::ThreadBSS);
asle0d0f482008-07-19 13:14:11 +000029
Chris Lattner64630562009-07-27 06:17:14 +000030 DataRelSection = getOrCreateSection("\t.data.rel", false,
31 SectionKind::DataRel);
32 DataRelLocalSection = getOrCreateSection("\t.data.rel.local", false,
33 SectionKind::DataRelLocal);
34 DataRelROSection = getOrCreateSection("\t.data.rel.ro", false,
35 SectionKind::ReadOnlyWithRel);
36 DataRelROLocalSection =
37 getOrCreateSection("\t.data.rel.ro.local", false,
38 SectionKind::ReadOnlyWithRelLocal);
Chris Lattner52954842009-07-26 06:16:11 +000039
Chris Lattner64630562009-07-27 06:17:14 +000040 MergeableConst4Section = getOrCreateSection(".rodata.cst4", false,
41 SectionKind::MergeableConst4);
42 MergeableConst8Section = getOrCreateSection(".rodata.cst8", false,
43 SectionKind::MergeableConst8);
44 MergeableConst16Section = getOrCreateSection(".rodata.cst16", false,
45 SectionKind::MergeableConst16);
asle0d0f482008-07-19 13:14:11 +000046}
47
Chris Lattnerdfd15982009-07-24 17:02:17 +000048/// getFlagsForNamedSection - If this target wants to be able to infer
49/// section flags based on the name of the section specified for a global
50/// variable, it can implement this.
Chris Lattnerd8310522009-07-27 05:32:16 +000051SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
52 SectionKind::Kind K) const {
53 if (Name[0] != '.') return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +000054
55 // Some lame default implementation based on some magic section names.
56 if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
57 strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
58 strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
59 strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
Chris Lattnerd8310522009-07-27 05:32:16 +000060 return SectionKind::BSS;
Chris Lattnerdfd15982009-07-24 17:02:17 +000061
Chris Lattnerd8310522009-07-27 05:32:16 +000062 if (strcmp(Name, ".tdata") == 0 ||
63 strncmp(Name, ".tdata.", 7) == 0 ||
64 strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
65 strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
66 return SectionKind::ThreadData;
67
68 if (strcmp(Name, ".tbss") == 0 ||
69 strncmp(Name, ".tbss.", 6) == 0 ||
70 strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
71 strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
72 return SectionKind::ThreadBSS;
73
74 return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +000075}
76
Chris Lattner4c530ee2009-07-25 18:57:34 +000077
Chris Lattnerd8310522009-07-27 05:32:16 +000078void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
79 SmallVectorImpl<char> &Str) const {
Chris Lattner94d8a762009-07-26 07:33:58 +000080 Str.push_back(',');
81 Str.push_back('"');
82
Chris Lattnerd8310522009-07-27 05:32:16 +000083 if (!Kind.isMetadata())
Chris Lattner94d8a762009-07-26 07:33:58 +000084 Str.push_back('a');
Chris Lattnerd8310522009-07-27 05:32:16 +000085 if (Kind.isText())
Chris Lattner94d8a762009-07-26 07:33:58 +000086 Str.push_back('x');
Chris Lattnerd8310522009-07-27 05:32:16 +000087 if (Kind.isWriteable())
Chris Lattner94d8a762009-07-26 07:33:58 +000088 Str.push_back('w');
Chris Lattnerd8310522009-07-27 05:32:16 +000089 if (Kind.isMergeableConst() || Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +000090 Str.push_back('M');
Chris Lattnerd8310522009-07-27 05:32:16 +000091 if (Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +000092 Str.push_back('S');
Chris Lattnerd8310522009-07-27 05:32:16 +000093 if (Kind.isThreadLocal())
Chris Lattner94d8a762009-07-26 07:33:58 +000094 Str.push_back('T');
asle0d0f482008-07-19 13:14:11 +000095
Chris Lattner94d8a762009-07-26 07:33:58 +000096 Str.push_back('"');
97 Str.push_back(',');
Anton Korobeynikov4183e112008-08-07 09:55:06 +000098
99 // If comment string is '@', e.g. as on ARM - use '%' instead
100 if (strcmp(CommentString, "@") == 0)
Chris Lattner94d8a762009-07-26 07:33:58 +0000101 Str.push_back('%');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000102 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000103 Str.push_back('@');
asle0d0f482008-07-19 13:14:11 +0000104
Chris Lattner94d8a762009-07-26 07:33:58 +0000105 const char *KindStr;
Chris Lattnerd8310522009-07-27 05:32:16 +0000106 if (Kind.isBSS())
Chris Lattner94d8a762009-07-26 07:33:58 +0000107 KindStr = "nobits";
asle0d0f482008-07-19 13:14:11 +0000108 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000109 KindStr = "progbits";
110
111 Str.append(KindStr, KindStr+strlen(KindStr));
asle0d0f482008-07-19 13:14:11 +0000112
Chris Lattnerd8310522009-07-27 05:32:16 +0000113 if (Kind.isMergeableCString()) {
114 // TODO: Eventually handle multiple byte character strings. For now, all
115 // mergable C strings are single byte.
Chris Lattner94d8a762009-07-26 07:33:58 +0000116 Str.push_back(',');
Chris Lattnerd8310522009-07-27 05:32:16 +0000117 Str.push_back('1');
118 } else if (Kind.isMergeableConst4()) {
119 Str.push_back(',');
120 Str.push_back('4');
121 } else if (Kind.isMergeableConst8()) {
122 Str.push_back(',');
123 Str.push_back('8');
124 } else if (Kind.isMergeableConst16()) {
125 Str.push_back(',');
126 Str.push_back('1');
127 Str.push_back('6');
Chris Lattner94d8a762009-07-26 07:33:58 +0000128 }
asle0d0f482008-07-19 13:14:11 +0000129}
Chris Lattner000f7232009-07-27 19:14:14 +0000130
131
132
133//===----------------------------------------------------------------------===//
134// Move to AsmPrinter (mangler access).
135//===----------------------------------------------------------------------===//
136
137#include "llvm/DerivedTypes.h"
138#include "llvm/GlobalVariable.h"
139#include "llvm/Target/TargetData.h"
140#include "llvm/Target/TargetMachine.h"
141#include "llvm/ADT/StringExtras.h"
142
143static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
144 if (Kind.isText()) return ".gnu.linkonce.t.";
145 if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
146
147 if (Kind.isThreadData()) return ".gnu.linkonce.td.";
148 if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
149
150 if (Kind.isBSS()) return ".gnu.linkonce.b.";
151 if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
152 if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
153 if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
154 if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
155
156 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
157 return ".gnu.linkonce.d.rel.ro.";
158}
159
160const Section*
161ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
162 SectionKind Kind) const {
163
164 // If this global is linkonce/weak and the target handles this by emitting it
165 // into a 'uniqued' section name, create and return the section now.
166 if (Kind.isWeak()) {
167 const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
168 // FIXME: Use mangler interface (PR4584).
169 std::string Name = Prefix+GV->getNameStr();
170 return getOrCreateSection(Name.c_str(), false, Kind.getKind());
171 }
172
173 if (Kind.isText()) return TextSection;
174 if (Kind.isMergeableCString()) {
175 const TargetData *TD = TM.getTargetData();
176 Constant *C = cast<GlobalVariable>(GV)->getInitializer();
177 const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
178
179 unsigned Size = TD->getTypeAllocSize(Ty);
180 if (Size <= 16) {
181 assert(getCStringSection() && "Should have string section prefix");
182
183 // We also need alignment here.
184 // FIXME: this is getting the alignment of the character, not the
185 // alignment of the string!!
186 unsigned Align = TD->getPrefTypeAlignment(Ty);
187 if (Align < Size)
188 Align = Size;
189
190 std::string Name = getCStringSection() + utostr(Size) + '.' +
191 utostr(Align);
192 return getOrCreateSection(Name.c_str(), false,
193 SectionKind::MergeableCString);
194 }
195
196 return getReadOnlySection();
197 }
198
199 if (Kind.isMergeableConst()) {
200 if (Kind.isMergeableConst4())
201 return MergeableConst4Section;
202 if (Kind.isMergeableConst8())
203 return MergeableConst8Section;
204 if (Kind.isMergeableConst16())
205 return MergeableConst16Section;
206 return ReadOnlySection; // .const
207 }
208
209 if (Kind.isReadOnly()) return getReadOnlySection();
210
211
212 if (Kind.isThreadData()) return TLSDataSection;
213 if (Kind.isThreadBSS()) return TLSBSSSection;
214
215 if (Kind.isBSS()) return getBSSSection_();
216
217
218 if (Kind.isDataNoRel()) return DataSection;
219 if (Kind.isDataRelLocal()) return DataRelLocalSection;
220 if (Kind.isDataRel()) return DataRelSection;
221 if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
222
223 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
224 return DataRelROSection;
225}
226
227/// getSectionForMergeableConstant - Given a Mergeable constant with the
228/// specified size and relocation information, return a section that it
229/// should be placed in.
230const Section *
231ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
232 return SelectSectionForGlobal(0, Kind);
233}
234