Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: src/IceELFObjectWriter.cpp

Issue 828873002: Subzero: Start writing out some relocation sections (text) (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: review fixes Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceELFObjectWriter.h ('k') | src/IceELFSection.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "assembler.h"
14 #include "IceDefs.h" 15 #include "IceDefs.h"
15 #include "IceELFObjectWriter.h" 16 #include "IceELFObjectWriter.h"
16 #include "IceELFSection.h" 17 #include "IceELFSection.h"
17 #include "IceELFStreamer.h" 18 #include "IceELFStreamer.h"
18 #include "IceGlobalContext.h" 19 #include "IceGlobalContext.h"
19 #include "IceGlobalInits.h" 20 #include "IceGlobalInits.h"
20 #include "IceOperand.h" 21 #include "IceOperand.h"
21 22
22 using namespace llvm::ELF; 23 using namespace llvm::ELF;
23 24
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 UserSectionList &UserSections, 108 UserSectionList &UserSections,
108 RelSectionList &RelSections, 109 RelSectionList &RelSections,
109 SectionList &AllSections) { 110 SectionList &AllSections) {
110 RelSectionList::iterator RelIt = RelSections.begin(); 111 RelSectionList::iterator RelIt = RelSections.begin();
111 RelSectionList::iterator RelE = RelSections.end(); 112 RelSectionList::iterator RelE = RelSections.end();
112 for (ELFSection *UserSection : UserSections) { 113 for (ELFSection *UserSection : UserSections) {
113 UserSection->setNumber(CurSectionNumber++); 114 UserSection->setNumber(CurSectionNumber++);
114 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); 115 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName()));
115 AllSections.push_back(UserSection); 116 AllSections.push_back(UserSection);
116 if (RelIt != RelE) { 117 if (RelIt != RelE) {
117 ELFRelocationSectionBase *RelSection = *RelIt; 118 ELFRelocationSection *RelSection = *RelIt;
118 if (RelSection->getRelatedSection() == UserSection) { 119 if (RelSection->getRelatedSection() == UserSection) {
119 RelSection->setInfoNum(UserSection->getNumber()); 120 RelSection->setInfoNum(UserSection->getNumber());
120 RelSection->setNumber(CurSectionNumber++); 121 RelSection->setNumber(CurSectionNumber++);
121 RelSection->setNameStrIndex(ShStrTab->getIndex(RelSection->getName())); 122 RelSection->setNameStrIndex(ShStrTab->getIndex(RelSection->getName()));
122 AllSections.push_back(RelSection); 123 AllSections.push_back(RelSection);
123 ++RelIt; 124 ++RelIt;
124 } 125 }
125 } 126 }
126 } 127 }
127 // Should finish with UserIt at the same time as RelIt. 128 // Should finish with UserIt at the same time as RelIt.
128 assert(RelIt == RelE); 129 assert(RelIt == RelE);
129 return; 130 return;
130 } 131 }
131 132
132 void ELFObjectWriter::assignRelLinkNum(SizeT SymTabNumber, 133 void ELFObjectWriter::assignRelLinkNum(SizeT SymTabNumber,
133 RelSectionList &RelSections) { 134 RelSectionList &RelSections) {
134 for (ELFRelocationSectionBase *S : RelSections) { 135 for (ELFRelocationSection *S : RelSections) {
135 S->setLinkNum(SymTabNumber); 136 S->setLinkNum(SymTabNumber);
136 } 137 }
137 } 138 }
138 139
139 void ELFObjectWriter::assignSectionNumbersInfo(SectionList &AllSections) { 140 void ELFObjectWriter::assignSectionNumbersInfo(SectionList &AllSections) {
140 // Go through each section, assigning them section numbers and 141 // Go through each section, assigning them section numbers and
141 // and fill in the size for sections that aren't incrementally updated. 142 // and fill in the size for sections that aren't incrementally updated.
142 assert(!SectionNumbersAssigned); 143 assert(!SectionNumbersAssigned);
143 SizeT CurSectionNumber = 0; 144 SizeT CurSectionNumber = 0;
144 NullSection->setNumber(CurSectionNumber++); 145 NullSection->setNumber(CurSectionNumber++);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 if (Mod == 0) 181 if (Mod == 0)
181 return OffsetInFile; 182 return OffsetInFile;
182 Elf64_Xword AlignDiff = Align - Mod; 183 Elf64_Xword AlignDiff = Align - Mod;
183 Str.writeZeroPadding(AlignDiff); 184 Str.writeZeroPadding(AlignDiff);
184 OffsetInFile += AlignDiff; 185 OffsetInFile += AlignDiff;
185 assert((OffsetInFile & (Align - 1)) == 0); 186 assert((OffsetInFile & (Align - 1)) == 0);
186 return OffsetInFile; 187 return OffsetInFile;
187 } 188 }
188 189
189 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, 190 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName,
190 bool IsInternal, 191 bool IsInternal, const Assembler *Asm) {
191 const llvm::StringRef Data) {
192 assert(!SectionNumbersAssigned); 192 assert(!SectionNumbersAssigned);
193 ELFTextSection *Section = nullptr;
193 // TODO(jvoung): handle ffunction-sections. 194 // TODO(jvoung): handle ffunction-sections.
194 IceString SectionName = ".text"; 195 IceString SectionName = ".text";
195 ELFTextSection *Section = nullptr;
196 if (TextSections.size() == 0) { 196 if (TextSections.size() == 0) {
197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; 197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR;
198 // TODO(jvoung): Should be bundle size. Grab it from that target? 198 // TODO(jvoung): Should be bundle size. Grab it from that target?
199 const Elf64_Xword ShAlign = 32; 199 const Elf64_Xword ShAlign = 32;
200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, 200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags,
201 ShAlign, 0); 201 ShAlign, 0);
202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); 202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign());
203 Section->setFileOffset(OffsetInFile); 203 Section->setFileOffset(OffsetInFile);
204 TextSections.push_back(Section); 204 TextSections.push_back(Section);
205 } else { 205 } else {
206 Section = TextSections[0]; 206 Section = TextSections[0];
207 } 207 }
208 RelocOffsetT OffsetInSection = Section->getCurrentSize(); 208 RelocOffsetT OffsetInSection = Section->getCurrentSize();
209 // Function symbols are set to 0 size in the symbol table, 209 // Function symbols are set to 0 size in the symbol table,
210 // in contrast to data symbols which have a proper size. 210 // in contrast to data symbols which have a proper size.
211 SizeT SymbolSize = 0; 211 SizeT SymbolSize = 0;
212 Section->appendData(Str, Data); 212 Section->appendData(Str, Asm->getBufferView());
213 uint8_t SymbolType; 213 uint8_t SymbolType;
214 uint8_t SymbolBinding; 214 uint8_t SymbolBinding;
215 if (IsInternal) { 215 if (IsInternal) {
216 SymbolType = STT_NOTYPE; 216 SymbolType = STT_NOTYPE;
217 SymbolBinding = STB_LOCAL; 217 SymbolBinding = STB_LOCAL;
218 } else { 218 } else {
219 SymbolType = STT_FUNC; 219 SymbolType = STT_FUNC;
220 SymbolBinding = STB_GLOBAL; 220 SymbolBinding = STB_GLOBAL;
221 } 221 }
222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, 222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section,
223 OffsetInSection, SymbolSize); 223 OffsetInSection, SymbolSize);
224 StrTab->add(FuncName); 224 StrTab->add(FuncName);
225
226 // Create a relocation section for the text section if needed, and copy the
227 // fixup information from per-function Assembler memory to the object
228 // writer's memory, for writing later.
229 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());
256 }
225 } 257 }
226 258
227 void ELFObjectWriter::writeDataInitializer(const IceString &VarName, 259 void ELFObjectWriter::writeDataInitializer(const IceString &VarName,
228 const llvm::StringRef Data) { 260 const llvm::StringRef Data) {
229 assert(!SectionNumbersAssigned); 261 assert(!SectionNumbersAssigned);
230 (void)Data; 262 (void)Data;
231 llvm_unreachable("TODO"); 263 llvm_unreachable("TODO");
232 StrTab->add(VarName); 264 StrTab->add(VarName);
233 } 265 }
234 266
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 372
341 // Instantiate known needed versions of the template, since we are 373 // Instantiate known needed versions of the template, since we are
342 // defining the function in the .cpp file instead of the .h file. 374 // defining the function in the .cpp file instead of the .h file.
343 // We may need to instantiate constant pools for integers as well 375 // We may need to instantiate constant pools for integers as well
344 // if we do constant-pooling of large integers to remove them 376 // if we do constant-pooling of large integers to remove them
345 // from the instruction stream (fewer bytes controlled by an attacker). 377 // from the instruction stream (fewer bytes controlled by an attacker).
346 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); 378 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty);
347 379
348 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); 380 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty);
349 381
382 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) {
383 writeRelocationSections(IsELF64, RelTextSections);
384 writeRelocationSections(IsELF64, RelDataSections);
385 writeRelocationSections(IsELF64, RelRoDataSections);
386 }
387
388 void ELFObjectWriter::writeRelocationSections(bool IsELF64,
389 RelSectionList &RelSections) {
390 for (ELFRelocationSection *RelSec : RelSections) {
391 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign());
392 RelSec->setFileOffset(Offset);
393 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab));
394 if (IsELF64) {
395 RelSec->writeData<true>(Ctx, Str, SymTab);
396 } else {
397 RelSec->writeData<false>(Ctx, Str, SymTab);
398 }
399 }
400 }
401
350 void ELFObjectWriter::writeNonUserSections() { 402 void ELFObjectWriter::writeNonUserSections() {
351 bool IsELF64 = isELF64(Ctx.getTargetArch()); 403 bool IsELF64 = isELF64(Ctx.getTargetArch());
352 404
353 // Write out the shstrtab now that all sections are known. 405 // Write out the shstrtab now that all sections are known.
354 ShStrTab->doLayout(); 406 ShStrTab->doLayout();
355 ShStrTab->setSize(ShStrTab->getSectionDataSize()); 407 ShStrTab->setSize(ShStrTab->getSectionDataSize());
356 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); 408 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign());
357 ShStrTab->setFileOffset(ShStrTabOffset); 409 ShStrTab->setFileOffset(ShStrTabOffset);
358 Str.writeBytes(ShStrTab->getSectionData()); 410 Str.writeBytes(ShStrTab->getSectionData());
359 411
360 SectionList AllSections; 412 SectionList AllSections;
361 assignSectionNumbersInfo(AllSections); 413 assignSectionNumbersInfo(AllSections);
362 414
363 // Finalize the regular StrTab and fix up references in the SymTab. 415 // Finalize the regular StrTab and fix up references in the SymTab.
364 StrTab->doLayout(); 416 StrTab->doLayout();
365 StrTab->setSize(StrTab->getSectionDataSize()); 417 StrTab->setSize(StrTab->getSectionDataSize());
366 418
367 SymTab->updateIndices(StrTab); 419 SymTab->updateIndices(StrTab);
368 420
369 Elf64_Off SymTabOffset = alignFileOffset(SymTab->getSectionAlign()); 421 Elf64_Off SymTabOffset = alignFileOffset(SymTab->getSectionAlign());
370 SymTab->setFileOffset(SymTabOffset); 422 SymTab->setFileOffset(SymTabOffset);
371 SymTab->setSize(SymTab->getSectionDataSize()); 423 SymTab->setSize(SymTab->getSectionDataSize());
372 SymTab->writeData(Str, IsELF64); 424 SymTab->writeData(Str, IsELF64);
373 425
374 Elf64_Off StrTabOffset = alignFileOffset(StrTab->getSectionAlign()); 426 Elf64_Off StrTabOffset = alignFileOffset(StrTab->getSectionAlign());
375 StrTab->setFileOffset(StrTabOffset); 427 StrTab->setFileOffset(StrTabOffset);
376 Str.writeBytes(StrTab->getSectionData()); 428 Str.writeBytes(StrTab->getSectionData());
377 429
378 // TODO: Write out the relocation sections. 430 writeAllRelocationSections(IsELF64);
379 // May also be able to seek around the file and resolve function calls
380 // that are for functions within the same section.
381 431
382 // Write out the section headers. 432 // Write out the section headers.
383 const size_t ShdrAlign = IsELF64 ? 8 : 4; 433 const size_t ShdrAlign = IsELF64 ? 8 : 4;
384 Elf64_Off ShOffset = alignFileOffset(ShdrAlign); 434 Elf64_Off ShOffset = alignFileOffset(ShdrAlign);
385 for (const auto S : AllSections) { 435 for (const auto S : AllSections) {
386 if (IsELF64) 436 if (IsELF64)
387 S->writeHeader<true>(Str); 437 S->writeHeader<true>(Str);
388 else 438 else
389 S->writeHeader<false>(Str); 439 S->writeHeader<false>(Str);
390 } 440 }
391 441
392 // Finally write the updated ELF header w/ the correct number of sections. 442 // Finally write the updated ELF header w/ the correct number of sections.
393 Str.seek(0); 443 Str.seek(0);
394 if (IsELF64) { 444 if (IsELF64) {
395 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), 445 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(),
396 AllSections.size()); 446 AllSections.size());
397 } else { 447 } else {
398 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), 448 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(),
399 AllSections.size()); 449 AllSections.size());
400 } 450 }
401 } 451 }
402 452
403 } // end of namespace Ice 453 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceELFObjectWriter.h ('k') | src/IceELFSection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698