OLD | NEW |
---|---|
1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// | 1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines the writer for ELF relocatable object files. | 10 // This file defines the writer for ELF relocatable object files. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/Support/MathExtras.h" | |
15 | |
14 #include "assembler.h" | 16 #include "assembler.h" |
15 #include "IceDefs.h" | 17 #include "IceDefs.h" |
16 #include "IceELFObjectWriter.h" | 18 #include "IceELFObjectWriter.h" |
17 #include "IceELFSection.h" | 19 #include "IceELFSection.h" |
18 #include "IceELFStreamer.h" | 20 #include "IceELFStreamer.h" |
19 #include "IceGlobalContext.h" | 21 #include "IceGlobalContext.h" |
20 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
21 #include "IceOperand.h" | 23 #include "IceOperand.h" |
22 | 24 |
23 using namespace llvm::ELF; | 25 using namespace llvm::ELF; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, | 98 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, |
97 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, | 99 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
98 Elf64_Xword ShEntsize) { | 100 Elf64_Xword ShEntsize) { |
99 assert(!SectionNumbersAssigned); | 101 assert(!SectionNumbersAssigned); |
100 T *NewSection = | 102 T *NewSection = |
101 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); | 103 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); |
102 ShStrTab->add(Name); | 104 ShStrTab->add(Name); |
103 return NewSection; | 105 return NewSection; |
104 } | 106 } |
105 | 107 |
108 ELFRelocationSection * | |
109 ELFObjectWriter::createRelocationSection(bool IsELF64, | |
110 const ELFSection *RelatedSection) { | |
111 // Choice of RELA vs REL is actually separate from elf64 vs elf32, | |
112 // but in practice we've only had .rela for elf64 (x86-64). | |
113 // In the future, the two properties may need to be decoupled | |
114 // and the ShEntSize can vary more. | |
115 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; | |
116 IceString RelPrefix = IsELF64 ? ".rela" : ".rel"; | |
117 IceString RelSectionName = RelPrefix + RelatedSection->getName(); | |
118 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; | |
119 const Elf64_Xword ShEntSize = | |
120 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | |
121 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | |
122 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | |
123 const Elf64_Xword ShFlags = 0; | |
124 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( | |
125 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | |
126 RelSection->setRelatedSection(RelatedSection); | |
127 return RelSection; | |
128 } | |
129 | |
106 template <typename UserSectionList> | 130 template <typename UserSectionList> |
107 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, | 131 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, |
108 UserSectionList &UserSections, | 132 UserSectionList &UserSections, |
109 RelSectionList &RelSections, | 133 RelSectionList &RelSections, |
110 SectionList &AllSections) { | 134 SectionList &AllSections) { |
111 RelSectionList::iterator RelIt = RelSections.begin(); | 135 RelSectionList::iterator RelIt = RelSections.begin(); |
112 RelSectionList::iterator RelE = RelSections.end(); | 136 RelSectionList::iterator RelE = RelSections.end(); |
113 for (ELFSection *UserSection : UserSections) { | 137 for (ELFSection *UserSection : UserSections) { |
114 UserSection->setNumber(CurSectionNumber++); | 138 UserSection->setNumber(CurSectionNumber++); |
115 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); | 139 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); |
(...skipping 27 matching lines...) Expand all Loading... | |
143 assert(!SectionNumbersAssigned); | 167 assert(!SectionNumbersAssigned); |
144 SizeT CurSectionNumber = 0; | 168 SizeT CurSectionNumber = 0; |
145 NullSection->setNumber(CurSectionNumber++); | 169 NullSection->setNumber(CurSectionNumber++); |
146 // The rest of the fields are initialized to 0, and stay that way. | 170 // The rest of the fields are initialized to 0, and stay that way. |
147 AllSections.push_back(NullSection); | 171 AllSections.push_back(NullSection); |
148 | 172 |
149 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, | 173 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, |
150 RelTextSections, AllSections); | 174 RelTextSections, AllSections); |
151 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, | 175 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, |
152 RelDataSections, AllSections); | 176 RelDataSections, AllSections); |
153 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RoDataSections, | 177 for (ELFSection *BSSSection : BSSSections) { |
154 RelRoDataSections, AllSections); | 178 BSSSection->setNumber(CurSectionNumber++); |
179 BSSSection->setNameStrIndex(ShStrTab->getIndex(BSSSection->getName())); | |
180 AllSections.push_back(BSSSection); | |
181 } | |
182 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RODataSections, | |
183 RelRODataSections, AllSections); | |
155 | 184 |
156 ShStrTab->setNumber(CurSectionNumber++); | 185 ShStrTab->setNumber(CurSectionNumber++); |
157 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); | 186 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); |
158 AllSections.push_back(ShStrTab); | 187 AllSections.push_back(ShStrTab); |
159 | 188 |
160 SymTab->setNumber(CurSectionNumber++); | 189 SymTab->setNumber(CurSectionNumber++); |
161 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); | 190 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); |
162 AllSections.push_back(SymTab); | 191 AllSections.push_back(SymTab); |
163 | 192 |
164 StrTab->setNumber(CurSectionNumber++); | 193 StrTab->setNumber(CurSectionNumber++); |
165 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); | 194 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); |
166 AllSections.push_back(StrTab); | 195 AllSections.push_back(StrTab); |
167 | 196 |
168 SymTab->setLinkNum(StrTab->getNumber()); | 197 SymTab->setLinkNum(StrTab->getNumber()); |
169 SymTab->setInfoNum(SymTab->getNumLocals()); | 198 SymTab->setInfoNum(SymTab->getNumLocals()); |
170 | 199 |
171 assignRelLinkNum(SymTab->getNumber(), RelTextSections); | 200 assignRelLinkNum(SymTab->getNumber(), RelTextSections); |
172 assignRelLinkNum(SymTab->getNumber(), RelDataSections); | 201 assignRelLinkNum(SymTab->getNumber(), RelDataSections); |
173 assignRelLinkNum(SymTab->getNumber(), RelRoDataSections); | 202 assignRelLinkNum(SymTab->getNumber(), RelRODataSections); |
174 SectionNumbersAssigned = true; | 203 SectionNumbersAssigned = true; |
175 } | 204 } |
176 | 205 |
177 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { | 206 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { |
178 assert(llvm::isPowerOf2_32(Align)); | |
179 Elf64_Off OffsetInFile = Str.tell(); | 207 Elf64_Off OffsetInFile = Str.tell(); |
180 Elf64_Xword Mod = OffsetInFile & (Align - 1); | 208 Elf64_Xword AlignDiff = Utils::OffsetToAlignment(OffsetInFile, Align); |
181 if (Mod == 0) | 209 if (AlignDiff == 0) |
182 return OffsetInFile; | 210 return OffsetInFile; |
183 Elf64_Xword AlignDiff = Align - Mod; | |
184 Str.writeZeroPadding(AlignDiff); | 211 Str.writeZeroPadding(AlignDiff); |
185 OffsetInFile += AlignDiff; | 212 OffsetInFile += AlignDiff; |
186 assert((OffsetInFile & (Align - 1)) == 0); | |
187 return OffsetInFile; | 213 return OffsetInFile; |
188 } | 214 } |
189 | 215 |
190 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 216 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
191 bool IsInternal, const Assembler *Asm) { | 217 bool IsInternal, const Assembler *Asm) { |
192 assert(!SectionNumbersAssigned); | 218 assert(!SectionNumbersAssigned); |
193 ELFTextSection *Section = nullptr; | 219 ELFTextSection *Section = nullptr; |
194 // TODO(jvoung): handle ffunction-sections. | 220 ELFRelocationSection *RelSection = nullptr; |
195 IceString SectionName = ".text"; | 221 if (TextSections.empty()) { |
196 if (TextSections.size() == 0) { | 222 // TODO(jvoung): handle ffunction-sections. |
223 IceString SectionName = ".text"; | |
224 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 225 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
198 // TODO(jvoung): Should be bundle size. Grab it from that target? | 226 // TODO(jvoung): Should be bundle size. Grab it from that target? |
199 const Elf64_Xword ShAlign = 32; | 227 const Elf64_Xword ShAlign = 32; |
200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 228 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
201 ShAlign, 0); | 229 ShAlign, 0); |
202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 230 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
203 Section->setFileOffset(OffsetInFile); | 231 Section->setFileOffset(OffsetInFile); |
204 TextSections.push_back(Section); | 232 TextSections.push_back(Section); |
233 RelSection = createRelocationSection(IsELF64, Section); | |
234 RelTextSections.push_back(RelSection); | |
205 } else { | 235 } else { |
206 Section = TextSections[0]; | 236 Section = TextSections[0]; |
237 RelSection = RelTextSections[0]; | |
207 } | 238 } |
208 RelocOffsetT OffsetInSection = Section->getCurrentSize(); | 239 RelocOffsetT OffsetInSection = Section->getCurrentSize(); |
209 // Function symbols are set to 0 size in the symbol table, | 240 // Function symbols are set to 0 size in the symbol table, |
210 // in contrast to data symbols which have a proper size. | 241 // in contrast to data symbols which have a proper size. |
211 SizeT SymbolSize = 0; | 242 SizeT SymbolSize = 0; |
212 Section->appendData(Str, Asm->getBufferView()); | 243 Section->appendData(Str, Asm->getBufferView()); |
213 uint8_t SymbolType; | 244 uint8_t SymbolType; |
214 uint8_t SymbolBinding; | 245 uint8_t SymbolBinding; |
215 if (IsInternal) { | 246 if (IsInternal) { |
216 SymbolType = STT_NOTYPE; | 247 SymbolType = STT_NOTYPE; |
217 SymbolBinding = STB_LOCAL; | 248 SymbolBinding = STB_LOCAL; |
218 } else { | 249 } else { |
219 SymbolType = STT_FUNC; | 250 SymbolType = STT_FUNC; |
220 SymbolBinding = STB_GLOBAL; | 251 SymbolBinding = STB_GLOBAL; |
221 } | 252 } |
222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, | 253 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, |
223 OffsetInSection, SymbolSize); | 254 OffsetInSection, SymbolSize); |
224 StrTab->add(FuncName); | 255 StrTab->add(FuncName); |
225 | 256 |
226 // Create a relocation section for the text section if needed, and copy the | 257 // Create a relocation section for the text section if needed, and copy the |
227 // fixup information from per-function Assembler memory to the object | 258 // fixup information from per-function Assembler memory to the object |
228 // writer's memory, for writing later. | 259 // writer's memory, for writing later. |
229 if (!Asm->fixups().empty()) { | 260 if (!Asm->fixups().empty()) { |
230 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
231 IceString RelSectionName = IsELF64 ? ".rela" : ".rel"; | |
232 RelSectionName += SectionName; | |
233 ELFRelocationSection *RelSection = nullptr; | |
234 // TODO(jvoung): Make this more efficient if -ffunction-sections | |
235 // efficiency becomes a problem. | |
236 auto RSI = | |
237 std::find_if(RelTextSections.begin(), RelTextSections.end(), | |
238 [&RelSectionName](const ELFRelocationSection *S) | |
239 -> bool { return S->getName() == RelSectionName; }); | |
240 if (RSI != RelTextSections.end()) { | |
241 RelSection = *RSI; | |
242 } else { | |
243 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; | |
244 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; | |
245 const Elf64_Xword ShEntSize = | |
246 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | |
247 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | |
248 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | |
249 const Elf64_Xword ShFlags = 0; | |
250 RelSection = createSection<ELFRelocationSection>( | |
251 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | |
252 RelSection->setRelatedSection(Section); | |
253 RelTextSections.push_back(RelSection); | |
254 } | |
255 RelSection->addRelocations(OffsetInSection, Asm->fixups()); | 261 RelSection->addRelocations(OffsetInSection, Asm->fixups()); |
256 } | 262 } |
257 } | 263 } |
258 | 264 |
259 void ELFObjectWriter::writeDataInitializer(const IceString &VarName, | 265 namespace { |
260 const llvm::StringRef Data) { | 266 |
267 ELFObjectWriter::SectionType | |
268 classifyGlobalSection(const VariableDeclaration *Var) { | |
269 if (Var->getIsConstant()) | |
270 return ELFObjectWriter::ROData; | |
271 if (Var->hasNonzeroInitializer()) | |
272 return ELFObjectWriter::Data; | |
273 return ELFObjectWriter::BSS; | |
274 } | |
275 | |
276 // Partition the Vars list by SectionType into VarsBySection. | |
277 // If TranslateOnly is non-empty, then only the TranslateOnly variable | |
278 // is kept for emission. | |
279 void partitionGlobalsBySection(const VariableDeclarationList &Vars, | |
280 VariableDeclarationList VarsBySection[], | |
281 const IceString &TranslateOnly) { | |
282 for (VariableDeclaration *Var : Vars) { | |
283 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | |
284 size_t Section = classifyGlobalSection(Var); | |
285 assert(Section < ELFObjectWriter::SectionType::NumSectionTypes); | |
286 VarsBySection[Section].push_back(Var); | |
287 } | |
288 } | |
289 } | |
290 | |
291 } // end of anonymous namespace | |
292 | |
293 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, | |
294 FixupKind RelocationKind) { | |
261 assert(!SectionNumbersAssigned); | 295 assert(!SectionNumbersAssigned); |
262 (void)Data; | 296 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; |
263 llvm_unreachable("TODO"); | 297 for (auto &SectionList : VarsBySection) |
264 StrTab->add(VarName); | 298 SectionList.reserve(Vars.size()); |
299 partitionGlobalsBySection(Vars, VarsBySection, Ctx.getFlags().TranslateOnly); | |
300 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
301 for (size_t I = ELFObjectWriter::BaseSectionType; | |
Jim Stichnoth
2015/01/28 20:35:08
Consider doing something like this to make the sec
jvoung (off chromium)
2015/01/28 23:37:52
Done sort of -- If I is type SectionType, then I++
Jim Stichnoth
2015/01/29 00:38:14
BTW, JF pointed out this would be possible using a
| |
302 I < ELFObjectWriter::NumSectionTypes; ++I) { | |
303 writeDataOfType(static_cast<SectionType>(I), VarsBySection[I], | |
304 RelocationKind, IsELF64); | |
305 } | |
306 } | |
307 | |
308 void ELFObjectWriter::writeDataOfType(SectionType SectionType, | |
309 const VariableDeclarationList &Vars, | |
310 FixupKind RelocationKind, bool IsELF64) { | |
311 ELFDataSection *Section; | |
312 ELFRelocationSection *RelSection; | |
313 // TODO(jvoung): Handle fdata-sections. | |
314 IceString SectionName; | |
315 Elf64_Xword ShAddralign = 0; | |
316 for (auto *Var : Vars) { | |
Jim Stichnoth
2015/01/28 20:35:08
auto --> VariableDeclaration
jvoung (off chromium)
2015/01/28 23:37:53
Done.
| |
317 Elf64_Xword Align = Var->getAlignment(); | |
318 ShAddralign = std::max(ShAddralign, Align); | |
319 } | |
320 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. | |
321 // Lift this out, so it can be re-used if we do fdata-sections? | |
322 switch (SectionType) { | |
323 case SectionType::ROData: { | |
324 SectionName = ".rodata"; | |
325 // Only expecting to write the data sections all in one shot for now. | |
326 assert(RODataSections.empty()); | |
327 const Elf64_Xword ShFlags = SHF_ALLOC; | |
328 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | |
329 ShAddralign, ShEntsize); | |
330 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
331 RODataSections.push_back(Section); | |
332 RelSection = createRelocationSection(IsELF64, Section); | |
333 RelRODataSections.push_back(RelSection); | |
334 break; | |
335 } | |
336 case SectionType::Data: { | |
337 SectionName = ".data"; | |
338 assert(DataSections.empty()); | |
339 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | |
340 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | |
341 ShAddralign, ShEntsize); | |
342 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
343 DataSections.push_back(Section); | |
344 RelSection = createRelocationSection(IsELF64, Section); | |
345 RelDataSections.push_back(RelSection); | |
346 break; | |
347 } | |
348 case SectionType::BSS: { | |
349 SectionName = ".bss"; | |
350 assert(BSSSections.empty()); | |
351 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | |
352 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, | |
353 ShAddralign, ShEntsize); | |
354 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
355 BSSSections.push_back(Section); | |
356 break; | |
357 } | |
358 case SectionType::NumSectionTypes: | |
359 llvm::report_fatal_error("Unknown SectionType"); | |
360 break; | |
361 } | |
362 | |
363 const uint8_t SymbolType = STT_OBJECT; | |
364 for (auto *Var : Vars) { | |
Jim Stichnoth
2015/01/28 20:35:08
auto --> VariableDeclaration
jvoung (off chromium)
2015/01/28 23:37:53
Done.
| |
365 Elf64_Xword Align = Var->getAlignment(); | |
366 Section->padToAlignment(Str, Align); | |
367 SizeT SymbolSize = Var->getNumBytes(); | |
368 bool IsExternal = Var->isExternal() || Ctx.getFlags().DisableInternal; | |
369 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | |
370 IceString MangledName = Var->mangleName(&Ctx); | |
371 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, | |
372 Section->getCurrentSize(), SymbolSize); | |
373 StrTab->add(MangledName); | |
374 if (!Var->hasNonzeroInitializer()) { | |
375 assert(SectionType == SectionType::BSS || | |
376 SectionType == SectionType::ROData); | |
377 if (SectionType == SectionType::ROData) | |
378 Section->appendZeros(Str, SymbolSize); | |
379 else | |
380 Section->setSize(Section->getCurrentSize() + SymbolSize); | |
381 } else { | |
382 assert(SectionType != SectionType::BSS); | |
383 for (VariableDeclaration::Initializer *Init : Var->getInitializers()) { | |
384 switch (Init->getKind()) { | |
385 case VariableDeclaration::Initializer::DataInitializerKind: { | |
386 const auto Data = llvm::cast<VariableDeclaration::DataInitializer>( | |
387 Init)->getContents(); | |
388 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); | |
389 break; | |
390 } | |
391 case VariableDeclaration::Initializer::ZeroInitializerKind: | |
392 Section->appendZeros(Str, Init->getNumBytes()); | |
393 break; | |
394 case VariableDeclaration::Initializer::RelocInitializerKind: { | |
395 const auto Reloc = | |
396 llvm::cast<VariableDeclaration::RelocInitializer>(Init); | |
397 AssemblerFixup NewFixup; | |
398 NewFixup.set_position(Section->getCurrentSize()); | |
399 NewFixup.set_kind(RelocationKind); | |
400 const bool SuppressMangling = true; | |
401 NewFixup.set_value(Ctx.getConstantSym( | |
402 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), | |
403 SuppressMangling)); | |
404 RelSection->addRelocation(NewFixup); | |
405 Section->appendRelocationOffset(Str, RelSection->isRela(), | |
406 Reloc->getOffset()); | |
407 break; | |
408 } | |
409 } | |
410 } | |
411 } | |
412 } | |
265 } | 413 } |
266 | 414 |
267 void ELFObjectWriter::writeInitialELFHeader() { | 415 void ELFObjectWriter::writeInitialELFHeader() { |
268 assert(!SectionNumbersAssigned); | 416 assert(!SectionNumbersAssigned); |
269 const Elf64_Off DummySHOffset = 0; | 417 const Elf64_Off DummySHOffset = 0; |
270 const SizeT DummySHStrIndex = 0; | 418 const SizeT DummySHStrIndex = 0; |
271 const SizeT DummyNumSections = 0; | 419 const SizeT DummyNumSections = 0; |
272 if (isELF64(Ctx.getTargetArch())) { | 420 if (isELF64(Ctx.getTargetArch())) { |
273 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 421 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
274 DummyNumSections); | 422 DummyNumSections); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 // between entries. | 486 // between entries. |
339 assert(WriteAmt % Align == 0); | 487 assert(WriteAmt % Align == 0); |
340 // Check that we write the full PrimType. | 488 // Check that we write the full PrimType. |
341 assert(WriteAmt == sizeof(typename ConstType::PrimType)); | 489 assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
342 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | 490 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
343 std::string SecBuffer; | 491 std::string SecBuffer; |
344 llvm::raw_string_ostream SecStrBuf(SecBuffer); | 492 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
345 SecStrBuf << ".rodata.cst" << WriteAmt; | 493 SecStrBuf << ".rodata.cst" << WriteAmt; |
346 ELFDataSection *Section = createSection<ELFDataSection>( | 494 ELFDataSection *Section = createSection<ELFDataSection>( |
347 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); | 495 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
348 RoDataSections.push_back(Section); | 496 RODataSections.push_back(Section); |
349 SizeT OffsetInSection = 0; | 497 SizeT OffsetInSection = 0; |
350 // The symbol table entry doesn't need to know the defined symbol's | 498 // The symbol table entry doesn't need to know the defined symbol's |
351 // size since this is in a section with a fixed Entry Size. | 499 // size since this is in a section with a fixed Entry Size. |
352 const SizeT SymbolSize = 0; | 500 const SizeT SymbolSize = 0; |
353 Section->setFileOffset(alignFileOffset(Align)); | 501 Section->setFileOffset(alignFileOffset(Align)); |
354 | 502 |
355 // Write the data. | 503 // Write the data. |
356 for (Constant *C : Pool) { | 504 for (Constant *C : Pool) { |
357 auto Const = llvm::cast<ConstType>(C); | 505 auto Const = llvm::cast<ConstType>(C); |
358 std::string SymBuffer; | 506 std::string SymBuffer; |
(...skipping 16 matching lines...) Expand all Loading... | |
375 // We may need to instantiate constant pools for integers as well | 523 // We may need to instantiate constant pools for integers as well |
376 // if we do constant-pooling of large integers to remove them | 524 // if we do constant-pooling of large integers to remove them |
377 // from the instruction stream (fewer bytes controlled by an attacker). | 525 // from the instruction stream (fewer bytes controlled by an attacker). |
378 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); | 526 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
379 | 527 |
380 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); | 528 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
381 | 529 |
382 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { | 530 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { |
383 writeRelocationSections(IsELF64, RelTextSections); | 531 writeRelocationSections(IsELF64, RelTextSections); |
384 writeRelocationSections(IsELF64, RelDataSections); | 532 writeRelocationSections(IsELF64, RelDataSections); |
385 writeRelocationSections(IsELF64, RelRoDataSections); | 533 writeRelocationSections(IsELF64, RelRODataSections); |
386 } | 534 } |
387 | 535 |
388 void ELFObjectWriter::writeRelocationSections(bool IsELF64, | 536 void ELFObjectWriter::writeRelocationSections(bool IsELF64, |
389 RelSectionList &RelSections) { | 537 RelSectionList &RelSections) { |
390 for (ELFRelocationSection *RelSec : RelSections) { | 538 for (ELFRelocationSection *RelSec : RelSections) { |
391 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); | 539 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); |
392 RelSec->setFileOffset(Offset); | 540 RelSec->setFileOffset(Offset); |
393 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); | 541 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); |
394 if (IsELF64) { | 542 if (IsELF64) { |
395 RelSec->writeData<true>(Ctx, Str, SymTab); | 543 RelSec->writeData<true>(Ctx, Str, SymTab); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 if (IsELF64) { | 592 if (IsELF64) { |
445 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 593 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
446 AllSections.size()); | 594 AllSections.size()); |
447 } else { | 595 } else { |
448 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 596 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
449 AllSections.size()); | 597 AllSections.size()); |
450 } | 598 } |
451 } | 599 } |
452 | 600 |
453 } // end of namespace Ice | 601 } // end of namespace Ice |
OLD | NEW |