blob: dbb2ce30ca0ee69a3101c24a2018fb53ac42c17b [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 Lattnerea39cba2009-07-27 16:27:32 +000061 if (Kind.isMergeableCString()) {
62 const TargetData *TD = TM.getTargetData();
63 Constant *C = cast<GlobalVariable>(GV)->getInitializer();
64 const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
65
66 unsigned Size = TD->getTypeAllocSize(Ty);
67 if (Size <= 16) {
68 assert(getCStringSection() && "Should have string section prefix");
69
70 // We also need alignment here.
71 // FIXME: this is getting the alignment of the character, not the
72 // alignment of the string!!
73 unsigned Align = TD->getPrefTypeAlignment(Ty);
74 if (Align < Size)
75 Align = Size;
76
77 std::string Name = getCStringSection() + utostr(Size) + '.' +
78 utostr(Align);
79 return getOrCreateSection(Name.c_str(), false,
80 SectionKind::MergeableCString);
81 }
82
83 return getReadOnlySection();
84 }
Chris Lattner2a7dd7d2009-07-26 06:11:33 +000085
Chris Lattner1c379242009-07-26 06:48:26 +000086 if (Kind.isMergeableConst()) {
87 if (Kind.isMergeableConst4())
88 return MergeableConst4Section;
89 if (Kind.isMergeableConst8())
90 return MergeableConst8Section;
91 if (Kind.isMergeableConst16())
92 return MergeableConst16Section;
Chris Lattner52954842009-07-26 06:16:11 +000093 return ReadOnlySection; // .const
Chris Lattnera06e19b2009-07-24 05:01:55 +000094 }
Chris Lattner52954842009-07-26 06:16:11 +000095
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +000096 if (Kind.isReadOnly()) return getReadOnlySection();
97
98
99 if (Kind.isThreadData()) return TLSDataSection;
100 if (Kind.isThreadBSS()) return TLSBSSSection;
101
102 if (Kind.isBSS()) return getBSSSection_();
103
104
105 if (Kind.isDataNoRel()) return DataSection;
106 if (Kind.isDataRelLocal()) return DataRelLocalSection;
107 if (Kind.isDataRel()) return DataRelSection;
108 if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
109
110 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
111 return DataRelROSection;
asle0d0f482008-07-19 13:14:11 +0000112}
113
Chris Lattner1c379242009-07-26 06:48:26 +0000114/// getSectionForMergeableConstant - Given a Mergeable constant with the
Chris Lattner680c6f62009-07-22 00:28:43 +0000115/// specified size and relocation information, return a section that it
116/// should be placed in.
117const Section *
Chris Lattner1c379242009-07-26 06:48:26 +0000118ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
Chris Lattnerfc60ba12009-07-26 06:26:55 +0000119 return SelectSectionForGlobal(0, Kind);
Anton Korobeynikovfc54db12008-08-07 09:50:34 +0000120}
121
Chris Lattnerdfd15982009-07-24 17:02:17 +0000122/// getFlagsForNamedSection - If this target wants to be able to infer
123/// section flags based on the name of the section specified for a global
124/// variable, it can implement this.
Chris Lattnerd8310522009-07-27 05:32:16 +0000125SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
126 SectionKind::Kind K) const {
127 if (Name[0] != '.') return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000128
129 // Some lame default implementation based on some magic section names.
130 if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
131 strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
132 strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
133 strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
Chris Lattnerd8310522009-07-27 05:32:16 +0000134 return SectionKind::BSS;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000135
Chris Lattnerd8310522009-07-27 05:32:16 +0000136 if (strcmp(Name, ".tdata") == 0 ||
137 strncmp(Name, ".tdata.", 7) == 0 ||
138 strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
139 strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
140 return SectionKind::ThreadData;
141
142 if (strcmp(Name, ".tbss") == 0 ||
143 strncmp(Name, ".tbss.", 6) == 0 ||
144 strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
145 strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
146 return SectionKind::ThreadBSS;
147
148 return K;
Chris Lattnerdfd15982009-07-24 17:02:17 +0000149}
150
Chris Lattner4c530ee2009-07-25 18:57:34 +0000151const char *
Chris Lattnercc195212009-07-25 23:21:55 +0000152ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{
Chris Lattnerdc9d8cf2009-07-26 05:44:20 +0000153 if (Kind.isText()) return ".gnu.linkonce.t.";
154 if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
155
156 if (Kind.isThreadData()) return ".gnu.linkonce.td.";
157 if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
158
159 if (Kind.isBSS()) return ".gnu.linkonce.b.";
160 if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
161 if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
162 if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
163 if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
164
165 assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
166 return ".gnu.linkonce.d.rel.ro.";
Chris Lattner4c530ee2009-07-25 18:57:34 +0000167}
168
169
Chris Lattnerd8310522009-07-27 05:32:16 +0000170void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
171 SmallVectorImpl<char> &Str) const {
Chris Lattner94d8a762009-07-26 07:33:58 +0000172 Str.push_back(',');
173 Str.push_back('"');
174
Chris Lattnerd8310522009-07-27 05:32:16 +0000175 if (!Kind.isMetadata())
Chris Lattner94d8a762009-07-26 07:33:58 +0000176 Str.push_back('a');
Chris Lattnerd8310522009-07-27 05:32:16 +0000177 if (Kind.isText())
Chris Lattner94d8a762009-07-26 07:33:58 +0000178 Str.push_back('x');
Chris Lattnerd8310522009-07-27 05:32:16 +0000179 if (Kind.isWriteable())
Chris Lattner94d8a762009-07-26 07:33:58 +0000180 Str.push_back('w');
Chris Lattnerd8310522009-07-27 05:32:16 +0000181 if (Kind.isMergeableConst() || Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +0000182 Str.push_back('M');
Chris Lattnerd8310522009-07-27 05:32:16 +0000183 if (Kind.isMergeableCString())
Chris Lattner94d8a762009-07-26 07:33:58 +0000184 Str.push_back('S');
Chris Lattnerd8310522009-07-27 05:32:16 +0000185 if (Kind.isThreadLocal())
Chris Lattner94d8a762009-07-26 07:33:58 +0000186 Str.push_back('T');
asle0d0f482008-07-19 13:14:11 +0000187
Chris Lattner94d8a762009-07-26 07:33:58 +0000188 Str.push_back('"');
189 Str.push_back(',');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000190
191 // If comment string is '@', e.g. as on ARM - use '%' instead
192 if (strcmp(CommentString, "@") == 0)
Chris Lattner94d8a762009-07-26 07:33:58 +0000193 Str.push_back('%');
Anton Korobeynikov4183e112008-08-07 09:55:06 +0000194 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000195 Str.push_back('@');
asle0d0f482008-07-19 13:14:11 +0000196
Chris Lattner94d8a762009-07-26 07:33:58 +0000197 const char *KindStr;
Chris Lattnerd8310522009-07-27 05:32:16 +0000198 if (Kind.isBSS())
Chris Lattner94d8a762009-07-26 07:33:58 +0000199 KindStr = "nobits";
asle0d0f482008-07-19 13:14:11 +0000200 else
Chris Lattner94d8a762009-07-26 07:33:58 +0000201 KindStr = "progbits";
202
203 Str.append(KindStr, KindStr+strlen(KindStr));
asle0d0f482008-07-19 13:14:11 +0000204
Chris Lattnerd8310522009-07-27 05:32:16 +0000205 if (Kind.isMergeableCString()) {
206 // TODO: Eventually handle multiple byte character strings. For now, all
207 // mergable C strings are single byte.
Chris Lattner94d8a762009-07-26 07:33:58 +0000208 Str.push_back(',');
Chris Lattnerd8310522009-07-27 05:32:16 +0000209 Str.push_back('1');
210 } else if (Kind.isMergeableConst4()) {
211 Str.push_back(',');
212 Str.push_back('4');
213 } else if (Kind.isMergeableConst8()) {
214 Str.push_back(',');
215 Str.push_back('8');
216 } else if (Kind.isMergeableConst16()) {
217 Str.push_back(',');
218 Str.push_back('1');
219 Str.push_back('6');
Chris Lattner94d8a762009-07-26 07:33:58 +0000220 }
asle0d0f482008-07-19 13:14:11 +0000221}