aboutsummaryrefslogtreecommitdiff
path: root/tcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcc.c')
-rw-r--r--tcc.c100
1 files changed, 88 insertions, 12 deletions
diff --git a/tcc.c b/tcc.c
index 0803795..4410789 100644
--- a/tcc.c
+++ b/tcc.c
@@ -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 */