Exemplo n.º 1
0
Arquivo: pe.c Projeto: HarryR/sanos
static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) {
  const char *start_symbol;
  unsigned long addr = 0;
  int pe_type = 0;
  int start_sym_index;

  if (find_elf_sym(symtab_section, "_WinMain@16")) {
    pe_type = PE_GUI;
  } else if (s1->output_type == TCC_OUTPUT_DLL) {
    pe_type = PE_DLL;
    // Need this for 'tccelf.c:relocate_section()'
    s1->output_type = TCC_OUTPUT_EXE;
  } else {
    pe_type = PE_EXE;
  }

  start_symbol = s1->start_symbol;
  if (!start_symbol) {
    start_symbol = pe_type == PE_DLL ? "_DllMain@12" : "mainCRTStartup";
  }
  start_sym_index = add_elf_sym(symtab_section, 0, 0,
                                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
                                SHN_UNDEF, start_symbol);
  tcc_get_symbol_err(s1, start_symbol);

  if (s1->nostdlib == 0) {
    tcc_add_library(s1, "c");
    tcc_add_library(s1, "os");
  }

  if (pe) {
    pe->type = pe_type;
    pe->start_sym_index = start_sym_index;
    pe->stub = s1->stub;
    pe->def = s1->def_file;
    pe->filealign = s1->filealign;
  }
}
Exemplo n.º 2
0
ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
{
    const char *start_symbol;
    unsigned long addr = 0;
    int pe_type = 0;

    if (find_elf_sym(symtab_section, "_WinMain@16"))
        pe_type = PE_GUI;
    else
    if (TCC_OUTPUT_DLL == s1->output_type) {
        pe_type = PE_DLL;
        /* need this for 'tccelf.c:relocate_section()' */
        s1->output_type = TCC_OUTPUT_EXE;
    }

    start_symbol =
        TCC_OUTPUT_MEMORY == s1->output_type
        ? PE_GUI == pe_type ? "_runwinmain" : NULL
        : PE_DLL == pe_type ? "__dllstart@12"
        : PE_GUI == pe_type ? "_winstart" : "_start"
        ;

    /* grab the startup code from libtcc1 */
    if (start_symbol)
        add_elf_sym(symtab_section,
            0, 0,
            ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
            SHN_UNDEF, start_symbol);

    if (0 == s1->nostdlib) {
        tcc_add_library(s1, "tcc1");
#ifdef __CYGWIN__
        tcc_add_library(s1, "cygwin1");
#else
        tcc_add_library(s1, "msvcrt");
#endif
        tcc_add_library(s1, "kernel32");
        if (PE_DLL == pe_type || PE_GUI == pe_type) {
            tcc_add_library(s1, "user32");
            tcc_add_library(s1, "gdi32");
        }
    }

    if (start_symbol) {
        addr = (unsigned long)tcc_get_symbol_err(s1, start_symbol);
        if (s1->output_type == TCC_OUTPUT_MEMORY && addr)
            /* for -run GUI's, put '_runwinmain' instead of 'main' */
            add_elf_sym(symtab_section,
                    addr, 0,
                    ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
                    text_section->sh_num, "main");
    }

    if (pe) {
        pe->type = pe_type;
        pe->start_addr = addr;
    }
}
Exemplo n.º 3
0
Arquivo: tcc.c Projeto: raldoni/tcc
int main(int argc, char **argv)
{
    TCCState *s;
    int ret, optind, i;
    int64_t start_time = 0;

    s = tcc_new();

    optind = tcc_parse_args(s, argc - 1, argv + 1);

    if (s->do_bench)
        start_time = getclock_us();

    tcc_set_environment(s);

    if (optind == 0) {
        help();
        return 1;
    }

    if (s->option_m)
        exec_other_tcc(s, argv, s->option_m);

    if (s->verbose)
        display_info(s, 0);

    if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) {
        tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
        display_info(s, 1);
        return 0;
    }

    if (s->verbose && optind == 1)
        return 0;

    if (s->nb_files == 0)
        tcc_error("no input files\n");

    /* check -c consistency : only single file handled. XXX: checks file type */
    if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
        if (s->nb_libraries != 0)
            tcc_error("cannot specify libraries with -c");
        /* accepts only a single input file */
        if ((s->nb_files != 1) && s->outfile) {
            tcc_error("cannot specify multiple files with -c and -o");
        }
    }

    if (s->output_type == TCC_OUTPUT_PREPROCESS) {
        if (!s->outfile) {
            s->ppfp = stdout;
        } else {
            s->ppfp = fopen(s->outfile, "w");
            if (!s->ppfp)
                tcc_error("could not write '%s'", s->outfile);
        }
    }

    tcc_set_output_type(s, s->output_type);

    /* compile or add each files or library */
    for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
        int filetype = *(unsigned char *)s->files[i];
        const char *filename = s->files[i] + 1;
        if (filename[0] == '-' && filename[1] == 'l') {
            if (tcc_add_library(s, filename + 2) < 0) {
                tcc_error_noabort("cannot find library 'lib%s'", filename+2);
                ret = 1;
            }
        } else {
            if (1 == s->verbose)
                printf("-> %s\n", filename);
            if (!s->outfile)
                s->outfile = default_outputfile(s, filename);
            if (tcc_add_file(s, filename, filetype) < 0)
                ret = 1;
            else
            if (s->output_type == TCC_OUTPUT_OBJ) {
                ret = !!tcc_output_file(s, s->outfile);
                if (s->gen_deps && !ret)
                    gen_makedeps(s, s->outfile, s->deps_outfile);
                if (!ret) {
                    if ((i+1) < s->nb_files) {
                        tcc_delete(s);
                        s = tcc_new();
                        tcc_parse_args(s, argc - 1, argv + 1);
                        tcc_set_environment(s);
                        if (s->output_type != TCC_OUTPUT_OBJ)
                            tcc_error("interlnal error");
                        tcc_set_output_type(s, s->output_type);
                    }
                }
            }
        }
    }

    if (0 == ret) {
        if (s->output_type == TCC_OUTPUT_MEMORY) {
#ifdef TCC_IS_NATIVE
            ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind);
#else
            tcc_error_noabort("-run is not available in a cross compiler");
            ret = 1;
#endif
        } else
        if (s->output_type == TCC_OUTPUT_EXE ||
            s->output_type == TCC_OUTPUT_DLL)
        {
            ret = !!tcc_output_file(s, s->outfile);
            if (s->gen_deps && !ret)
                gen_makedeps(s, s->outfile, s->deps_outfile);
        }
    }

    if (s->do_bench)
        tcc_print_stats(s, getclock_us() - start_time);

    tcc_delete(s);
    return ret;
}