Ejemplo n.º 1
0
static TString EmitExports(const std::vector<TString> &escaped_args) {
    auto uuid_lib_file = TempFile::Create(TEXT(".lib"), true);
    auto uuid_exp_file = uuid_lib_file;
    uuid_exp_file.replace(uuid_exp_file.length() - 4, 4, TEXT(".exp"));
    TempFile::AutoDeleteFile(uuid_exp_file);

    // Call link.exe -lib -def <rest of linker arguments> -out:<uuid_lib_file>
    auto linker_exe = LocateMSVCLinker();
    auto linker_exe_esc = QuoteSpaces(linker_exe.data());
    std::vector<const _TCHAR*> export_args;
    export_args.push_back(linker_exe_esc.data());
    export_args.push_back(TEXT("-lib"));
    export_args.push_back(TEXT("-def")); // If the original includes "/DEF" or "-DEF", it should override this one
    // FIXME: this passes many link.exe args to lib.exe which generates warnings
    for (auto &escaped_arg : escaped_args)
        export_args.push_back(escaped_arg.data());
    TString out_arg(TEXT("-out:"));
    out_arg += uuid_lib_file;
    export_args.push_back(out_arg.data());
    export_args.push_back(NULL);
	//PrintArgs(export_args);
	auto errnum = _tspawnvp(_P_WAIT, linker_exe.data(), export_args.data());
	if (errnum) {
		perror("LinkWrapper:EmitExports");
		exit(errnum);
	}

    // Convert the exports file to the trampoline object file
    auto exports_obj_file = TempFile::Create(TEXT(".obj"), true);
    bool converted = ConvertExports(uuid_exp_file.data(), exports_obj_file.data());
    return converted ? exports_obj_file : TString();
}
Ejemplo n.º 2
0
void Convert (const O65Data* D)
/* Convert the o65 file in D using the given output file. */
{
    FILE*       F;
    unsigned    I;
    char*       Author = 0;

    /* For now, we do only accept o65 files generated by the ld65 linker which
     * have a specific format.
     */
    if (!Debug && D->Header.mode != O65_MODE_CC65) {
        Error ("Cannot convert o65 files of this type");
    }

    /* Output statistics */
    PrintO65Stats (D);

    /* Walk through the options and print them if verbose mode is enabled.
     * Check for a os=cc65 option and bail out if we didn't find one (for
     * now - later we switch to special handling).
     */
    for (I = 0; I < CollCount (&D->Options); ++I) {

        /* Get the next option */
        const O65Option* O = CollConstAt (&D->Options, I);

        /* Check the type of the option */
        switch (O->Type) {

            case O65_OPT_FILENAME:
                Print (stdout, 1, "O65 filename option:         `%s'\n",
                       GetO65OptionText (O));
                break;

            case O65_OPT_OS:
                if (O->Len == 2) {
                    Warning ("Operating system option without data found");
                } else {
                    Print (stdout, 1, "O65 operating system option: `%s'\n",
                           GetO65OSName (O->Data[0]));
                    switch (O->Data[0]) {
                        case O65_OS_CC65_MODULE:
                            if (Model != O65_MODEL_NONE &&
                                Model != O65_MODEL_CC65_MODULE) {
                                Warning ("Wrong o65 model for input file specified");
                            } else {
                                Model = O65_MODEL_CC65_MODULE;
                            }
                            break;
                    }
                }
                break;

            case O65_OPT_ASM:
                Print (stdout, 1, "O65 assembler option:        `%s'\n",
                       GetO65OptionText (O));
                break;

            case O65_OPT_AUTHOR:
                if (Author) {
                    xfree (Author);
                }
                Author = xstrdup (GetO65OptionText (O));
                Print (stdout, 1, "O65 author option:           `%s'\n", Author);
                break;

            case O65_OPT_TIMESTAMP:
                Print (stdout, 1, "O65 timestamp option:        `%s'\n",
                       GetO65OptionText (O));
                break;

            default:
                Warning ("Found unknown option, type %d, length %d",
                         O->Type, O->Len);
                break;
        }
    }

    /* If we shouldn't generate output, we're done here */
    if (NoOutput) {
        return;
    }

    /* Open the output file */
    F = fopen (OutputName, "w");
    if (F == 0) {
        Error ("Cannot open `%s': %s", OutputName, strerror (errno));
    }

    /* Create a header */
    fprintf (F, ";\n; File generated by co65 v %s using model `%s'\n;\n",
             GetVersionAsString (), GetModelName (Model));

    /* Select the CPU */
    if ((D->Header.mode & O65_CPU_MASK) == O65_CPU_65816) {
    	fprintf (F, ".p816\n");
    }

    /* Object file options */
    fprintf (F, ".fopt\t\tcompiler,\"co65 v %s\"\n", GetVersionAsString ());
    if (Author) {
        fprintf (F, ".fopt\t\tauthor, \"%s\"\n", Author);
        xfree (Author);
        Author = 0;
    }

    /* Several other assembler options */
    fprintf (F, ".case\t\ton\n");
    fprintf (F, ".debuginfo\t%s\n", (DebugInfo != 0)? "on" : "off");

    /* Setup/export the segment labels */
    SetupSegLabels (F);

    /* End of header */
    fprintf (F, "\n");

    /* Imported identifiers */
    ConvertImports (F, D);

    /* Exported identifiers */
    ConvertExports (F, D);

    /* Code segment */
    ConvertCodeSeg (F, D);

    /* Data segment */
    ConvertDataSeg (F, D);

    /* BSS segment */
    ConvertBssSeg (F, D);

    /* Zero page segment */
    ConvertZeropageSeg (F, D);

    /* End of data */
    fprintf (F, ".end\n");
    fclose (F);
}