static int do_assemble(SourceManager& source_mgr, DiagnosticsEngine& diags) { // Apply warning settings ApplyWarningSettings(diags); // Determine objfmt_bits based on -32 and -64 options std::string objfmt_bits = GetBitsSetting(); FileManager& file_mgr = source_mgr.getFileManager(); Assembler assembler("x86", YGAS_OBJFMT_BASE + objfmt_bits, diags, dump_object); HeaderSearch headers(file_mgr); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Set object filename if specified. if (!obj_filename.empty()) assembler.setObjectFilename(obj_filename); // Set parser. assembler.setParser("gas", diags); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Set debug format to dwarf2pass if it's legal for this object format. if (assembler.isOkDebugFormat("dwarf2pass")) { assembler.setDebugFormat("dwarf2pass", diags); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; } // open the input file or STDIN (for filename of "-") if (in_filename == "-") { OwningPtr<MemoryBuffer> my_stdin; if (llvm::error_code err = MemoryBuffer::getSTDIN(my_stdin)) { diags.Report(SourceLocation(), diag::fatal_file_open) << in_filename << err.message(); return EXIT_FAILURE; } source_mgr.createMainFileIDForMemBuffer(my_stdin.take()); } else { const FileEntry* in = file_mgr.getFile(in_filename); if (!in) { diags.Report(SourceLocation(), diag::fatal_file_open) << in_filename; return EXIT_FAILURE; } source_mgr.createMainFileID(in); } // Initialize the object. if (!assembler.InitObject(source_mgr, diags)) return EXIT_FAILURE; // Configure object per command line parameters. ConfigureObject(*assembler.getObject()); // Predefine symbols. for (std::vector<std::string>::const_iterator i=defsym.begin(), end=defsym.end(); i != end; ++i) { StringRef str(*i); size_t equalpos = str.find('='); if (equalpos == StringRef::npos) { diags.Report(diag::fatal_bad_defsym) << str; continue; } StringRef name = str.slice(0, equalpos); StringRef vstr = str.slice(equalpos+1, StringRef::npos); IntNum value; if (!vstr.empty()) { // determine radix unsigned int radix; if (vstr[0] == '0' && vstr.size() > 1 && (vstr[1] == 'x' || vstr[1] == 'X')) { vstr = vstr.substr(2); radix = 16; } else if (vstr[0] == '0') { vstr = vstr.substr(1); radix = 8; } else radix = 10; // check validity const char* ptr = vstr.begin(); const char* end = vstr.end(); if (radix == 16) { while (ptr != end && isxdigit(*ptr)) ++ptr; } else if (radix == 8) { while (ptr != end && (*ptr >= '0' && *ptr <= '7')) ++ptr; } else { while (ptr != end && isdigit(*ptr)) ++ptr; } if (ptr != end) { diags.Report(diag::fatal_bad_defsym) << name; continue; } value.setStr(vstr, radix); } // define equ assembler.getObject()->getSymbol(name)->DefineEqu(Expr(value)); } if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Initialize the parser. assembler.InitParser(source_mgr, diags, headers); // Assemble the input. if (!assembler.Assemble(source_mgr, diags)) { // An error occurred during assembly. return EXIT_FAILURE; } // open the object file for output std::string err; raw_fd_ostream out(assembler.getObjectFilename().str().c_str(), err, raw_fd_ostream::F_Binary); if (!err.empty()) { diags.Report(SourceLocation(), diag::err_cannot_open_file) << obj_filename << err; return EXIT_FAILURE; } if (!assembler.Output(out, diags)) { // An error occurred during output. // If we had an error at this point, we also need to delete the output // object file (to make sure it's not left newer than the source). out.close(); remove(assembler.getObjectFilename().str().c_str()); return EXIT_FAILURE; } // close object file out.close(); return EXIT_SUCCESS; }