aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard>2002-01-12 16:39:35 +0000
committerbellard <bellard>2002-01-12 16:39:35 +0000
commit9c06595a1e83aba45c757df3c232b3dc42aa0214 (patch)
tree71c006ef1ae3a73aba99840d89c5f015568e1b0e
parentbbd541d760251b2c1f76cf3992b5574ce99579ce (diff)
downloadtinycc-9c06595a1e83aba45c757df3c232b3dc42aa0214.tar.gz
tinycc-9c06595a1e83aba45c757df3c232b3dc42aa0214.tar.bz2
win32 defines + new internal file layer
-rw-r--r--bcheck.c19
-rw-r--r--tcc.c260
2 files changed, 192 insertions, 87 deletions
diff --git a/bcheck.c b/bcheck.c
index f4351cf..eff0525 100644
--- a/bcheck.c
+++ b/bcheck.c
@@ -80,10 +80,12 @@ static void libc_free(void *ptr);
static void install_malloc_hooks(void);
static void restore_malloc_hooks(void);
+#ifndef WIN32
static void *saved_malloc_hook;
static void *saved_free_hook;
static void *saved_realloc_hook;
static void *saved_memalign_hook;
+#endif
extern char _end;
@@ -123,8 +125,7 @@ static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
return __bound_empty_t2;
}
-/* print a bound error and recurse thru 'nb_callers' to get the error
- position */
+/* print a bound error message */
static void bound_error(const void *caller, const char *fmt, ...)
{
rt_error((unsigned long)caller, "%s", fmt);
@@ -132,7 +133,7 @@ static void bound_error(const void *caller, const char *fmt, ...)
static void bound_alloc_error(void)
{
- bound_error(NULL, "not enough memory for bound checking code\n");
+ bound_error(NULL, "not enough memory for bound checking code");
}
/* currently, tcc cannot compile that because we use GNUC extensions */
@@ -406,7 +407,7 @@ void __bound_init(void)
size = BOUND_T23_SIZE;
mark_invalid(start, size);
-#if !defined(__TINYC__)
+#if !defined(__TINYC__) && !defined(WIN32)
/* malloc zone is also marked invalid */
start = (unsigned long)&_end;
size = 128 * 0x100000;
@@ -641,6 +642,7 @@ static unsigned long get_region_size(void *p)
static void install_malloc_hooks(void)
{
+#ifndef WIN32
saved_malloc_hook = __malloc_hook;
saved_free_hook = __free_hook;
saved_realloc_hook = __realloc_hook;
@@ -649,14 +651,17 @@ static void install_malloc_hooks(void)
__free_hook = __bound_free;
__realloc_hook = __bound_realloc;
__memalign_hook = __bound_memalign;
+#endif
}
static void restore_malloc_hooks(void)
{
+#ifndef WIN32
__malloc_hook = saved_malloc_hook;
__free_hook = saved_free_hook;
__realloc_hook = saved_realloc_hook;
__memalign_hook = saved_memalign_hook;
+#endif
}
static void *libc_malloc(size_t size)
@@ -693,6 +698,7 @@ void *__bound_malloc(size_t size, const void *caller)
return ptr;
}
+#ifndef WIN32
void *__bound_memalign(size_t size, size_t align, const void *caller)
{
void *ptr;
@@ -711,6 +717,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
__bound_new_region(ptr, size);
return ptr;
}
+#endif
void __bound_free(void *ptr, const void *caller)
{
@@ -773,7 +780,7 @@ static void bound_dump(void)
/* some useful checked functions */
/* check that (p ... p + size - 1) lies inside 'p' region, if any */
-static void __bound_check(const void *p, ssize_t size)
+static void __bound_check(const void *p, size_t size)
{
if (size == 0)
return;
@@ -805,7 +812,7 @@ void *__bound_memset(void *dst, int c, size_t size)
return memset(dst, c, size);
}
-/* resolve check check syms */
+/* resolve bound check syms */
typedef struct BCSyms {
char *str;
void *ptr;
diff --git a/tcc.c b/tcc.c
index 21ad98b..93c0c59 100644
--- a/tcc.c
+++ b/tcc.c
@@ -25,11 +25,15 @@
#include <math.h>
#include <unistd.h>
#include <signal.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifndef WIN32
#include <sys/ucontext.h>
#include <sys/mman.h>
-#include <elf.h>
-#include <stab.h>
-#include <malloc.h>
+#endif
+#include "elf.h"
+#include "stab.h"
#ifndef CONFIG_TCC_STATIC
#include <dlfcn.h>
#endif
@@ -145,15 +149,22 @@ typedef struct AttributeDef {
#define TYPE_ABSTRACT 1 /* type without variable */
#define TYPE_DIRECT 2 /* type with variable */
-typedef struct {
- FILE *file;
- char *filename;
- int line_num;
-} IncludeFile;
+#define IO_BUF_SIZE 8192
+
+typedef struct BufferedFile {
+ unsigned char *buf_ptr;
+ unsigned char *buf_end;
+ int fd;
+ int line_num; /* current line number - here to simply code */
+ char filename[1024]; /* current filename - here to simply code */
+ unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
+} BufferedFile;
+
+#define CH_EOB 0 /* end of buffer or '\0' char in file */
+#define CH_EOF (-1) /* end of file */
/* parser */
-FILE *file;
-int line_num;
+struct BufferedFile *file;
int ch, ch1, tok, tok1;
CValue tokc, tok1c;
@@ -185,14 +196,14 @@ int tok_ident;
TokenSym **table_ident;
TokenSym *hash_ident[TOK_HASH_SIZE];
char token_buf[STRING_MAX_SIZE + 1];
-char *filename, *funcname;
+char *funcname;
/* contains global symbols which remain between each translation unit */
SymStack extern_stack;
SymStack define_stack, global_stack, local_stack, label_stack;
SValue vstack[VSTACK_SIZE], *vtop;
int *macro_ptr, *macro_ptr_allocated;
-IncludeFile include_stack[INCLUDE_STACK_SIZE], *include_stack_ptr;
+BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr;
int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
char *include_paths[INCLUDE_PATHS_MAX];
int nb_include_paths;
@@ -316,6 +327,8 @@ int tcc_ext = 1;
#define TOK_A_SHL 0x81
#define TOK_A_SAR 0x82
+#define TOK_EOF (-1) /* end of file */
+
/* all identificators and strings have token above that */
#define TOK_IDENT 256
@@ -344,8 +357,10 @@ enum {
TOK_LONG,
TOK_REGISTER,
TOK_SIGNED,
+ TOK___SIGNED__, /* gcc keyword */
TOK_AUTO,
TOK_INLINE,
+ TOK___INLINE__, /* gcc keyword */
TOK_RESTRICT,
/* unsupported type */
@@ -392,9 +407,22 @@ enum {
TOK___UNUSED__,
};
+#ifdef WIN32
+#define snprintf _snprintf
+/* currently incorrect */
+long double strtold(const char *nptr, char **endptr)
+{
+ return (long double)strtod(nptr, endptr);
+}
+float strtof(const char *nptr, char **endptr)
+{
+ return (float)strtod(nptr, endptr);
+}
+#else
/* XXX: need to define this to use them in non ISOC99 context */
extern float strtof (const char *__nptr, char **__endptr);
extern long double strtold (const char *__nptr, char **__endptr);
+#endif
void sum(int l);
void next(void);
@@ -495,7 +523,7 @@ static TCCSyms tcc_syms[] = {
{ NULL, NULL },
};
-void *dlsym(void *handle, char *symbol)
+void *dlsym(void *handle, const char *symbol)
{
TCCSyms *p;
p = tcc_syms;
@@ -582,25 +610,27 @@ unsigned long long __ldtoull(long double a)
/********************************************************/
-/* copy a string and truncate it */
+/* copy a string and truncate it. */
char *pstrcpy(char *buf, int buf_size, const char *s)
{
char *q, *q_end;
int c;
- q = buf;
- q_end = buf + buf_size - 1;
- while (q < q_end) {
- c = *s++;
- if (c == '\0')
- break;
- *q++ = c;
+ if (buf_size > 0) {
+ q = buf;
+ q_end = buf + buf_size - 1;
+ while (q < q_end) {
+ c = *s++;
+ if (c == '\0')
+ break;
+ *q++ = c;
+ }
+ *q = '\0';
}
- *q = '\0';
return buf;
}
-/* strcat and truncate */
+/* strcat and truncate. */
char *pstrcat(char *buf, int buf_size, const char *s)
{
int len;
@@ -624,12 +654,19 @@ Section *new_section(const char *name, int sh_type, int sh_flags)
sec->sh_num = ++section_num;
sec->sh_type = sh_type;
sec->sh_flags = sh_flags;
+#ifdef WIN32
+ /* XXX: currently, a single malloc */
+ data = malloc(SECTION_VSIZE);
+ if (data == NULL)
+ error("could not alloc section '%s'", name);
+#else
data = mmap(NULL, SECTION_VSIZE,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (data == (void *)(-1))
error("could not mmap section '%s'", name);
+#endif
sec->data = data;
sec->data_ptr = data;
psec = &first_section;
@@ -706,11 +743,11 @@ static inline int toup(int c)
void printline(void)
{
- IncludeFile *f;
+ BufferedFile **f;
for(f = include_stack; f < include_stack_ptr; f++)
fprintf(stderr, "In file included from %s:%d:\n",
- f->filename, f->line_num);
- fprintf(stderr, "%s:%d: ", filename, line_num);
+ (*f)->filename, (*f)->line_num);
+ fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
}
void error(const char *fmt, ...)
@@ -976,39 +1013,94 @@ void sym_undef(SymStack *st, Sym *s)
s->v = 0;
}
+/* I/O layer */
+
+BufferedFile *tcc_open(const char *filename)
+{
+ int fd;
+ BufferedFile *bf;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return NULL;
+ bf = malloc(sizeof(BufferedFile));
+ if (!bf) {
+ close(fd);
+ return NULL;
+ }
+ bf->fd = fd;
+ bf->buf_ptr = bf->buffer;
+ bf->buf_end = bf->buffer;
+ bf->buffer[0] = CH_EOB; /* put eob symbol */
+ pstrcpy(bf->filename, sizeof(bf->filename), filename);
+ bf->line_num = 1;
+ return bf;
+}
+
+void tcc_close(BufferedFile *bf)
+{
+ close(bf->fd);
+ free(bf);
+}
+
+/* read one char. MUST call tcc_fillbuf if CH_EOB is read */
+#define TCC_GETC(bf) (*(bf)->buf_ptr++)
+
+/* fill input buffer and return next char */
+int tcc_getc_slow(BufferedFile *bf)
+{
+ int len;
+ /* only tries to read if really end of buffer */
+ if (bf->buf_ptr >= bf->buf_end) {
+ if (bf->fd != -1) {
+ len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
+ if (len < 0)
+ len = 0;
+ } else {
+ len = 0;
+ }
+ bf->buf_ptr = bf->buffer;
+ bf->buf_end = bf->buffer + len;
+ *bf->buf_end = CH_EOB;
+ }
+ if (bf->buf_ptr < bf->buf_end) {
+ return *bf->buf_ptr++;
+ } else {
+ bf->buf_ptr = bf->buf_end;
+ return CH_EOF;
+ }
+}
+
/* no need to put that inline */
-int handle_eof(void)
+void handle_eob(void)
{
- if (include_stack_ptr == include_stack)
- return -1;
- /* add end of include file debug info */
- if (do_debug) {
- put_stabd(N_EINCL, 0, 0);
+ for(;;) {
+ ch1 = tcc_getc_slow(file);
+ if (ch1 != CH_EOF)
+ return;
+
+ if (include_stack_ptr == include_stack)
+ return;
+ /* add end of include file debug info */
+ if (do_debug) {
+ put_stabd(N_EINCL, 0, 0);
+ }
+ /* pop include stack */
+ tcc_close(file);
+ include_stack_ptr--;
+ file = *include_stack_ptr;
}
- /* pop include stack */
- fclose(file);
- free(filename);
- include_stack_ptr--;
- file = include_stack_ptr->file;
- filename = include_stack_ptr->filename;
- line_num = include_stack_ptr->line_num;
- return 0;
}
/* read next char from current input file */
static inline void inp(void)
{
- redo:
- /* faster than fgetc */
- ch1 = getc_unlocked(file);
- if (ch1 == -1) {
- if (handle_eof() < 0)
- return;
- else
- goto redo;
- }
+ ch1 = TCC_GETC(file);
+ /* end of buffer/file handling */
+ if (ch1 == CH_EOB)
+ handle_eob();
if (ch1 == '\n')
- line_num++;
+ file->line_num++;
// printf("ch1=%c 0x%x\n", ch1, ch1);
}
@@ -1219,7 +1311,7 @@ void preprocess(void)
int size, i, c, v, t, *str, len;
char buf[1024], *q, *p;
char buf1[1024];
- FILE *f;
+ BufferedFile *f;
Sym **ps, *first, *s;
cinp();
@@ -1304,15 +1396,15 @@ void preprocess(void)
if (c == '\"') {
/* first search in current dir if "header.h" */
size = 0;
- p = strrchr(filename, '/');
+ p = strrchr(file->filename, '/');
if (p)
- size = p + 1 - filename;
+ size = p + 1 - file->filename;
if (size > sizeof(buf1) - 1)
size = sizeof(buf1) - 1;
- memcpy(buf1, filename, size);
+ memcpy(buf1, file->filename, size);
buf1[size] = '\0';
pstrcat(buf1, sizeof(buf1), buf);
- f = fopen(buf1, "r");
+ f = tcc_open(buf1);
if (f)
goto found;
}
@@ -1321,7 +1413,7 @@ void preprocess(void)
strcpy(buf1, include_paths[i]);
strcat(buf1, "/");
strcat(buf1, buf);
- f = fopen(buf1, "r");
+ f = tcc_open(buf1);
if (f)
goto found;
}
@@ -1330,16 +1422,11 @@ void preprocess(void)
found:
/* push current file in stack */
/* XXX: fix current line init */
- include_stack_ptr->file = file;
- include_stack_ptr->filename = filename;
- include_stack_ptr->line_num = line_num;
- include_stack_ptr++;
+ *include_stack_ptr++ = file;
file = f;
- filename = strdup(buf1);
- line_num = 1;
/* add include file debug info */
if (do_debug) {
- put_stabs(filename, N_BINCL, 0, 0, 0);
+ put_stabs(file->filename, N_BINCL, 0, 0, 0);
}
} else if (tok == TOK_IFNDEF) {
c = 1;
@@ -1382,14 +1469,14 @@ void preprocess(void)
next();
if (tok != TOK_CINT)
error("#line");
- line_num = tokc.i;
+ file->line_num = tokc.i;
skip_spaces();
if (ch != '\n') {
next();
if (tok != TOK_STR)
error("#line");
- /* XXX: potential memory leak */
- filename = strdup(get_tok_str(tok, &tokc));
+ pstrcpy(file->filename, sizeof(file->filename),
+ get_tok_str(tok, &tokc));
}
} else if (tok == TOK_ERROR) {
error("#error");
@@ -2025,10 +2112,10 @@ void macro_subst(int **tok_str, int *tok_len,
break;
/* special macros */
if (tok == TOK___LINE__) {
- cval.i = line_num;
+ cval.i = file->line_num;
tok_add2(tok_str, tok_len, TOK_CINT, &cval);
} else if (tok == TOK___FILE__) {
- cval.ts = tok_alloc(filename, 0);
+ cval.ts = tok_alloc(file->filename, 0);
tok_add2(tok_str, tok_len, TOK_STR, &cval);
} else if (tok == TOK___DATE__) {
cval.ts = tok_alloc("Jan 1 1970", 0);
@@ -3912,8 +3999,10 @@ int parse_btype(int *type_ptr, AttributeDef *ad)
case TOK_VOLATILE:
case TOK_REGISTER:
case TOK_SIGNED:
+ case TOK___SIGNED__:
case TOK_AUTO:
case TOK_INLINE:
+ case TOK___INLINE__:
case TOK_RESTRICT:
next();
break;
@@ -4665,10 +4754,10 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
/* generate line number info */
if (do_debug &&
- (last_line_num != line_num || last_ind != ind)) {
- put_stabn(N_SLINE, 0, line_num, ind - func_ind);
+ (last_line_num != file->line_num || last_ind != ind)) {
+ put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
last_ind = ind;
- last_line_num = line_num;
+ last_line_num = file->line_num;
}
if (tok == TOK_IF) {
@@ -5339,7 +5428,7 @@ void put_func_debug(int t)
/* XXX: we put here a dummy type */
snprintf(buf, sizeof(buf), "%s:%c1",
funcname, t & VT_STATIC ? 'f' : 'F');
- put_stabs(buf, N_FUN, 0, line_num, ind);
+ put_stabs(buf, N_FUN, 0, file->line_num, ind);
func_ind = ind;
last_ind = 0;
last_line_num = 0;
@@ -5533,13 +5622,11 @@ int tcc_compile_file(const char *filename1)
Sym *define_start;
char buf[512];
- line_num = 1;
funcname = "";
- filename = (char *)filename1;
- file = fopen(filename, "r");
+ file = tcc_open(filename1);
if (!file)
- error("file '%s' not found", filename);
+ error("file '%s' not found", filename1);
include_stack_ptr = include_stack;
ifdef_stack_ptr = ifdef_stack;
@@ -5551,7 +5638,8 @@ int tcc_compile_file(const char *filename1)
getcwd(buf, sizeof(buf));
pstrcat(buf, sizeof(buf), "/");
put_stabs(buf, N_SO, 0, 0, (unsigned long)text_section->data_ptr);
- put_stabs(filename, N_SO, 0, 0, (unsigned long)text_section->data_ptr);
+ put_stabs(file->filename, N_SO, 0, 0,
+ (unsigned long)text_section->data_ptr);
}
/* define common 'char *' type because it is often used internally
for arrays and struct dereference */
@@ -5564,7 +5652,7 @@ int tcc_compile_file(const char *filename1)
decl(VT_CONST);
if (tok != -1)
expect("declaration");
- fclose(file);
+ tcc_close(file);
/* end of translation unit info */
if (do_debug) {
@@ -5993,6 +6081,7 @@ void rt_error(unsigned long pc, const char *fmt, ...)
va_end(ap);
}
+#ifndef WIN32
/* signal handler for fatal errors */
static void sig_error(int signum, siginfo_t *siginf, void *puc)
{
@@ -6033,19 +6122,23 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc)
}
exit(255);
}
+#endif
/* launch the compiled program with the given arguments */
int launch_exe(int argc, char **argv)
{
Sym *s;
int (*t)();
- struct sigaction sigact;
s = sym_find1(&extern_stack, TOK_MAIN);
if (!s || (s->r & VT_FORWARD))
error("main() not defined");
if (do_debug) {
+#ifdef WIN32
+ error("debug mode currently not available for Windows");
+#else
+ struct sigaction sigact;
/* install TCC signal handlers to print debug info on fatal
runtime errors */
sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
@@ -6056,9 +6149,13 @@ int launch_exe(int argc, char **argv)
sigaction(SIGSEGV, &sigact, NULL);
sigaction(SIGBUS, &sigact, NULL);
sigaction(SIGABRT, &sigact, NULL);
+#endif
}
if (do_bounds_check) {
+#ifdef WIN32
+ error("bound checking currently not available for Windows");
+#else
int *p, *p_end;
__bound_init();
/* add all known static regions */
@@ -6068,6 +6165,7 @@ int launch_exe(int argc, char **argv)
__bound_new_region((void *)p[0], p[1]);
p += 2;
}
+#endif
}
t = (int (*)())s->c;
@@ -6077,7 +6175,7 @@ int launch_exe(int argc, char **argv)
void help(void)
{
- printf("tcc version 0.9.3 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
+ printf("tcc version 0.9.4 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
"usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
" [-i infile] infile [infile_args...]\n"
"\n"
@@ -6103,7 +6201,7 @@ int main(int argc, char **argv)
/* add all tokens */
tok_ident = TOK_IDENT;
- p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0auto\0inline\0restrict\0float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0__attribute__\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0";
+ p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0__attribute__\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0";
while (*p) {
r = p;
while (*r++);