mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-26 08:00:09 +08:00
initial PE format support
This commit is contained in:
parent
bdd09709d7
commit
2c538d7a2b
5
Makefile
5
Makefile
@ -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
100
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);
|
||||
@ -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 */
|
||||
|
7
tccelf.c
7
tccelf.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user