-/// EmitSectionTable - Now that we have emitted the entire contents of the file
-/// (all of the sections), emit the section table which informs the reader where
-/// the boundaries are.
-void ELFWriter::EmitSectionTable() {
- // Now that all of the sections have been emitted, set the e_shnum entry in
- // the ELF header.
- fixhalf(SectionList.size(), ELFHeader_e_shnum_Offset);
-
- // Now that we know the offset in the file of the section table (which we emit
- // next), update the e_shoff address in the ELF header.
- fixaddr(OutputBuffer.size(), ELFHeader_e_shoff_Offset);
-
- // Emit all of the section table entries.
- for (unsigned i = 0, e = SectionList.size(); i != e; ++i) {
- const ELFSection &S = SectionList[i];
- outword(S.NameIdx); // sh_name - Symbol table name idx
- outword(S.Type); // sh_type - Section contents & semantics
- outword(S.Flags); // sh_flags - Section flags.
- outaddr(S.Addr); // sh_addr - The mem address this section appears in.
- outaddr(S.Offset); // sh_offset - The offset from the start of the file.
- outword(S.Size); // sh_size - The section size.
- outword(S.Link); // sh_link - Section header table index link.
- outword(S.Info); // sh_info - Auxillary information.
- outword(S.Align); // sh_addralign - Alignment of section.
- outword(S.EntSize); // sh_entsize - Size of each entry in the section.
+/// OutputSectionsAndSectionTable - Now that we have constructed the file header
+/// and all of the sections, emit these to the ostream destination and emit the
+/// SectionTable.
+void ELFWriter::OutputSectionsAndSectionTable() {
+ // Pass #1: Compute the file offset for each section.
+ size_t FileOff = FileHeader.size(); // File header first.
+
+ // Emit all of the section data in order.
+ for (std::list<ELFSection>::iterator I = SectionList.begin(),
+ E = SectionList.end(); I != E; ++I) {
+ // Align FileOff to whatever the alignment restrictions of the section are.
+ if (I->Align)
+ FileOff = (FileOff+I->Align-1) & ~(I->Align-1);
+ I->Offset = FileOff;
+ FileOff += I->SectionData.size();
+ }
+
+ // Align Section Header.
+ unsigned TableAlign = is64Bit ? 8 : 4;
+ FileOff = (FileOff+TableAlign-1) & ~(TableAlign-1);
+
+ // Now that we know where all of the sections will be emitted, set the e_shnum
+ // entry in the ELF header.
+ OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
+ FHOut.fixhalf(NumSections, ELFHeader_e_shnum_Offset);
+
+ // Now that we know the offset in the file of the section table, update the
+ // e_shoff address in the ELF header.
+ FHOut.fixaddr(FileOff, ELFHeader_e_shoff_Offset);
+
+ // Now that we know all of the data in the file header, emit it and all of the
+ // sections!
+ O.write((char*)&FileHeader[0], FileHeader.size());
+ FileOff = FileHeader.size();
+ DataBuffer().swap(FileHeader);
+
+ DataBuffer Table;
+ OutputBuffer TableOut(Table, is64Bit, isLittleEndian);
+
+ // Emit all of the section data and build the section table itself.
+ while (!SectionList.empty()) {
+ const ELFSection &S = *SectionList.begin();
+
+ // Align FileOff to whatever the alignment restrictions of the section are.
+ if (S.Align)
+ for (size_t NewFileOff = (FileOff+S.Align-1) & ~(S.Align-1);
+ FileOff != NewFileOff; ++FileOff)
+ O.put((char)0xAB);
+ O.write((char*)&S.SectionData[0], S.SectionData.size());
+ FileOff += S.SectionData.size();
+
+ TableOut.outword(S.NameIdx); // sh_name - Symbol table name idx
+ TableOut.outword(S.Type); // sh_type - Section contents & semantics
+ TableOut.outword(S.Flags); // sh_flags - Section flags.
+ TableOut.outaddr(S.Addr); // sh_addr - The mem addr this section is in.
+ TableOut.outaddr(S.Offset); // sh_offset - Offset from the file start.
+ TableOut.outword(S.Size); // sh_size - The section size.
+ TableOut.outword(S.Link); // sh_link - Section header table index link.
+ TableOut.outword(S.Info); // sh_info - Auxillary information.
+ TableOut.outword(S.Align); // sh_addralign - Alignment of section.
+ TableOut.outword(S.EntSize); // sh_entsize - Size of entries in the section
+
+ SectionList.pop_front();