unsorted adjustments
- configure
* use aarch64 instead of arm64
- Makefile
* rename the custom include file to "config-extra.mak"
* Also avoid "rm -r /*" if $(tccdir) is empty
- pp/Makefile
* fix .expect generation with gcc
- tcc.h
* cleanup #defines for _MSC_VER
- tccgen.c:
* fix const-propagation for &,|
* fix anonymous named struct (ms-extension) and enable
-fms-extension by default
- i386-gen.c
* clear VT_DEFSIGN
- x86_64-gen.c/win64:
* fix passing structs in registers
* fix alloca (need to keep "func_scratch" below each alloca area on stack)
(This allows to compile a working gnu-make on win64)
- tccpp.c
* alternative approach to 37999a4fbf
This is to avoid some slowdown with ## token pasting.
* get_tok_str() : return <eof> for TOK_EOF
* -funsigned-char: apply to "string" literals as well
- tccpe/tools.c: -impdef: support both 32 and 64 bit dlls anyway
This commit is contained in:
parent
6c468c10f7
commit
9f79b62ec4
11 changed files with 105 additions and 80 deletions
29
Makefile
29
Makefile
|
@ -151,8 +151,8 @@ DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# include custom cross-compiler configuration (see make help)
|
# include custom configuration (see make help)
|
||||||
-include config-cross.mak
|
-include config-extra.mak
|
||||||
|
|
||||||
CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
||||||
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
||||||
|
@ -318,7 +318,7 @@ install-win : INSTALL = cp
|
||||||
|
|
||||||
# uninstall on windows
|
# uninstall on windows
|
||||||
uninstall-win:
|
uninstall-win:
|
||||||
rm -r "$(tccdir)/"*
|
rm -r "$(tccdir)"
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# other stuff
|
# other stuff
|
||||||
|
@ -374,19 +374,24 @@ help:
|
||||||
@echo " build one specific cross compiler for 'TARGET', as in"
|
@echo " build one specific cross compiler for 'TARGET', as in"
|
||||||
@echo " $(TCC_X)"
|
@echo " $(TCC_X)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Cross compiler configuration:"
|
@echo "Custom configuration:"
|
||||||
@echo " make will read custom configuration for cross compilers from a file"
|
@echo " The makefile includes a file 'config-extra.mak' if it is present."
|
||||||
@echo " 'config-cross.mak' if present. For example for a windows->i386-linux"
|
@echo " This file may contain some custom configuration. For example:"
|
||||||
@echo " cross-compiler that expects the linux files in <tccdir>/i386-linux:"
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " ROOT-i386 = {B}/i386-linux"
|
@echo " NATIVE_DEFINES += -D..."
|
||||||
@echo " CRT-i386 = {B}/i386-linux/usr/lib"
|
@echo ""
|
||||||
@echo " LIB-i386 = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
|
@echo " Or for example to configure the search paths for a cross-compiler"
|
||||||
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
|
@echo " that expects the linux files in <tccdir>/i386-linux:"
|
||||||
@echo " DEF-i386 += -D__linux__"
|
@echo ""
|
||||||
|
@echo " ROOT-i386 = {B}/i386-linux"
|
||||||
|
@echo " CRT-i386 = {B}/i386-linux/usr/lib"
|
||||||
|
@echo " LIB-i386 = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
|
||||||
|
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
|
||||||
|
@echo " DEF-i386 += -D__linux__"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Other supported make targets:"
|
@echo "Other supported make targets:"
|
||||||
@echo " install install-strip test tags ETAGS tar clean distclean help"
|
@echo " install install-strip test tags ETAGS tar clean distclean help"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
endif # ($(INCLUDED),no)
|
endif # ($(INCLUDED),no)
|
||||||
|
|
14
configure
vendored
14
configure
vendored
|
@ -161,7 +161,7 @@ fi
|
||||||
|
|
||||||
case "$cpu" in
|
case "$cpu" in
|
||||||
x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
|
x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
|
||||||
cpu="x86"
|
cpu="i386"
|
||||||
;;
|
;;
|
||||||
x86_64|amd64|x86-64)
|
x86_64|amd64|x86-64)
|
||||||
cpu="x86_64"
|
cpu="x86_64"
|
||||||
|
@ -184,7 +184,7 @@ case "$cpu" in
|
||||||
cpu="arm"
|
cpu="arm"
|
||||||
;;
|
;;
|
||||||
aarch64)
|
aarch64)
|
||||||
cpu="arm64"
|
cpu="aarch64"
|
||||||
;;
|
;;
|
||||||
alpha)
|
alpha)
|
||||||
cpu="alpha"
|
cpu="alpha"
|
||||||
|
@ -301,7 +301,7 @@ Advanced options (experts only):
|
||||||
--disable-static make libtcc.so instead of libtcc.a
|
--disable-static make libtcc.so instead of libtcc.a
|
||||||
--enable-static make libtcc.a instead of libtcc.dll (win32)
|
--enable-static make libtcc.a instead of libtcc.dll (win32)
|
||||||
--disable-rpath disable use of -rpath with the above
|
--disable-rpath disable use of -rpath with the above
|
||||||
--with-libgcc use libgcc_s.so.1 instead of libtcc1.a in dynamic link
|
--with-libgcc use libgcc_s.so.1 instead of libtcc1.a
|
||||||
--enable-mingw32 build windows version on linux with mingw32
|
--enable-mingw32 build windows version on linux with mingw32
|
||||||
--enable-cross build cross compilers
|
--enable-cross build cross compilers
|
||||||
--with-selinux use mmap for executable memory (with tcc -run)
|
--with-selinux use mmap for executable memory (with tcc -run)
|
||||||
|
@ -340,7 +340,7 @@ if test -z "$cross_prefix" ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -z "$triplet"; then
|
if test -z "$triplet"; then
|
||||||
if test $cpu = "x86_64" -o $cpu = "arm64" ; then
|
if test $cpu = "x86_64" -o $cpu = "aarch64" ; then
|
||||||
if test -f "/usr/lib64/crti.o" ; then
|
if test -f "/usr/lib64/crti.o" ; then
|
||||||
tcc_lddir="lib64"
|
tcc_lddir="lib64"
|
||||||
fi
|
fi
|
||||||
|
@ -473,13 +473,11 @@ print_mak_int TCC_CPU_VERSION "$cpuver"
|
||||||
|
|
||||||
echo "#define GCC_MAJOR $gcc_major" >> $TMPH
|
echo "#define GCC_MAJOR $gcc_major" >> $TMPH
|
||||||
echo "#define GCC_MINOR $gcc_minor" >> $TMPH
|
echo "#define GCC_MINOR $gcc_minor" >> $TMPH
|
||||||
|
if test "$cpu" = "aarch64" ; then
|
||||||
if test "$cpu" = "x86" ; then
|
echo "ARCH=arm64" >> config.mak
|
||||||
echo "ARCH=i386" >> config.mak
|
|
||||||
else
|
else
|
||||||
echo "ARCH=$cpu" >> config.mak
|
echo "ARCH=$cpu" >> config.mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "TARGETOS=$targetos" >> config.mak
|
echo "TARGETOS=$targetos" >> config.mak
|
||||||
|
|
||||||
for v in $confvars ; do
|
for v in $confvars ; do
|
||||||
|
|
|
@ -210,7 +210,7 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fr = sv->r;
|
fr = sv->r;
|
||||||
ft = sv->type.t;
|
ft = sv->type.t & ~VT_DEFSIGN;
|
||||||
fc = sv->c.i;
|
fc = sv->c.i;
|
||||||
|
|
||||||
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
||||||
|
|
|
@ -27,10 +27,6 @@ p2:
|
||||||
|
|
||||||
sub %rax,%rsp
|
sub %rax,%rsp
|
||||||
mov %rsp,%rax
|
mov %rsp,%rax
|
||||||
#ifdef TCC_TARGET_PE
|
|
||||||
add $32,%rax
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p3:
|
p3:
|
||||||
push %rdx
|
push %rdx
|
||||||
ret
|
ret
|
||||||
|
|
14
libtcc.c
14
libtcc.c
|
@ -264,7 +264,7 @@ struct mem_debug_header {
|
||||||
int line_num;
|
int line_num;
|
||||||
char file_name[MEM_DEBUG_FILE_LEN + 1];
|
char file_name[MEM_DEBUG_FILE_LEN + 1];
|
||||||
unsigned magic2;
|
unsigned magic2;
|
||||||
__attribute__((aligned(16))) unsigned magic3;
|
ALIGNED(16) unsigned magic3;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct mem_debug_header mem_debug_header_t;
|
typedef struct mem_debug_header mem_debug_header_t;
|
||||||
|
@ -581,10 +581,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
|
||||||
bf->buf_end = bf->buffer + initlen;
|
bf->buf_end = bf->buffer + initlen;
|
||||||
bf->buf_end[0] = CH_EOB; /* put eob symbol */
|
bf->buf_end[0] = CH_EOB; /* put eob symbol */
|
||||||
pstrcpy(bf->filename, sizeof(bf->filename), filename);
|
pstrcpy(bf->filename, sizeof(bf->filename), filename);
|
||||||
pstrcpy(bf->filename2, sizeof(bf->filename2), filename);
|
bf->true_filename = bf->filename;
|
||||||
#ifdef _WIN32
|
|
||||||
normalize_slashes(bf->filename);
|
|
||||||
#endif
|
|
||||||
bf->line_num = 1;
|
bf->line_num = 1;
|
||||||
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||||
bf->fd = -1;
|
bf->fd = -1;
|
||||||
|
@ -599,6 +596,8 @@ ST_FUNC void tcc_close(void)
|
||||||
close(bf->fd);
|
close(bf->fd);
|
||||||
total_lines += bf->line_num;
|
total_lines += bf->line_num;
|
||||||
}
|
}
|
||||||
|
if (bf->true_filename != bf->filename)
|
||||||
|
tcc_free(bf->true_filename);
|
||||||
file = bf->prev;
|
file = bf->prev;
|
||||||
tcc_free(bf);
|
tcc_free(bf);
|
||||||
}
|
}
|
||||||
|
@ -615,8 +614,10 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename)
|
||||||
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
|
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tcc_open_bf(s1, filename, 0);
|
tcc_open_bf(s1, filename, 0);
|
||||||
|
#ifdef _WIN32
|
||||||
|
normalize_slashes(file->filename);
|
||||||
|
#endif
|
||||||
file->fd = fd;
|
file->fd = fd;
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -737,6 +738,7 @@ LIBTCCAPI TCCState *tcc_new(void)
|
||||||
s->alacarte_link = 1;
|
s->alacarte_link = 1;
|
||||||
s->nocommon = 1;
|
s->nocommon = 1;
|
||||||
s->warn_implicit_function_declaration = 1;
|
s->warn_implicit_function_declaration = 1;
|
||||||
|
s->ms_extensions = 1;
|
||||||
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
#ifdef CHAR_IS_UNSIGNED
|
||||||
s->char_is_unsigned = 1;
|
s->char_is_unsigned = 1;
|
||||||
|
|
22
tcc.h
22
tcc.h
|
@ -41,10 +41,11 @@
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
# endif
|
# endif
|
||||||
/* XXX: need to define this to use them in non ISOC99 context */
|
/* XXX: need to define this to use them in non ISOC99 context */
|
||||||
extern float strtof (const char *__nptr, char **__endptr);
|
extern float strtof (const char *__nptr, char **__endptr);
|
||||||
extern long double strtold (const char *__nptr, char **__endptr);
|
extern long double strtold (const char *__nptr, char **__endptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
#else /* on _WIN32: */
|
#ifdef _WIN32
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <io.h> /* open, close etc. */
|
# include <io.h> /* open, close etc. */
|
||||||
# include <direct.h> /* getcwd */
|
# include <direct.h> /* getcwd */
|
||||||
|
@ -52,7 +53,6 @@
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# endif
|
# endif
|
||||||
# define inline __inline
|
# define inline __inline
|
||||||
# define inp next_inp /* inp is an intrinsic on msvc */
|
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
# define vsnprintf _vsnprintf
|
# define vsnprintf _vsnprintf
|
||||||
# ifndef __GNUC__
|
# ifndef __GNUC__
|
||||||
|
@ -65,6 +65,7 @@
|
||||||
# define LIBTCCAPI __declspec(dllexport)
|
# define LIBTCCAPI __declspec(dllexport)
|
||||||
# define PUB_FUNC LIBTCCAPI
|
# define PUB_FUNC LIBTCCAPI
|
||||||
# endif
|
# endif
|
||||||
|
# define inp next_inp /* inp is an intrinsic on msvc/mingw */
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data
|
# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data
|
||||||
# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data
|
# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data
|
||||||
|
@ -72,9 +73,6 @@
|
||||||
# pragma warning (disable : 4018) // signed/unsigned mismatch
|
# pragma warning (disable : 4018) // signed/unsigned mismatch
|
||||||
# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||||
# define ssize_t intptr_t
|
# define ssize_t intptr_t
|
||||||
# define __attribute__(x) __declspec x
|
|
||||||
# define aligned align
|
|
||||||
# else
|
|
||||||
# endif
|
# endif
|
||||||
# undef CONFIG_TCC_STATIC
|
# undef CONFIG_TCC_STATIC
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,12 +81,12 @@
|
||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef _MSC_VER
|
||||||
# define NORETURN __attribute__ ((noreturn))
|
|
||||||
#elif defined _MSC_VER
|
|
||||||
# define NORETURN __declspec(noreturn)
|
# define NORETURN __declspec(noreturn)
|
||||||
|
# define ALIGNED(x) __declspec(align(x))
|
||||||
#else
|
#else
|
||||||
# define NORETURN
|
# define NORETURN __attribute__((noreturn))
|
||||||
|
# define ALIGNED(x) __attribute__((aligned(x)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -540,7 +538,7 @@ typedef struct BufferedFile {
|
||||||
int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
|
int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
|
||||||
int include_next_index; /* next search path */
|
int include_next_index; /* next search path */
|
||||||
char filename[1024]; /* filename */
|
char filename[1024]; /* filename */
|
||||||
char filename2[1024]; /* filename not modified by # line directive */
|
char *true_filename; /* filename not modified by # line directive */
|
||||||
unsigned char unget[4];
|
unsigned char unget[4];
|
||||||
unsigned char buffer[1]; /* extra size for CH_EOB char */
|
unsigned char buffer[1]; /* extra size for CH_EOB char */
|
||||||
} BufferedFile;
|
} BufferedFile;
|
||||||
|
|
14
tccgen.c
14
tccgen.c
|
@ -1752,8 +1752,8 @@ static void gen_opic(int op)
|
||||||
vtop--;
|
vtop--;
|
||||||
} else if (!const_wanted &&
|
} else if (!const_wanted &&
|
||||||
c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
|
c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
|
||||||
(l2 == -1 && op == '|') ||
|
(op == '|' &&
|
||||||
(l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
|
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
|
||||||
(l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
|
(l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
|
||||||
/* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
|
/* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
|
||||||
if (l2 == 1)
|
if (l2 == 1)
|
||||||
|
@ -1767,7 +1767,7 @@ static void gen_opic(int op)
|
||||||
op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
|
op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
|
||||||
l2 == 0) ||
|
l2 == 0) ||
|
||||||
(op == '&' &&
|
(op == '&' &&
|
||||||
l2 == -1))) {
|
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
|
||||||
/* filter out NOP operations like x*1, x-0, x&-1... */
|
/* filter out NOP operations like x*1, x-0, x&-1... */
|
||||||
vtop--;
|
vtop--;
|
||||||
} else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
|
} else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
|
||||||
|
@ -1817,6 +1817,10 @@ static void gen_opif(int op)
|
||||||
{
|
{
|
||||||
int c1, c2;
|
int c1, c2;
|
||||||
SValue *v1, *v2;
|
SValue *v1, *v2;
|
||||||
|
#if defined _MSC_VER && defined _AMD64_
|
||||||
|
/* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
|
||||||
|
volatile
|
||||||
|
#endif
|
||||||
long double f1, f2;
|
long double f1, f2;
|
||||||
|
|
||||||
v1 = vtop - 1;
|
v1 = vtop - 1;
|
||||||
|
@ -3497,7 +3501,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
|
||||||
if (v < TOK_IDENT)
|
if (v < TOK_IDENT)
|
||||||
expect("struct/union/enum name");
|
expect("struct/union/enum name");
|
||||||
s = struct_find(v);
|
s = struct_find(v);
|
||||||
if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
|
if (s && (s->scope == local_scope || tok != '{')) {
|
||||||
if (s->type.t != a)
|
if (s->type.t != a)
|
||||||
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
|
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
|
||||||
goto do_decl;
|
goto do_decl;
|
||||||
|
@ -4381,6 +4385,8 @@ ST_FUNC void unary(void)
|
||||||
case TOK_STR:
|
case TOK_STR:
|
||||||
/* string parsing */
|
/* string parsing */
|
||||||
t = VT_BYTE;
|
t = VT_BYTE;
|
||||||
|
if (tcc_state->char_is_unsigned)
|
||||||
|
t = VT_BYTE | VT_UNSIGNED;
|
||||||
str_init:
|
str_init:
|
||||||
if (tcc_state->warn_write_strings)
|
if (tcc_state->warn_write_strings)
|
||||||
t |= VT_CONSTANT;
|
t |= VT_CONSTANT;
|
||||||
|
|
37
tccpe.c
37
tccpe.c
|
@ -1547,11 +1547,7 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||||
IMAGE_DOS_HEADER dh;
|
IMAGE_DOS_HEADER dh;
|
||||||
IMAGE_FILE_HEADER ih;
|
IMAGE_FILE_HEADER ih;
|
||||||
DWORD sig, ref, addr, ptr, namep;
|
DWORD sig, ref, addr, ptr, namep;
|
||||||
#ifdef TCC_TARGET_X86_64
|
|
||||||
IMAGE_OPTIONAL_HEADER64 oh;
|
|
||||||
#else
|
|
||||||
IMAGE_OPTIONAL_HEADER32 oh;
|
|
||||||
#endif
|
|
||||||
int pef_hdroffset, opt_hdroffset, sec_hdroffset;
|
int pef_hdroffset, opt_hdroffset, sec_hdroffset;
|
||||||
|
|
||||||
n = n0 = 0;
|
n = n0 = 0;
|
||||||
|
@ -1562,7 +1558,6 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto the_end_1;
|
goto the_end_1;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
if (!read_mem(fd, 0, &dh, sizeof dh))
|
if (!read_mem(fd, 0, &dh, sizeof dh))
|
||||||
goto the_end;
|
goto the_end;
|
||||||
if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
|
if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
|
||||||
|
@ -1572,22 +1567,26 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||||
pef_hdroffset = dh.e_lfanew + sizeof sig;
|
pef_hdroffset = dh.e_lfanew + sizeof sig;
|
||||||
if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
|
if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
|
||||||
goto the_end;
|
goto the_end;
|
||||||
if (IMAGE_FILE_MACHINE != ih.Machine) {
|
|
||||||
if (ih.Machine == 0x014C)
|
|
||||||
ret = 32;
|
|
||||||
else if (ih.Machine == 0x8664)
|
|
||||||
ret = 64;
|
|
||||||
goto the_end;
|
|
||||||
}
|
|
||||||
opt_hdroffset = pef_hdroffset + sizeof ih;
|
opt_hdroffset = pef_hdroffset + sizeof ih;
|
||||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
if (ih.Machine == 0x014C) {
|
||||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
IMAGE_OPTIONAL_HEADER32 oh;
|
||||||
|
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||||
|
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||||
|
goto the_end;
|
||||||
|
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||||
|
goto the_end_0;
|
||||||
|
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||||
|
} else if (ih.Machine == 0x8664) {
|
||||||
|
IMAGE_OPTIONAL_HEADER64 oh;
|
||||||
|
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||||
|
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||||
|
goto the_end;
|
||||||
|
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||||
|
goto the_end_0;
|
||||||
|
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||||
|
} else
|
||||||
goto the_end;
|
goto the_end;
|
||||||
|
|
||||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
|
||||||
goto the_end_0;
|
|
||||||
|
|
||||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
||||||
//printf("addr: %08x\n", addr);
|
//printf("addr: %08x\n", addr);
|
||||||
for (i = 0; i < ih.NumberOfSections; ++i) {
|
for (i = 0; i < ih.NumberOfSections; ++i) {
|
||||||
if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
|
if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
|
||||||
|
|
11
tccpp.c
11
tccpp.c
|
@ -531,7 +531,6 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* above tokens have value, the ones below don't */
|
/* above tokens have value, the ones below don't */
|
||||||
|
|
||||||
case TOK_LT:
|
case TOK_LT:
|
||||||
v = '<';
|
v = '<';
|
||||||
goto addv;
|
goto addv;
|
||||||
|
@ -544,6 +543,8 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
||||||
return strcpy(p, "<<=");
|
return strcpy(p, "<<=");
|
||||||
case TOK_A_SAR:
|
case TOK_A_SAR:
|
||||||
return strcpy(p, ">>=");
|
return strcpy(p, ">>=");
|
||||||
|
case TOK_EOF:
|
||||||
|
return strcpy(p, "<eof>");
|
||||||
default:
|
default:
|
||||||
if (v < TOK_IDENT) {
|
if (v < TOK_IDENT) {
|
||||||
/* search in two bytes table */
|
/* search in two bytes table */
|
||||||
|
@ -1791,7 +1792,7 @@ ST_FUNC void preprocess(int is_bof)
|
||||||
if (c != '\"')
|
if (c != '\"')
|
||||||
continue;
|
continue;
|
||||||
/* https://savannah.nongnu.org/bugs/index.php?50847 */
|
/* https://savannah.nongnu.org/bugs/index.php?50847 */
|
||||||
path = file->filename2;
|
path = file->true_filename;
|
||||||
pstrncpy(buf1, path, tcc_basename(path) - path);
|
pstrncpy(buf1, path, tcc_basename(path) - path);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1921,9 +1922,11 @@ include_done:
|
||||||
_line_num:
|
_line_num:
|
||||||
next();
|
next();
|
||||||
if (tok != TOK_LINEFEED) {
|
if (tok != TOK_LINEFEED) {
|
||||||
if (tok == TOK_STR)
|
if (tok == TOK_STR) {
|
||||||
|
if (file->true_filename == file->filename)
|
||||||
|
file->true_filename = tcc_strdup(file->filename);
|
||||||
pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
|
pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
|
||||||
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
goto _line_err;
|
goto _line_err;
|
||||||
|
|
|
@ -363,9 +363,8 @@ usage:
|
||||||
ret = tcc_get_dllexports(file, &p);
|
ret = tcc_get_dllexports(file, &p);
|
||||||
if (ret || !p) {
|
if (ret || !p) {
|
||||||
fprintf(stderr, "tcc: impdef: %s '%s'\n",
|
fprintf(stderr, "tcc: impdef: %s '%s'\n",
|
||||||
ret == 32 ? "can't read symbols from 32bit" :
|
|
||||||
ret == 64 ? "can't read symbols from 64bit" :
|
|
||||||
ret == -1 ? "can't find file" :
|
ret == -1 ? "can't find file" :
|
||||||
|
ret == 1 ? "can't read symbols" :
|
||||||
ret == 0 ? "no symbols found in" :
|
ret == 0 ? "no symbols found in" :
|
||||||
"unknown file type", file);
|
"unknown file type", file);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
35
x86_64-gen.c
35
x86_64-gen.c
|
@ -728,13 +728,13 @@ static int arg_prepare_reg(int idx) {
|
||||||
return arg_regs[idx];
|
return arg_regs[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int func_scratch;
|
static int func_scratch, func_alloca;
|
||||||
|
|
||||||
/* Generate function call. The function address is pushed first, then
|
/* Generate function call. The function address is pushed first, then
|
||||||
all the parameters in call order. This functions pops all the
|
all the parameters in call order. This functions pops all the
|
||||||
parameters and the function address. */
|
parameters and the function address. */
|
||||||
|
|
||||||
void gen_offs_sp(int b, int r, int d)
|
static void gen_offs_sp(int b, int r, int d)
|
||||||
{
|
{
|
||||||
orex(1,0,r & 0x100 ? 0 : r, b);
|
orex(1,0,r & 0x100 ? 0 : r, b);
|
||||||
if (d == (char)d) {
|
if (d == (char)d) {
|
||||||
|
@ -746,6 +746,11 @@ void gen_offs_sp(int b, int r, int d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int using_regs(int size)
|
||||||
|
{
|
||||||
|
return !(size > 8 || (size & (size - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the number of registers needed to return the struct, or 0 if
|
/* Return the number of registers needed to return the struct, or 0 if
|
||||||
returning via struct pointer. */
|
returning via struct pointer. */
|
||||||
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
|
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
|
||||||
|
@ -754,7 +759,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int
|
||||||
*ret_align = 1; // Never have to re-align return values for x86-64
|
*ret_align = 1; // Never have to re-align return values for x86-64
|
||||||
*regsize = 8;
|
*regsize = 8;
|
||||||
size = type_size(vt, &align);
|
size = type_size(vt, &align);
|
||||||
if (size > 8 || (size & (size - 1)))
|
if (!using_regs(size))
|
||||||
return 0;
|
return 0;
|
||||||
if (size == 8)
|
if (size == 8)
|
||||||
ret->t = VT_LLONG;
|
ret->t = VT_LLONG;
|
||||||
|
@ -774,7 +779,7 @@ static int is_sse_float(int t) {
|
||||||
return bt == VT_DOUBLE || bt == VT_FLOAT;
|
return bt == VT_DOUBLE || bt == VT_FLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gfunc_arg_size(CType *type) {
|
static int gfunc_arg_size(CType *type) {
|
||||||
int align;
|
int align;
|
||||||
if (type->t & (VT_ARRAY|VT_BITFIELD))
|
if (type->t & (VT_ARRAY|VT_BITFIELD))
|
||||||
return 8;
|
return 8;
|
||||||
|
@ -801,7 +806,7 @@ void gfunc_call(int nb_args)
|
||||||
bt = (sv->type.t & VT_BTYPE);
|
bt = (sv->type.t & VT_BTYPE);
|
||||||
size = gfunc_arg_size(&sv->type);
|
size = gfunc_arg_size(&sv->type);
|
||||||
|
|
||||||
if (size <= 8)
|
if (using_regs(size))
|
||||||
continue; /* arguments smaller than 8 bytes passed in registers or on stack */
|
continue; /* arguments smaller than 8 bytes passed in registers or on stack */
|
||||||
|
|
||||||
if (bt == VT_STRUCT) {
|
if (bt == VT_STRUCT) {
|
||||||
|
@ -835,7 +840,7 @@ void gfunc_call(int nb_args)
|
||||||
bt = (vtop->type.t & VT_BTYPE);
|
bt = (vtop->type.t & VT_BTYPE);
|
||||||
|
|
||||||
size = gfunc_arg_size(&vtop->type);
|
size = gfunc_arg_size(&vtop->type);
|
||||||
if (size > 8) {
|
if (!using_regs(size)) {
|
||||||
/* align to stack align size */
|
/* align to stack align size */
|
||||||
size = (size + 15) & ~15;
|
size = (size + 15) & ~15;
|
||||||
if (arg >= REGN) {
|
if (arg >= REGN) {
|
||||||
|
@ -895,6 +900,12 @@ void gfunc_call(int nb_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
gcall_or_jmp(0);
|
gcall_or_jmp(0);
|
||||||
|
|
||||||
|
if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
|
||||||
|
/* need to add the "func_scratch" area after alloca */
|
||||||
|
o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
|
||||||
|
}
|
||||||
|
|
||||||
/* other compilers don't clear the upper bits when returning char/short */
|
/* other compilers don't clear the upper bits when returning char/short */
|
||||||
bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
|
bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
|
||||||
if (bt == (VT_BYTE | VT_UNSIGNED))
|
if (bt == (VT_BYTE | VT_UNSIGNED))
|
||||||
|
@ -926,6 +937,7 @@ void gfunc_prolog(CType *func_type)
|
||||||
|
|
||||||
func_ret_sub = 0;
|
func_ret_sub = 0;
|
||||||
func_scratch = 0;
|
func_scratch = 0;
|
||||||
|
func_alloca = 0;
|
||||||
loc = 0;
|
loc = 0;
|
||||||
|
|
||||||
addr = PTR_SIZE * 2;
|
addr = PTR_SIZE * 2;
|
||||||
|
@ -940,7 +952,7 @@ void gfunc_prolog(CType *func_type)
|
||||||
func_vt = sym->type;
|
func_vt = sym->type;
|
||||||
func_var = (sym->c == FUNC_ELLIPSIS);
|
func_var = (sym->c == FUNC_ELLIPSIS);
|
||||||
size = gfunc_arg_size(&func_vt);
|
size = gfunc_arg_size(&func_vt);
|
||||||
if (size > 8) {
|
if (!using_regs(size)) {
|
||||||
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
|
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
|
||||||
func_vc = addr;
|
func_vc = addr;
|
||||||
reg_param_index++;
|
reg_param_index++;
|
||||||
|
@ -952,7 +964,7 @@ void gfunc_prolog(CType *func_type)
|
||||||
type = &sym->type;
|
type = &sym->type;
|
||||||
bt = type->t & VT_BTYPE;
|
bt = type->t & VT_BTYPE;
|
||||||
size = gfunc_arg_size(type);
|
size = gfunc_arg_size(type);
|
||||||
if (size > 8) {
|
if (!using_regs(size)) {
|
||||||
if (reg_param_index < REGN) {
|
if (reg_param_index < REGN) {
|
||||||
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
|
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
|
||||||
}
|
}
|
||||||
|
@ -1015,6 +1027,13 @@ void gfunc_epilog(void)
|
||||||
gen_le32(v);
|
gen_le32(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add the "func_scratch" area after each alloca seen */
|
||||||
|
while (func_alloca) {
|
||||||
|
unsigned char *ptr = cur_text_section->data + func_alloca;
|
||||||
|
func_alloca = read32le(ptr);
|
||||||
|
write32le(ptr, func_scratch);
|
||||||
|
}
|
||||||
|
|
||||||
cur_text_section->data_offset = saved_ind;
|
cur_text_section->data_offset = saved_ind;
|
||||||
pe_add_unwind_data(ind, saved_ind, v);
|
pe_add_unwind_data(ind, saved_ind, v);
|
||||||
ind = cur_text_section->data_offset;
|
ind = cur_text_section->data_offset;
|
||||||
|
|
Loading…
Reference in a new issue