initial PE format support

tcc-xref
bellard 2005-04-10 21:46:58 +00:00
parent bdd09709d7
commit 2c538d7a2b
5 changed files with 1314 additions and 19 deletions

View File

@ -20,7 +20,7 @@ endif
DISAS=objdump -d
INSTALL=install
PROGS=tcc$(EXESUF) c67-tcc$(EXESUF) arm-tcc$(EXESUF)
PROGS=tcc$(EXESUF) c67-tcc$(EXESUF) arm-tcc$(EXESUF) i386-win32-tcc$(EXESUF)
# run local version of tcc with local libraries and includes
TCC=./tcc -B. -I.
@ -125,6 +125,9 @@ c67-tcc$(EXESUF): tcc.c c67-gen.c tccelf.c tccasm.c tcctok.h libtcc.h tcccoff.c
arm-tcc$(EXESUF): tcc.c arm-gen.c tccelf.c tccasm.c tcctok.h libtcc.h Makefile
$(CC) $(CFLAGS) -DTCC_TARGET_ARM -o $@ $< $(LIBS)
i386-win32-tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h tccpe.c Makefile
$(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS)
# TinyCC runtime libraries
libtcc1.o: libtcc1.c
$(CC) -O2 -Wall -c -o $@ $<

100
tcc.c
View File

@ -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);
@ -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 */

View File

@ -385,11 +385,6 @@ static void relocate_common_syms(void)
}
}
static void *resolve_sym(const char *sym)
{
return dlsym(RTLD_DEFAULT, sym);
}
/* relocate symbol table, resolve undefined symbols if do_resolve is
true and output error if undefined symbol. */
static void relocate_syms(TCCState *s1, int do_resolve)
@ -408,7 +403,7 @@ static void relocate_syms(TCCState *s1, int do_resolve)
name = strtab_section->data + sym->st_name;
if (do_resolve) {
name = symtab_section->link->data + sym->st_name;
addr = (unsigned long)resolve_sym(name);
addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
if (addr) {
sym->st_value = addr;
goto found;

1220
tccpe.c 100644

File diff suppressed because it is too large Load Diff

View File

@ -100,6 +100,7 @@
DEF(TOK_STDCALL1, "stdcall")
DEF(TOK_STDCALL2, "__stdcall")
DEF(TOK_STDCALL3, "__stdcall__")
DEF(TOK_DLLEXPORT, "dllexport")
DEF(TOK_NORETURN1, "noreturn")
DEF(TOK_NORETURN2, "__noreturn__")
DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")