From 2c538d7a2b0fb9e72c0fbb9af5d351302584aca0 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 10 Apr 2005 21:46:58 +0000 Subject: initial PE format support --- tcc.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 12 deletions(-) (limited to 'tcc.c') diff --git a/tcc.c b/tcc.c index 0803795..4410789 100644 --- a/tcc.c +++ b/tcc.c @@ -35,13 +35,11 @@ #include #include #include -#include #include #include #include #ifdef WIN32 #include -#define CONFIG_TCC_STATIC #endif #ifndef WIN32 #include @@ -52,9 +50,7 @@ #include "elf.h" #include "stab.h" -#ifndef CONFIG_TCC_STATIC -#include -#endif + #ifndef O_BINARY #define O_BINARY 0 #endif @@ -218,6 +214,7 @@ typedef struct AttributeDef { int packed; Section *section; unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */ + unsigned char dllexport; } AttributeDef; #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */ @@ -719,6 +716,7 @@ extern long double strtold (const char *__nptr, char **__endptr); static char *pstrcpy(char *buf, int buf_size, const char *s); static char *pstrcat(char *buf, int buf_size, const char *s); +static const char *tcc_basename(const char *name); static void next(void); static void next_nomacro(void); @@ -809,6 +807,13 @@ static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); /* tcccoff.c */ int tcc_output_coff(TCCState *s1, FILE *f); +/* tccpe.c */ +void *resolve_sym(TCCState *s1, const char *sym, int type); +int pe_load_def_file(struct TCCState *s1, FILE *fp); +void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file); +unsigned long pe_add_runtime(struct TCCState *s1); +int tcc_output_pe(struct TCCState *s1, const char *filename); + /* tccasm.c */ #ifdef CONFIG_TCC_ASM @@ -902,7 +907,7 @@ static TCCSyms tcc_syms[] = { { NULL, NULL }, }; -void *dlsym(void *handle, const char *symbol) +void *resolve_sym(TCCState *s1, const char *symbol, int type) { TCCSyms *p; p = tcc_syms; @@ -914,6 +919,15 @@ void *dlsym(void *handle, const char *symbol) return NULL; } +#elif !defined(WIN32) + +#include + +void *resolve_sym(TCCState *s1, const char *sym, int type) +{ + return dlsym(RTLD_DEFAULT, sym); +} + #endif /********************************************************/ @@ -6290,6 +6304,9 @@ static void parse_attribute(AttributeDef *ad) skip(')'); break; #endif + case TOK_DLLEXPORT: + ad->dllexport = 1; + break; default: if (tcc_state->warn_unsupported) warning("'%s' attribute ignored", get_tok_str(t, NULL)); @@ -9195,6 +9212,10 @@ static void asm_global_instr(void) #include "tcccoff.c" #endif +#ifdef TCC_TARGET_PE +#include "tccpe.c" +#endif + /* print the position in the source file of PC value 'pc' by reading the stabs debug information */ static void rt_printline(unsigned long wanted_pc) @@ -9442,7 +9463,11 @@ int tcc_relocate(TCCState *s1) s1->nb_errors = 0; +#ifdef TCC_TARGET_PE + pe_add_runtime(s1); +#else tcc_add_runtime(s1); +#endif relocate_common_syms(); @@ -9588,9 +9613,17 @@ TCCState *tcc_new(void) tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); /* default library paths */ +#ifdef TCC_TARGET_PE + { + char buf[1024]; + snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path); + tcc_add_library_path(s, buf); + } +#else tcc_add_library_path(s, "/usr/local/lib"); tcc_add_library_path(s, "/usr/lib"); tcc_add_library_path(s, "/lib"); +#endif /* no section zero */ dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); @@ -9727,6 +9760,11 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) /* non preprocessed assembler */ ret = tcc_assemble(s1, 0); } else +#endif +#ifdef TCC_TARGET_PE + if (!strcmp(ext, "def")) { + ret = pe_load_def_file(s1, fdopen(file->fd, "rb")); + } else #endif { fd = file->fd; @@ -9749,12 +9787,16 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) ret = tcc_load_object_file(s1, fd, 0); } else if (ehdr.e_type == ET_DYN) { if (s1->output_type == TCC_OUTPUT_MEMORY) { +#ifdef TCC_TARGET_PE + ret = -1; +#else void *h; h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); if (h) ret = 0; else ret = -1; +#endif } else { ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); @@ -9830,7 +9872,11 @@ int tcc_add_library(TCCState *s, const char *libraryname) /* first we look for the dynamic library if not static linking */ if (!s->static_link) { +#ifdef TCC_TARGET_PE + snprintf(buf, sizeof(buf), "%s.def", libraryname); +#else snprintf(buf, sizeof(buf), "lib%s.so", libraryname); +#endif if (tcc_add_dll(s, buf, 0) == 0) return 0; } @@ -9855,17 +9901,23 @@ int tcc_add_symbol(TCCState *s, const char *name, unsigned long val) int tcc_set_output_type(TCCState *s, int output_type) { - char buf[1024]; - s->output_type = output_type; if (!s->nostdinc) { + char buf[1024]; + /* default include paths */ /* XXX: reverse order needed if -isystem support */ +#ifndef TCC_TARGET_PE tcc_add_sysinclude_path(s, "/usr/local/include"); tcc_add_sysinclude_path(s, "/usr/include"); +#endif snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path); tcc_add_sysinclude_path(s, buf); +#ifdef TCC_TARGET_PE + snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path); + tcc_add_sysinclude_path(s, buf); +#endif } /* if bound checking, then add corresponding sections */ @@ -9898,12 +9950,14 @@ int tcc_set_output_type(TCCState *s, int output_type) } /* add libc crt1/crti objects */ +#ifndef TCC_TARGET_PE if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && !s->nostdlib) { if (output_type != TCC_OUTPUT_DLL) tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o"); tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o"); } +#endif return 0; } @@ -10013,7 +10067,7 @@ static int64_t getclock_us(void) void help(void) { - printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2004 Fabrice Bellard\n" + printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2005 Fabrice Bellard\n" "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n" " [infile1 infile2...] [-run infile args...]\n" @@ -10370,6 +10424,22 @@ int main(int argc, char **argv) char objfilename[1024]; int64_t start_time = 0; +#ifdef WIN32 + /* on win32, we suppose the lib and includes are at the location + of 'tcc.exe' */ + { + static char path[1024]; + + GetModuleFileNameA(NULL, path, sizeof path); + p = d = strlwr(path); + while (*d) + if (*d++ == '\\') + (p = d)[-1] = '/'; + *p = '\0'; + tcc_lib_path = path; + } +#endif + s = tcc_new(); output_type = TCC_OUTPUT_EXE; outfile = NULL; @@ -10461,11 +10531,17 @@ int main(int argc, char **argv) total_bytes / total_time / 1000000.0); } - if (s->output_type != TCC_OUTPUT_MEMORY) { + if (s->output_type == TCC_OUTPUT_MEMORY) { + ret = tcc_run(s, argc - optind, argv + optind); + } else +#ifdef TCC_TARGET_PE + if (s->output_type != TCC_OUTPUT_OBJ) { + ret = tcc_output_pe(s, outfile); + } else +#endif + { tcc_output_file(s, outfile); ret = 0; - } else { - ret = tcc_run(s, argc - optind, argv + optind); } the_end: /* XXX: cannot do it with bound checking because of the malloc hooks */ -- cgit v1.3.1