blob: 391e348ba21a6a3e6c06520dcaaad8285de2cf48 [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) {
Chris Lattner60c128a2009-07-27 16:20:58 +000029
30 TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
31 DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
Chris Lattner64630562009-07-27 06:17:14 +000032 ReadOnlySection =
33 getOrCreateSection("\t.rodata", false, SectionKind::ReadOnly);
34 TLSDataSection =
35 getOrCreateSection("\t.tdata", false, SectionKind::ThreadData);
36 TLSBSSSection = getOrCreateSection("\t.tbss", false, SectionKind::ThreadBSS);
asle0d0f482008-07-19 13:14:11 +000037
Chris Lattner64630562009-07-27 06:17:14 +000038 DataRelSection = getOrCreateSection("\t.data.rel", false,
39 SectionKind::DataRel);
40 DataRelLocalSection = getOrCreateSection("\t.data.rel.local", false,
41 SectionKind::DataRelLocal);
42 DataRelROSection = getOrCreateSection("\t.data.rel.ro", false,
43 SectionKind::ReadOnlyWithRel);
44 DataRelROLocalSection =
45 getOrCreateSection("\t.data.rel.ro.local", false,
46 SectionKind::ReadOnlyWithRelLocal);
Chris Lattner52954842009-07-26 06:16:11 +000047
Chris Lattner64630562009-07-27 06:17:14 +000048 MergeableConst4Section = getOrCreateSection(".rodata.cst4", false,
49 SectionKind::MergeableConst4);
50 MergeableConst8Section = getOrCreateSection(".rodata.cst8", false,
51 SectionKind::MergeableConst8);
52 MergeableConst16Section = getOrCreateSection(".rodata.cst16", false,
53 SectionKind::MergeableConst16);
asle0d0f482008-07-19 13:14:11 +000054}
55
Anton Korobeynikovb3882b62009-03-30 15:27:43 +000056
asle0d0f482008-07-19 13:14:11 +000057const Section*
Chris Lattnerbb0c9bf2009-07-24 18:42:53 +000058ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
Chris Lattnercc195212009-07-25 23:21:55 +000059 SectionKind Kind) const {
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +000060 if (Kind.isText()) return TextSection;
Chris Lattner1c379242009-07-26 06:48:26 +000061 if (Kind.isMergeableCString())
Chris Lattner3a2a55a2009-07-26 03:06:11 +000062 return MergeableStringSection(cast<GlobalVariable>(GV));
Chris Lattner2a7dd7d2009-07-26 06:11:33 +000063
Chris Lattner1c379242009-07-26 06:48:26 +000064 if (Kind.isMergeableConst()) {
65 if (Kind.isMergeableConst4())
66 return MergeableConst4Section;
67 if (Kind.isMergeableConst8())
68 return MergeableConst8Section;
69 if (Kind.isMergeableConst16())
70 return MergeableConst16Section;
Chris Lattner52954842009-07-26 06:16:11 +000071 return ReadOnlySection; // .const
Chris Lattnera06e19b2009-07-24 05:01:55 +000072 }
Chris Lattner52954842009-07-26 06:16:11 +000073
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +000074 if (Kind.isReadOnly()) return getReadOnlySection();
75
76
77 if (Kind.isThreadData()) return TLSDataSection;
78 if (Kind.isThreadBSS()) return TLSBSSSection;
79
80 if (Kind.isBSS()) return getBSSSection_();
81
82
83 if (Kind.isDataNoRel()) return DataSection;
84 if (Kind.isDataRelLocal()) return DataRelLocalSection;
85 if (Kind.isDataRel()) return DataRelSection;
86 if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
87
88 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
89 return DataRelROSection;
asle0d0f482008-07-19 13:14:11 +000090}
91
Chris Lattner1c379242009-07-26 06:48:26 +000092/// getSectionForMergeableConstant - Given a Mergeable constant with the
Chris Lattner680c6f62009-07-22 00:28:43 +000093/// specified size and relocation information, return a section that it
94/// should be placed in.
95const Section *
Chris Lattner1c379242009-07-26 06:48:26 +000096ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
Chris Lattnerfc60ba12009-07-26 06:26:55 +000097 return SelectSectionForGlobal(0, Kind);
Anton Korobeynikovfc54db12008-08-07 09:50:34 +000098}
99
Chris Lattnerdfd15982009-07-24 17:02:17 +0000100/// getFlagsForNamedSection - If this target wants to be able to infer
101/// section flags based on the name of the section specified for a global
102/// variable, it can implement this.
Chris Lattnerd8310522009-07-27 05:32:16 +0000103SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
104 SectionKind::Kind K) const {
105 if (Name[0] != '.') return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000106
107 // Some lame default implementation based on some magic section names.
108 if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
109 strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
110 strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
111 strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
Chris Lattnerd8310522009-07-27 05:32:16 +0000112 return SectionKind::BSS;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000113
Chris Lattnerd8310522009-07-27 05:32:16 +0000114 if (strcmp(Name, ".tdata") == 0 ||
115 strncmp(Name, ".tdata.", 7) == 0 ||
116 strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
117 strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
118 return SectionKind::ThreadData;
119
120 if (strcmp(Name, ".tbss") == 0 ||
121 strncmp(Name, ".tbss.", 6) == 0 ||
122 strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
123 strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
124 return SectionKind::ThreadBSS;
125
126 return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000127}
128
Chris Lattner4c530ee2009-07-25 18:57:34 +0000129const char *
Chris Lattnercc195212009-07-25 23:21:55 +0000130ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +0000131 if (Kind.isText()) return ".gnu.linkonce.t.";
132 if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
133
134 if (Kind.isThreadData()) return ".gnu.linkonce.td.";
135 if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
136
137 if (Kind.isBSS()) return ".gnu.linkonce.b.";
138 if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
139 if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
140 if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
141 if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
142
143 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
144 return ".gnu.linkonce.d.rel.ro.";
Chris Lattner4c530ee2009-07-25 18:57:34 +0000145}
146
147
148
Anton Korobeynikovfc54db12008-08-07 09:50:34 +0000149const Section*
asle0d0f482008-07-19 13:14:11 +0000150ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
Dan Gohmana004d7b2008-11-03 18:22:42 +0000151 const TargetData *TD = TM.getTargetData();
asle0d0f482008-07-19 13:14:11 +0000152 Constant *C = cast<GlobalVariable>(GV)->getInitializer();
asl4eeee012009-01-27 22:29:24 +0000153 const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
asle0d0f482008-07-19 13:14:11 +0000154
Duncan Sandsec4f97d2009-05-09 07:06:46 +0000155 unsigned Size = TD->getTypeAllocSize(Ty);
asle0d0f482008-07-19 13:14:11 +0000156 if (Size <= 16) {
Anton Korobeynikovfb4bf862008-08-07 09:54:40 +0000157 assert(getCStringSection() && "Should have string section prefix");
158
Chris Lattnerd8310522009-07-27 05:32:16 +0000159 // We also need alignment here.
160 // FIXME: this is getting the alignment of the character, not the alignment
161 // of the string!!
Anton Korobeynikov6fbf6d52008-07-21 18:29:23 +0000162 unsigned Align = TD->getPrefTypeAlignment(Ty);
asle0d0f482008-07-19 13:14:11 +0000163 if (Align < Size)
164 Align = Size;
165
166 std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align);
Chris Lattner64630562009-07-27 06:17:14 +0000167 return getOrCreateSection(Name.c_str(), false,
168 SectionKind::MergeableCString);
asle0d0f482008-07-19 13:14:11 +0000169 }
170
Anton Korobeynikov4d433222008-09-24 22:20:27 +0000171 return getReadOnlySection();
asle0d0f482008-07-19 13:14:11 +0000172}
173
Chris Lattnerd8310522009-07-27 05:32:16 +0000174void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
175 SmallVectorImpl<char> &Str) const {
Chris Lattner94d8a762009-07-26 07:33:58 +0000176 Str.push_back(',');
177 Str.push_back('"');
178
Chris Lattnerd8310522009-07-27 05:32:16 +0000179 if (!Kind.isMetadata())
Chris Lattner94d8a762009-07-26 07:33:58 +0000180 Str.push_back('a');
Chris Lattnerd8310522009-07-27 05:32:16 +0000181 if (Kind.isText())
Chris Lattner94d8a762009-07-26 07:33:58 +0000182 Str.push_back('x');
Chris Lattnerd8310522009-07-27 05:32:16 +0000183 if (Kind.isWriteable())
Chris Lattner94d8a762009-07-26 07:33:58 +0000184 Str.push_back('w');
Chris Lattnerd8310522009-07-27 05:32:16 +0000185 if (Kind.isMergeableConst() || Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +0000186 Str.push_back('M');
Chris Lattnerd8310522009-07-27 05:32:16 +0000187 if (Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +0000188 Str.push_back('S');
Chris Lattnerd8310522009-07-27 05:32:16 +0000189 if (Kind.isThreadLocal())
Chris Lattner94d8a762009-07-26 07:33:58 +0000190 Str.push_back('T');
asle0d0f482008-07-19 13:14:11 +0000191
Chris Lattner94d8a762009-07-26 07:33:58 +0000192 Str.push_back('"');
193 Str.push_back(',');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000194
195 // If comment string is '@', e.g. as on ARM - use '%' instead
196 if (strcmp(CommentString, "@") == 0)
Chris Lattner94d8a762009-07-26 07:33:58 +0000197 Str.push_back('%');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000198 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000199 Str.push_back('@');
asle0d0f482008-07-19 13:14:11 +0000200
Chris Lattner94d8a762009-07-26 07:33:58 +0000201 const char *KindStr;
Chris Lattnerd8310522009-07-27 05:32:16 +0000202 if (Kind.isBSS())
Chris Lattner94d8a762009-07-26 07:33:58 +0000203 KindStr = "nobits";
asle0d0f482008-07-19 13:14:11 +0000204 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000205 KindStr = "progbits";
206
207 Str.append(KindStr, KindStr+strlen(KindStr));
asle0d0f482008-07-19 13:14:11 +0000208
Chris Lattnerd8310522009-07-27 05:32:16 +0000209 if (Kind.isMergeableCString()) {
210 // TODO: Eventually handle multiple byte character strings. For now, all
211 // mergable C strings are single byte.
Chris Lattner94d8a762009-07-26 07:33:58 +0000212 Str.push_back(',');
Chris Lattnerd8310522009-07-27 05:32:16 +0000213 Str.push_back('1');
214 } else if (Kind.isMergeableConst4()) {
215 Str.push_back(',');
216 Str.push_back('4');
217 } else if (Kind.isMergeableConst8()) {
218 Str.push_back(',');
219 Str.push_back('8');
220 } else if (Kind.isMergeableConst16()) {
221 Str.push_back(',');
222 Str.push_back('1');
223 Str.push_back('6');
Chris Lattner94d8a762009-07-26 07:33:58 +0000224 }
asle0d0f482008-07-19 13:14:11 +0000225}