void BinOutput::OutputSection(Section& sect, const IntNum& origin) { BytecodeOutput* outputter; if (sect.isBSS()) { outputter = &m_no_output; } else { IntNum file_start = sect.getLMA(); file_start -= origin; if (file_start.getSign() < 0) { Diag(SourceLocation(), diag::err_section_before_origin) << sect.getName(); return; } if (!file_start.isOkSize(sizeof(unsigned long)*8, 0, 0)) { Diag(SourceLocation(), diag::err_start_too_large) << sect.getName(); return; } m_fd_os.seek(file_start.getUInt()); if (m_os.has_error()) { Diag(SourceLocation(), diag::err_file_output_seek); return; } outputter = this; } for (Section::bc_iterator i=sect.bytecodes_begin(), end=sect.bytecodes_end(); i != end; ++i) { i->Output(*outputter); } }
void XdfOutput::OutputSection(Section& sect) { BytecodeOutput* outputter = this; XdfSection* xsect = sect.getAssocData<XdfSection>(); assert(xsect != NULL); uint64_t pos; if (sect.isBSS()) { // Don't output BSS sections. outputter = &m_no_output; pos = 0; // position = 0 because it's not in the file } else { pos = m_os.tell(); if (m_os.has_error()) { Diag(SourceLocation(), diag::err_file_output_position); return; } } // Output bytecodes xsect->size = 0; for (Section::bc_iterator i=sect.bytecodes_begin(), end=sect.bytecodes_end(); i != end; ++i) { if (i->Output(*outputter)) xsect->size += i->getTotalLen(); } // Sanity check final section size assert(xsect->size == sect.bytecodes_back().getNextOffset()); // Empty? Go on to next section if (xsect->size == 0) return; sect.setFilePos(static_cast<unsigned long>(pos)); // No relocations to output? Go on to next section if (sect.getRelocs().size() == 0) return; pos = m_os.tell(); if (m_os.has_error()) { Diag(SourceLocation(), diag::err_file_output_position); return; } xsect->relptr = static_cast<unsigned long>(pos); for (Section::const_reloc_iterator i=sect.relocs_begin(), end=sect.relocs_end(); i != end; ++i) { const XdfReloc& reloc = static_cast<const XdfReloc&>(*i); Bytes& scratch = getScratch(); reloc.Write(scratch); assert(scratch.size() == RELOC_SIZE); m_os << scratch; } }