#include "Builders.h" #include "coff.h" String MaxLenString(const byte *b, int maxlen) { const byte *e = b + maxlen; while(e > b && e[-1] == 0) e--; return String(b, int(e - b)); } String COFFSymbolName(const COFF_IMAGE_SYMBOL& sym, const char *strtbl) { String name; if(sym.N.Name.Short) name = MaxLenString(sym.N.ShortName, 8); else name = strtbl + sym.N.Name.Long; return name; } #ifdef PLATFORM_WIN32 static bool HasTail(String s, const char *tail) { int tl = (int)strlen(tail); int sl = s.GetLength(); if(sl < tl) return false; for(const char *p = s.GetIter(sl - tl); *p; p++, tail++) if(*tail != '*' && *tail != *p) return false; return *tail == 0; } #endif static void AddObjectExports(const char *path, Index& out) { #ifdef PLATFORM_WIN32 FileMapping mapping; if(!mapping.Open(path)) return; const byte *begin = mapping.Begin(); if(!begin) return; const COFF_IMAGE_FILE_HEADER *hdr = (const COFF_IMAGE_FILE_HEADER *)begin; if(hdr->Machine != COFF_IMAGE_FILE_MACHINE_I386) return; const COFF_IMAGE_SECTION_HEADER *sechdr = (const COFF_IMAGE_SECTION_HEADER *)(begin + sizeof(COFF_IMAGE_FILE_HEADER) + hdr->SizeOfOptionalHeader); Index code_sections; for(int i = 0; i < hdr->NumberOfSections; i++) if(sechdr[i].Characteristics & COFF_IMAGE_SCN_CNT_CODE) code_sections.Add(i + 1); const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + hdr->PointerToSymbolTable); const char *strtbl = (const char *)(symtbl + hdr->NumberOfSymbols); for(int i = 0; i < (int)hdr->NumberOfSymbols; i++) { const COFF_IMAGE_SYMBOL& sym = symtbl[i]; if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL && code_sections.Find(sym.SectionNumber) >= 0) { String name = COFFSymbolName(sym, strtbl); if(!HasTail(name, "AEPAXI@Z")) { if(*name == '_' && name.Find('@') < 0) name.Remove(0, 1); out.FindAdd(name); } } i += sym.NumberOfAuxSymbols; } #endif } void MscBuilder::AddFlags(Index& cfg) { cfg.FindAdd("MSC"); } String MscBuilder::CmdLine(const String& package, const Package& pkg) { String cc; if(HasFlag("ARM")) cc = "clarm"; else if(HasFlag("MIPS")) cc = "clmips"; else if(HasFlag("SH3")) cc = "shcl /Qsh3"; else if(HasFlag("SH4")) cc = "shcl /Qsh4"; else if(HasFlag("MSC8ARM")) cc = "cl -GS- "; else cc = HasFlag("INTEL") ? "icl" : "cl"; // TRC 080605-documentation says Wp64 works in 32-bit compilation only // cc << (IsMsc64() ? " -nologo -Wp64 -W3 -GR -c" : " -nologo -W3 -GR -c"); cc << " -nologo -W" << (pkg.nowarnings ? "0" : "3") << " -GR -c"; cc << IncludesDefinesTargetTime(package, pkg); return cc; } String MscBuilder::MachineName() const { if(HasFlag("ARM")) return "ARM"; if(HasFlag("MIPS")) return "MIPS"; if(HasFlag("SH3")) return "SH3"; if(HasFlag("SH4")) return "SH4"; if(IsMscArm()) return "ARM"; if(IsMsc64()) return "x64"; if(HasFlag("WIN32")) return "I386"; return "IX86"; } bool MscBuilder::IsMsc89() const { return IsMsc86() || IsMsc64() || IsMscArm(); } bool MscBuilder::IsMsc86() const { return HasFlag("MSC8") || HasFlag("MSC9") || HasFlag("MSC10") || HasFlag("MSC11") || HasFlag("MSC12") || HasFlag("MSC15") || HasFlag("MSC14") || HasFlag("MSC17") || HasFlag("MSC19") || HasFlag("MSC22"); } bool MscBuilder::IsMscArm() const { return HasFlag("MSC8ARM") || HasFlag("MSC9ARM"); } bool MscBuilder::IsMsc64() const { return HasFlag("MSC8X64") || HasFlag("MSC9X64") || HasFlag("MSC10X64") || HasFlag("MSC11X64") || HasFlag("MSC12X64") || HasFlag("MSC14X64") || HasFlag("MSC15X64") || HasFlag("MSC17X64") || HasFlag("MSC19X64") || HasFlag("MSC22X64"); } String MscBuilder::LinkerName() const { if(HasFlag("ULD")) return "uld"; if(HasFlag("INTEL")) return "xilink"; return "link"; } static bool sContainsPchOptions(const String& x) { Index a(Split(x, ' ')); return a.Find("-GL") >= 0 || a.Find("/GL") >= 0 || a.Find("-Y-") >= 0 || a.Find("/Y-") >= 0 || a.Find("-Yc") >= 0 || a.Find("/Yc") >= 0 || a.Find("-Yd") >= 0 || a.Find("/Yd") >= 0 || a.Find("-Yl") >= 0 || a.Find("/Yl") >= 0 || a.Find("-Yu") >= 0 || a.Find("/Yu") >= 0 || a.Find("-YX") >= 0 || a.Find("/YX") >= 0; } String MscBuilder::Pdb(String package, int slot, bool separate_pdb) const { String pdb_name = GetAnyFileName(package); if(separate_pdb) pdb_name << '-' << (slot + 1); return " -Gy -Fd" + GetPathQ(CatAnyPath(outdir, pdb_name + ".pdb")); } void DeletePCHFile(const String& pch_file) { DeleteFile(pch_file); PutVerbose("Deleting precompiled header: " + pch_file); } bool MscBuilder::BuildPackage(const String& package, Vector& linkfile, Vector& immfile, String& linkoptions, const Vector& all_uses, const Vector& all_libraries, int opt) { if(HasFlag("MAKE_MLIB") && !HasFlag("MAIN")) return true; SaveBuildInfo(package); int i; String packagepath = PackagePath(package); Package pkg; pkg.Load(packagepath); String packagedir = GetFileFolder(packagepath); ChDir(packagedir); PutVerbose("cd " + packagedir); IdeConsoleBeginGroup(package); Vector obj; bool is_shared = HasFlag("SO"), is_clr = HasFlag("CLR"); Vector sfile, isfile; Vector soptions, isoptions; Vector sobjfile; bool error = false; String pch_header; Index nopch, noblitz; bool blitz = HasFlag("BLITZ"); bool release = !HasFlag("DEBUG"); for(i = 0; i < pkg.GetCount(); i++) { if(!IdeIsBuilding()) return false; if(!pkg[i].separator) { String gop = Gather(pkg[i].option, config.GetKeys()); Vector srcfile = CustomStep(pkg[i], package, error); if(srcfile.GetCount() == 0) error = true; for(int j = 0; j < srcfile.GetCount(); j++) { String fn = NormalizePath(srcfile[j]); String ext = ToLower(GetFileExt(fn)); if(findarg(ext, ".c", ".cpp", ".cc", ".cxx", ".rc", ".brc") >= 0 || (!release && blitz && ext == ".icpp")) { if(FindIndex(sfile, fn) < 0) { sfile.Add(fn); soptions.Add(gop); } } else if(ext == ".icpp") { isfile.Add(fn); isoptions.Add(gop); } else if(ext == ".obj") obj.Add(fn); else if(ext == ".lib") linkfile.Add(fn); else if(IsHeaderExt(ext) && pkg[i].pch && allow_pch && IsMsc89() && release && !HasAnyDebug() && !blitz) { if(pch_header.GetCount()) PutConsole(GetFileName(fn) + ": multiple PCHs are not allowed. Check your package configuration"); else pch_header = fn; } if(pkg[i].nopch) { nopch.Add(fn); if(allow_pch && release) noblitz.Add(fn); } if(pkg[i].noblitz) noblitz.Add(fn); if(ext == ".c") nopch.Add(fn); } } } String cc = CmdLine(package, pkg); if(HasFlag("EVC")) { if(!HasFlag("SH3") && !HasFlag("SH4")) cc << " -Gs8192"; // disable stack checking cc << " -GF" // read-only string pooling " -GX-"; // turn off exception handling } else if(is_clr) cc << " -EHac"; else if(IsMsc89()) cc << " -EHsc"; else cc << " -GX"; // String pdb = GetPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pdb")); // String pch; // if(!HasFlag("MSC8")) // MSC8 does not support automatic precompiled headers... // pch << " -YX -Fp" << GetPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pch")) << ' '; // cc << " -Gy -Fd" << pdb; // if(HasFlag("SSE2") && !IsMsc64()) // cc << " /arch:SSE2"; if(HasFlag("DEBUG_MINIMAL")) cc << " -Zd"; if(HasFlag("DEBUG_FULL")) cc << " -Zi"; cc << ' ' << Gather(pkg.option, config.GetKeys()); cc << (HasFlag("SHARED") || is_shared || is_clr ? " -MD" : " -MT"); String cc_size = cc; String cc_speed = cc; if(release) cc << ' ' << release_options; else cc << "d " << debug_options; int recompile = 0; Blitz b; if(blitz) { BlitzBuilderComponent bc(this); b = bc.MakeBlitzStep(*this, sfile, soptions, obj, immfile, ".obj", noblitz, package); recompile = b.build; } for(i = 0; i < sfile.GetCount(); i++) { String fn = sfile[i]; String ext = ToLower(GetFileExt(fn)); if(findarg(ext, ".rc", ".brc", ".c") < 0 && HdependFileTime(sfile[i]) > GetFileTime(CatAnyPath(outdir, GetFileTitle(fn) + ".obj"))) recompile++; } String pch_use; String pch_file; if(pch_header.GetCount()) { String pch_obj = CatAnyPath(outdir, GetFileTitle(pch_header) + "$pch.obj"); pch_file = CatAnyPath(outdir, GetFileTitle(pch_header) + ".pch"); RegisterPCHFile(pch_file); String pch_common = GetPathQ(pch_header) + " -Fp" + GetPathQ(pch_file) + " -FI" + GetPathQ(pch_header); if(blitz) // enable MK__s macros pch_common.Cat(" -DBLITZ_INDEX__=FPCH"); if(recompile > 0 || !FileExists(pch_file)) { int pch_slot = AllocSlot(); StringBuffer sb; sb << Join(cc, cpp_options) << Pdb(package, pch_slot, false) << " -Yc" << pch_common << " -Tp " << GetPathQ(pch_header) << " -Fo" + GetPathQ(pch_obj); PutConsole("Precompiling header: " + GetFileName(pch_header)); if(pch_slot < 0 || !Run(~sb, pch_slot, pch_obj, 1)) error = true; Wait(); } pch_use = " -Yu" + pch_common; obj.Add(pch_obj); } if(blitz && b.build) { PutConsole("BLITZ:" + b.info); int slot = AllocSlot(); String c = Join(cc, cpp_options); if(HasAnyDebug()) c << Pdb(package, slot, false); if(slot < 0 || !Run(c + " -Tp " + GetPathQ(b.path) + " -Fo" + GetPathQ(b.object), slot, b.object, b.count)) error = true; } int first_ifile = sfile.GetCount(); sfile.AppendPick(pick(isfile)); soptions.AppendPick(pick(isoptions)); for(i = 0; i < sfile.GetCount(); i++) { if(!IdeIsBuilding()) return false; String fn = sfile[i]; String ext = ToLower(GetFileExt(fn)); bool rc = (ext == ".rc"); bool brc = (ext == ".brc"); bool init = (i >= first_ifile); String objfile = CatAnyPath(outdir, SourceToObjName(package, fn) + (rc ? "$rc.obj" : brc ? "$brc.obj" : ".obj")); if(HdependFileTime(fn) > GetFileTime(objfile)) { int time = msecs(); bool execerr = false; if(rc) { PutConsole(GetFileNamePos(fn)); int slot = AllocSlot(); if(slot < 0 || !Run("rc /fo" + GetPathQ(objfile) + Includes(" /i", package, pkg) + DefinesTargetTime(" /d", package, pkg) + (HasFlag("DEBUG")?" /d_DEBUG":"") + ' ' + GetPathQ(fn), slot, objfile, 1)) execerr = true; } else if(brc) { try { // String hfn = GetHostPath(fn); String brcdata = LoadFile(fn); if(brcdata.IsVoid()) throw Exc(Format("error reading file '%s'", fn)); CParser parser(brcdata, fn); String fo = BrcToC(parser, GetFileDirectory(fn)); String tmpfile = ForceExt(objfile, ".c"); SaveFile(tmpfile, fo); int slot = AllocSlot(); StringBuffer cmdline; cmdline << cc << Pdb(package, slot, false) << " -Tc " << GetPathQ(tmpfile) << " -Fo" << GetPathQ(objfile); if(slot < 0 || !Run(String(cmdline), slot, objfile, 1)) throw Exc(Format("Error compiling binary object '%s'.", objfile)); } catch(Exc e) { PutConsole(e); execerr = true; } } else { String c = cc; int slot = AllocSlot(); if(HasAnyDebug()) c << Pdb(package, slot, !sContainsPchOptions(cc) && !sContainsPchOptions(soptions[i])); c << " " + soptions[i] + (ext == ".c" ? Join(c_options, " -Tc") : Join(cpp_options, " -Tp")) + ' ' + GetPathQ(fn) + " -Fo" + GetPathQ(objfile); if(nopch.Find(fn) < 0) c << pch_use; if(slot < 0 || !Run(c, slot, objfile, 1)) execerr = true; } if(execerr) DeleteFile(objfile); error |= execerr; PutVerbose("compiled in " + GetPrintTime(time)); } if(init) linkfile.Add(objfile); else obj.Add(objfile); immfile.Add(objfile); } if(error) { IdeConsoleEndGroup(); return false; } bool making_lib = HasFlag("MAKE_LIB") || HasFlag("MAKE_MLIB"); if(!making_lib) { Vector pkglibs = Split(Gather(pkg.library, config.GetKeys()), ' '); for(int i = 0; i < pkglibs.GetCount(); i++) { String libfile = AppendExt(pkglibs[i], ".lib"); if(!IsFullPath(libfile)) { for(int p = 0; p < libpath.GetCount(); p++) { String nf = NormalizePath(libfile, libpath[p]); if(FileExists(nf)) { libfile = nf; break; } } } linkfile.Add(libfile); } } linkoptions << ' ' << Gather(pkg.link, config.GetKeys()); // if(pch_file.GetCount()) // OnFinish(callback1(DeletePCHFile, pch_file)); if(!HasFlag("MAIN")) { if(HasFlag("BLITZ") || HasFlag("NOLIB") || making_lib) { linkfile.Append(obj); // ShowTime(ccount, time); IdeConsoleEndGroup(); return true; } String product; if(is_shared) product = GetSharedLibPath(package); else product = CatAnyPath(outdir, GetAnyFileName(package) + ".lib"); Time producttime = GetFileTime(product); if(obj.GetCount()) { String h = ForceExt(product, ".lib"); linkfile.Add(h); immfile.Add(h); } if(!Wait()) { IdeConsoleEndGroup(); return false; } Vector objinfo = host->GetFileInfo(obj); for(int i = 0; i < obj.GetCount(); i++) if(objinfo[i] > producttime) return CreateLib(product, obj, all_uses, all_libraries, Gather(pkg.link, config.GetKeys())); return true; } IdeConsoleEndGroup(); obj.Append(linkfile); linkfile = pick(obj); return true; } bool MscBuilder::CreateLib(const String& product, const Vector& obj, const Vector& all_uses, const Vector& all_libraries, const String& link_options) { int linktime = msecs(); bool isgemsc10 = HasFlag("MSC10") || HasFlag("MSC10X64") || HasFlag("MSC11") || HasFlag("MSC11X64") || HasFlag("MSC12") || HasFlag("MSC12X64") || HasFlag("MSC14") || HasFlag("MSC14X64") || HasFlag("MSC15") || HasFlag("MSC15X64") || HasFlag("MSC17") || HasFlag("MSC17X64") || HasFlag("MSC19") || HasFlag("MSC19X64") || HasFlag("MSC22") || HasFlag("MSC22X64") ; bool is_shared = HasFlag("SO"); String linker, lib; if(is_shared) { linker << LinkerName() << " -dll -nologo "; lib << "-machine:" << MachineName() << " -pdb:" << GetPathQ(ForceExt(product, ".pdb")) << " -out:" << GetPathQ(product); if(!isgemsc10) lib << " -incremental:no"; if(HasAnyDebug()) lib << " -debug -OPT:NOREF"; else lib << " -release -OPT:REF,ICF"; if(IsMscArm()) lib << " -subsystem:windowsce,4.20 /ARMPADCODE"; else if(HasFlag("GUI")) lib << (HasFlag("WIN32") ? " -subsystem:windows" : " -subsystem:windowsce"); else lib << " -subsystem:console"; Index exports; for(int o = 0; o < obj.GetCount(); o++) AddObjectExports(obj[o], exports); String def; def << "LIBRARY " << AsCString(GetFileName(product)) << "\n\n" "EXPORTS\n"; for(int o = 0; o < exports.GetCount(); o++) def << '\t' << exports[o] << "\n"; //" @" << (o + 1) << "\n"; String deffile = ForceExt(product, ".def"); if(!SaveChangedFile(deffile, def)) { PutConsole(Format("%s: error saving file", deffile)); return false; } lib << " -def:" << GetPathQ(deffile); for(int i = 0; i < libpath.GetCount(); i++) lib << " -LIBPATH:" << GetPathQ(libpath[i]); lib << ' ' << link_options; for(int i = 0; i < all_uses.GetCount(); i++) lib << ' ' << GetPathQ(ForceExt(GetSharedLibPath(all_uses[i]), ".lib")); for(int i = 0; i < all_libraries.GetCount(); i++) { String libfile = AppendExt(all_libraries[i], ".lib"); if(!IsFullPath(libfile)) { for(int p = 0; p < libpath.GetCount(); p++) { String nf = NormalizePath(libfile, libpath[p]); if(FileExists(nf)) { libfile = nf; break; } } } lib << ' ' << GetPathQ(libfile); } } else{ linker << (HasFlag("INTEL") ? "xilib" : "link /lib") << " -nologo "; lib << " -out:" << GetPathQ(product) << ' ' << link_options; } for(int i = 0; i < obj.GetCount(); i++) lib << ' ' << GetPathQ(obj[i]); PutConsole("Creating library..."); IdeConsoleEndGroup(); DeleteFile(product); String tmpFileName; if(linker.GetCount() + lib.GetCount() >= 8192) { tmpFileName = GetTempFileName(); // we can't simply put all data on a single line // as it has a limit of around 130000 chars too, so we split // in multiple lines FileOut f(tmpFileName); while(lib != "") { int found = 0; bool quotes = false; int lim = min(8192, lib.GetCount()); for(int i = 0; i < lim; i++) { char c = lib[i]; if(isspace(c) && !quotes) found = i; else if(c == '"') quotes = !quotes; } if(!found) found = lib.GetCount(); f.PutLine(lib.Left(found)); lib.Remove(0, found); } f.Close(); linker << "@" << tmpFileName; } else linker << lib; bool res = Execute(linker); if(tmpFileName != "") FileDelete(tmpFileName); if(res) { DeleteFile(product); return false; } else if((IsMsc86() || IsMsc64()) && is_shared) { String mt("mt -nologo -manifest "); mt << GetPathQ(product) << ".manifest -outputresource:" << GetPathQ(product) << ";2"; Execute(mt); } PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length << " B) created in " << GetPrintTime(linktime)); return true; } bool MscBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) { int time = msecs(); if(!Wait()) return false; PutLinking(); if(HasFlag("MAKE_MLIB") || HasFlag("MAKE_LIB")) return CreateLib(ForceExt(target, ".lib"), linkfile, Vector(), Vector(), linkoptions); bool isgemsc10 = HasFlag("MSC10") || HasFlag("MSC10X64") || HasFlag("MSC11") || HasFlag("MSC11X64") || HasFlag("MSC12") || HasFlag("MSC12X64") || HasFlag("MSC14") || HasFlag("MSC14X64") || HasFlag("MSC15") || HasFlag("MSC15X64") || HasFlag("MSC17") || HasFlag("MSC17X64") || HasFlag("MSC19") || HasFlag("MSC19X64") || HasFlag("MSC22") || HasFlag("MSC22X64") ; for(int i = 0; i < linkfile.GetCount(); i++) if(GetFileTime(linkfile[i]) > targettime) { String link, lib; link << LinkerName() << " -nologo -machine:" << MachineName() << " -pdb:" << GetPathQ(ForceExt(target, ".pdb")) << " -out:" << GetPathQ(target); if(!isgemsc10) if(HasAnyDebug()) link << " -incremental:yes -debug -OPT:NOREF"; else link << " -incremental:no -release -OPT:REF,ICF"; else if(HasAnyDebug()) link << " -debug -OPT:NOREF"; else link << " -release -OPT:REF,ICF"; if(IsMscArm()) link << " -subsystem:windowsce,4.20 /ARMPADCODE -NODEFAULTLIB:\"oldnames.lib\" "; else if(HasFlag("GUI") || IsMscArm()) link << " -subsystem:windows"; else link << " -subsystem:console"; if(!IsMsc64()) link << ",5.01"; //,5.01 needed to support WindowsXP if(createmap) link << " -MAP"; if(HasFlag("DLL")) link << " -DLL"; for(i = 0; i < libpath.GetCount(); i++) link << " -LIBPATH:\"" << libpath[i] << '\"'; link << ' ' << linkoptions << ' '; for(i = 0; i < linkfile.GetCount(); i++) lib << ' ' << GetPathQ(AppendExt(linkfile[i], ".lib")); PutConsole("Linking..."); bool error = false; String tmpFileName; if(link.GetCount() + lib.GetCount() >= 8192) { tmpFileName = GetTempFileName(); // we can't simply put all data on a single line // as it has a limit of around 130000 chars too, so we split // in multiple lines FileOut f(tmpFileName); while(lib != "") { int found = 0; bool quotes = false; int lim = min(8192, lib.GetCount()); for(int i = 0; i < lim; i++) { char c = lib[i]; if(isspace(c) && !quotes) found = i; else if(c == '"') quotes = !quotes; } if(!found) found = lib.GetCount(); f.PutLine(lib.Left(found)); lib.Remove(0, found); } f.Close(); link << "@" << tmpFileName; } else link << lib; CustomStep(".pre-link", Null, error); if(!error && Execute(link) == 0) { CustomStep(".post-link", Null, error); if((IsMsc86() || IsMsc64()) && HasFlag("SHARED")) { String mt("mt -nologo -manifest "); mt << GetPathQ(target) << ".manifest -outputresource:" << GetPathQ(target) << (HasFlag("DLL") ? ";2" : ";1"); Execute(mt); } PutConsole(String().Cat() << target << " (" << GetFileInfo(target).length << " B) linked in " << GetPrintTime(time)); } else { DeleteFile(target); error = true; } if(tmpFileName != "") FileDelete(tmpFileName); return !error; } PutConsole(String().Cat() << target << " (" << GetFileInfo(target).length << " B) is up to date."); return true; } bool MscBuilder::Preprocess(const String& package, const String& file, const String& target, bool) { FileOut out(target); String packagepath = PackagePath(package); Package pkg; pkg.Load(packagepath); return Execute(CmdLine(package, pkg) + " -E " + file, out); } Builder *CreateMscBuilder() { return new MscBuilder; } INITIALIZER(MscBuilder) { RegisterBuilder("MSC71", CreateMscBuilder); RegisterBuilder("MSC8", CreateMscBuilder); RegisterBuilder("MSC8X64", CreateMscBuilder); RegisterBuilder("MSC8ARM", CreateMscBuilder); RegisterBuilder("MSC9", CreateMscBuilder); RegisterBuilder("MSC9X64", CreateMscBuilder); RegisterBuilder("MSC9ARM", CreateMscBuilder); RegisterBuilder("MSC10", CreateMscBuilder); RegisterBuilder("MSC10X64", CreateMscBuilder); RegisterBuilder("MSC11", CreateMscBuilder); RegisterBuilder("MSC11X64", CreateMscBuilder); RegisterBuilder("MSC12", CreateMscBuilder); RegisterBuilder("MSC12X64", CreateMscBuilder); RegisterBuilder("MSC14", CreateMscBuilder); RegisterBuilder("MSC14X64", CreateMscBuilder); RegisterBuilder("MSC15", CreateMscBuilder); RegisterBuilder("MSC15X64", CreateMscBuilder); RegisterBuilder("MSC17", CreateMscBuilder); RegisterBuilder("MSC17X64", CreateMscBuilder); RegisterBuilder("MSC19", CreateMscBuilder); RegisterBuilder("MSC19X64", CreateMscBuilder); RegisterBuilder("MSC22", CreateMscBuilder); RegisterBuilder("MSC22X64", CreateMscBuilder); RegisterBuilder("EVC_ARM", CreateMscBuilder); RegisterBuilder("EVC_MIPS", CreateMscBuilder); RegisterBuilder("EVC_SH3", CreateMscBuilder); RegisterBuilder("EVC_SH4", CreateMscBuilder); RegisterBuilder("INTEL", CreateMscBuilder); }