blob: dbb2ce30ca0ee69a3101c24a2018fb53ac42c17b [file] [log] [blame]
Anton Korobeynikovdebe34b2008-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 Korobeynikov93cacf12008-08-07 09:50:34 +000020#include "llvm/CodeGen/MachineConstantPool.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000021#include "llvm/Support/ErrorHandling.h"
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +000022#include "llvm/Target/ELFTargetAsmInfo.h"
23#include "llvm/Target/TargetMachine.h"
24#include "llvm/Target/TargetData.h"
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +000025using namespace llvm;
26
Dan Gohman8f092252008-11-03 18:22:42 +000027ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
28 : TargetAsmInfo(TM) {
Chris Lattner92ef3f62009-07-27 16:20:58 +000029
30 TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
31 DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
Chris Lattnere3466942009-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);
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +000037
Chris Lattnere3466942009-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 Lattnerf1532722009-07-26 06:16:11 +000047
Chris Lattnere3466942009-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);
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +000054}
55
Anton Korobeynikovfca82de2009-03-30 15:27:43 +000056
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +000057const Section*
Chris Lattnerf20f2502009-07-24 18:42:53 +000058ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
Chris Lattner460d51e2009-07-25 23:21:55 +000059 SectionKind Kind) const {
Chris Lattnere346e182009-07-26 05:44:20 +000060 if (Kind.isText()) return TextSection;
Chris Lattner33ae7a42009-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 Lattner8ca52092009-07-26 06:11:33 +000085
Chris Lattner2ceb60a2009-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 Lattnerf1532722009-07-26 06:16:11 +000093 return ReadOnlySection; // .const
Chris Lattner57743ef2009-07-24 05:01:55 +000094 }
Chris Lattnerf1532722009-07-26 06:16:11 +000095
Chris Lattnere346e182009-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;
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +0000112}
113
Chris Lattner2ceb60a2009-07-26 06:48:26 +0000114/// getSectionForMergeableConstant - Given a Mergeable constant with the
Chris Lattner298414e2009-07-22 00:28:43 +0000115/// specified size and relocation information, return a section that it
116/// should be placed in.
117const Section *
Chris Lattner2ceb60a2009-07-26 06:48:26 +0000118ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
Chris Lattner5c2f7892009-07-26 06:26:55 +0000119 return SelectSectionForGlobal(0, Kind);
Anton Korobeynikov93cacf12008-08-07 09:50:34 +0000120}
121
Chris Lattner2dcafe42009-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 Lattner5fe575f2009-07-27 05:32:16 +0000125SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
126 SectionKind::Kind K) const {
127 if (Name[0] != '.') return K;
Chris Lattner2dcafe42009-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 Lattner5fe575f2009-07-27 05:32:16 +0000134 return SectionKind::BSS;
Chris Lattner2dcafe42009-07-24 17:02:17 +0000135
Chris Lattner5fe575f2009-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 Lattner2dcafe42009-07-24 17:02:17 +0000149}
150
Chris Lattnerb4fc4192009-07-25 18:57:34 +0000151const char *
Chris Lattner460d51e2009-07-25 23:21:55 +0000152ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{
Chris Lattnere346e182009-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 Lattnerb4fc4192009-07-25 18:57:34 +0000167}
168
169
Chris Lattner5fe575f2009-07-27 05:32:16 +0000170void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
171 SmallVectorImpl<char> &Str) const {
Chris Lattnerf40761d2009-07-26 07:33:58 +0000172 Str.push_back(',');
173 Str.push_back('"');
174
Chris Lattner5fe575f2009-07-27 05:32:16 +0000175 if (!Kind.isMetadata())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000176 Str.push_back('a');
Chris Lattner5fe575f2009-07-27 05:32:16 +0000177 if (Kind.isText())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000178 Str.push_back('x');
Chris Lattner5fe575f2009-07-27 05:32:16 +0000179 if (Kind.isWriteable())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000180 Str.push_back('w');
Chris Lattner5fe575f2009-07-27 05:32:16 +0000181 if (Kind.isMergeableConst() || Kind.isMergeableCString())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000182 Str.push_back('M');
Chris Lattner5fe575f2009-07-27 05:32:16 +0000183 if (Kind.isMergeableCString())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000184 Str.push_back('S');
Chris Lattner5fe575f2009-07-27 05:32:16 +0000185 if (Kind.isThreadLocal())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000186 Str.push_back('T');
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +0000187
Chris Lattnerf40761d2009-07-26 07:33:58 +0000188 Str.push_back('"');
189 Str.push_back(',');
Anton Korobeynikovfeac94b2008-08-07 09:55:06 +0000190
191 // If comment string is '@', e.g. as on ARM - use '%' instead
192 if (strcmp(CommentString, "@") == 0)
Chris Lattnerf40761d2009-07-26 07:33:58 +0000193 Str.push_back('%');
Anton Korobeynikovfeac94b2008-08-07 09:55:06 +0000194 else
Chris Lattnerf40761d2009-07-26 07:33:58 +0000195 Str.push_back('@');
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +0000196
Chris Lattnerf40761d2009-07-26 07:33:58 +0000197 const char *KindStr;
Chris Lattner5fe575f2009-07-27 05:32:16 +0000198 if (Kind.isBSS())
Chris Lattnerf40761d2009-07-26 07:33:58 +0000199 KindStr = "nobits";
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +0000200 else
Chris Lattnerf40761d2009-07-26 07:33:58 +0000201 KindStr = "progbits";
202
203 Str.append(KindStr, KindStr+strlen(KindStr));
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +0000204
Chris Lattner5fe575f2009-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 Lattnerf40761d2009-07-26 07:33:58 +0000208 Str.push_back(',');
Chris Lattner5fe575f2009-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 Lattnerf40761d2009-07-26 07:33:58 +0000220 }
Anton Korobeynikovdebe34b2008-07-19 13:14:11 +0000221}