static void MapPrescanBytes(const Section& sect, const BinSection& bsd, int* bytes) { while (!bsd.length.isOkSize(*bytes * 8, 0, 0)) *bytes *= 2; while (!sect.getLMA().isOkSize(*bytes * 8, 0, 0)) *bytes *= 2; while (!sect.getVMA().isOkSize(*bytes * 8, 0, 0)) *bytes *= 2; }
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 XdfObject::DirSection(DirectiveInfo& info, Diagnostic& diags) { assert(info.isObject(m_object)); NameValues& nvs = info.getNameValues(); NameValue& sectname_nv = nvs.front(); if (!sectname_nv.isString()) { diags.Report(sectname_nv.getValueRange().getBegin(), diag::err_value_string_or_id); return; } llvm::StringRef sectname = sectname_nv.getString(); Section* sect = m_object.FindSection(sectname); bool first = true; if (sect) first = sect->isDefault(); else sect = AppendSection(sectname, info.getSource(), diags); XdfSection* xsect = sect->getAssocData<XdfSection>(); assert(xsect != 0); m_object.setCurSection(sect); sect->setDefault(false); if (xsect->bits != 0) m_object.getArch()->setVar("mode_bits", xsect->bits); // reapply // No name/values, so nothing more to do if (nvs.size() <= 1) return; // Ignore flags if we've seen this section before if (!first) { diags.Report(info.getSource(), diag::warn_section_redef_flags); return; } // Parse section flags IntNum align; bool has_align = false; unsigned long bss = sect->isBSS(); unsigned long code = sect->isCode(); IntNum vma = sect->getVMA(); IntNum lma = sect->getLMA(); unsigned long flat = xsect->flat; DirHelpers helpers; helpers.Add("use16", false, TR1::bind(&DirResetFlag, _1, _2, &xsect->bits, 16)); helpers.Add("use32", false, TR1::bind(&DirResetFlag, _1, _2, &xsect->bits, 32)); helpers.Add("use64", false, TR1::bind(&DirResetFlag, _1, _2, &xsect->bits, 64)); helpers.Add("bss", false, TR1::bind(&DirSetFlag, _1, _2, &bss, 1)); helpers.Add("nobss", false, TR1::bind(&DirClearFlag, _1, _2, &bss, 1)); helpers.Add("code", false, TR1::bind(&DirSetFlag, _1, _2, &code, 1)); helpers.Add("data", false, TR1::bind(&DirClearFlag, _1, _2, &code, 1)); helpers.Add("flat", false, TR1::bind(&DirSetFlag, _1, _2, &flat, 1)); helpers.Add("noflat", false, TR1::bind(&DirClearFlag, _1, _2, &flat, 1)); helpers.Add("absolute", true, TR1::bind(&DirIntNum, _1, _2, &m_object, &lma, &xsect->has_addr)); helpers.Add("virtual", true, TR1::bind(&DirIntNum, _1, _2, &m_object, &vma, &xsect->has_vaddr)); helpers.Add("align", true, TR1::bind(&DirIntNumPower2, _1, _2, &m_object, &align, &has_align)); helpers(++nvs.begin(), nvs.end(), info.getSource(), diags, DirNameValueWarn); if (has_align) { unsigned long aligni = align.getUInt(); // Check to see if alignment is supported size // FIXME: Use actual value source location if (aligni > 4096) { diags.Report(info.getSource(), diags.getCustomDiagID(Diagnostic::Error, "XDF does not support alignments > 4096")); } sect->setAlign(aligni); } sect->setBSS(bss); sect->setCode(code); sect->setVMA(vma); sect->setLMA(lma); xsect->flat = flat; if (xsect->bits != 0) m_object.getArch()->setVar("mode_bits", xsect->bits); }