diff options
| author | bellard <bellard> | 2005-04-10 21:46:58 +0000 |
|---|---|---|
| committer | bellard <bellard> | 2005-04-10 21:46:58 +0000 |
| commit | 2c538d7a2b0fb9e72c0fbb9af5d351302584aca0 (patch) | |
| tree | 0f89e8ac6f2fa62a0beb3915b13a4767968b772f /tcc.c | |
| parent | bdd09709d7b412c2cd7380172264d985fabafa6d (diff) | |
| download | tinycc-2c538d7a2b0fb9e72c0fbb9af5d351302584aca0.tar.gz tinycc-2c538d7a2b0fb9e72c0fbb9af5d351302584aca0.tar.bz2 | |
initial PE format support
Diffstat (limited to 'tcc.c')
| -rw-r--r-- | tcc.c | 100 |
1 files changed, 88 insertions, 12 deletions
@@ -35,13 +35,11 @@ #include <math.h> #include <unistd.h> #include <signal.h> -#include <unistd.h> #include <fcntl.h> #include <setjmp.h> #include <time.h> #ifdef WIN32 #include <sys/timeb.h> -#define CONFIG_TCC_STATIC #endif #ifndef WIN32 #include <sys/time.h> @@ -52,9 +50,7 @@ #include "elf.h" #include "stab.h" -#ifndef CONFIG_TCC_STATIC -#include <dlfcn.h> -#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 <dlfcn.h> + +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); @@ -9728,6 +9761,11 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) 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; /* assume executable format: auto guess file type */ @@ -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 */ |
