debug_modes, re-unalign, cleanups
tccgen.c: debug_modes - don't waste debug function calls during normal execution. libtcc.c: - mem_debug: no C99 features in tcc please, for example ({compound expressions}): do not use. tccgen.c: struct_layout: - unaligned access is completely ok for most targets. - Moreover the patch was triggering single byte mode even for normal aligned access (as with tcc's SymAttr) static Sym label: don't do this arm-gen.c: - use some #ifdefs to explain some code tccpp.c: - cleanup UCN chars libtcc.c: - replace openbsd library search configure: - cleanup strip fallouts tccgen.c: - expr_cond(): remove an exotic optimization that eventually got fixed to do the contrary by a gv(RC_InT) - pop_local_syms(): remove some args - init_putv() : use write##le functions to avoid cross-compiler unaligned access - __bt_init(): remove unused param 'mode'
This commit is contained in:
parent
5043268cb1
commit
1ed4b6ba1a
13 changed files with 356 additions and 419 deletions
4
Makefile
4
Makefile
|
@ -12,8 +12,6 @@ ifeq ($(findstring $(MAKECMDGOALS),clean distclean),)
|
|||
include $(TOP)/config.mak
|
||||
endif
|
||||
|
||||
CONFIG_strip = no
|
||||
|
||||
ifeq (-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-4--)
|
||||
CFLAGS += -D_FORTIFY_SOURCE=0
|
||||
endif
|
||||
|
@ -221,7 +219,7 @@ $(TCC_FILES) : DEFINES += -DONE_SOURCE=0
|
|||
$(X)tccpp.o : $(TCCDEFS_H)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_strip),no)
|
||||
ifeq ($(CONFIG_debug),yes)
|
||||
CFLAGS += -g
|
||||
LDFLAGS += -g
|
||||
else
|
||||
|
|
26
arm-gen.c
26
arm-gen.c
|
@ -541,8 +541,13 @@ static int negcc(int cc)
|
|||
Use relative/got addressing to avoid setting DT_TEXTREL */
|
||||
static void load_value(SValue *sv, int r)
|
||||
{
|
||||
o(0xE59F0000|(intr(r)<<12));
|
||||
o(0xEA000000);
|
||||
o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */
|
||||
o(0xEA000000); /* b $+4 */
|
||||
#ifndef CONFIG_TCC_PIE
|
||||
if(sv->r & VT_SYM)
|
||||
greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
|
||||
o(sv->c.i);
|
||||
#else
|
||||
if(sv->r & VT_SYM) {
|
||||
if (sv->sym->type.t & VT_STATIC) {
|
||||
greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);
|
||||
|
@ -561,6 +566,7 @@ static void load_value(SValue *sv, int r)
|
|||
}
|
||||
else
|
||||
o(sv->c.i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* load 'r' from value 'sv' */
|
||||
|
@ -1731,11 +1737,13 @@ void gen_opi(int op)
|
|||
}
|
||||
}
|
||||
fr=intr(gv(RC_INT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
c=intr(gv(RC_INT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
|
||||
o(opc|(c<<16)|fr);
|
||||
else {
|
||||
|
@ -1761,11 +1769,13 @@ done:
|
|||
o(opc|r|(c<<7)|(fr<<12));
|
||||
} else {
|
||||
fr=intr(gv(RC_INT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=intr(gv(RC_INT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
|
||||
o(opc|r|(c<<12)|(fr<<8)|0x10);
|
||||
}
|
||||
|
@ -1877,12 +1887,14 @@ void gen_opf(int op)
|
|||
r2=gv(RC_FLOAT);
|
||||
x|=vfpr(r2)<<16;
|
||||
r|=regmask(r2);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=gv(RC_FLOAT);
|
||||
vswap();
|
||||
x=(x&~0xf)|vfpr(r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
vtop->r=get_reg_ex(RC_FLOAT,r);
|
||||
if(!fneg)
|
||||
|
@ -1965,11 +1977,13 @@ void gen_opf(int op)
|
|||
r2=c2&0xf;
|
||||
} else {
|
||||
r2=fpr(gv(RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
|
@ -1991,11 +2005,13 @@ void gen_opf(int op)
|
|||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
r2=fpr(gv(RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
|
@ -2010,11 +2026,13 @@ void gen_opf(int op)
|
|||
r2=c2;
|
||||
else {
|
||||
r2=fpr(gv(RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
x|=0x100000; // muf
|
||||
break;
|
||||
|
@ -2036,11 +2054,13 @@ void gen_opf(int op)
|
|||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
r2=fpr(gv(RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -2093,11 +2113,13 @@ void gen_opf(int op)
|
|||
r2=c2&0xf;
|
||||
} else {
|
||||
r2=fpr(gv(RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap();
|
||||
r=fpr(gv(RC_FLOAT));
|
||||
vswap();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
--vtop;
|
||||
vset_VT_CMP(op);
|
||||
|
|
53
configure
vendored
Executable file → Normal file
53
configure
vendored
Executable file → Normal file
|
@ -29,7 +29,6 @@ sysroot=""
|
|||
cross_prefix=""
|
||||
cc="gcc"
|
||||
ar="ar"
|
||||
strip="strip"
|
||||
bigendian="no"
|
||||
mingw32="no"
|
||||
LIBSUF=".a"
|
||||
|
@ -44,13 +43,14 @@ triplet=
|
|||
tcc_lddir=
|
||||
confvars=
|
||||
suggest="yes"
|
||||
cpu=
|
||||
cpuver=
|
||||
gcc_major=0
|
||||
gcc_minor=0
|
||||
cc_name="gcc"
|
||||
ar_set=
|
||||
|
||||
cpu=`uname -m`
|
||||
cpuver=
|
||||
|
||||
# OS specific
|
||||
targetos=`uname`
|
||||
case $targetos in
|
||||
|
@ -140,9 +140,7 @@ for opt do
|
|||
;;
|
||||
--disable-rpath) confvars="$confvars rpath=no"
|
||||
;;
|
||||
--strip-binaries) echo deprecate, use 'make install-strip' to strip binaries
|
||||
;;
|
||||
--debug) confvars="$confvars strip=no"
|
||||
--debug) confvars="$confvars debug"
|
||||
;;
|
||||
--with-libgcc) confvars="$confvars libgcc"
|
||||
;;
|
||||
|
@ -161,15 +159,6 @@ done
|
|||
|
||||
cc="${cross_prefix}${cc}"
|
||||
ar="${cross_prefix}${ar}"
|
||||
strip="${cross_prefix}${strip}"
|
||||
|
||||
if test -z "$cpu" ; then
|
||||
if test -n "$ARCH" ; then
|
||||
cpu="$ARCH"
|
||||
else
|
||||
cpu=`uname -m`
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$cpu" in
|
||||
x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
|
||||
|
@ -181,7 +170,7 @@ case "$cpu" in
|
|||
evbarm)
|
||||
case "`uname -p`" in
|
||||
aarch64|arm64)
|
||||
cpu="aarch64"
|
||||
cpu="arm64"
|
||||
;;
|
||||
earmv*)
|
||||
cpu="arm"
|
||||
|
@ -189,7 +178,7 @@ case "$cpu" in
|
|||
esac
|
||||
;;
|
||||
aarch64|arm64|evbarm)
|
||||
cpu="aarch64"
|
||||
cpu="arm64"
|
||||
;;
|
||||
arm*)
|
||||
case "$cpu" in
|
||||
|
@ -302,30 +291,33 @@ Standard options:
|
|||
Advanced options (experts only):
|
||||
--source-path=PATH path of source code [$source_path]
|
||||
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
|
||||
--sysroot=PREFIX prepend PREFIX to library/include paths []
|
||||
--sysroot=PREFIX prepend PREFIX to library/include paths [$sysroot]
|
||||
--cc=CC use C compiler CC [$cc]
|
||||
--ar=AR create archives using AR [$ar]
|
||||
--extra-cflags= specify compiler flags [$CFLAGS]
|
||||
--extra-ldflags= specify linker options []
|
||||
--extra-ldflags= specify linker options [$LDFLAGS]
|
||||
--cpu=CPU CPU [$cpu]
|
||||
--strip-binaries strip symbol tables from resulting binaries
|
||||
|
||||
--debug include debug info with resulting binaries
|
||||
--disable-static make libtcc.so instead of libtcc.a
|
||||
--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 libtcc.so
|
||||
--with-libgcc use libgcc_s.so.1 instead of libtcc1.a
|
||||
--enable-cross build cross compilers
|
||||
--with-selinux use mmap for executable memory (with tcc -run)
|
||||
--with-selinux use mmap for executable memory (tcc -run)
|
||||
--enable-cross build cross compilers (see also 'make help')
|
||||
|
||||
--sysincludepaths=... specify system include paths, colon separated
|
||||
--libpaths=... specify system library paths, colon separated
|
||||
--crtprefix=... specify locations of crt?.o, colon separated
|
||||
--elfinterp=... specify elf interpreter
|
||||
--triplet=... specify system library/include directory triplet
|
||||
--config-uClibc,-musl,-mingw32... enable system specific configurations
|
||||
--config-bcheck=no/-backtrace=no disable bounds checker/stack backtraces
|
||||
|
||||
--config-uClibc,-musl enable system specific configurations
|
||||
--config-mingw32 build on windows using msys, busybox, etc.
|
||||
--config-backtrace=no disable stack backtraces (with -run or -bt)
|
||||
--config-bcheck=no disable bounds checker (-b)
|
||||
--config-predefs=no do not compile tccdefs.h, instead just include
|
||||
EOF
|
||||
#echo "NOTE: The object files are build at the place where configure is launched"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -349,7 +341,7 @@ if test -z "$cross_prefix" ; then
|
|||
fi
|
||||
|
||||
if test -z "$triplet"; then
|
||||
if test $cpu = "x86_64" -o $cpu = "aarch64" -o $cpu = "riscv64" ; then
|
||||
if test $cpu = "x86_64" -o $cpu = "arm64" -o $cpu = "riscv64" ; then
|
||||
if test -f "/usr/lib64/crti.o" ; then
|
||||
tcc_lddir="lib64"
|
||||
fi
|
||||
|
@ -453,7 +445,6 @@ CC_NAME=$cc_name
|
|||
GCC_MAJOR=$gcc_major
|
||||
GCC_MINOR=$gcc_minor
|
||||
AR=$ar
|
||||
STRIP=$strip -s -R .comment -R .note
|
||||
CFLAGS=$CFLAGS
|
||||
LDFLAGS=$LDFLAGS
|
||||
LIBSUF=$LIBSUF
|
||||
|
@ -492,11 +483,7 @@ print_mak CONFIG_LDDIR "$tcc_lddir"
|
|||
print_mak CONFIG_TRIPLET "$triplet"
|
||||
print_mak TCC_CPU_VERSION "$cpuver" num
|
||||
|
||||
if test "$cpu" = "aarch64" ; then
|
||||
echo "ARCH=arm64" >> config.mak
|
||||
else
|
||||
echo "ARCH=$cpu" >> config.mak
|
||||
fi
|
||||
echo "ARCH=$cpu" >> config.mak
|
||||
echo "TARGETOS=$targetos" >> config.mak
|
||||
|
||||
predefs="1"
|
||||
|
|
|
@ -12,15 +12,17 @@ int (*__rt_error)(void*, void*, const char *, va_list);
|
|||
#endif
|
||||
|
||||
__declspec(dllexport)
|
||||
void __bt_init(rt_context *p, int num_callers, int mode)
|
||||
void __bt_init(rt_context *p, int num_callers)
|
||||
{
|
||||
__attribute__((weak)) int main();
|
||||
__attribute__((weak)) void __bound_init(void*, int);
|
||||
struct rt_context *rc = &g_rtctxt;
|
||||
//fprintf(stderr, "__bt_init %d %p %p %d\n", num_callers, p->stab_sym, p->bounds_start, mode), fflush(stderr);
|
||||
//fprintf(stderr, "__bt_init %d %p %p\n", num_callers, p->stab_sym, p->bounds_start), fflush(stderr);
|
||||
#ifdef __APPLE__
|
||||
/* call __bound_init here due to redirection of sigaction */
|
||||
if (__bound_init && p->bounds_start)
|
||||
__bound_init(p->bounds_start, mode);
|
||||
__bound_init(p->bounds_start, 0);
|
||||
#endif
|
||||
if (num_callers) {
|
||||
memcpy(rc, p, offsetof(rt_context, next));
|
||||
rc->num_callers = num_callers - 1;
|
||||
|
|
156
libtcc.c
156
libtcc.c
|
@ -273,20 +273,12 @@ PUB_FUNC char *tcc_strdup(const char *str)
|
|||
#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
|
||||
#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
|
||||
#define MEM_DEBUG_FILE_LEN 40
|
||||
#define MEM_DEBUG_OFF3 offsetof(mem_debug_header_t, magic3)
|
||||
#define MEM_DEBUG_CHECK3(header) \
|
||||
({unsigned magic3; \
|
||||
memcpy(&magic3, (char*)header + MEM_DEBUG_OFF3 + header->size, \
|
||||
sizeof (magic3)); \
|
||||
magic3;})
|
||||
#define MEM_DEBUG_SET3(header) \
|
||||
{unsigned magic3 = MEM_DEBUG_MAGIC3; \
|
||||
memcpy((char*)header + MEM_DEBUG_OFF3 + header->size, &magic3, \
|
||||
sizeof (magic3));}
|
||||
((mem_debug_header_t*)((char*)header + header->size))->magic3
|
||||
#define MEM_USER_PTR(header) \
|
||||
((char *)header + MEM_DEBUG_OFF3)
|
||||
((char *)header + offsetof(mem_debug_header_t, magic3))
|
||||
#define MEM_HEADER_PTR(ptr) \
|
||||
(mem_debug_header_t *)((char*)ptr - MEM_DEBUG_OFF3)
|
||||
(mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))
|
||||
|
||||
struct mem_debug_header {
|
||||
unsigned magic1;
|
||||
|
@ -296,7 +288,7 @@ struct mem_debug_header {
|
|||
int line_num;
|
||||
char file_name[MEM_DEBUG_FILE_LEN + 1];
|
||||
unsigned magic2;
|
||||
ALIGNED(16) unsigned magic3;
|
||||
ALIGNED(16) unsigned char magic3[4];
|
||||
};
|
||||
|
||||
typedef struct mem_debug_header mem_debug_header_t;
|
||||
|
@ -310,7 +302,7 @@ static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
|
|||
mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
|
||||
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
|
||||
header->magic2 != MEM_DEBUG_MAGIC2 ||
|
||||
MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 ||
|
||||
read32le(MEM_DEBUG_CHECK3(header)) != MEM_DEBUG_MAGIC3 ||
|
||||
header->size == (unsigned)-1) {
|
||||
fprintf(stderr, "%s check failed\n", msg);
|
||||
if (header->magic1 == MEM_DEBUG_MAGIC1)
|
||||
|
@ -333,7 +325,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
|
|||
header->magic1 = MEM_DEBUG_MAGIC1;
|
||||
header->magic2 = MEM_DEBUG_MAGIC2;
|
||||
header->size = size;
|
||||
MEM_DEBUG_SET3(header);
|
||||
write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
|
||||
header->line_num = line;
|
||||
ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
|
||||
strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
|
||||
|
@ -390,7 +382,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file
|
|||
if (!header)
|
||||
_tcc_error("memory full (realloc)");
|
||||
header->size = size;
|
||||
MEM_DEBUG_SET3(header);
|
||||
write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
|
||||
if (header->next)
|
||||
header->next->prev = header;
|
||||
if (header->prev)
|
||||
|
@ -901,7 +893,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
|
|||
/* add libc crt1/crti objects */
|
||||
if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
|
||||
!s->nostdlib) {
|
||||
#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
|
||||
#if TARGETOS_OpenBSD
|
||||
if (output_type != TCC_OUTPUT_DLL)
|
||||
tcc_add_crt(s, "crt0.o");
|
||||
|
@ -929,9 +920,9 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
|
|||
tcc_add_crt(s, "crtbeginS.o");
|
||||
else
|
||||
tcc_add_crt(s, "crtbegin.o");
|
||||
#endif
|
||||
#elif !TCC_TARGET_MACHO
|
||||
#elif TCC_TARGET_MACHO
|
||||
/* Mach-O with LC_MAIN doesn't need any crt startup code. */
|
||||
#else
|
||||
if (output_type != TCC_OUTPUT_DLL)
|
||||
tcc_add_crt(s, "crt1.o");
|
||||
tcc_add_crt(s, "crti.o");
|
||||
|
@ -963,10 +954,41 @@ ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* OpenBSD: choose latest from libxxx.so.x.y versions */
|
||||
#if defined TARGETOS_OpenBSD && !defined _WIN32
|
||||
#include <glob.h>
|
||||
static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size)
|
||||
{
|
||||
const char *star;
|
||||
glob_t g;
|
||||
char *p;
|
||||
int i, v, v1, v2, v3;
|
||||
|
||||
star = strchr(pattern, '*');
|
||||
if (!star || glob(pattern, 0, NULL, &g))
|
||||
return -1;
|
||||
for (v = -1, i = 0; i < g.gl_pathc; ++i) {
|
||||
p = g.gl_pathv[i];
|
||||
if (2 != sscanf(p + (star - pattern), "%d.%d.%d", &v1, &v2, &v3))
|
||||
continue;
|
||||
if ((v1 = v1 * 1000 + v2) > v)
|
||||
v = v1, pstrcpy(buf, size, p);
|
||||
}
|
||||
globfree(&g);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
{
|
||||
int fd, ret = -1;
|
||||
|
||||
#if defined TARGETOS_OpenBSD && !defined _WIN32
|
||||
char buf[1024];
|
||||
if (tcc_glob_so(s1, filename, buf, sizeof buf) >= 0)
|
||||
filename = buf;
|
||||
#endif
|
||||
|
||||
/* open the file */
|
||||
fd = _tcc_open(s1, filename);
|
||||
if (fd < 0) {
|
||||
|
@ -1111,101 +1133,21 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* OpenBSD only has suffixed .so files; e.g., libc.so.96.0 */
|
||||
/* So we must process that */
|
||||
#if defined TARGETOS_OpenBSD && !defined _WIN32/* no dirent */
|
||||
#include <dirent.h>
|
||||
ST_FUNC char *tcc_openbsd_library_soversion(TCCState *s, const char *libraryname)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *e;
|
||||
char **libpaths, *t, *u, *v;
|
||||
char soname[1024];
|
||||
long long maj, min, tmaj, tmin;
|
||||
int i;
|
||||
static char soversion[1024];
|
||||
|
||||
snprintf(soname, sizeof(soname), "lib%s.so", libraryname);
|
||||
|
||||
libpaths = s->library_paths;
|
||||
for (i = 0; i < s->nb_library_paths; ++i) {
|
||||
if ((dirp = opendir(libpaths[i])) == NULL)
|
||||
continue;
|
||||
|
||||
maj = -1;
|
||||
min = -1;
|
||||
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (!strncmp(dp->d_name, soname, strlen(soname))) {
|
||||
t = tcc_strdup(dp->d_name);
|
||||
u = strrchr(t, '.');
|
||||
*u = '\0';
|
||||
|
||||
tmin = strtoll(u + 1, &e, 10);
|
||||
|
||||
if (*e != 0) {
|
||||
tcc_free(t);
|
||||
t = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
v = strrchr(t, '.');
|
||||
tmaj = strtoll(v + 1, &e, 10);
|
||||
|
||||
if (*e != 0) {
|
||||
tcc_free(t);
|
||||
t = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
tcc_free(t);
|
||||
t = NULL;
|
||||
|
||||
if (maj == tmaj) {
|
||||
if (min < tmin)
|
||||
min = tmin;
|
||||
} else if (maj < tmaj) {
|
||||
maj = tmaj;
|
||||
min = tmin;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
if (maj == -1 || min == -1)
|
||||
continue;
|
||||
|
||||
snprintf(soversion, sizeof(soversion), "%s/%s.%lld.%lld", libpaths[i],
|
||||
soname, maj, min);
|
||||
}
|
||||
|
||||
return soversion;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* the library name is the same as the argument of the '-l' option */
|
||||
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
|
||||
{
|
||||
#if defined TCC_TARGET_PE
|
||||
const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
|
||||
const char **pp = s->static_link ? libs + 4 : libs;
|
||||
static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
|
||||
const char * const *pp = s->static_link ? libs + 4 : libs;
|
||||
#elif defined TCC_TARGET_MACHO
|
||||
const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
|
||||
const char **pp = s->static_link ? libs + 1 : libs;
|
||||
#elif defined TARGETOS_OpenBSD && !defined _WIN32
|
||||
const char *libs[] = { s->static_link
|
||||
? NULL
|
||||
/* find exact versionned .so.x.y name as no
|
||||
symlink exists on OpenBSD. */
|
||||
: tcc_openbsd_library_soversion(s, libraryname),
|
||||
"%s/lib%s.a",
|
||||
NULL
|
||||
};
|
||||
const char **pp = s->static_link ? libs + 1 : libs;
|
||||
static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
|
||||
const char * const *pp = s->static_link ? libs + 1 : libs;
|
||||
#elif defined TARGETOS_OpenBSD
|
||||
static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };
|
||||
const char * const *pp = s->static_link ? libs + 1 : libs;
|
||||
#else
|
||||
const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
|
||||
const char **pp = s->static_link ? libs + 1 : libs;
|
||||
static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
|
||||
const char * const *pp = s->static_link ? libs + 1 : libs;
|
||||
#endif
|
||||
int flags = s->filetype & AFF_WHOLE_ARCHIVE;
|
||||
while (*pp) {
|
||||
|
|
|
@ -166,10 +166,10 @@ ST_FUNC void gsym_addr(int t_, int a_)
|
|||
|
||||
static int load_symofs(int r, SValue *sv, int forstore)
|
||||
{
|
||||
static Sym label;
|
||||
int rr, doload = 0;
|
||||
int fc = sv->c.i, v = sv->r & VT_VALMASK;
|
||||
if (sv->r & VT_SYM) {
|
||||
Sym label = {0};
|
||||
assert(v == VT_CONST);
|
||||
if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
|
||||
greloca(cur_text_section, sv->sym, ind,
|
||||
|
@ -182,11 +182,7 @@ static int load_symofs(int r, SValue *sv, int forstore)
|
|||
R_RISCV_GOT_HI20, 0);
|
||||
doload = 1;
|
||||
}
|
||||
if (!label.v) {
|
||||
label.v = tok_alloc(".L0 ", 4)->tok;
|
||||
label.type.t = VT_VOID | VT_STATIC;
|
||||
}
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
put_extern_sym(&label, cur_text_section, ind, 0);
|
||||
rr = is_ireg(r) ? ireg(r) : 5;
|
||||
o(0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend
|
||||
|
@ -459,10 +455,11 @@ static void gen_bounds_prolog(void)
|
|||
|
||||
static void gen_bounds_epilog(void)
|
||||
{
|
||||
static Sym label;
|
||||
addr_t saved_ind;
|
||||
addr_t *bounds_ptr;
|
||||
Sym *sym_data;
|
||||
Sym label = {0};
|
||||
|
||||
int offset_modified = func_bound_offset != lbounds_section->data_offset;
|
||||
|
||||
if (!offset_modified && !func_bound_add_epilog)
|
||||
|
@ -475,15 +472,11 @@ static void gen_bounds_epilog(void)
|
|||
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
||||
func_bound_offset, lbounds_section->data_offset);
|
||||
|
||||
if (!label.v) {
|
||||
label.v = tok_alloc(".LB0 ", 5)->tok;
|
||||
label.type.t = VT_VOID | VT_STATIC;
|
||||
}
|
||||
/* generate bound local allocation */
|
||||
if (offset_modified) {
|
||||
saved_ind = ind;
|
||||
ind = func_bound_ind;
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
put_extern_sym(&label, cur_text_section, ind, 0);
|
||||
greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0);
|
||||
o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
|
||||
|
@ -491,12 +484,12 @@ static void gen_bounds_epilog(void)
|
|||
EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0)
|
||||
gen_bounds_call(TOK___bound_local_new);
|
||||
ind = saved_ind;
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
}
|
||||
|
||||
/* generate bound check local freeing */
|
||||
o(0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */
|
||||
o(0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
put_extern_sym(&label, cur_text_section, ind, 0);
|
||||
greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0);
|
||||
o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
|
||||
|
@ -1352,19 +1345,15 @@ ST_FUNC void gen_cvt_ftof(int dt)
|
|||
ST_FUNC void gen_increment_tcov (SValue *sv)
|
||||
{
|
||||
int r1, r2;
|
||||
static Sym label;
|
||||
|
||||
if (!label.v) {
|
||||
label.v = tok_alloc(".T0 ", 4)->tok;
|
||||
Sym label = {0};
|
||||
label.type.t = VT_VOID | VT_STATIC;
|
||||
}
|
||||
|
||||
vpushv(sv);
|
||||
vtop->r = r1 = get_reg(RC_INT);
|
||||
r2 = get_reg(RC_INT);
|
||||
r1 = ireg(r1);
|
||||
r2 = ireg(r2);
|
||||
greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0);
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
put_extern_sym(&label, cur_text_section, ind, 0);
|
||||
o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
|
||||
greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
|
|
8
tcc.h
8
tcc.h
|
@ -764,7 +764,6 @@ struct TCCState {
|
|||
unsigned char leading_underscore;
|
||||
unsigned char ms_extensions; /* allow nested named struct w/o identifier behave like unnamed */
|
||||
unsigned char dollars_in_identifiers; /* allows '$' char in identifiers */
|
||||
unsigned char test_coverage; /* generate test coverage code */
|
||||
unsigned char ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
|
||||
|
||||
/* warning switches */
|
||||
|
@ -782,6 +781,8 @@ struct TCCState {
|
|||
/* compile with built-in memory and bounds checker */
|
||||
unsigned char do_bounds_check;
|
||||
#endif
|
||||
unsigned char test_coverage; /* generate test coverage code */
|
||||
|
||||
#ifdef TCC_TARGET_ARM
|
||||
enum float_abi float_abi; /* float ABI of the generated code*/
|
||||
#endif
|
||||
|
@ -1447,6 +1448,7 @@ ST_DATA Sym *define_stack;
|
|||
ST_DATA CType int_type, func_old_type, char_pointer_type;
|
||||
ST_DATA SValue *vtop;
|
||||
ST_DATA int rsym, anon_sym, ind, loc;
|
||||
ST_DATA char debug_modes;
|
||||
|
||||
ST_DATA int const_wanted; /* true if constant wanted */
|
||||
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
|
||||
|
@ -1461,9 +1463,7 @@ ST_FUNC void tcc_debug_end(TCCState *s1);
|
|||
ST_FUNC void tcc_debug_bincl(TCCState *s1);
|
||||
ST_FUNC void tcc_debug_eincl(TCCState *s1);
|
||||
ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename);
|
||||
ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
|
||||
ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
|
||||
ST_FUNC void tcc_debug_line(TCCState *s1);
|
||||
ST_FUNC void tcc_add_tcov(TCCState *s1);
|
||||
|
||||
ST_FUNC void tccgen_init(TCCState *s1);
|
||||
ST_FUNC int tccgen_compile(TCCState *s1);
|
||||
|
|
4
tccelf.c
4
tccelf.c
|
@ -1419,7 +1419,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1)
|
|||
cstr_printf(&cstr, "__bt_init_dll(0);");
|
||||
#endif
|
||||
#endif
|
||||
cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
|
||||
cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
|
||||
s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
|
||||
tcc_compile_string(s1, cstr.data);
|
||||
cstr_free(&cstr);
|
||||
|
@ -1450,7 +1450,7 @@ static void tcc_tcov_add_file(TCCState *s1, const char *filename)
|
|||
cstr_free (&cstr);
|
||||
}
|
||||
|
||||
static void tcc_add_tcov(TCCState *s1)
|
||||
ST_FUNC void tcc_add_tcov(TCCState *s1)
|
||||
{
|
||||
CString cstr;
|
||||
|
||||
|
|
409
tccgen.c
409
tccgen.c
|
@ -46,15 +46,12 @@ static int local_scope;
|
|||
static int in_sizeof;
|
||||
static int in_generic;
|
||||
static int section_sym;
|
||||
ST_DATA char debug_modes;
|
||||
|
||||
ST_DATA SValue *vtop;
|
||||
static SValue _vstack[1 + VSTACK_SIZE];
|
||||
#define vstack (_vstack + 1)
|
||||
|
||||
static void tcc_tcov_block_begin(void);
|
||||
static void tcc_tcov_block_end(int line);
|
||||
static void tcc_tcov_check_line(int start);
|
||||
|
||||
ST_DATA int const_wanted; /* true if constant wanted */
|
||||
ST_DATA int nocode_wanted; /* no code generation wanted */
|
||||
#define unevalmask 0xffff /* unevaluated subexpression */
|
||||
|
@ -65,9 +62,11 @@ ST_DATA int nocode_wanted; /* no code generation wanted */
|
|||
#define CODE_OFF() (nocode_wanted |= 0x20000000)
|
||||
#define CODE_ON() (nocode_wanted &= ~0x20000000)
|
||||
|
||||
static void tcc_tcov_block_begin(void);
|
||||
|
||||
/* Clear 'nocode_wanted' at label if it was used */
|
||||
ST_FUNC void gsym(int t) { if (t) { gsym_addr(t, ind); CODE_ON(); }}
|
||||
static int gind(void) { int t; CODE_ON(); t = ind; tcc_tcov_block_begin(); return t; }
|
||||
static int gind(void) { int t = ind; CODE_ON(); if (debug_modes) tcc_tcov_block_begin(); return t; }
|
||||
|
||||
/* Set 'nocode_wanted' after unconditional jumps */
|
||||
static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); }
|
||||
|
@ -214,7 +213,6 @@ static struct {
|
|||
unsigned long last_func_name;
|
||||
int ind;
|
||||
int line;
|
||||
Sym label;
|
||||
} tcov_data;
|
||||
|
||||
/********************************************************/
|
||||
|
@ -460,6 +458,74 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
|
|||
SHN_ABS, file->filename);
|
||||
}
|
||||
|
||||
/* put end of translation unit info */
|
||||
ST_FUNC void tcc_debug_end(TCCState *s1)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
put_stabs_r(s1, NULL, N_SO, 0, 0,
|
||||
text_section->data_offset, text_section, section_sym);
|
||||
tcc_free(debug_hash);
|
||||
}
|
||||
|
||||
static BufferedFile* put_new_file(TCCState *s1)
|
||||
{
|
||||
BufferedFile *f = file;
|
||||
/* use upper file if from inline ":asm:" */
|
||||
if (f->filename[0] == ':')
|
||||
f = f->prev;
|
||||
if (f && new_file) {
|
||||
put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
|
||||
new_file = last_line_num = 0;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/* put alternative filename */
|
||||
ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
|
||||
{
|
||||
if (0 == strcmp(file->filename, filename))
|
||||
return;
|
||||
pstrcpy(file->filename, sizeof(file->filename), filename);
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
/* begin of #include */
|
||||
ST_FUNC void tcc_debug_bincl(TCCState *s1)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
/* end of #include */
|
||||
ST_FUNC void tcc_debug_eincl(TCCState *s1)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
put_stabn(s1, N_EINCL, 0, 0, 0);
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
/* generate line number info */
|
||||
static void tcc_debug_line(TCCState *s1)
|
||||
{
|
||||
BufferedFile *f;
|
||||
if (!s1->do_debug
|
||||
|| cur_text_section != text_section
|
||||
|| !(f = put_new_file(s1))
|
||||
|| last_line_num == f->line_num)
|
||||
return;
|
||||
if (func_ind != -1) {
|
||||
put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
|
||||
} else {
|
||||
/* from tcc_assemble */
|
||||
put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
|
||||
}
|
||||
last_line_num = f->line_num;
|
||||
}
|
||||
|
||||
static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
|
||||
Section *sec, int sym_index)
|
||||
{
|
||||
|
@ -483,8 +549,10 @@ static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned l
|
|||
put_stabs (s1, str, type, 0, 0, value);
|
||||
}
|
||||
|
||||
static void tcc_debug_stabn(int type, int value)
|
||||
static void tcc_debug_stabn(TCCState *s1, int type, int value)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
if (type == N_LBRAC) {
|
||||
struct debug_info *info =
|
||||
(struct debug_info *) tcc_mallocz(sizeof (*info));
|
||||
|
@ -659,6 +727,8 @@ static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
|
|||
static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
|
||||
{
|
||||
CString debug_str;
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
cstr_new (&debug_str);
|
||||
for (; s != e; s = s->prev) {
|
||||
if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
|
||||
|
@ -671,11 +741,48 @@ static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
|
|||
cstr_free (&debug_str);
|
||||
}
|
||||
|
||||
static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind)
|
||||
/* put function symbol */
|
||||
static void tcc_debug_funcstart(TCCState *s1, Sym *sym)
|
||||
{
|
||||
Section *s = s1->sections[sh_num];
|
||||
CString debug_str;
|
||||
BufferedFile *f;
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
debug_info_root = NULL;
|
||||
debug_info = NULL;
|
||||
tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
|
||||
if (!(f = put_new_file(s1)))
|
||||
return;
|
||||
cstr_new (&debug_str);
|
||||
cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
|
||||
tcc_get_debug_info(s1, sym->type.ref, &debug_str);
|
||||
put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
|
||||
cstr_free (&debug_str);
|
||||
|
||||
tcc_debug_line(s1);
|
||||
}
|
||||
|
||||
/* put function size */
|
||||
static void tcc_debug_funcend(TCCState *s1, int size)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
tcc_debug_stabn(s1, N_RBRAC, size);
|
||||
tcc_debug_finish (s1, debug_info_root);
|
||||
}
|
||||
|
||||
|
||||
static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
|
||||
{
|
||||
Section *s;
|
||||
CString str;
|
||||
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
|
||||
return;
|
||||
s = s1->sections[sh_num];
|
||||
|
||||
cstr_new (&str);
|
||||
cstr_printf (&str, "%s:%c",
|
||||
get_tok_str(sym->v, NULL),
|
||||
|
@ -695,6 +802,8 @@ static void tcc_debug_typedef(TCCState *s1, Sym *sym)
|
|||
{
|
||||
CString str;
|
||||
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
cstr_new (&str);
|
||||
cstr_printf (&str, "%s:t",
|
||||
(sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
|
||||
|
@ -704,17 +813,11 @@ static void tcc_debug_typedef(TCCState *s1, Sym *sym)
|
|||
cstr_free (&str);
|
||||
}
|
||||
|
||||
/* put end of translation unit info */
|
||||
ST_FUNC void tcc_debug_end(TCCState *s1)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
put_stabs_r(s1, NULL, N_SO, 0, 0,
|
||||
text_section->data_offset, text_section, section_sym);
|
||||
tcc_free(debug_hash);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* for section layout see lib/tcov.c */
|
||||
|
||||
static void tcc_tcov_block_end(int line);
|
||||
|
||||
static void tcc_tcov_block_begin(void)
|
||||
{
|
||||
SValue sv;
|
||||
|
@ -764,21 +867,19 @@ static void tcc_tcov_block_begin(void)
|
|||
if (ind == tcov_data.ind && tcov_data.line == file->line_num)
|
||||
tcov_data.offset = tcov_data.last_offset;
|
||||
else {
|
||||
if (!tcov_data.label.v) {
|
||||
tcov_data.label.v = tok_alloc(".TCOV ", 6)->tok;
|
||||
tcov_data.label.type.t = VT_LLONG | VT_STATIC;
|
||||
}
|
||||
tcov_data.label.c = 0; /* force new local ELF symbol */
|
||||
Sym label = {0};
|
||||
label.type.t = VT_LLONG | VT_STATIC;
|
||||
|
||||
ptr = section_ptr_add(tcov_section, 16);
|
||||
tcov_data.line = file->line_num;
|
||||
write64le (ptr, (tcov_data.line << 8) | 0xff);
|
||||
put_extern_sym(&tcov_data.label, tcov_section,
|
||||
put_extern_sym(&label, tcov_section,
|
||||
((unsigned char *)ptr - tcov_section->data) + 8, 0);
|
||||
sv.type = tcov_data.label.type;
|
||||
sv.type = label.type;
|
||||
sv.r = VT_SYM | VT_LVAL | VT_CONST;
|
||||
sv.r2 = VT_CONST;
|
||||
sv.c.i = 0;
|
||||
sv.sym = &tcov_data.label;
|
||||
sv.sym = &label;
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
|
||||
defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
|
||||
defined TCC_TARGET_RISCV64
|
||||
|
@ -844,94 +945,6 @@ static void tcc_tcov_end(void)
|
|||
section_ptr_add(tcov_section, 1);
|
||||
}
|
||||
|
||||
static BufferedFile* put_new_file(TCCState *s1)
|
||||
{
|
||||
BufferedFile *f = file;
|
||||
/* use upper file if from inline ":asm:" */
|
||||
if (f->filename[0] == ':')
|
||||
f = f->prev;
|
||||
if (f && new_file) {
|
||||
put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
|
||||
new_file = last_line_num = 0;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/* generate line number info */
|
||||
ST_FUNC void tcc_debug_line(TCCState *s1)
|
||||
{
|
||||
BufferedFile *f;
|
||||
if (!s1->do_debug
|
||||
|| cur_text_section != text_section
|
||||
|| !(f = put_new_file(s1))
|
||||
|| last_line_num == f->line_num)
|
||||
return;
|
||||
if (func_ind != -1) {
|
||||
put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
|
||||
} else {
|
||||
/* from tcc_assemble */
|
||||
put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
|
||||
}
|
||||
last_line_num = f->line_num;
|
||||
}
|
||||
|
||||
/* put function symbol */
|
||||
ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
|
||||
{
|
||||
CString debug_str;
|
||||
BufferedFile *f;
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
debug_info_root = NULL;
|
||||
debug_info = NULL;
|
||||
tcc_debug_stabn(N_LBRAC, ind - func_ind);
|
||||
if (!(f = put_new_file(s1)))
|
||||
return;
|
||||
cstr_new (&debug_str);
|
||||
cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
|
||||
tcc_get_debug_info(s1, sym->type.ref, &debug_str);
|
||||
put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
|
||||
cstr_free (&debug_str);
|
||||
|
||||
tcc_debug_line(s1);
|
||||
}
|
||||
|
||||
/* put function size */
|
||||
ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
tcc_debug_stabn(N_RBRAC, size);
|
||||
tcc_debug_finish (s1, debug_info_root);
|
||||
}
|
||||
|
||||
/* put alternative filename */
|
||||
ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
|
||||
{
|
||||
if (0 == strcmp(file->filename, filename))
|
||||
return;
|
||||
pstrcpy(file->filename, sizeof(file->filename), filename);
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
/* begin of #include */
|
||||
ST_FUNC void tcc_debug_bincl(TCCState *s1)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
/* end of #include */
|
||||
ST_FUNC void tcc_debug_eincl(TCCState *s1)
|
||||
{
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
put_stabn(s1, N_EINCL, 0, 0, 0);
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* initialize vstack and types. This must be done also for tcc -E */
|
||||
ST_FUNC void tccgen_init(TCCState *s1)
|
||||
|
@ -967,6 +980,7 @@ ST_FUNC int tccgen_compile(TCCState *s1)
|
|||
const_wanted = 0;
|
||||
nocode_wanted = 0x80000000;
|
||||
local_scope = 0;
|
||||
debug_modes = s1->do_debug | s1->test_coverage << 1;
|
||||
|
||||
tcc_debug_start(s1);
|
||||
tcc_tcov_start ();
|
||||
|
@ -1111,10 +1125,8 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
|
|||
info = ELFW(ST_INFO)(sym_bind, sym_type);
|
||||
sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
|
||||
|
||||
if (tcc_state->do_debug
|
||||
&& sym_type != STT_FUNC
|
||||
&& sym->v < SYM_FIRST_ANOM)
|
||||
tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind);
|
||||
if (debug_modes)
|
||||
tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind, sym_type);
|
||||
|
||||
} else {
|
||||
esym = elfsym(sym);
|
||||
|
@ -2188,15 +2200,15 @@ static void add_local_bounds(Sym *s, Sym *e)
|
|||
#endif
|
||||
|
||||
/* Wrapper around sym_pop, that potentially also registers local bounds. */
|
||||
static void pop_local_syms(Sym **ptop, Sym *b, int keep, int ellipsis)
|
||||
static void pop_local_syms(Sym *b, int keep)
|
||||
{
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (tcc_state->do_bounds_check && !ellipsis && !keep)
|
||||
add_local_bounds(*ptop, b);
|
||||
if (tcc_state->do_bounds_check && !keep && (local_scope || !func_var))
|
||||
add_local_bounds(local_stack, b);
|
||||
#endif
|
||||
if (tcc_state->do_debug)
|
||||
tcc_add_debug_info (tcc_state, !local_scope, *ptop, b);
|
||||
sym_pop(ptop, b, keep);
|
||||
if (debug_modes)
|
||||
tcc_add_debug_info (tcc_state, !local_scope, local_stack, b);
|
||||
sym_pop(&local_stack, b, keep);
|
||||
}
|
||||
|
||||
static void incr_bf_adr(int o)
|
||||
|
@ -2246,7 +2258,6 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size)
|
|||
static void store_packed_bf(int bit_pos, int bit_size)
|
||||
{
|
||||
int bits, n, o, m, c;
|
||||
|
||||
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
vswap(); // X B
|
||||
save_reg_upstack(vtop->r, 1);
|
||||
|
@ -4727,10 +4738,12 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||
continue;
|
||||
bit_pos = BIT_POS(f->type.t);
|
||||
size = type_size(&f->type, &align);
|
||||
if (c & 3) /* packed struct */
|
||||
goto single_byte;
|
||||
if (bit_pos + bit_size <= size * 8 && f->c + size <= c &&
|
||||
(f->c & (align - 1)) == 0)
|
||||
|
||||
if (bit_pos + bit_size <= size * 8 && f->c + size <= c
|
||||
#ifdef TCC_TARGET_ARM
|
||||
&& !(f->c & (align - 1))
|
||||
#endif
|
||||
)
|
||||
continue;
|
||||
|
||||
/* try to access the field using a different type */
|
||||
|
@ -4756,7 +4769,11 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||
c0 = cx;
|
||||
}
|
||||
|
||||
if (px + bit_size <= s * 8 && cx + s <= c) {
|
||||
if (px + bit_size <= s * 8 && cx + s <= c
|
||||
#ifdef TCC_TARGET_ARM
|
||||
&& !(cx & (align - 1))
|
||||
#endif
|
||||
) {
|
||||
/* update offset and bit position */
|
||||
f->c = cx;
|
||||
bit_pos = px;
|
||||
|
@ -4771,7 +4788,6 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||
cx, s, align, px, bit_size);
|
||||
#endif
|
||||
} else {
|
||||
single_byte:
|
||||
/* fall back to load/store single-byte wise */
|
||||
f->auxtype = VT_STRUCT;
|
||||
#ifdef BF_DEBUG
|
||||
|
@ -5696,9 +5712,8 @@ ST_FUNC void unary(void)
|
|||
AttributeDef ad;
|
||||
|
||||
/* generate line number info */
|
||||
if (tcc_state->do_debug)
|
||||
tcc_debug_line(tcc_state);
|
||||
tcc_tcov_check_line (1);
|
||||
if (debug_modes)
|
||||
tcc_debug_line(tcc_state), tcc_tcov_check_line (1);
|
||||
|
||||
sizeof_caller = in_sizeof;
|
||||
in_sizeof = 0;
|
||||
|
@ -6419,6 +6434,7 @@ special_math_val:
|
|||
}
|
||||
}
|
||||
if (s->f.func_noreturn) {
|
||||
if (debug_modes)
|
||||
tcc_tcov_block_end (tcov_data.line);
|
||||
CODE_OFF();
|
||||
}
|
||||
|
@ -6678,13 +6694,6 @@ static void expr_cond(void)
|
|||
if (!g)
|
||||
gexpr();
|
||||
|
||||
if (c < 0 && vtop->r == VT_CMP) {
|
||||
t1 = gvtst(0, 0);
|
||||
vpushi(0);
|
||||
gvtst_set(0, t1);
|
||||
gv(RC_INT);
|
||||
}
|
||||
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
|
||||
mk_pointer(&vtop->type);
|
||||
sv = *vtop; /* save value to handle it later */
|
||||
|
@ -6705,15 +6714,14 @@ static void expr_cond(void)
|
|||
expr_cond();
|
||||
|
||||
if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) {
|
||||
if (sv.r == VT_CMP) {
|
||||
t1 = sv.jtrue;
|
||||
t2 = u;
|
||||
} else {
|
||||
/* optimize "if (f ? a > b : c || d) ..." for example, where normally
|
||||
"a < b" and "c || d" would be forced to "(int)0/1" first, whereas
|
||||
this code jumps directly to the if's then/else branches. */
|
||||
t1 = gvtst(0, 0);
|
||||
t2 = gjmp(0);
|
||||
gsym(u);
|
||||
vpushv(&sv);
|
||||
}
|
||||
/* combine jump targets of 2nd op with VT_CMP of 1st op */
|
||||
gvtst_set(0, t1);
|
||||
gvtst_set(1, t2);
|
||||
nocode_wanted = ncw_prev;
|
||||
|
@ -7099,11 +7107,10 @@ void new_scope(struct scope *o)
|
|||
/* record local declaration stack position */
|
||||
o->lstk = local_stack;
|
||||
o->llstk = local_label_stack;
|
||||
|
||||
++local_scope;
|
||||
|
||||
if (tcc_state->do_debug)
|
||||
tcc_debug_stabn(N_LBRAC, ind - func_ind);
|
||||
if (debug_modes)
|
||||
tcc_debug_stabn(tcc_state, N_LBRAC, ind - func_ind);
|
||||
}
|
||||
|
||||
void prev_scope(struct scope *o, int is_expr)
|
||||
|
@ -7125,12 +7132,12 @@ void prev_scope(struct scope *o, int is_expr)
|
|||
tables, though. sym_pop will do that. */
|
||||
|
||||
/* pop locally defined symbols */
|
||||
pop_local_syms(&local_stack, o->lstk, is_expr, 0);
|
||||
pop_local_syms(o->lstk, is_expr);
|
||||
cur_scope = o->prev;
|
||||
--local_scope;
|
||||
|
||||
if (tcc_state->do_debug)
|
||||
tcc_debug_stabn(N_RBRAC, ind - func_ind);
|
||||
if (debug_modes)
|
||||
tcc_debug_stabn(tcc_state, N_RBRAC, ind - func_ind);
|
||||
}
|
||||
|
||||
/* leave a scope via break/continue(/goto) */
|
||||
|
@ -7182,8 +7189,9 @@ again:
|
|||
goto expr;
|
||||
next();
|
||||
|
||||
tcc_tcov_check_line (0);
|
||||
tcc_tcov_block_begin ();
|
||||
if (debug_modes)
|
||||
tcc_tcov_check_line (0), tcc_tcov_block_begin ();
|
||||
|
||||
if (t == TOK_IF) {
|
||||
skip('(');
|
||||
gexpr();
|
||||
|
@ -7264,6 +7272,7 @@ again:
|
|||
/* jump unless last stmt in top-level block */
|
||||
if (tok != '}' || local_scope != 1)
|
||||
rsym = gjmp(rsym);
|
||||
if (debug_modes)
|
||||
tcc_tcov_block_end (tcov_data.line);
|
||||
CODE_OFF();
|
||||
|
||||
|
@ -7498,8 +7507,9 @@ again:
|
|||
}
|
||||
}
|
||||
}
|
||||
tcc_tcov_check_line (0);
|
||||
tcc_tcov_block_end (0);
|
||||
|
||||
if (debug_modes)
|
||||
tcc_tcov_check_line (0), tcc_tcov_block_end (0);
|
||||
}
|
||||
|
||||
/* This skips over a stream of tokens containing balanced {} and ()
|
||||
|
@ -7779,6 +7789,7 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
|
|||
CType dtype;
|
||||
int size, align;
|
||||
Section *sec = p->sec;
|
||||
uint64_t val;
|
||||
|
||||
dtype = *type;
|
||||
dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
|
||||
|
@ -7796,7 +7807,6 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
|
|||
|
||||
if ((vtop->r & VT_SYM)
|
||||
&& bt != VT_PTR
|
||||
&& bt != VT_FUNC
|
||||
&& (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
|
||||
|| (type->t & VT_BITFIELD))
|
||||
&& !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
|
||||
|
@ -7809,6 +7819,7 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
|
|||
}
|
||||
|
||||
ptr = sec->data + c;
|
||||
val = vtop->c.i;
|
||||
|
||||
/* XXX: make code faster ? */
|
||||
if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
|
||||
|
@ -7868,33 +7879,38 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
|
|||
n = 8 - bit_pos;
|
||||
if (n > bit_size)
|
||||
n = bit_size;
|
||||
v = vtop->c.i >> bits << bit_pos;
|
||||
v = val >> bits << bit_pos;
|
||||
m = ((1 << n) - 1) << bit_pos;
|
||||
*p = (*p & ~m) | (v & m);
|
||||
bits += n, bit_size -= n, bit_pos = 0, ++p;
|
||||
}
|
||||
} else
|
||||
switch(bt) {
|
||||
/* XXX: when cross-compiling we assume that each type has the
|
||||
same representation on host and target, which is likely to
|
||||
be wrong in the case of long double */
|
||||
case VT_BOOL:
|
||||
vtop->c.i = vtop->c.i != 0;
|
||||
*(char *)ptr = val != 0;
|
||||
break;
|
||||
case VT_BYTE:
|
||||
*(char *)ptr = vtop->c.i;
|
||||
*(char *)ptr = val;
|
||||
break;
|
||||
case VT_SHORT:
|
||||
*(short *)ptr = vtop->c.i;
|
||||
write16le(ptr, val);
|
||||
break;
|
||||
case VT_FLOAT:
|
||||
*(float*)ptr = vtop->c.f;
|
||||
write32le(ptr, val);
|
||||
break;
|
||||
case VT_DOUBLE:
|
||||
*(double *)ptr = vtop->c.d;
|
||||
write64le(ptr, val);
|
||||
break;
|
||||
case VT_LDOUBLE:
|
||||
#if defined TCC_IS_NATIVE_387
|
||||
if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
|
||||
/* Host and target platform may be different but both have x87.
|
||||
On windows, tcc does not use VT_LDOUBLE, except when it is a
|
||||
cross compiler. In this case a mingw gcc as host compiler
|
||||
comes here with 10-byte long doubles, while msvc or tcc won't.
|
||||
tcc itself can still translate by asm.
|
||||
In any case we avoid possibly random bytes 11 and 12.
|
||||
*/
|
||||
if (sizeof (long double) >= 10)
|
||||
memcpy(ptr, &vtop->c.ld, 10);
|
||||
#ifdef __TINYC__
|
||||
else if (sizeof (long double) == sizeof (double))
|
||||
|
@ -7904,54 +7920,46 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
|
|||
;
|
||||
else
|
||||
#endif
|
||||
/* For other platforms it should work natively, but may not work
|
||||
for cross compilers */
|
||||
if (sizeof(long double) == LDOUBLE_SIZE)
|
||||
*(long double*)ptr = vtop->c.ld;
|
||||
memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE);
|
||||
else if (sizeof(double) == LDOUBLE_SIZE)
|
||||
*(double *)ptr = (double)vtop->c.ld;
|
||||
memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE);
|
||||
#ifndef TCC_CROSS_TEST
|
||||
else
|
||||
tcc_error("can't cross compile long double constants");
|
||||
#endif
|
||||
break;
|
||||
#if PTR_SIZE != 8
|
||||
|
||||
#if PTR_SIZE == 8
|
||||
/* intptr_t may need a reloc too, see tcctest.c:relocation_test() */
|
||||
case VT_LLONG:
|
||||
*(long long *)ptr = vtop->c.i;
|
||||
break;
|
||||
#else
|
||||
case VT_LLONG:
|
||||
#endif
|
||||
case VT_PTR:
|
||||
{
|
||||
addr_t val = vtop->c.i;
|
||||
#if PTR_SIZE == 8
|
||||
if (vtop->r & VT_SYM)
|
||||
greloca(sec, vtop->sym, c, R_DATA_PTR, val);
|
||||
else
|
||||
*(addr_t *)ptr = val;
|
||||
write64le(ptr, val);
|
||||
break;
|
||||
case VT_INT:
|
||||
write32le(ptr, val);
|
||||
break;
|
||||
#else
|
||||
case VT_LLONG:
|
||||
write64le(ptr, val);
|
||||
break;
|
||||
case VT_PTR:
|
||||
case VT_INT:
|
||||
if (vtop->r & VT_SYM)
|
||||
greloc(sec, vtop->sym, c, R_DATA_PTR);
|
||||
*(addr_t *)ptr = val;
|
||||
#endif
|
||||
write32le(ptr, val);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
int val = vtop->c.i;
|
||||
#if PTR_SIZE == 8
|
||||
if (vtop->r & VT_SYM)
|
||||
greloca(sec, vtop->sym, c, R_DATA_PTR, val);
|
||||
else
|
||||
*(int *)ptr = val;
|
||||
#else
|
||||
if (vtop->r & VT_SYM)
|
||||
greloc(sec, vtop->sym, c, R_DATA_PTR);
|
||||
*(int *)ptr = val;
|
||||
#endif
|
||||
//tcc_internal_error("unexpected type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
vtop--;
|
||||
} else {
|
||||
vset(&dtype, VT_LOCAL|VT_LVAL, c);
|
||||
|
@ -7975,9 +7983,8 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f
|
|||
CType *t1;
|
||||
|
||||
/* generate line number info */
|
||||
if (!p->sec && tcc_state->do_debug)
|
||||
tcc_debug_line(tcc_state);
|
||||
tcc_tcov_check_line (1);
|
||||
if (debug_modes && !p->sec)
|
||||
tcc_debug_line(tcc_state), tcc_tcov_check_line (1);
|
||||
|
||||
if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
|
||||
/* In case of strings we have special handling for arrays, so
|
||||
|
@ -8453,7 +8460,7 @@ static void gen_function(Sym *sym)
|
|||
gsym(rsym);
|
||||
nocode_wanted = 0;
|
||||
/* reset local stack */
|
||||
pop_local_syms(&local_stack, NULL, 0, func_var);
|
||||
pop_local_syms(NULL, 0);
|
||||
gfunc_epilog();
|
||||
cur_text_section->data_offset = ind;
|
||||
local_scope = 0;
|
||||
|
@ -8737,7 +8744,7 @@ found:
|
|||
}
|
||||
sym->a = ad.a;
|
||||
sym->f = ad.f;
|
||||
if (tcc_state->do_debug)
|
||||
if (debug_modes)
|
||||
tcc_debug_typedef (tcc_state, sym);
|
||||
} else if ((type.t & VT_BTYPE) == VT_VOID
|
||||
&& !(type.t & VT_EXTERN)) {
|
||||
|
|
42
tccpp.c
42
tccpp.c
|
@ -358,18 +358,11 @@ char *unicode_to_utf8 (char *b, uint32_t Uc)
|
|||
/* add a unicode character expanded into utf8 */
|
||||
void cstr_u8cat(CString *cstr, int ch)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int size;
|
||||
int add = (int)((unsigned char*)unicode_to_utf8((char *)&buf[0],(uint32_t)ch) - &buf[0]);
|
||||
unsigned char *p,*b=buf;
|
||||
size = cstr->size + add;
|
||||
if (size > cstr->size_allocated)
|
||||
cstr_realloc(cstr, size);
|
||||
for(p = (unsigned char*)cstr->data + (size - add); add; add--) *p++=*b++;
|
||||
cstr->size = size;
|
||||
char buf[4], *e;
|
||||
e = unicode_to_utf8(buf, (uint32_t)ch);
|
||||
cstr_cat(cstr, buf, e - buf);
|
||||
}
|
||||
|
||||
|
||||
ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
|
||||
{
|
||||
int size;
|
||||
|
@ -617,6 +610,7 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
|||
}
|
||||
addv:
|
||||
*p++ = v;
|
||||
case 0: /* nameless anonymous symbol */
|
||||
*p = '\0';
|
||||
} else if (v < tok_ident) {
|
||||
return table_ident[v - TOK_IDENT]->str;
|
||||
|
@ -2095,7 +2089,7 @@ include_done:
|
|||
/* evaluate escape codes in a string. */
|
||||
static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
|
||||
{
|
||||
int c, n;
|
||||
int c, n, i;
|
||||
const uint8_t *p;
|
||||
|
||||
p = buf;
|
||||
|
@ -2125,13 +2119,13 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
|
|||
}
|
||||
c = n;
|
||||
goto add_char_nonext;
|
||||
case 'x': { unsigned int i; unsigned ucn_chars_nr = -1u; goto parse_hex_or_ucn;
|
||||
case 'u': ucn_chars_nr = 4; goto parse_hex_or_ucn;
|
||||
case 'U': ucn_chars_nr = 8; goto parse_hex_or_ucn;
|
||||
parse_hex_or_ucn:;
|
||||
case 'x': i = 0; goto parse_hex_or_ucn;
|
||||
case 'u': i = 4; goto parse_hex_or_ucn;
|
||||
case 'U': i = 8; goto parse_hex_or_ucn;
|
||||
parse_hex_or_ucn:
|
||||
p++;
|
||||
n = 0;
|
||||
for(i=1;i<=ucn_chars_nr;i++) {
|
||||
do {
|
||||
c = *p;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
c = c - 'a' + 10;
|
||||
|
@ -2139,19 +2133,17 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
|
|||
c = c - 'A' + 10;
|
||||
else if (isnum(c))
|
||||
c = c - '0';
|
||||
else{
|
||||
if (ucn_chars_nr!=-1)
|
||||
tcc_error("%u hex digits expected in universal-character-name\n", ucn_chars_nr);
|
||||
break;
|
||||
else if (i > 0)
|
||||
expect("more hex digits in universal-character-name");
|
||||
else {
|
||||
c = n;
|
||||
goto add_char_nonext;
|
||||
}
|
||||
n = n * 16 + c;
|
||||
p++;
|
||||
}
|
||||
c = n;
|
||||
if(ucn_chars_nr==-1) goto add_char_nonext;
|
||||
cstr_u8cat(outstr, c);
|
||||
} while (--i);
|
||||
cstr_u8cat(outstr, n);
|
||||
continue;
|
||||
}
|
||||
case 'a':
|
||||
c = '\a';
|
||||
break;
|
||||
|
|
2
tccrun.c
2
tccrun.c
|
@ -183,7 +183,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (s1->do_bounds_check) {
|
||||
if ((p = tcc_get_symbol(s1, "__bound_init")))
|
||||
((void(*)(void*, int))p)(bounds_section->data, 1);
|
||||
((void(*)(addr_t, int))p)(bounds_section->sh_addr, 1);
|
||||
}
|
||||
#endif
|
||||
set_exception_handler();
|
||||
|
|
6
tcctok.h
6
tcctok.h
|
@ -100,8 +100,10 @@
|
|||
DEF(TOK___NAN__, "__nan__")
|
||||
DEF(TOK___SNAN__, "__snan__")
|
||||
DEF(TOK___INF__, "__inf__")
|
||||
DEF(TOK___mzerosf, "__mzerosf")
|
||||
DEF(TOK___mzerodf, "__mzerodf")
|
||||
#if defined TCC_TARGET_X86_64
|
||||
DEF(TOK___mzerosf, "__mzerosf") /* -0.0 */
|
||||
DEF(TOK___mzerodf, "__mzerodf") /* -0.0 */
|
||||
#endif
|
||||
|
||||
/* attribute identifiers */
|
||||
/* XXX: handle all tokens generically since speed is not critical */
|
||||
|
|
|
@ -2830,9 +2830,6 @@ int reltab[3] = { 1, 2, 3 };
|
|||
int *rel1 = &reltab[1];
|
||||
int *rel2 = &reltab[2];
|
||||
|
||||
#ifdef _WIN64
|
||||
void relocation_test(void) {}
|
||||
#else
|
||||
void getmyaddress(void)
|
||||
{
|
||||
printf("in getmyaddress\n");
|
||||
|
@ -2850,7 +2847,7 @@ long __pa_symbol(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
unsigned long theaddress = (unsigned long)getmyaddress;
|
||||
uintptr_t theaddress = (uintptr_t)getmyaddress;
|
||||
void relocation_test(void)
|
||||
{
|
||||
void (*fptr)(void) = (void (*)(void))theaddress;
|
||||
|
@ -2861,7 +2858,6 @@ void relocation_test(void)
|
|||
printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void old_style_f(a,b,c)
|
||||
int a, b;
|
||||
|
|
Loading…
Reference in a new issue