Revert all of my changes to directories & codingstyle.

master
gus knight 2015-07-29 16:53:57 -04:00
parent 5a16f5ea98
commit 89ad24e7d6
52 changed files with 4438 additions and 4461 deletions

4
.gitignore vendored
View File

@ -5,7 +5,7 @@ a.out
*.log *.log
tcc_g tcc_g
tcc tcc
/src/*-tcc /*-tcc
tc2.c tc2.c
doc doc
tc3s.c tc3s.c
@ -63,7 +63,7 @@ lib/i386-win32
lib/arm lib/arm
lib/arm64 lib/arm64
tcc-doc.info tcc-doc.info
conftest*!conftest.c conftest*
tiny_libmaker tiny_libmaker
*.dSYM *.dSYM
*~ *~

View File

@ -85,14 +85,14 @@ endif()
file(STRINGS "VERSION" TCC_VERSION) file(STRINGS "VERSION" TCC_VERSION)
list(GET TCC_VERSION 0 TCC_VERSION) list(GET TCC_VERSION 0 TCC_VERSION)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/) include_directories(${CMAKE_BINARY_DIR})
configure_file(src/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/config.h) configure_file(config.h.in config.h)
configure_file(docs/config.texi.in ${CMAKE_CURRENT_SOURCE_DIR}/docs/config.texi) configure_file(config.texi.in config.texi)
# Utility variables # Utility variables
set(I386_SOURCES src/x86/i386-gen.c src/x86/i386-asm.c src/x86/i386-asm.h src/x86/i386-tok.h) set(I386_SOURCES i386-gen.c i386-asm.c i386-asm.h i386-tok.h)
set(X86_64_SOURCES src/x86/x86_64-gen.c src/x86/i386-asm.c src/x86/x86_64-asm.h) set(X86_64_SOURCES x86_64-gen.c i386-asm.c x86_64-asm.h)
set(ARM_SOURCES src/arm/arm_gen.c) set(ARM_SOURCES arm_gen.c)
set(LIBTCC1_I386_SOURCES lib/alloca86.S lib/alloca86-bt.S) set(LIBTCC1_I386_SOURCES lib/alloca86.S lib/alloca86-bt.S)
set(LIBTCC1_WIN_SOURCES win32/lib/crt1.c win32/lib/wincrt1.c win32/lib/dllcrt1.c win32/lib/dllmain.c win32/lib/chkstk.S) set(LIBTCC1_WIN_SOURCES win32/lib/crt1.c win32/lib/wincrt1.c win32/lib/dllcrt1.c win32/lib/dllmain.c win32/lib/chkstk.S)
@ -154,41 +154,41 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS}) foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS})
set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def}) set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def})
endforeach() endforeach()
if (TCC_BUILD_NATIVE) if (TCC_BUILD_NATIVE)
add_library(libtcc add_library(libtcc
src/libtcc.c libtcc.c
src/tccpp.c tccpp.c
src/tccgen.c tccgen.c
src/tccelf.c tccelf.c
src/tccasm.c tccasm.c
src/tccrun.c tccrun.c
src/tcc.h tcc.h
src/libtcc.h libtcc.h
src/tcctok.h tcctok.h
${tcc_sources} ${tcc_sources}
) )
set_target_properties(libtcc PROPERTIES OUTPUT_NAME tcc PREFIX lib) set_target_properties(libtcc PROPERTIES OUTPUT_NAME tcc PREFIX lib)
if(WIN32) if(WIN32)
set_target_properties(libtcc PROPERTIES LINK_FLAGS "-Wl,--output-def,libtcc.def") set_target_properties(libtcc PROPERTIES LINK_FLAGS "-Wl,--output-def,libtcc.def")
endif() endif()
add_executable(tcc src/tcc.c) add_executable(tcc tcc.c)
target_link_libraries(tcc libtcc) target_link_libraries(tcc libtcc)
if(NOT WIN32) if(NOT WIN32)
target_link_libraries(tcc dl) target_link_libraries(tcc dl)
endif() endif()
install(TARGETS tcc libtcc RUNTIME DESTINATION ${EXE_PATH} LIBRARY DESTINATION ${NATIVE_LIB_PATH} ARCHIVE DESTINATION ${NATIVE_LIB_PATH}) install(TARGETS tcc libtcc RUNTIME DESTINATION ${EXE_PATH} LIBRARY DESTINATION ${NATIVE_LIB_PATH} ARCHIVE DESTINATION ${NATIVE_LIB_PATH})
set_target_properties(tcc libtcc PROPERTIES COMPILE_DEFINITIONS "${TCC_NATIVE_DEFINITIONS}") set_target_properties(tcc libtcc PROPERTIES COMPILE_DEFINITIONS "${TCC_NATIVE_DEFINITIONS}")
if("${libtcc_sources}" STRGREATER "") if("${libtcc_sources}" STRGREATER "")
make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}") make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}")
endif() endif()
endif() endif()
elseif(${cross_enabled}) elseif(${cross_enabled})
add_executable(${cross_name}-tcc src/tcc.c) add_executable(${cross_name}-tcc tcc.c)
set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}") set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}")
install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH}) install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH})
if("${libtcc_sources}" STRGREATER "") if("${libtcc_sources}" STRGREATER "")
make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}") make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}")
endif() endif()
@ -197,17 +197,17 @@ endmacro()
make_tcc("Win32" i386-w64-mingw32 TCC_BUILD_WIN32 make_tcc("Win32" i386-w64-mingw32 TCC_BUILD_WIN32
"TCC_TARGET_I386;TCC_TARGET_PE" "TCC_TARGET_I386;TCC_TARGET_PE"
"${I386_SOURCES};src/tccpe.c" "${I386_SOURCES};tccpe.c"
tiny_libmaker_32 "${LIBTCC1_I386_SOURCES};${LIBTCC1_WIN_SOURCES}" "win32/include;win32/include/winapi" tiny_libmaker_32 "${LIBTCC1_I386_SOURCES};${LIBTCC1_WIN_SOURCES}" "win32/include;win32/include/winapi"
) )
make_tcc("Win64" x86_64-w64-mingw32 TCC_BUILD_WIN64 make_tcc("Win64" x86_64-w64-mingw32 TCC_BUILD_WIN64
"TCC_TARGET_X86_64;TCC_TARGET_PE" "TCC_TARGET_X86_64;TCC_TARGET_PE"
"${X86_64_SOURCES};src/tccpe.c" "${X86_64_SOURCES};tccpe.c"
tiny_libmaker_64 "lib/alloca86_64.S;${LIBTCC1_WIN_SOURCES}" "win32/include;win32/include/winapi" tiny_libmaker_64 "lib/alloca86_64.S;${LIBTCC1_WIN_SOURCES}" "win32/include;win32/include/winapi"
) )
make_tcc("WinCE" arm-wince-mingw32ce TCC_BUILD_WINCE make_tcc("WinCE" arm-wince-mingw32ce TCC_BUILD_WINCE
"TCC_TARGET_ARM;TCC_ARM_VERSION=${TCC_ARM_VERSION};TCC_TARGET_PE" "TCC_TARGET_ARM;TCC_ARM_VERSION=${TCC_ARM_VERSION};TCC_TARGET_PE"
"${ARM_SOURCES};src/tccpe.c" "${ARM_SOURCES};tccpe.c"
"" "" "" "" "" ""
) )
make_tcc("i386" i386-linux-gnu TCC_BUILD_I386 make_tcc("i386" i386-linux-gnu TCC_BUILD_I386
@ -248,7 +248,7 @@ make_tcc("" arm-linux-gnu TCC_BUILD_ARM_VFP
) )
make_tcc("" c67 TCC_BUILD_C67 make_tcc("" c67 TCC_BUILD_C67
TCC_TARGET_C67 TCC_TARGET_C67
"c67-gen.c;src/tcccoff.c" "c67-gen.c;tcccoff.c"
"" "" "" "" "" ""
) )
@ -257,14 +257,14 @@ add_subdirectory(tests)
find_program(MAKEINFO NAMES makeinfo PATHS C:/MinGW/MSYS/1.0/bin) find_program(MAKEINFO NAMES makeinfo PATHS C:/MinGW/MSYS/1.0/bin)
if(MAKEINFO) if(MAKEINFO)
add_custom_command(OUTPUT tcc-doc.html add_custom_command(OUTPUT tcc-doc.html
COMMAND ${MAKEINFO} --no-split --html -o tcc-doc.html ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi COMMAND ${MAKEINFO} --no-split --html -o tcc-doc.html ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
) )
set(TCC_DOC_FILES tcc-doc.html) set(TCC_DOC_FILES tcc-doc.html)
if(NOT WIN32) if(NOT WIN32)
add_custom_command(OUTPUT tcc-doc.info add_custom_command(OUTPUT tcc-doc.info
COMMAND ${MAKEINFO} -o tcc-doc.info ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi COMMAND ${MAKEINFO} -o tcc-doc.info ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
) )
set(TCC_DOC_FILES ${TCC_DOC_FILES} tcc-doc.info) set(TCC_DOC_FILES ${TCC_DOC_FILES} tcc-doc.info)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tcc-doc.info DESTINATION share/info) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tcc-doc.info DESTINATION share/info)
@ -290,3 +290,4 @@ else()
install(DIRECTORY win32/include/ DESTINATION lib/tcc/win32/include) install(DIRECTORY win32/include/ DESTINATION lib/tcc/win32/include)
install(DIRECTORY include/ DESTINATION lib/tcc/win32/include) install(DIRECTORY include/ DESTINATION lib/tcc/win32/include)
endif() endif()

View File

@ -1,9 +1,5 @@
TinyCC Coding Style Indentation
==========================
Lines should be no more than 80 columns long.
Indentation
--------------------------------------
Turn on a "fill tabs with spaces" option in your editor. Turn on a "fill tabs with spaces" option in your editor.
Be also careful that some files are indented with 2 spaces (when they Be also careful that some files are indented with 2 spaces (when they

423
Makefile
View File

@ -1,8 +1,421 @@
SRC_DIR = src #
# Tiny C Compiler Makefile
#
.PHONY: default TOP ?= .
default: include $(TOP)/config.mak
$(MAKE) -C $(SRC_DIR) VPATH = $(top_srcdir)
CPPFLAGS += -I$(TOP) # for config.h
ifneq (-$(findstring gcc,$(CC))-,-gcc-)
ifeq (-$(findstring clang,$(CC))-,-clang-)
# make clang accept gnuisms in libtcc1.c
CFLAGS+=-fheinous-gnu-extensions
endif
endif
CPPFLAGS_P=$(CPPFLAGS) -DCONFIG_TCC_STATIC
CFLAGS_P=$(CFLAGS) -pg -static
LIBS_P=
LDFLAGS_P=$(LDFLAGS)
ifdef CONFIG_WIN64
CONFIG_WIN32=yes
endif
ifndef CONFIG_WIN32
LIBS=-lm
ifndef CONFIG_NOLDL
LIBS+=-ldl
endif
endif
# make libtcc as static or dynamic library?
ifdef DISABLE_STATIC
ifndef CONFIG_WIN32
LIBTCC=libtcc.so.1.0
else
LIBTCC=libtcc.dll
LIBTCC_DLL=yes
LIBTCC_EXTRA=libtcc.def libtcc.a
endif
LINK_LIBTCC=-Wl,-rpath,"$(libdir)"
ifdef DISABLE_RPATH
LINK_LIBTCC=
endif
else
LIBTCC=libtcc.a
LINK_LIBTCC=
endif
CONFIG_$(ARCH) = yes
NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
NATIVE_DEFINES_$(CONFIG_x86-64) += -DTCC_TARGET_X86_64
NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
ifeq ($(TOP),.)
PROGS=tcc$(EXESUF)
I386_CROSS = i386-linux-gnu-tcc$(EXESUF)
WIN32_CROSS = i386-win-mingw32-tcc$(EXESUF)
WIN64_CROSS = x86_64-win-mingw32-tcc$(EXESUF)
WINCE_CROSS = arm-win-mingw32ce-tcc$(EXESUF)
X64_CROSS = x86_64-linux-gnu-tcc$(EXESUF)
ARM_FPA_CROSS = arm-linux-fpa-tcc$(EXESUF)
ARM_FPA_LD_CROSS = arm-linux-fpa-ld-tcc$(EXESUF)
ARM_VFP_CROSS = arm-linux-gnu-tcc$(EXESUF)
ARM_EABI_CROSS = arm-linux-gnueabi-tcc$(EXESUF)
ARM_EABIHF_CROSS = arm-linux-gnueabihf-tcc$(EXESUF)
ARM_CROSS = $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS)
ARM64_CROSS = arm64-tcc$(EXESUF)
C67_CROSS = c67-tcc$(EXESUF)
# Legacy symlinks for cross compilers
$(I386_CROSS)_LINK = i386-tcc$(EXESUF)
$(WIN32_CROSS)_LINK = i386-win-tcc$(EXESUF)
$(WIN64_CROSS)_LINK = x86_64-win-tcc$(EXESUF)
$(WINCE_CROSS)_LINK = arm-win-tcc$(EXESUF)
$(X64_CROSS)_LINK = x86_64-tcc$(EXESUF)
$(ARM_FPA_CROSS)_LINK = arm-fpa-tcc$(EXESUF)
$(ARM_FPA_LD_CROSS)_LINK = arm-fpa-ld-tcc$(EXESUF)
$(ARM_VFP_CROSS)_LINK = arm-vfp-tcc$(EXESUF)
$(ARM_EABI_CROSS)_LINK = arm-eabi-tcc$(EXESUF)
ifeq ($(TARGETOS),Windows)
ifeq ($(ARCH),i386)
PROGS:=$($(WIN32_CROSS)_LINK)
$($(WIN32_CROSS)_LINK)_TCC = yes
endif
ifeq ($(ARCH),x86-64)
PROGS:=$($(WIN64_CROSS)_LINK)
$($(WIN64_CROSS)_LINK)_TCC = yes
endif
endif
ifeq ($(TARGETOS),Linux)
ifeq ($(ARCH),i386)
PROGS:=$($(I386_CROSS)_LINK)
$($(I386_CROSS)_LINK)_TCC = yes
endif
ifeq ($(ARCH),x86-64)
PROGS:=$($(X64_CROSS)_LINK)
$($(X64_CROSS)_LINK)_TCC = yes
endif
endif
CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h
WIN32_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h tccpe.c
WIN64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h tccpe.c
WINCE_FILES = $(CORE_FILES) arm-gen.c tccpe.c
X86_64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h
ARM_FILES = $(CORE_FILES) arm-gen.c
ARM64_FILES = $(CORE_FILES) arm64-gen.c
C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
ifdef CONFIG_WIN64
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
NATIVE_FILES=$(WIN64_FILES)
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a
LIBTCC1=libtcc1.a
else ifdef CONFIG_WIN32
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
NATIVE_FILES=$(WIN32_FILES)
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/x86_64-win/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),i386)
NATIVE_FILES=$(I386_FILES)
PROGS_CROSS=$($(X64_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
lib/arm64/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),x86-64)
ifeq ($(TARGETOS),Darwin)
NATIVE_FILES=$(X86_64_FILES)
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a
LIBTCC1=libtcc1.a
else
NATIVE_FILES=$(X86_64_FILES)
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
lib/arm64/libtcc1.a
LIBTCC1=libtcc1.a
endif
else ifeq ($(ARCH),arm)
NATIVE_FILES=$(ARM_FILES)
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1=libtcc1.a
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
else ifeq ($(ARCH),arm64)
NATIVE_FILES=$(ARM64_FILES)
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1=libtcc1.a
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
endif
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
ifeq ($(TARGETOS),Darwin)
PROGS+=tiny_libmaker$(EXESUF)
endif
TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCC_EXTRA)
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
ifdef CONFIG_CROSS
PROGS+=$(PROGS_CROSS)
TCCLIBS+=$(LIBTCC1_CROSS)
endif
all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
# Host Tiny C Compiler
tcc$(EXESUF): tcc.o $(LIBTCC)
$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
# Cross Tiny C Compilers
%-tcc$(EXESUF): tcc.c
$(CC) -o $@ $< -DONE_SOURCE $(if $($@_TCC),$(NATIVE_DEFINES),$(DEFINES)) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
$(if $($@_LINK),ln -sf $@ $($@_LINK))
$(if $($@_TCC),ln -sf $@ tcc$(EXESUF))
# profiling version
tcc_p$(EXESUF): $(NATIVE_FILES)
$(CC) -o $@ $< -DONE_SOURCE $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
$(I386_CROSS) $($(I386_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386
$(X64_CROSS) $($(X64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/32;{B}/lib\""
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/64;{B}/lib\""
$(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE
$(C67_CROSS): DEFINES = -DTCC_TARGET_C67
$(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM
$(ARM_FPA_LD_CROSS)$(EXESUF): DEFINES = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
$(ARM_VFP_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_VFP
$(ARM_EABI_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP
$(ARM64_CROSS): DEFINES = -DTCC_TARGET_ARM64
$(I386_CROSS) $($(I386_CROSS)_LINK): $(I386_FILES)
$(X64_CROSS) $($(X64_CROSS)_LINK): $(X86_64_FILES)
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): $(WIN32_FILES)
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): $(WIN64_FILES)
$(WINCE_CROSS) $($(WINCE_CROSS)_LINK): $(WINCE_FILES)
$(C67_CROSS) $($(C67_CROSS)_LINK): $(C67_FILES)
$(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS): $(ARM_FILES)
$($(ARM_FPA_CROSS)_LINK) $($(ARM_FPA_LD_CROSS)_LINK) $($(ARM_VFP_CROSS)_LINK) $($(ARM_EABI_CROSS)_LINK): $(ARM_FILES)
$(ARM64_CROSS): $(ARM64_FILES)
# libtcc generation and test
ifndef ONE_SOURCE
LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
else
LIBTCC_OBJ = libtcc.o
LIBTCC_INC = $(NATIVE_FILES)
libtcc.o : NATIVE_DEFINES += -DONE_SOURCE
endif
$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
$(CC) -o $@ -c $< $(NATIVE_DEFINES) $(CPPFLAGS) $(CFLAGS)
ifndef LIBTCC_DLL
libtcc.a: $(LIBTCC_OBJ)
$(AR) rcs $@ $^
endif
libtcc.so.1.0: $(LIBTCC_OBJ)
$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
libtcc.so.1.0: CFLAGS+=-fPIC
ifdef LIBTCC_DLL
libtcc.dll libtcc.def libtcc.a: $(LIBTCC_OBJ)
$(CC) -shared $^ -o $@ $(LDFLAGS) -Wl,--output-def,libtcc.def,--out-implib,libtcc.a
endif
# windows utilities
tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
# TinyCC runtime libraries
libtcc1.a : FORCE
$(MAKE) -C lib native
if test ! -d $(ARCH); then mkdir $(ARCH); fi
if test ! -L $(ARCH)/$@; then ln -sf ../$@ $(ARCH)/$@; fi
lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
$(MAKE) -C lib cross TARGET=$*
FORCE:
# install
TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h
INSTALL=install
ifdef STRIP_BINARIES
INSTALLBIN=$(INSTALL) -s
else
INSTALLBIN=$(INSTALL)
endif
install-strip: install
strip $(foreach PROG,$(PROGS),"$(bindir)"/$(PROG))
ifndef CONFIG_WIN32
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
mkdir -p "$(bindir)"
$(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
cp -P tcc$(EXESUF) "$(bindir)"
mkdir -p "$(mandir)/man1"
-$(INSTALL) -m644 tcc.1 "$(mandir)/man1"
mkdir -p "$(infodir)"
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
mkdir -p "$(tccdir)"
mkdir -p "$(tccdir)/include"
ifneq ($(LIBTCC1),)
mkdir -p "$(tccdir)/$(ARCH)"
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)/$(ARCH)"
endif
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
mkdir -p "$(libdir)"
$(INSTALL) -m644 $(LIBTCC) "$(libdir)"
ifdef DISABLE_STATIC
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so.1"
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so"
endif
mkdir -p "$(includedir)"
$(INSTALL) -m644 $(top_srcdir)/libtcc.h "$(includedir)"
mkdir -p "$(docdir)"
-$(INSTALL) -m644 tcc-doc.html "$(docdir)"
ifdef CONFIG_CROSS
mkdir -p "$(tccdir)/win32/lib/32"
mkdir -p "$(tccdir)/win32/lib/64"
mkdir -p "$(tccdir)/i386"
mkdir -p "$(tccdir)/x86-64"
ifneq ($(HOST_OS),Darwin)
mkdir -p "$(tccdir)/arm64"
$(INSTALL) -m644 lib/arm64/libtcc1.a "$(tccdir)/arm64"
endif
$(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
$(INSTALL) -m644 lib/x86_64/libtcc1.a "$(tccdir)/x86-64"
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/win32/lib/32"
$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/win32/lib/64"
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
cp -r "$(tccdir)/include" "$(tccdir)/win32"
endif
uninstall:
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
rm -fv "$(bindir)/tcc$(EXESUF)"
rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
rm -fv "$(libdir)/libtcc.so*"
rm -rv "$(tccdir)"
rm -rv "$(docdir)"
else
# on windows
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
mkdir -p "$(tccdir)"
mkdir -p "$(tccdir)/lib"
mkdir -p "$(tccdir)/include"
mkdir -p "$(tccdir)/examples"
mkdir -p "$(tccdir)/doc"
mkdir -p "$(tccdir)/libtcc"
$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
$(INSTALLBIN) -m755 tcc.exe "$(tccdir)"
$(INSTALL) -m644 $(LIBTCC1) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib"
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include"
cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples"
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
$(INSTALL) -m644 tcc-doc.html $(top_srcdir)/win32/tcc-win32.txt "$(tccdir)/doc"
$(INSTALL) -m644 $(top_srcdir)/libtcc.h $(LIBTCC_EXTRA) "$(tccdir)/libtcc"
$(INSTALL) -m644 $(LIBTCC) "$(tccdir)"
ifdef CONFIG_CROSS
mkdir -p "$(tccdir)/lib/32"
mkdir -p "$(tccdir)/lib/64"
-$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/lib/32"
-$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/lib/64"
endif
uninstall:
rm -rfv "$(tccdir)/*"
endif
# documentation and man page
tcc-doc.html: tcc-doc.texi
-makeinfo --no-split --html --number-sections -o $@ $<
tcc.1: tcc-doc.texi
-$(top_srcdir)/texi2pod.pl $< tcc.pod
-pod2man --section=1 --center="Tiny C Compiler" --release=`cat $(top_srcdir)/VERSION` tcc.pod > $@
tcc-doc.info: tcc-doc.texi
-makeinfo $<
# in tests subdir
export LIBTCC1
%est:
$(MAKE) -C tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
clean: clean:
$(MAKE) -C $(SRC_DIR) clean rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.log \
*.exe a.out tags TAGS libtcc_test$(EXESUF) tcc$(EXESUF)
-rm -r $(ARCH) arm64
ifeq ($(HOST_OS),Linux)
-rm -r ./C:
endif
-rm *-tcc$(EXESUF)
$(MAKE) -C tests $@
ifneq ($(LIBTCC1),)
$(MAKE) -C lib $@
endif
distclean: clean
rm -vf config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
config.mak:
@echo "Please run ./configure."
@exit 1
tags:
ctags $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
TAGS:
ctags -e $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
# create release tarball from *current* git branch (including tcc-doc.html
# and converting two files to CRLF)
TCC-VERSION := tcc-$(shell cat $(top_srcdir)/VERSION)
tar: tcc-doc.html
mkdir $(TCC-VERSION)
( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
cp tcc-doc.html $(TCC-VERSION)
for f in tcc-win32.txt build-tcc.bat ; do \
cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
done
tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
rm -rf $(TCC-VERSION)
git reset
.PHONY: all clean tar tags TAGS distclean install uninstall FORCE
endif # ifeq ($(TOP),.)

View File

2123
arm-gen.c 100644

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,7 @@ typedef int RegArgs;
/******************************************************/ /******************************************************/
#else /* ! TARGET_DEFS_ONLY */ #else /* ! TARGET_DEFS_ONLY */
/******************************************************/ /******************************************************/
#include "../tcc.h" #include "tcc.h"
#include <assert.h> #include <assert.h>
ST_DATA const int reg_classes[NB_REGS] = { ST_DATA const int reg_classes[NB_REGS] = {

View File

@ -1,6 +1,6 @@
/* /*
* TMS320C67xx code generator for TCC * TMS320C67xx code generator for TCC
* *
* Copyright (c) 2001, 2002 Fabrice Bellard * Copyright (c) 2001, 2002 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -127,10 +127,10 @@ enum {
/******************************************************/ /******************************************************/
#else /* ! TARGET_DEFS_ONLY */ #else /* ! TARGET_DEFS_ONLY */
/******************************************************/ /******************************************************/
#include "../tcc.h" #include "tcc.h"
ST_DATA const int reg_classes[NB_REGS] = { ST_DATA const int reg_classes[NB_REGS] = {
/* eax */ RC_INT | RC_FLOAT | RC_EAX, /* eax */ RC_INT | RC_FLOAT | RC_EAX,
// only allow even regs for floats (allow for doubles) // only allow even regs for floats (allow for doubles)
/* ecx */ RC_INT | RC_ECX, /* ecx */ RC_INT | RC_ECX,
/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX, /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
@ -161,7 +161,7 @@ ST_DATA const int reg_classes[NB_REGS] = {
// although tcc thinks it is passing parameters on the stack, // although tcc thinks it is passing parameters on the stack,
// the C67 really passes up to the first 10 params in special // the C67 really passes up to the first 10 params in special
// regs or regs pairs (for 64 bit params). So keep track of // regs or regs pairs (for 64 bit params). So keep track of
// the stack offsets so we can translate to the appropriate // the stack offsets so we can translate to the appropriate
// reg (pair) // reg (pair)
#define NoCallArgsPassedOnStack 10 #define NoCallArgsPassedOnStack 10
@ -204,7 +204,7 @@ void C67_g(int c)
#endif #endif
ind1 = ind + 4; ind1 = ind + 4;
if (ind1 > (int) cur_text_section->data_allocated) if (ind1 > (int) cur_text_section->data_allocated)
section_realloc(cur_text_section, ind1); section_realloc(cur_text_section, ind1);
cur_text_section->data[ind] = c & 0xff; cur_text_section->data[ind] = c & 0xff;
cur_text_section->data[ind + 1] = (c >> 8) & 0xff; cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
cur_text_section->data[ind + 2] = (c >> 16) & 0xff; cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
@ -218,26 +218,26 @@ void gsym_addr(int t, int a)
{ {
int n, *ptr; int n, *ptr;
while (t) { while (t) {
ptr = (int *) (cur_text_section->data + t); ptr = (int *) (cur_text_section->data + t);
{ {
Sym *sym; Sym *sym;
// extract 32 bit address from MVKH/MVKL // extract 32 bit address from MVKH/MVKL
n = ((*ptr >> 7) & 0xffff); n = ((*ptr >> 7) & 0xffff);
n |= ((*(ptr + 1) >> 7) & 0xffff) << 16; n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
// define a label that will be relocated // define a label that will be relocated
sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
greloc(cur_text_section, sym, t, R_C60LO16); greloc(cur_text_section, sym, t, R_C60LO16);
greloc(cur_text_section, sym, t + 4, R_C60HI16); greloc(cur_text_section, sym, t + 4, R_C60HI16);
// clear out where the pointer was // clear out where the pointer was
*ptr &= ~(0xffff << 7); *ptr &= ~(0xffff << 7);
*(ptr + 1) &= ~(0xffff << 7); *(ptr + 1) &= ~(0xffff << 7);
} }
t = n; t = n;
} }
} }
@ -246,7 +246,7 @@ void gsym(int t)
gsym_addr(t, ind); gsym_addr(t, ind);
} }
// these are regs that tcc doesn't really know about, // these are regs that tcc doesn't really know about,
// but assign them unique values so the mapping routines // but assign them unique values so the mapping routines
// can distinguish them // can distinguish them
@ -298,7 +298,7 @@ int C67_map_regn(int r)
return 0; return 0;
} }
// mapping from tcc reg number to // mapping from tcc reg number to
// C67 register to condition code field // C67 register to condition code field
// //
// valid condition code regs are: // valid condition code regs are:
@ -343,15 +343,15 @@ int C67_map_regs(int r)
else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
return (r & 2) >> 1; return (r & 2) >> 1;
else if (r == C67_A0) else if (r == C67_A0)
return 0; // set to A side return 0; // set to A side
else if (r == C67_B2) else if (r == C67_B2)
return 1; // set to B side return 1; // set to B side
else if (r == C67_B3) else if (r == C67_B3)
return 1; // set to B side return 1; // set to B side
else if (r == C67_SP) else if (r == C67_SP)
return 0x1; // set to SP (B15) B side return 0x1; // set to SP (B15) B side
else if (r == C67_FP) else if (r == C67_FP)
return 0x0; // set to FP (A15) A side return 0x0; // set to FP (A15) A side
else else
ALWAYS_ASSERT(FALSE); ALWAYS_ASSERT(FALSE);
@ -420,7 +420,7 @@ void C67_asm(char *s, int a, int b, int c)
(5 << 9) | //mode 5 = pos offset, base reg + off reg (5 << 9) | //mode 5 = pos offset, base reg + off reg
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(0 << 7) | //y D1/D2 A side (0 << 7) | //y D1/D2 A side
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -442,7 +442,7 @@ void C67_asm(char *s, int a, int b, int c)
(5 << 9) | //mode 5 = pos offset, base reg + off reg (5 << 9) | //mode 5 = pos offset, base reg + off reg
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(0 << 7) | //y D1/D2 A side (0 << 7) | //y D1/D2 A side
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -464,7 +464,7 @@ void C67_asm(char *s, int a, int b, int c)
(5 << 9) | //mode 5 = pos offset, base reg + off reg (5 << 9) | //mode 5 = pos offset, base reg + off reg
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(0 << 7) | //y D1/D2 A side (0 << 7) | //y D1/D2 A side
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -475,7 +475,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -486,7 +486,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -497,7 +497,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -509,7 +509,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -641,7 +641,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(a) << 7) | //y D1/D2 src side (C67_map_regs(a) << 7) | //y D1/D2 src side
(2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(b) << 1) | //side of dst (C67_map_regs(b) << 1) | //side of dst
(0 << 0)); //parallel (0 << 0)); //parallel
@ -652,7 +652,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(a) << 7) | //y D1/D2 src side (C67_map_regs(a) << 7) | //y D1/D2 src side
(0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(b) << 1) | //side of dst (C67_map_regs(b) << 1) | //side of dst
(0 << 0)); //parallel (0 << 0)); //parallel
@ -674,7 +674,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(a) << 7) | //y D1/D2 src side (C67_map_regs(a) << 7) | //y D1/D2 src side
(6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(b) << 1) | //side of dst (C67_map_regs(b) << 1) | //side of dst
(0 << 0)); //parallel (0 << 0)); //parallel
@ -877,7 +877,7 @@ void C67_asm(char *s, int a, int b, int c)
C67_g((0 << 29) | //creg C67_g((0 << 29) | //creg
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(0 << 13) | //src1 NA (0 << 13) | //src1 NA
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x4a << 5) | //opcode (0x4a << 5) | //opcode
@ -890,7 +890,7 @@ void C67_asm(char *s, int a, int b, int c)
C67_g((0 << 29) | //creg C67_g((0 << 29) | //creg
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(0 << 13) | //src1 NA (0 << 13) | //src1 NA
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x49 << 5) | //opcode (0x49 << 5) | //opcode
@ -903,7 +903,7 @@ void C67_asm(char *s, int a, int b, int c)
C67_g((0 << 29) | //creg C67_g((0 << 29) | //creg
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(0 << 13) | //src1 NA (0 << 13) | //src1 NA
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x39 << 5) | //opcode (0x39 << 5) | //opcode
@ -958,7 +958,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x3 << 5) | //opcode (0x3 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -973,7 +973,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x7 << 5) | //opcode (0x7 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -988,7 +988,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x7f << 5) | //opcode (0x7f << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1003,7 +1003,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x7b << 5) | //opcode (0x7b << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1018,7 +1018,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x6f << 5) | //opcode (0x6f << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1033,7 +1033,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x10 << 5) | //opcode (0x10 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1048,7 +1048,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x18 << 5) | //opcode (0x18 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1063,7 +1063,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x11 << 5) | //opcode (0x11 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1078,7 +1078,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x19 << 5) | //opcode (0x19 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1093,7 +1093,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x1c << 7) | //opcode (0x1c << 7) | //opcode
(0x0 << 2) | //opcode fixed (0x0 << 2) | //opcode fixed
@ -1108,7 +1108,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x0e << 7) | //opcode (0x0e << 7) | //opcode
(0x0 << 2) | //opcode fixed (0x0 << 2) | //opcode fixed
@ -1138,7 +1138,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x37 << 6) | //opcode (0x37 << 6) | //opcode
(0x8 << 2) | //opcode fixed (0x8 << 2) | //opcode fixed
@ -1153,7 +1153,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x27 << 6) | //opcode (0x27 << 6) | //opcode
(0x8 << 2) | //opcode fixed (0x8 << 2) | //opcode fixed
@ -1168,7 +1168,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x33 << 6) | //opcode (0x33 << 6) | //opcode
(0x8 << 2) | //opcode fixed (0x8 << 2) | //opcode fixed
@ -1597,7 +1597,7 @@ void load(int r, SValue * sv)
size = 4; size = 4;
} }
// check if fc is a positive reference on the stack, // check if fc is a positive reference on the stack,
// if it is tcc is referencing what it thinks is a parameter // if it is tcc is referencing what it thinks is a parameter
// on the stack, so check if it is really in a register. // on the stack, so check if it is really in a register.
@ -1962,7 +1962,7 @@ void gfunc_call(int nb_args)
// ending with B12:B13. // ending with B12:B13.
// //
// When a call is made, if the caller has its parameters // When a call is made, if the caller has its parameters
// in regs A4-B13 these must be saved before/as the call // in regs A4-B13 these must be saved before/as the call
// parameters are loaded and restored upon return (or if/when needed). // parameters are loaded and restored upon return (or if/when needed).
/* generate function prolog of type 't' */ /* generate function prolog of type 't' */
@ -2033,7 +2033,7 @@ void gfunc_prolog(CType * func_type)
TotalBytesPushedOnStack = -loc; TotalBytesPushedOnStack = -loc;
func_sub_sp_offset = ind; // remember where we put the stack instruction func_sub_sp_offset = ind; // remember where we put the stack instruction
C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily) C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
C67_PUSH(C67_A0); C67_PUSH(C67_A0);
@ -2049,11 +2049,11 @@ void gfunc_epilog(void)
C67_NOP(4); // NOP wait for load C67_NOP(4); // NOP wait for load
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
C67_POP(C67_FP); C67_POP(C67_FP);
C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
C67_Adjust_ADDK((int *) (cur_text_section->data + C67_Adjust_ADDK((int *) (cur_text_section->data +
func_sub_sp_offset), func_sub_sp_offset),
-local + TotalBytesPushedOnStack); -local + TotalBytesPushedOnStack);
C67_NOP(3); // NOP C67_NOP(3); // NOP
} }
} }

View File

@ -31,9 +31,9 @@ struct filehdr {
#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */ #define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */ #define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
#define F_PATCH 0x400 /* contains "patch" list in optional header */ #define F_PATCH 0x400 /* contains "patch" list in optional header */
#define F_NODF 0x400 #define F_NODF 0x400
#define F_VERSION (F_GSP10 | F_GSP20) #define F_VERSION (F_GSP10 | F_GSP20)
#define F_BYTE_ORDER (F_LITTLE | F_BIG) #define F_BYTE_ORDER (F_LITTLE | F_BIG)
#define FILHDR struct filehdr #define FILHDR struct filehdr
@ -68,7 +68,7 @@ typedef struct aouthdr {
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* When a UNIX aout header is to be built in the optional header, */ /* When a UNIX aout header is to be built in the optional header, */
/* the following magic numbers can appear in that header: */ /* the following magic numbers can appear in that header: */
/* */ /* */
/* AOUT1MAGIC : default : readonly sharable text segment */ /* AOUT1MAGIC : default : readonly sharable text segment */
/* AOUT2MAGIC: : writable text segment */ /* AOUT2MAGIC: : writable text segment */
@ -164,7 +164,7 @@ struct scnhdr {
#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */ #define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */ #define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */ #define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */
#define STYP_COPY 0x10 /* "copy" : used for C init tables - #define STYP_COPY 0x10 /* "copy" : used for C init tables -
not allocated, relocated, not allocated, relocated,
loaded; reloc & lineno loaded; reloc & lineno
entries processed normally */ entries processed normally */
@ -358,11 +358,11 @@ struct syment
#define N_BTSHFT_COFF 4 #define N_BTSHFT_COFF 4
#define N_TSHIFT_COFF 2 #define N_TSHIFT_COFF 2
#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF) #define BTYPE_COFF(x) ((x) & N_BTMASK_COFF)
#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \ #define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \
((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM) ((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT) #define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT)
#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF)) #define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF))
#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF)) #define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF)) #define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG) #define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
@ -370,7 +370,7 @@ struct syment
#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF)) #define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
#define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF)) #define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* AUXILIARY SYMBOL ENTRY */ /* AUXILIARY SYMBOL ENTRY */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/

10
configure vendored
View File

@ -66,7 +66,7 @@ case $targetos in
esac esac
# find source path # find source path
# XXX: we assume an absolute path is given when launching configure, # XXX: we assume an absolute path is given when launching configure,
# except in './configure' case. # except in './configure' case.
source_path=${0%configure} source_path=${0%configure}
source_path=${source_path%/} source_path=${source_path%/}
@ -337,7 +337,7 @@ strip="${cross_prefix}${strip}"
CONFTEST=./conftest$EXESUF CONFTEST=./conftest$EXESUF
if test -z "$cross_prefix" ; then if test -z "$cross_prefix" ; then
if ! $cc -o $CONFTEST $source_path/src/conftest.c 2>/dev/null ; then if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
echo "configure: error: '$cc' failed to compile conftest.c." echo "configure: error: '$cc' failed to compile conftest.c."
else else
bigendian="$($CONFTEST bigendian)" bigendian="$($CONFTEST bigendian)"
@ -560,7 +560,7 @@ fi
version=`head $source_path/VERSION` version=`head $source_path/VERSION`
echo "VERSION=$version" >>config.mak echo "VERSION=$version" >>config.mak
echo "#define TCC_VERSION \"$version\"" >> $TMPH echo "#define TCC_VERSION \"$version\"" >> $TMPH
echo "@set VERSION $version" >docs/config.texi echo "@set VERSION $version" > config.texi
echo "SRC_PATH=$source_path" >>config.mak echo "SRC_PATH=$source_path" >>config.mak
if test "$source_path_used" = "yes" ; then if test "$source_path_used" = "yes" ; then
@ -573,9 +573,9 @@ else
fi fi
echo 'top_builddir=$(TOP)' >>config.mak echo 'top_builddir=$(TOP)' >>config.mak
diff $TMPH src/config.h >/dev/null 2>&1 diff $TMPH config.h >/dev/null 2>&1
if test $? -ne 0 ; then if test $? -ne 0 ; then
mv -f $TMPH src/config.h mv -f $TMPH config.h
else else
echo "config.h is unchanged" echo "config.h is unchanged"
fi fi

View File

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "../tcc.h" #include "tcc.h"
/* #define NB_ASM_REGS 8 */ /* #define NB_ASM_REGS 8 */
#define MAX_OPERANDS 3 #define MAX_OPERANDS 3
@ -712,7 +712,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
a32 = addr32 = 1; a32 = addr32 = 1;
} }
#endif #endif
if (b & 0xff00) if (b & 0xff00)
g(b >> 8); g(b >> 8);
g(b); g(b);
return; return;

View File

@ -57,7 +57,7 @@ ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
/* bits */ /* bits */
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
@ -91,7 +91,7 @@ ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)
DEF_ASM_OP0(repz, 0xf3) DEF_ASM_OP0(repz, 0xf3)
DEF_ASM_OP0(repne, 0xf2) DEF_ASM_OP0(repne, 0xf2)
DEF_ASM_OP0(repnz, 0xf2) DEF_ASM_OP0(repnz, 0xf2)
DEF_ASM_OP0(invd, 0x0f08) DEF_ASM_OP0(invd, 0x0f08)
DEF_ASM_OP0(wbinvd, 0x0f09) DEF_ASM_OP0(wbinvd, 0x0f09)
DEF_ASM_OP0(cpuid, 0x0fa2) DEF_ASM_OP0(cpuid, 0x0fa2)
@ -236,7 +236,7 @@ ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
/* float */ /* float */
/* specific fcomp handling */ /* specific fcomp handling */
ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
@ -298,7 +298,7 @@ ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
/* fp store */ /* fp store */
DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
@ -380,7 +380,7 @@ ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT
/* pentium */ /* pentium */
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
/* pentium pro */ /* pentium pro */
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
#ifdef I386_ASM_16 #ifdef I386_ASM_16

View File

@ -1,6 +1,6 @@
/* /*
* X86 code generator for TCC * X86 code generator for TCC
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -32,7 +32,7 @@ typedef int RegArgs;
#define RC_INT 0x0001 /* generic integer register */ #define RC_INT 0x0001 /* generic integer register */
#define RC_FLOAT 0x0002 /* generic float register */ #define RC_FLOAT 0x0002 /* generic float register */
#define RC_EAX 0x0004 #define RC_EAX 0x0004
#define RC_ST0 0x0008 #define RC_ST0 0x0008
#define RC_ECX 0x0010 #define RC_ECX 0x0010
#define RC_EDX 0x0020 #define RC_EDX 0x0020
#define RC_IRET RC_EAX /* function return: integer register */ #define RC_IRET RC_EAX /* function return: integer register */
@ -89,7 +89,7 @@ enum {
/******************************************************/ /******************************************************/
#else /* ! TARGET_DEFS_ONLY */ #else /* ! TARGET_DEFS_ONLY */
/******************************************************/ /******************************************************/
#include "../tcc.h" #include "tcc.h"
ST_DATA const int reg_classes[NB_REGS] = { ST_DATA const int reg_classes[NB_REGS] = {
/* eax */ RC_INT | RC_EAX, /* eax */ RC_INT | RC_EAX,
@ -357,11 +357,11 @@ static void gcall_or_jmp(int is_jmp)
/* constant case */ /* constant case */
if (vtop->r & VT_SYM) { if (vtop->r & VT_SYM) {
/* relocation case */ /* relocation case */
greloc(cur_text_section, vtop->sym, greloc(cur_text_section, vtop->sym,
ind + 1, R_386_PC32); ind + 1, R_386_PC32);
} else { } else {
/* put an empty PC32 relocation */ /* put an empty PC32 relocation */
put_elf_reloc(symtab_section, cur_text_section, put_elf_reloc(symtab_section, cur_text_section,
ind + 1, R_386_PC32, 0); ind + 1, R_386_PC32, 0);
} }
oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
@ -417,7 +417,7 @@ ST_FUNC void gfunc_call(int nb_args)
{ {
int size, align, r, args_size, i, func_call; int size, align, r, args_size, i, func_call;
Sym *func_sym; Sym *func_sym;
args_size = 0; args_size = 0;
for(i = 0;i < nb_args; i++) { for(i = 0;i < nb_args; i++) {
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@ -610,7 +610,7 @@ ST_FUNC void gfunc_epilog(void)
/* generate bound local allocation */ /* generate bound local allocation */
saved_ind = ind; saved_ind = ind;
ind = func_sub_sp_offset; ind = func_sub_sp_offset;
sym_data = get_sym_ref(&char_pointer_type, lbounds_section, sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
func_bound_offset, lbounds_section->data_offset); func_bound_offset, lbounds_section->data_offset);
greloc(cur_text_section, sym_data, greloc(cur_text_section, sym_data,
ind + 1, R_386_32); ind + 1, R_386_32);
@ -637,8 +637,8 @@ ST_FUNC void gfunc_epilog(void)
g(func_ret_sub >> 8); g(func_ret_sub >> 8);
} }
/* align local size to word & save local variables */ /* align local size to word & save local variables */
v = (-loc + 3) & -4; v = (-loc + 3) & -4;
saved_ind = ind; saved_ind = ind;
ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
@ -741,7 +741,7 @@ ST_FUNC void gen_opi(int op)
r = vtop[-1].r; r = vtop[-1].r;
fr = vtop[0].r; fr = vtop[0].r;
o((opc << 3) | 0x01); o((opc << 3) | 0x01);
o(0xc0 + r + fr * 8); o(0xc0 + r + fr * 8);
} }
vtop--; vtop--;
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
@ -911,7 +911,7 @@ ST_FUNC void gen_opf(int op)
load(TREG_ST0, vtop); load(TREG_ST0, vtop);
swapped = !swapped; swapped = !swapped;
} }
switch(op) { switch(op) {
default: default:
case '+': case '+':
@ -972,7 +972,7 @@ ST_FUNC void gen_cvt_itof(int t)
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
o(0x242cdf); /* fildll (%esp) */ o(0x242cdf); /* fildll (%esp) */
o(0x08c483); /* add $8, %esp */ o(0x08c483); /* add $8, %esp */
} else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED)) { (VT_INT | VT_UNSIGNED)) {
/* unsigned int to float/double/long double */ /* unsigned int to float/double/long double */
o(0x6a); /* push $0 */ o(0x6a); /* push $0 */
@ -1060,7 +1060,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
vtop++; vtop++;
vtop->r = TREG_EAX | VT_BOUNDED; vtop->r = TREG_EAX | VT_BOUNDED;
/* address of bounding function call point */ /* address of bounding function call point */
vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
} }
/* patch pointer addition in vtop so that pointer dereferencing is /* patch pointer addition in vtop so that pointer dereferencing is

View File

@ -1,6 +1,6 @@
/* /*
* CIL code generator for TCC * CIL code generator for TCC
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -112,7 +112,7 @@ static void init_outfile(void)
{ {
if (!il_outfile) { if (!il_outfile) {
il_outfile = stdout; il_outfile = stdout;
fprintf(il_outfile, fprintf(il_outfile,
".assembly extern mscorlib\n" ".assembly extern mscorlib\n"
"{\n" "{\n"
".ver 1:0:2411:0\n" ".ver 1:0:2411:0\n"
@ -149,7 +149,7 @@ static void out_opi(int op, int c)
} }
/* XXX: not complete */ /* XXX: not complete */
static void il_type_to_str(char *buf, int buf_size, static void il_type_to_str(char *buf, int buf_size,
int t, const char *varstr) int t, const char *varstr)
{ {
int bt; int bt;
@ -301,12 +301,12 @@ void load(int r, SValue *sv)
out_op(IL_OP_LDIND_U2); out_op(IL_OP_LDIND_U2);
else else
out_op(IL_OP_LDIND_I4); out_op(IL_OP_LDIND_I4);
} }
} else { } else {
if (v == VT_CONST) { if (v == VT_CONST) {
/* XXX: handle globals */ /* XXX: handle globals */
if (fc >= -1 && fc <= 8) { if (fc >= -1 && fc <= 8) {
out_op(IL_OP_LDC_I4_M1 + fc + 1); out_op(IL_OP_LDC_I4_M1 + fc + 1);
} else { } else {
out_opi(IL_OP_LDC_I4, fc); out_opi(IL_OP_LDC_I4, fc);
} }
@ -430,10 +430,10 @@ void gfunc_prolog(int t)
/* XXX: cannot do better now */ /* XXX: cannot do better now */
fprintf(il_outfile, " .maxstack %d\n", NB_REGS); fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n"); fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
if (!strcmp(funcname, "main")) if (!strcmp(funcname, "main"))
fprintf(il_outfile, " .entrypoint\n"); fprintf(il_outfile, " .entrypoint\n");
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT); sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
func_call = sym->r; func_call = sym->r;

View File

@ -1,6 +1,6 @@
/* /*
* CIL opcode definition * CIL opcode definition
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify

View File

@ -2,9 +2,9 @@
# Tiny C Compiler Makefile for libtcc1.a # Tiny C Compiler Makefile for libtcc1.a
# #
TOP = ../src TOP = ..
include $(TOP)/Makefile include $(TOP)/Makefile
VPATH = $(top_srcdir)/../lib $(top_srcdir)/../win32/lib VPATH = $(top_srcdir)/lib $(top_srcdir)/win32/lib
ifndef TARGET # native library ifndef TARGET # native library
ifdef CONFIG_WIN64 ifdef CONFIG_WIN64
@ -37,7 +37,7 @@ endif
BCHECK_O = bcheck.o BCHECK_O = bcheck.o
DIR = $(TARGET) DIR = $(TARGET)
native : $(DIR)/libtcc1.a native : ../libtcc1.a
cross : $(DIR)/libtcc1.a cross : $(DIR)/libtcc1.a
native : TCC = $(TOP)/tcc$(EXESUF) native : TCC = $(TOP)/tcc$(EXESUF)
@ -61,26 +61,26 @@ CFLAGS := $(filter-out -fstack-protector-strong,$(CFLAGS))
ifeq "$(TARGET)" "i386-win" ifeq "$(TARGET)" "i386-win"
OBJ = $(addprefix $(DIR)/,$(WIN32_O)) OBJ = $(addprefix $(DIR)/,$(WIN32_O))
TGT = -DTCC_TARGET_I386 -DTCC_TARGET_PE TGT = -DTCC_TARGET_I386 -DTCC_TARGET_PE
XCC ?= $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/../include XCC ?= $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
XAR ?= $(DIR)/tiny_libmaker$(EXESUF) XAR ?= $(DIR)/tiny_libmaker$(EXESUF)
PICFLAGS = PICFLAGS =
else else
ifeq "$(TARGET)" "x86_64-win" ifeq "$(TARGET)" "x86_64-win"
OBJ = $(addprefix $(DIR)/,$(WIN64_O)) OBJ = $(addprefix $(DIR)/,$(WIN64_O))
TGT = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE TGT = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/../include XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
XAR ?= $(DIR)/tiny_libmaker$(EXESUF) XAR ?= $(DIR)/tiny_libmaker$(EXESUF)
PICFLAGS = PICFLAGS =
else else
ifeq "$(TARGET)" "i386" ifeq "$(TARGET)" "i386"
OBJ = $(addprefix $(DIR)/,$(I386_O)) OBJ = $(addprefix $(DIR)/,$(I386_O))
TGT = -DTCC_TARGET_I386 TGT = -DTCC_TARGET_I386
XCC ?= $(TCC) -B$(TOP) -I$(top_srcdir)/../include XCC ?= $(TCC) -B$(TOP)
else else
ifeq "$(TARGET)" "x86_64" ifeq "$(TARGET)" "x86_64"
OBJ = $(addprefix $(DIR)/,$(X86_64_O)) OBJ = $(addprefix $(DIR)/,$(X86_64_O))
TGT = -DTCC_TARGET_X86_64 TGT = -DTCC_TARGET_X86_64
XCC ?= $(TCC) -B$(TOP) -I$(top_srcdir)/../include XCC ?= $(TCC) -B$(TOP)
else else
ifeq "$(TARGET)" "arm" ifeq "$(TARGET)" "arm"
OBJ = $(addprefix $(DIR)/,$(ARM_O)) OBJ = $(addprefix $(DIR)/,$(ARM_O))
@ -110,7 +110,7 @@ endif
XAR ?= $(AR) XAR ?= $(AR)
$(DIR)/libtcc1.a : $(OBJ) $(XAR) $(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
$(XAR) rcs $@ $(OBJ) $(XAR) rcs $@ $(OBJ)
$(DIR)/%.o : %.c $(DIR)/%.o : %.c
$(XCC) -c $< -o $@ $(XFLAGS) $(XCC) -c $< -o $@ $(XFLAGS)

View File

@ -1,6 +1,6 @@
/* /*
* Tiny C Memory and bounds checker * Tiny C Memory and bounds checker
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -88,7 +88,7 @@ int __bound_delete_region(void *p);
#ifdef __attribute__ #ifdef __attribute__
/* an __attribute__ macro is defined in the system headers */ /* an __attribute__ macro is defined in the system headers */
#undef __attribute__ #undef __attribute__
#endif #endif
#define FASTCALL __attribute__((regparm(3))) #define FASTCALL __attribute__((regparm(3)))
@ -177,8 +177,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset); dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset);
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e + e = (BoundEntry *)((char *)e +
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
addr -= e->start; addr -= e->start;
if (addr > e->size) { if (addr > e->size) {
@ -236,7 +236,7 @@ BOUND_PTR_INDIR(16)
} }
/* called when entering a function to add all the local regions */ /* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1) void FASTCALL __bound_local_new(void *p1)
{ {
size_t addr, size, fp, *p = p1; size_t addr, size, fp, *p = p1;
@ -255,7 +255,7 @@ void FASTCALL __bound_local_new(void *p1)
} }
/* called when leaving a function to delete all the local regions */ /* called when leaving a function to delete all the local regions */
void FASTCALL __bound_local_delete(void *p1) void FASTCALL __bound_local_delete(void *p1)
{ {
size_t addr, fp, *p = p1; size_t addr, fp, *p = p1;
GET_CALLER_FP(fp); GET_CALLER_FP(fp);
@ -331,14 +331,14 @@ static void mark_invalid(size_t addr, size_t size)
#if 0 #if 0
dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end); dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
#endif #endif
/* first we handle full pages */ /* first we handle full pages */
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS; t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
t1_end = t2_end >> BOUND_T2_BITS; t1_end = t2_end >> BOUND_T2_BITS;
i = t2_start & (BOUND_T2_SIZE - 1); i = t2_start & (BOUND_T2_SIZE - 1);
j = t2_end & (BOUND_T2_SIZE - 1); j = t2_end & (BOUND_T2_SIZE - 1);
if (t1_start == t1_end) { if (t1_start == t1_end) {
page = get_page(t2_start >> BOUND_T2_BITS); page = get_page(t2_start >> BOUND_T2_BITS);
for(; i < j; i++) { for(; i < j; i++) {
@ -456,7 +456,7 @@ void __bound_main_arg(void **p)
void *start = p; void *start = p;
while (*p++); while (*p++);
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, (void *) p - start); __FILE__, __FUNCTION__, (void *) p - start);
__bound_new_region(start, (void *) p - start); __bound_new_region(start, (void *) p - start);
@ -467,7 +467,7 @@ void __bound_exit(void)
restore_malloc_hooks(); restore_malloc_hooks();
} }
static inline void add_region(BoundEntry *e, static inline void add_region(BoundEntry *e,
size_t start, size_t size) size_t start, size_t size)
{ {
BoundEntry *e1; BoundEntry *e1;
@ -496,7 +496,7 @@ void __bound_new_region(void *p, size_t size)
__bound_init(); __bound_init();
dprintf(stderr, "%s, %s(%p, %p) start\n", dprintf(stderr, "%s, %s(%p, %p) start\n",
__FILE__, __FUNCTION__, p, size); __FILE__, __FUNCTION__, p, size);
start = (size_t)p; start = (size_t)p;
@ -506,9 +506,9 @@ void __bound_new_region(void *p, size_t size)
/* start */ /* start */
page = get_page(t1_start); page = get_page(t1_start);
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
@ -557,7 +557,7 @@ void __bound_new_region(void *p, size_t size)
} }
/* delete a region */ /* delete a region */
static inline void delete_region(BoundEntry *e, static inline void delete_region(BoundEntry *e,
void *p, size_t empty_size) void *p, size_t empty_size)
{ {
size_t addr; size_t addr;
@ -612,9 +612,9 @@ int __bound_delete_region(void *p)
start = (size_t)p; start = (size_t)p;
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
/* find region size */ /* find region size */
page = __bound_t1[t1_start]; page = __bound_t1[t1_start];
e = (BoundEntry *)((char *)page + t2_start); e = (BoundEntry *)((char *)page + t2_start);
@ -622,7 +622,7 @@ int __bound_delete_region(void *p)
if (addr > e->size) if (addr > e->size)
e = __bound_find_region(e, p); e = __bound_find_region(e, p);
/* test if invalid region */ /* test if invalid region */
if (e->size == EMPTY_SIZE || (size_t)p != e->start) if (e->size == EMPTY_SIZE || (size_t)p != e->start)
return -1; return -1;
/* compute the size we put in invalid regions */ /* compute the size we put in invalid regions */
if (e->is_invalid) if (e->is_invalid)
@ -634,7 +634,7 @@ int __bound_delete_region(void *p)
/* now we can free each entry */ /* now we can free each entry */
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS); t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
delete_region(e, p, empty_size); delete_region(e, p, empty_size);
@ -690,8 +690,8 @@ static size_t get_region_size(void *p)
BoundEntry *e; BoundEntry *e;
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e + e = (BoundEntry *)((char *)e +
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
addr -= e->start; addr -= e->start;
if (addr > e->size) if (addr > e->size)
@ -756,16 +756,16 @@ static void libc_free(void *ptr)
void *__bound_malloc(size_t size, const void *caller) void *__bound_malloc(size_t size, const void *caller)
{ {
void *ptr; void *ptr;
/* we allocate one more byte to ensure the regions will be /* we allocate one more byte to ensure the regions will be
separated by at least one byte. With the glibc malloc, it may separated by at least one byte. With the glibc malloc, it may
be in fact not necessary */ be in fact not necessary */
ptr = libc_malloc(size + 1); ptr = libc_malloc(size + 1);
if (!ptr) if (!ptr)
return NULL; return NULL;
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, ptr, size); __FILE__, __FUNCTION__, ptr, size);
__bound_new_region(ptr, size); __bound_new_region(ptr, size);
@ -792,13 +792,13 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
be in fact not necessary */ be in fact not necessary */
ptr = memalign(size + 1, align); ptr = memalign(size + 1, align);
#endif #endif
install_malloc_hooks(); install_malloc_hooks();
if (!ptr) if (!ptr)
return NULL; return NULL;
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, ptr, size); __FILE__, __FUNCTION__, ptr, size);
__bound_new_region(ptr, size); __bound_new_region(ptr, size);
@ -862,8 +862,8 @@ static void bound_dump(void)
e = page + j; e = page + j;
/* do not print invalid or empty entries */ /* do not print invalid or empty entries */
if (e->size != EMPTY_SIZE && e->start != 0) { if (e->size != EMPTY_SIZE && e->start != 0) {
fprintf(stderr, "%08x:", fprintf(stderr, "%08x:",
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) + (i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
(j << BOUND_T3_BITS)); (j << BOUND_T3_BITS));
do { do {
fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size); fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);

View File

@ -1,5 +1,5 @@
/* TCC runtime library. /* TCC runtime library.
Parts of this code are (c) 2002 Fabrice Bellard Parts of this code are (c) 2002 Fabrice Bellard
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc. Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
@ -25,7 +25,7 @@ General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
*/ */
#include <stdint.h> #include <stdint.h>
@ -370,10 +370,10 @@ long long __divdi3(long long u, long long v)
int c = 0; int c = 0;
DWunion uu, vv; DWunion uu, vv;
DWtype w; DWtype w;
uu.ll = u; uu.ll = u;
vv.ll = v; vv.ll = v;
if (uu.s.high < 0) { if (uu.s.high < 0) {
c = ~c; c = ~c;
uu.ll = __negdi2 (uu.ll); uu.ll = __negdi2 (uu.ll);
@ -393,17 +393,17 @@ long long __moddi3(long long u, long long v)
int c = 0; int c = 0;
DWunion uu, vv; DWunion uu, vv;
DWtype w; DWtype w;
uu.ll = u; uu.ll = u;
vv.ll = v; vv.ll = v;
if (uu.s.high < 0) { if (uu.s.high < 0) {
c = ~c; c = ~c;
uu.ll = __negdi2 (uu.ll); uu.ll = __negdi2 (uu.ll);
} }
if (vv.s.high < 0) if (vv.s.high < 0)
vv.ll = __negdi2 (vv.ll); vv.ll = __negdi2 (vv.ll);
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w); __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
if (c) if (c)
w = __negdi2 (w); w = __negdi2 (w);
@ -418,7 +418,7 @@ unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
unsigned long long __umoddi3(unsigned long long u, unsigned long long v) unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
{ {
UDWtype w; UDWtype w;
__udivmoddi4 (u, v, &w); __udivmoddi4 (u, v, &w);
return w; return w;
} }
@ -499,7 +499,7 @@ long long __tcc_cvt_ftol(long double x)
/* XXX: fix tcc's code generator to do this instead */ /* XXX: fix tcc's code generator to do this instead */
float __floatundisf(unsigned long long a) float __floatundisf(unsigned long long a)
{ {
DWunion uu; DWunion uu;
XFtype r; XFtype r;
uu.ll = a; uu.ll = a;
@ -514,7 +514,7 @@ float __floatundisf(unsigned long long a)
double __floatundidf(unsigned long long a) double __floatundidf(unsigned long long a)
{ {
DWunion uu; DWunion uu;
XFtype r; XFtype r;
uu.ll = a; uu.ll = a;
@ -529,7 +529,7 @@ double __floatundidf(unsigned long long a)
long double __floatundixf(unsigned long long a) long double __floatundixf(unsigned long long a)
{ {
DWunion uu; DWunion uu;
XFtype r; XFtype r;
uu.ll = a; uu.ll = a;
@ -608,7 +608,7 @@ unsigned long long __fixunsxfdi (long double a1)
if (exp > 0) if (exp > 0)
return (unsigned long long)-1; return (unsigned long long)-1;
else if (exp >= -63) else if (exp >= -63)
return l >> -exp; return l >> -exp;
else else
return 0; return 0;

View File

@ -40,24 +40,24 @@ ST_DATA struct TCCState *tcc_state;
#include "tccelf.c" #include "tccelf.c"
#include "tccrun.c" #include "tccrun.c"
#ifdef TCC_TARGET_I386 #ifdef TCC_TARGET_I386
#include "x86/i386-gen.c" #include "i386-gen.c"
#endif #endif
#ifdef TCC_TARGET_ARM #ifdef TCC_TARGET_ARM
#include "arm/arm-gen.c" #include "arm-gen.c"
#endif #endif
#ifdef TCC_TARGET_ARM64 #ifdef TCC_TARGET_ARM64
#include "arm/arm64-gen.c" #include "arm64-gen.c"
#endif #endif
#ifdef TCC_TARGET_C67 #ifdef TCC_TARGET_C67
#include "tms320c67/c67-gen.c" #include "c67-gen.c"
#endif #endif
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
#include "x86/x86_64-gen.c" #include "x86_64-gen.c"
#endif #endif
#ifdef CONFIG_TCC_ASM #ifdef CONFIG_TCC_ASM
#include "tccasm.c" #include "tccasm.c"
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
#include "x86/i386-asm.c" #include "i386-asm.c"
#endif #endif
#endif #endif
#ifdef TCC_TARGET_COFF #ifdef TCC_TARGET_COFF
@ -318,7 +318,7 @@ PUB_FUNC void tcc_free_debug(void *ptr)
mem_cur_size -= header->size; mem_cur_size -= header->size;
header->size = (size_t)-1; header->size = (size_t)-1;
if (header->next) if (header->next)
header->next->prev = header->prev; header->next->prev = header->prev;
@ -672,7 +672,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
} }
#else #else
if (! (sym->type.t & VT_STATIC)) if (! (sym->type.t & VT_STATIC))
other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
#endif #endif
if (tcc_state->leading_underscore && can_add_underscore) { if (tcc_state->leading_underscore && can_add_underscore) {
buf1[0] = '_'; buf1[0] = '_';
@ -2101,11 +2101,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
s->static_link = 1; s->static_link = 1;
break; break;
case TCC_OPTION_std: case TCC_OPTION_std:
/* silently ignore, a current purpose: /* silently ignore, a current purpose:
allow to use a tcc as a reference compiler for "make test" */ allow to use a tcc as a reference compiler for "make test" */
break; break;
case TCC_OPTION_shared: case TCC_OPTION_shared:
if (s->output_type) if (s->output_type)
tcc_warning("-shared: some compiler action already specified (%d)", s->output_type); tcc_warning("-shared: some compiler action already specified (%d)", s->output_type);
s->output_type = TCC_OUTPUT_DLL; s->output_type = TCC_OUTPUT_DLL;
break; break;
@ -2124,7 +2124,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
break; break;
case TCC_OPTION_r: case TCC_OPTION_r:
/* generate a .o merging several output files */ /* generate a .o merging several output files */
if (s->output_type) if (s->output_type)
tcc_warning("-r: some compiler action already specified (%d)", s->output_type); tcc_warning("-r: some compiler action already specified (%d)", s->output_type);
s->option_r = 1; s->option_r = 1;
s->output_type = TCC_OUTPUT_OBJ; s->output_type = TCC_OUTPUT_OBJ;
@ -2163,7 +2163,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
s->print_search_dirs = 1; s->print_search_dirs = 1;
break; break;
case TCC_OPTION_run: case TCC_OPTION_run:
if (s->output_type) if (s->output_type)
tcc_warning("-run: some compiler action already specified (%d)", s->output_type); tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
s->output_type = TCC_OUTPUT_MEMORY; s->output_type = TCC_OUTPUT_MEMORY;
tcc_set_options(s, optarg); tcc_set_options(s, optarg);
@ -2194,7 +2194,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
cstr_ccat(&linker_arg, '\0'); cstr_ccat(&linker_arg, '\0');
break; break;
case TCC_OPTION_E: case TCC_OPTION_E:
if (s->output_type) if (s->output_type)
tcc_warning("-E: some compiler action already specified (%d)", s->output_type); tcc_warning("-E: some compiler action already specified (%d)", s->output_type);
s->output_type = TCC_OUTPUT_PREPROCESS; s->output_type = TCC_OUTPUT_PREPROCESS;
break; break;
@ -2251,13 +2251,13 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
} }
if (s->output_type == 0) if (s->output_type == 0)
s->output_type = TCC_OUTPUT_EXE; s->output_type = TCC_OUTPUT_EXE;
if (pthread && s->output_type != TCC_OUTPUT_OBJ) if (pthread && s->output_type != TCC_OUTPUT_OBJ)
tcc_set_options(s, "-lpthread"); tcc_set_options(s, "-lpthread");
if (s->output_type == TCC_OUTPUT_EXE) if (s->output_type == TCC_OUTPUT_EXE)
tcc_set_linker(s, (const char *)linker_arg.data); tcc_set_linker(s, (const char *)linker_arg.data);
cstr_free(&linker_arg); cstr_free(&linker_arg);
return optind; return optind;

View File

@ -1,421 +0,0 @@
#
# Tiny C Compiler Makefile
#
TOP ?= .
include $(TOP)/../config.mak
VPATH = $(top_srcdir)
CPPFLAGS += -I$(TOP) # for config.h
ifneq (-$(findstring gcc,$(CC))-,-gcc-)
ifeq (-$(findstring clang,$(CC))-,-clang-)
# make clang accept gnuisms in libtcc1.c
CFLAGS+=-fheinous-gnu-extensions
endif
endif
CPPFLAGS_P=$(CPPFLAGS) -DCONFIG_TCC_STATIC
CFLAGS_P=$(CFLAGS) -pg -static
LIBS_P=
LDFLAGS_P=$(LDFLAGS)
ifdef CONFIG_WIN64
CONFIG_WIN32=yes
endif
ifndef CONFIG_WIN32
LIBS=-lm
ifndef CONFIG_NOLDL
LIBS+=-ldl
endif
endif
# make libtcc as static or dynamic library?
ifdef DISABLE_STATIC
ifndef CONFIG_WIN32
LIBTCC=libtcc.so.1.0
else
LIBTCC=libtcc.dll
LIBTCC_DLL=yes
LIBTCC_EXTRA=libtcc.def libtcc.a
endif
LINK_LIBTCC=-Wl,-rpath,"$(libdir)"
ifdef DISABLE_RPATH
LINK_LIBTCC=
endif
else
LIBTCC=libtcc.a
LINK_LIBTCC=
endif
CONFIG_$(ARCH) = yes
NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
NATIVE_DEFINES_$(CONFIG_x86-64) += -DTCC_TARGET_X86_64
NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
ifeq ($(TOP),.)
PROGS=tcc$(EXESUF)
I386_CROSS = i386-linux-gnu-tcc$(EXESUF)
WIN32_CROSS = i386-win-mingw32-tcc$(EXESUF)
WIN64_CROSS = x86_64-win-mingw32-tcc$(EXESUF)
WINCE_CROSS = arm-win-mingw32ce-tcc$(EXESUF)
X64_CROSS = x86_64-linux-gnu-tcc$(EXESUF)
ARM_FPA_CROSS = arm-linux-fpa-tcc$(EXESUF)
ARM_FPA_LD_CROSS = arm-linux-fpa-ld-tcc$(EXESUF)
ARM_VFP_CROSS = arm-linux-gnu-tcc$(EXESUF)
ARM_EABI_CROSS = arm-linux-gnueabi-tcc$(EXESUF)
ARM_EABIHF_CROSS = arm-linux-gnueabihf-tcc$(EXESUF)
ARM_CROSS = $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS)
ARM64_CROSS = arm64-tcc$(EXESUF)
C67_CROSS = c67-tcc$(EXESUF)
# Legacy symlinks for cross compilers
$(I386_CROSS)_LINK = i386-tcc$(EXESUF)
$(WIN32_CROSS)_LINK = i386-win-tcc$(EXESUF)
$(WIN64_CROSS)_LINK = x86_64-win-tcc$(EXESUF)
$(WINCE_CROSS)_LINK = arm-win-tcc$(EXESUF)
$(X64_CROSS)_LINK = x86_64-tcc$(EXESUF)
$(ARM_FPA_CROSS)_LINK = arm-fpa-tcc$(EXESUF)
$(ARM_FPA_LD_CROSS)_LINK = arm-fpa-ld-tcc$(EXESUF)
$(ARM_VFP_CROSS)_LINK = arm-vfp-tcc$(EXESUF)
$(ARM_EABI_CROSS)_LINK = arm-eabi-tcc$(EXESUF)
ifeq ($(TARGETOS),Windows)
ifeq ($(ARCH),i386)
PROGS:=$($(WIN32_CROSS)_LINK)
$($(WIN32_CROSS)_LINK)_TCC = yes
endif
ifeq ($(ARCH),x86-64)
PROGS:=$($(WIN64_CROSS)_LINK)
$($(WIN64_CROSS)_LINK)_TCC = yes
endif
endif
ifeq ($(TARGETOS),Linux)
ifeq ($(ARCH),i386)
PROGS:=$($(I386_CROSS)_LINK)
$($(I386_CROSS)_LINK)_TCC = yes
endif
ifeq ($(ARCH),x86-64)
PROGS:=$($(X64_CROSS)_LINK)
$($(X64_CROSS)_LINK)_TCC = yes
endif
endif
CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
I386_FILES = $(CORE_FILES) x86/i386-gen.c x86/i386-asm.c x86/i386-asm.h x86/i386-tok.h
WIN32_FILES = $(CORE_FILES) x86/i386-gen.c x86/i386-asm.c x86/i386-asm.h x86/i386-tok.h tccpe.c
WIN64_FILES = $(CORE_FILES) x86/x86_64-gen.c x86/i386-asm.c x86/x86_64-asm.h tccpe.c
WINCE_FILES = $(CORE_FILES) arm/arm-gen.c tccpe.c
X86_64_FILES = $(CORE_FILES) x86/x86_64-gen.c x86/i386-asm.c x86/x86_64-asm.h
ARM_FILES = $(CORE_FILES) arm/arm-gen.c
ARM64_FILES = $(CORE_FILES) arm/arm64-gen.c
C67_FILES = $(CORE_FILES) tms320c67/c67-gen.c tcccoff.c
ifdef CONFIG_WIN64
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
NATIVE_FILES=$(WIN64_FILES)
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a
LIBTCC1=libtcc1.a
else ifdef CONFIG_WIN32
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
NATIVE_FILES=$(WIN32_FILES)
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/x86_64-win/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),i386)
NATIVE_FILES=$(I386_FILES)
PROGS_CROSS=$($(X64_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
lib/arm64/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),x86-64)
ifeq ($(TARGETOS),Darwin)
NATIVE_FILES=$(X86_64_FILES)
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a
LIBTCC1=libtcc1.a
else
NATIVE_FILES=$(X86_64_FILES)
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
lib/arm64/libtcc1.a
LIBTCC1=libtcc1.a
endif
else ifeq ($(ARCH),arm)
NATIVE_FILES=$(ARM_FILES)
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1=libtcc1.a
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
else ifeq ($(ARCH),arm64)
NATIVE_FILES=$(ARM64_FILES)
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
LIBTCC1=libtcc1.a
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
endif
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
ifeq ($(TARGETOS),Darwin)
PROGS+=tiny_libmaker$(EXESUF)
endif
TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCC_EXTRA)
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
ifdef CONFIG_CROSS
PROGS+=$(PROGS_CROSS)
TCCLIBS+=$(LIBTCC1_CROSS)
endif
all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
# Host Tiny C Compiler
tcc$(EXESUF): tcc.o $(LIBTCC)
$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
# Cross Tiny C Compilers
%-tcc$(EXESUF): tcc.c
$(CC) -o $@ $< -DONE_SOURCE $(if $($@_TCC),$(NATIVE_DEFINES),$(DEFINES)) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
$(if $($@_LINK),ln -sf $@ $($@_LINK))
$(if $($@_TCC),ln -sf $@ tcc$(EXESUF))
# profiling version
tcc_p$(EXESUF): $(NATIVE_FILES)
$(CC) -o $@ $< -DONE_SOURCE $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
$(I386_CROSS) $($(I386_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386
$(X64_CROSS) $($(X64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/32;{B}/lib\""
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/64;{B}/lib\""
$(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE
$(C67_CROSS): DEFINES = -DTCC_TARGET_C67
$(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM
$(ARM_FPA_LD_CROSS)$(EXESUF): DEFINES = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
$(ARM_VFP_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_VFP
$(ARM_EABI_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP
$(ARM64_CROSS): DEFINES = -DTCC_TARGET_ARM64
$(I386_CROSS) $($(I386_CROSS)_LINK): $(I386_FILES)
$(X64_CROSS) $($(X64_CROSS)_LINK): $(X86_64_FILES)
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): $(WIN32_FILES)
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): $(WIN64_FILES)
$(WINCE_CROSS) $($(WINCE_CROSS)_LINK): $(WINCE_FILES)
$(C67_CROSS) $($(C67_CROSS)_LINK): $(C67_FILES)
$(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS): $(ARM_FILES)
$($(ARM_FPA_CROSS)_LINK) $($(ARM_FPA_LD_CROSS)_LINK) $($(ARM_VFP_CROSS)_LINK) $($(ARM_EABI_CROSS)_LINK): $(ARM_FILES)
$(ARM64_CROSS): $(ARM64_FILES)
# libtcc generation and test
ifndef ONE_SOURCE
LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
else
LIBTCC_OBJ = libtcc.o
LIBTCC_INC = $(NATIVE_FILES)
libtcc.o : NATIVE_DEFINES += -DONE_SOURCE
endif
$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
$(CC) -o $@ -c $< $(NATIVE_DEFINES) $(CPPFLAGS) $(CFLAGS)
ifndef LIBTCC_DLL
libtcc.a: $(LIBTCC_OBJ)
$(AR) rcs $@ $^
endif
libtcc.so.1.0: $(LIBTCC_OBJ)
$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
libtcc.so.1.0: CFLAGS+=-fPIC
ifdef LIBTCC_DLL
libtcc.dll libtcc.def libtcc.a: $(LIBTCC_OBJ)
$(CC) -shared $^ -o $@ $(LDFLAGS) -Wl,--output-def,libtcc.def,--out-implib,libtcc.a
endif
# windows utilities
tiny_impdef$(EXESUF): ../win32/tools/tiny_impdef.c
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
tiny_libmaker$(EXESUF): ../win32/tools/tiny_libmaker.c
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
# TinyCC runtime libraries
libtcc1.a : FORCE
$(MAKE) -C ../lib native
if test ! -d $(ARCH); then mkdir $(ARCH); fi
if test ! -L $(ARCH)/$@; then ln -sf ../$@ $(ARCH)/$@; fi
lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
$(MAKE) -C ../lib cross TARGET=$*
FORCE:
# install
TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h
INSTALL=install
ifdef STRIP_BINARIES
INSTALLBIN=$(INSTALL) -s
else
INSTALLBIN=$(INSTALL)
endif
install-strip: install
strip $(foreach PROG,$(PROGS),"$(bindir)"/$(PROG))
ifndef CONFIG_WIN32
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
mkdir -p "$(bindir)"
$(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
cp -P tcc$(EXESUF) "$(bindir)"
mkdir -p "$(mandir)/man1"
-$(INSTALL) -m644 tcc.1 "$(mandir)/man1"
mkdir -p "$(infodir)"
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
mkdir -p "$(tccdir)"
mkdir -p "$(tccdir)/include"
ifneq ($(LIBTCC1),)
mkdir -p "$(tccdir)/$(ARCH)"
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)/$(ARCH)"
endif
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
mkdir -p "$(libdir)"
$(INSTALL) -m644 $(LIBTCC) "$(libdir)"
ifdef DISABLE_STATIC
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so.1"
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so"
endif
mkdir -p "$(includedir)"
$(INSTALL) -m644 $(top_srcdir)/libtcc.h "$(includedir)"
mkdir -p "$(docdir)"
-$(INSTALL) -m644 tcc-doc.html "$(docdir)"
ifdef CONFIG_CROSS
mkdir -p "$(tccdir)/win32/lib/32"
mkdir -p "$(tccdir)/win32/lib/64"
mkdir -p "$(tccdir)/i386"
mkdir -p "$(tccdir)/x86-64"
ifneq ($(HOST_OS),Darwin)
mkdir -p "$(tccdir)/arm64"
$(INSTALL) -m644 lib/arm64/libtcc1.a "$(tccdir)/arm64"
endif
$(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
$(INSTALL) -m644 lib/x86_64/libtcc1.a "$(tccdir)/x86-64"
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/win32/lib/32"
$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/win32/lib/64"
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
cp -r "$(tccdir)/include" "$(tccdir)/win32"
endif
uninstall:
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
rm -fv "$(bindir)/tcc$(EXESUF)"
rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
rm -fv "$(libdir)/libtcc.so*"
rm -rv "$(tccdir)"
rm -rv "$(docdir)"
else
# on windows
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
mkdir -p "$(tccdir)"
mkdir -p "$(tccdir)/lib"
mkdir -p "$(tccdir)/include"
mkdir -p "$(tccdir)/examples"
mkdir -p "$(tccdir)/doc"
mkdir -p "$(tccdir)/libtcc"
$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
$(INSTALLBIN) -m755 tcc.exe "$(tccdir)"
$(INSTALL) -m644 $(LIBTCC1) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib"
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include"
cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples"
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
$(INSTALL) -m644 tcc-doc.html $(top_srcdir)/win32/tcc-win32.txt "$(tccdir)/doc"
$(INSTALL) -m644 $(top_srcdir)/libtcc.h $(LIBTCC_EXTRA) "$(tccdir)/libtcc"
$(INSTALL) -m644 $(LIBTCC) "$(tccdir)"
ifdef CONFIG_CROSS
mkdir -p "$(tccdir)/lib/32"
mkdir -p "$(tccdir)/lib/64"
-$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/lib/32"
-$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/lib/64"
endif
uninstall:
rm -rfv "$(tccdir)/*"
endif
# documentation and man page
tcc-doc.html: ../docs/tcc-doc.texi
-makeinfo --no-split --html --number-sections -o $@ $<
tcc.1: ../docs/tcc-doc.texi
-$(top_srcdir)/../docs/texi2pod.pl $< tcc.pod
-pod2man --section=1 --center="Tiny C Compiler" --release=`cat $(top_srcdir)/../VERSION` tcc.pod > $@
tcc-doc.info: ../docs/tcc-doc.texi
-makeinfo $<
# in tests subdir
export LIBTCC1
%est:
$(MAKE) -C ../tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
clean:
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.log \
*.exe a.out tags TAGS libtcc_test$(EXESUF) tcc$(EXESUF)
-rm -r $(ARCH) arm64
ifeq ($(HOST_OS),Linux)
-rm -r ./C:
endif
-rm *-tcc$(EXESUF)
$(MAKE) -C ../tests $@
ifneq ($(LIBTCC1),)
$(MAKE) -C ../lib $@
endif
distclean: clean
rm -vf config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
config.mak:
@echo "Please run ./configure."
@exit 1
tags:
ctags $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
TAGS:
ctags -e $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
# create release tarball from *current* git branch (including tcc-doc.html
# and converting two files to CRLF)
TCC-VERSION := tcc-$(shell cat $(top_srcdir)/../VERSION)
tar: tcc-doc.html
mkdir $(TCC-VERSION)
( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
cp tcc-doc.html $(TCC-VERSION)
for f in tcc-win32.txt build-tcc.bat ; do \
cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
done
tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
rm -rf $(TCC-VERSION)
git reset
.PHONY: all clean tar tags TAGS distclean install uninstall FORCE
endif # ifeq ($(TOP),.)

File diff suppressed because it is too large Load Diff

View File

@ -1,924 +0,0 @@
/*
* COFF file handling for TCC
*
* Copyright (c) 2003, 2004 TK
* Copyright (c) 2004 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tcc.h"
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
#define MAX_STR_TABLE 1000000
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
SCNHDR section_header[MAXNSCNS];
#define MAX_FUNCS 1000
#define MAX_FUNC_NAME_LENGTH 128
int nFuncs;
char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
int LineNoFilePtr[MAX_FUNCS];
int EndAddress[MAX_FUNCS];
int LastLineNo[MAX_FUNCS];
int FuncEntries[MAX_FUNCS];
int OutputTheSection(Section* sect);
short int GetCoffFlags(const char* s);
void SortSymbolTable(void);
Section* FindSection(TCCState* s1, const char* sname);
int C67_main_entry_point;
int FindCoffSymbolIndex(const char* func_name);
int nb_syms;
typedef struct {
long tag;
long size;
long fileptr;
long nextsym;
short int dummy;
} AUXFUNC;
typedef struct {
long regmask;
unsigned short lineno;
unsigned short nentries;
int localframe;
int nextentry;
short int dummy;
} AUXBF;
typedef struct {
long dummy;
unsigned short lineno;
unsigned short dummy1;
int dummy2;
int dummy3;
unsigned short dummy4;
} AUXEF;
ST_FUNC int tcc_output_coff(TCCState* s1, FILE* f)
{
Section* tcc_sect;
SCNHDR* coff_sec;
int file_pointer;
char* Coff_str_table, *pCoff_str_table;
int CoffTextSectionNo, coff_nb_syms;
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
Section* stext, *sdata, *sbss;
int i, NSectionsToOutput = 0;
Coff_str_table = pCoff_str_table = NULL;
stext = FindSection(s1, ".text");
sdata = FindSection(s1, ".data");
sbss = FindSection(s1, ".bss");
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
file_hdr.f_timdat = 0; /* time & date stamp */
file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
o_filehdr.magic = 0x0108; /* see magic.h */
o_filehdr.vstamp = 0x0190; /* version stamp */
o_filehdr.tsize =
stext->data_offset; /* text size in bytes, padded to FW bdry */
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
// create all the section headers
file_pointer = FILHSZ + sizeof(AOUTHDR);
CoffTextSectionNo = -1;
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
NSectionsToOutput++;
if (CoffTextSectionNo == -1 && tcc_sect == stext)
CoffTextSectionNo = NSectionsToOutput; // rem which coff sect
// number the .text sect
// is
strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
coff_sec->s_size = tcc_sect->data_offset; /* section size */
coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
coff_sec->s_relptr = 0; /* file ptr to relocation */
coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
coff_sec->s_nreloc = 0; /* number of relocation entries */
coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
coff_sec->s_reserved = 0; /* reserved byte */
coff_sec->s_page = 0; /* memory page id */
file_pointer += sizeof(SCNHDR);
}
}
file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
// now loop through and determine file pointer locations
// for the raw data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
// put raw data
coff_sec->s_scnptr =
file_pointer; /* file ptr to raw data for section */
file_pointer += coff_sec->s_size;
}
}
// now loop through and determine file pointer locations
// for the relocation data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
// put relocations data
if (coff_sec->s_nreloc > 0) {
coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
}
}
}
// now loop through and determine file pointer locations
// for the line number data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
coff_sec->s_nlnno = 0;
coff_sec->s_lnnoptr = 0;
if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data
// also find association between source file name and function
// so we can sort the symbol table
Stab_Sym* sym, *sym_end;
char func_name[MAX_FUNC_NAME_LENGTH],
last_func_name[MAX_FUNC_NAME_LENGTH];
unsigned long func_addr, last_pc, pc;
const char* incl_files[INCLUDE_STACK_SIZE];
int incl_index, len, last_line_num;
const char* str, *p;
coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
func_name[0] = '\0';
func_addr = 0;
incl_index = 0;
last_func_name[0] = '\0';
last_pc = 0xffffffff;
last_line_num = 1;
sym = (Stab_Sym*)stab_section->data + 1;
sym_end =
(Stab_Sym*)(stab_section->data + stab_section->data_offset);
nFuncs = 0;
while (sym < sym_end) {
switch (sym->n_type) {
/* function start or end */
case N_FUN:
if (sym->n_strx == 0) {
// end of function
coff_sec->s_nlnno++;
file_pointer += LINESZ;
pc = sym->n_value + func_addr;
func_name[0] = '\0';
func_addr = 0;
EndAddress[nFuncs] = pc;
FuncEntries[nFuncs] =
(file_pointer - LineNoFilePtr[nFuncs]) / LINESZ - 1;
LastLineNo[nFuncs++] = last_line_num + 1;
} else {
// beginning of function
LineNoFilePtr[nFuncs] = file_pointer;
coff_sec->s_nlnno++;
file_pointer += LINESZ;
str = (const char*)stabstr_section->data + sym->n_strx;
p = strchr(str, ':');
if (!p) {
pstrcpy(func_name, sizeof(func_name), str);
pstrcpy(Func[nFuncs], sizeof(func_name), str);
} else {
len = p - str;
if (len > sizeof(func_name) - 1)
len = sizeof(func_name) - 1;
memcpy(func_name, str, len);
memcpy(Func[nFuncs], str, len);
func_name[len] = '\0';
}
// save the file that it came in so we can sort later
pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
incl_files[incl_index - 1]);
func_addr = sym->n_value;
}
break;
/* line number info */
case N_SLINE:
pc = sym->n_value + func_addr;
last_pc = pc;
last_line_num = sym->n_desc;
/* XXX: slow! */
strcpy(last_func_name, func_name);
coff_sec->s_nlnno++;
file_pointer += LINESZ;
break;
/* include files */
case N_BINCL:
str = (const char*)stabstr_section->data + sym->n_strx;
add_incl:
if (incl_index < INCLUDE_STACK_SIZE) {
incl_files[incl_index++] = str;
}
break;
case N_EINCL:
if (incl_index > 1)
incl_index--;
break;
case N_SO:
if (sym->n_strx == 0) {
incl_index = 0; /* end of translation unit */
} else {
str = (const char*)stabstr_section->data + sym->n_strx;
/* do not add path */
len = strlen(str);
if (len > 0 && str[len - 1] != '/')
goto add_incl;
}
break;
}
sym++;
}
}
}
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
if (s1->do_debug)
file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
else
file_hdr.f_nsyms = 0;
file_pointer += file_hdr.f_nsyms * SYMNMLEN;
// OK now we are all set to write the file
fwrite(&file_hdr, FILHSZ, 1, f);
fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
// write section headers
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
fwrite(coff_sec, sizeof(SCNHDR), 1, f);
}
}
// write raw data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
}
}
// write relocation data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
// put relocations data
if (coff_sec->s_nreloc > 0) {
fwrite(tcc_sect->reloc,
coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
}
}
}
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
if (s1->do_debug)
SortSymbolTable();
// write line no data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data
Stab_Sym* sym, *sym_end;
char func_name[128], last_func_name[128];
unsigned long func_addr, last_pc, pc;
const char* incl_files[INCLUDE_STACK_SIZE];
int incl_index, len, last_line_num;
const char* str, *p;
LINENO CoffLineNo;
func_name[0] = '\0';
func_addr = 0;
incl_index = 0;
last_func_name[0] = '\0';
last_pc = 0;
last_line_num = 1;
sym = (Stab_Sym*)stab_section->data + 1;
sym_end =
(Stab_Sym*)(stab_section->data + stab_section->data_offset);
while (sym < sym_end) {
switch (sym->n_type) {
/* function start or end */
case N_FUN:
if (sym->n_strx == 0) {
// end of function
CoffLineNo.l_addr.l_paddr = last_pc;
CoffLineNo.l_lnno = last_line_num + 1;
fwrite(&CoffLineNo, 6, 1, f);
pc = sym->n_value + func_addr;
func_name[0] = '\0';
func_addr = 0;
} else {
// beginning of function
str = (const char*)stabstr_section->data + sym->n_strx;
p = strchr(str, ':');
if (!p) {
pstrcpy(func_name, sizeof(func_name), str);
} else {
len = p - str;
if (len > sizeof(func_name) - 1)
len = sizeof(func_name) - 1;
memcpy(func_name, str, len);
func_name[len] = '\0';
}
func_addr = sym->n_value;
last_pc = func_addr;
last_line_num = -1;
// output a function begin
CoffLineNo.l_addr.l_symndx =
FindCoffSymbolIndex(func_name);
CoffLineNo.l_lnno = 0;
fwrite(&CoffLineNo, 6, 1, f);
}
break;
/* line number info */
case N_SLINE:
pc = sym->n_value + func_addr;
/* XXX: slow! */
strcpy(last_func_name, func_name);
// output a line reference
CoffLineNo.l_addr.l_paddr = last_pc;
if (last_line_num == -1) {
CoffLineNo.l_lnno = sym->n_desc;
} else {
CoffLineNo.l_lnno = last_line_num + 1;
}
fwrite(&CoffLineNo, 6, 1, f);
last_pc = pc;
last_line_num = sym->n_desc;
break;
/* include files */
case N_BINCL:
str = (const char*)stabstr_section->data + sym->n_strx;
add_incl2:
if (incl_index < INCLUDE_STACK_SIZE) {
incl_files[incl_index++] = str;
}
break;
case N_EINCL:
if (incl_index > 1)
incl_index--;
break;
case N_SO:
if (sym->n_strx == 0) {
incl_index = 0; /* end of translation unit */
} else {
str = (const char*)stabstr_section->data + sym->n_strx;
/* do not add path */
len = strlen(str);
if (len > 0 && str[len - 1] != '/')
goto add_incl2;
}
break;
}
sym++;
}
}
}
// write symbol table
if (s1->do_debug) {
int k;
struct syment csym;
AUXFUNC auxfunc;
AUXBF auxbf;
AUXEF auxef;
int i;
Elf32_Sym* p;
const char* name;
int nstr;
int n = 0;
Coff_str_table = (char*)tcc_malloc(MAX_STR_TABLE);
pCoff_str_table = Coff_str_table;
nstr = 0;
p = (Elf32_Sym*)symtab_section->data;
for (i = 0; i < nb_syms; i++) {
name = symtab_section->link->data + p->st_name;
for (k = 0; k < 8; k++)
csym._n._n_name[k] = 0;
if (strlen(name) <= 8) {
strcpy(csym._n._n_name, name);
} else {
if (pCoff_str_table - Coff_str_table + strlen(name) >
MAX_STR_TABLE - 1)
tcc_error("String table too large");
csym._n._n_n._n_zeroes = 0;
csym._n._n_n._n_offset = pCoff_str_table - Coff_str_table + 4;
strcpy(pCoff_str_table, name);
pCoff_str_table += strlen(name) + 1; // skip over null
nstr++;
}
if (p->st_info == 4) {
// put a filename symbol
csym.n_value = 33; // ?????
csym.n_scnum = N_DEBUG;
csym.n_type = 0;
csym.n_sclass = C_FILE;
csym.n_numaux = 0;
fwrite(&csym, 18, 1, f);
n++;
} else if (p->st_info == 0x12) {
// find the function data
for (k = 0; k < nFuncs; k++) {
if (strcmp(name, Func[k]) == 0)
break;
}
if (k >= nFuncs) {
tcc_error("debug info can't find function: %s", name);
}
// put a Function Name
csym.n_value = p->st_value; // physical address
csym.n_scnum = CoffTextSectionNo;
csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
csym.n_sclass = C_EXT;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
// now put aux info
auxfunc.tag = 0;
auxfunc.size = EndAddress[k] - p->st_value;
auxfunc.fileptr = LineNoFilePtr[k];
auxfunc.nextsym = n + 6; // tktk
auxfunc.dummy = 0;
fwrite(&auxfunc, 18, 1, f);
// put a .bf
strcpy(csym._n._n_name, ".bf");
csym.n_value = p->st_value; // physical address
csym.n_scnum = CoffTextSectionNo;
csym.n_type = 0;
csym.n_sclass = C_FCN;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
// now put aux info
auxbf.regmask = 0;
auxbf.lineno = 0;
auxbf.nentries = FuncEntries[k];
auxbf.localframe = 0;
auxbf.nextentry = n + 6;
auxbf.dummy = 0;
fwrite(&auxbf, 18, 1, f);
// put a .ef
strcpy(csym._n._n_name, ".ef");
csym.n_value = EndAddress[k]; // physical address
csym.n_scnum = CoffTextSectionNo;
csym.n_type = 0;
csym.n_sclass = C_FCN;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
// now put aux info
auxef.dummy = 0;
auxef.lineno = LastLineNo[k];
auxef.dummy1 = 0;
auxef.dummy2 = 0;
auxef.dummy3 = 0;
auxef.dummy4 = 0;
fwrite(&auxef, 18, 1, f);
n += 6;
} else {
// try an put some type info
if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
csym.n_type = T_DOUBLE; // int
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
csym.n_type = T_FLOAT;
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_INT) {
csym.n_type = T_INT; // int
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
csym.n_type = T_SHORT;
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
csym.n_type = T_CHAR;
csym.n_sclass = C_EXT;
} else {
csym.n_type = T_INT; // just mark as a label
csym.n_sclass = C_LABEL;
}
csym.n_value = p->st_value;
csym.n_scnum = 2;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
auxfunc.tag = 0;
auxfunc.size = 0x20;
auxfunc.fileptr = 0;
auxfunc.nextsym = 0;
auxfunc.dummy = 0;
fwrite(&auxfunc, 18, 1, f);
n++;
n++;
}
p++;
}
}
if (s1->do_debug) {
// write string table
// first write the size
i = pCoff_str_table - Coff_str_table;
fwrite(&i, 4, 1, f);
// then write the strings
fwrite(Coff_str_table, i, 1, f);
tcc_free(Coff_str_table);
}
return 0;
}
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
void SortSymbolTable(void)
{
int i, j, k, n = 0;
Elf32_Sym* p, *p2, *NewTable;
char* name, *name2;
NewTable = (Elf32_Sym*)tcc_malloc(nb_syms * sizeof(Elf32_Sym));
p = (Elf32_Sym*)symtab_section->data;
// find a file symbol, copy it over
// then scan the whole symbol list and copy any function
// symbols that match the file association
for (i = 0; i < nb_syms; i++) {
if (p->st_info == 4) {
name = (char*)symtab_section->link->data + p->st_name;
// this is a file symbol, copy it over
NewTable[n++] = *p;
p2 = (Elf32_Sym*)symtab_section->data;
for (j = 0; j < nb_syms; j++) {
if (p2->st_info == 0x12) {
// this is a func symbol
name2 = (char*)symtab_section->link->data + p2->st_name;
// find the function data index
for (k = 0; k < nFuncs; k++) {
if (strcmp(name2, Func[k]) == 0)
break;
}
if (k >= nFuncs) {
tcc_error("debug (sort) info can't find function: %s",
name2);
}
if (strcmp(AssociatedFile[k], name) == 0) {
// yes they match copy it over
NewTable[n++] = *p2;
}
}
p2++;
}
}
p++;
}
// now all the filename and func symbols should have been copied over
// copy all the rest over (all except file and funcs)
p = (Elf32_Sym*)symtab_section->data;
for (i = 0; i < nb_syms; i++) {
if (p->st_info != 4 && p->st_info != 0x12) {
NewTable[n++] = *p;
}
p++;
}
if (n != nb_syms)
tcc_error("Internal Compiler error, debug info");
// copy it all back
p = (Elf32_Sym*)symtab_section->data;
for (i = 0; i < nb_syms; i++) {
*p++ = NewTable[i];
}
tcc_free(NewTable);
}
int FindCoffSymbolIndex(const char* func_name)
{
int i, n = 0;
Elf32_Sym* p;
char* name;
p = (Elf32_Sym*)symtab_section->data;
for (i = 0; i < nb_syms; i++) {
name = (char*)symtab_section->link->data + p->st_name;
if (p->st_info == 4) {
// put a filename symbol
n++;
} else if (p->st_info == 0x12) {
if (strcmp(func_name, name) == 0)
return n;
n += 6;
// put a Function Name
// now put aux info
// put a .bf
// now put aux info
// put a .ef
// now put aux info
} else {
n += 2;
}
p++;
}
return n; // total number of symbols
}
int OutputTheSection(Section* sect)
{
const char* s = sect->name;
if (!strcmp(s, ".text"))
return 1;
else if (!strcmp(s, ".data"))
return 1;
else
return 0;
}
short int GetCoffFlags(const char* s)
{
if (!strcmp(s, ".text"))
return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
else if (!strcmp(s, ".data"))
return STYP_DATA;
else if (!strcmp(s, ".bss"))
return STYP_BSS;
else if (!strcmp(s, ".stack"))
return STYP_BSS | STYP_ALIGN | 0x200;
else if (!strcmp(s, ".cinit"))
return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
else
return 0;
}
Section* FindSection(TCCState* s1, const char* sname)
{
Section* s;
int i;
for (i = 1; i < s1->nb_sections; i++) {
s = s1->sections[i];
if (!strcmp(sname, s->name))
return s;
}
tcc_error("could not find section %s", sname);
return 0;
}
ST_FUNC int tcc_load_coff(TCCState* s1, int fd)
{
// tktk TokenSym *ts;
FILE* f;
unsigned int str_size;
char* Coff_str_table, *name;
int i, k;
struct syment csym;
char name2[9];
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
f = fdopen(fd, "rb");
if (!f) {
tcc_error("Unable to open .out file for input");
}
if (fread(&file_hdr, FILHSZ, 1, f) != 1)
tcc_error("error reading .out file for input");
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
tcc_error("error reading .out file for input");
// first read the string table
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
tcc_error("error reading .out file for input");
if (fread(&str_size, sizeof(int), 1, f) != 1)
tcc_error("error reading .out file for input");
Coff_str_table = (char*)tcc_malloc(str_size);
if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
tcc_error("error reading .out file for input");
// read/process all the symbols
// seek back to symbols
if (fseek(f, file_hdr.f_symptr, SEEK_SET))
tcc_error("error reading .out file for input");
for (i = 0; i < file_hdr.f_nsyms; i++) {
if (fread(&csym, SYMESZ, 1, f) != 1)
tcc_error("error reading .out file for input");
if (csym._n._n_n._n_zeroes == 0) {
name = Coff_str_table + csym._n._n_n._n_offset - 4;
} else {
name = csym._n._n_name;
if (name[7] != 0) {
for (k = 0; k < 8; k++)
name2[k] = name[k];
name2[8] = 0;
name = name2;
}
}
// if (strcmp("_DAC_Buffer",name)==0) // tktk
// name[0]=0;
if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) ||
((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) ||
(csym.n_type == 0x4 && csym.n_sclass == 0x2) ||
(csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
(csym.n_type == 0x18 &&
csym.n_sclass == 0x2) || // pointer to structure
(csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
(csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
{
// strip off any leading underscore (except for other main routine)
if (name[0] == '_' && strcmp(name, "_main") != 0)
name++;
tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
}
// skip any aux records
if (csym.n_numaux == 1) {
if (fread(&csym, SYMESZ, 1, f) != 1)
tcc_error("error reading .out file for input");
i++;
}
}
return 0;
}

View File

View File

@ -99,9 +99,9 @@ the @code{main()} of a.c.
@item @samp{tcc a.c -run b.c arg1} @item @samp{tcc a.c -run b.c arg1}
Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
as first argument to the @code{main()} of the resulting program. as first argument to the @code{main()} of the resulting program.
@ignore @ignore
Because multiple C files are specified, @option{--} are necessary to clearly Because multiple C files are specified, @option{--} are necessary to clearly
separate the program arguments from the TCC options. separate the program arguments from the TCC options.
@end ignore @end ignore
@ -136,14 +136,14 @@ need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source:
#!/usr/local/bin/tcc -run #!/usr/local/bin/tcc -run
#include <stdio.h> #include <stdio.h>
int main() int main()
@{ @{
printf("Hello World\n"); printf("Hello World\n");
return 0; return 0;
@} @}
@end example @end example
TCC can read C source code from @emph{standard input} when @option{-} is used in TCC can read C source code from @emph{standard input} when @option{-} is used in
place of @option{infile}. Example: place of @option{infile}. Example:
@example @example
@ -271,7 +271,7 @@ Make string constants be of type @code{const char *} instead of @code{char
@item -Werror @item -Werror
Abort compilation if warnings are issued. Abort compilation if warnings are issued.
@item -Wall @item -Wall
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
@option{-Wwrite-strings}. @option{-Wwrite-strings}.
@ -451,7 +451,7 @@ function name.
int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@}; int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
@end example @end example
@item Compound initializers are supported: @item Compound initializers are supported:
@example @example
int *p = (int [])@{ 1, 2, 3 @}; int *p = (int [])@{ 1, 2, 3 @};
@ -465,7 +465,7 @@ works for structures and strings.
@end example @end example
@noindent @noindent
is the same as writing is the same as writing
@example @example
double d = 4771840.0; double d = 4771840.0;
@end example @end example
@ -481,12 +481,12 @@ TCC implements some GNU C extensions:
@itemize @itemize
@item array designators can be used without '=': @item array designators can be used without '=':
@example @example
int a[10] = @{ [0] 1, [5] 2, 3, 4 @}; int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
@end example @end example
@item Structure field designators can be a label: @item Structure field designators can be a label:
@example @example
struct @{ int x, y; @} st = @{ x: 1, y: 1@}; struct @{ int x, y; @} st = @{ x: 1, y: 1@};
@end example @end example
@ -555,7 +555,7 @@ Here are some examples:
align variable @code{a} to 8 bytes and put it in section @code{.mysection}. align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
@example @example
int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
@{ @{
return a + b; return a + b;
@} @}
@ -572,17 +572,17 @@ generate function @code{my_add} in section @code{.mycodesection}.
dprintf("one arg %d\n", 1); dprintf("one arg %d\n", 1);
@end example @end example
@item @code{__FUNCTION__} is interpreted as C99 @code{__func__} @item @code{__FUNCTION__} is interpreted as C99 @code{__func__}
(so it has not exactly the same semantics as string literal GNUC (so it has not exactly the same semantics as string literal GNUC
where it is a string literal). where it is a string literal).
@item The @code{__alignof__} keyword can be used as @code{sizeof} @item The @code{__alignof__} keyword can be used as @code{sizeof}
to get the alignment of a type or an expression. to get the alignment of a type or an expression.
@item The @code{typeof(x)} returns the type of @code{x}. @item The @code{typeof(x)} returns the type of @code{x}.
@code{x} is an expression or a type. @code{x} is an expression or a type.
@item Computed gotos: @code{&&label} returns a pointer of type @item Computed gotos: @code{&&label} returns a pointer of type
@code{void *} on the goto label @code{label}. @code{goto *expr} can be @code{void *} on the goto label @code{label}. @code{goto *expr} can be
used to jump on the pointer resulting from @code{expr}. used to jump on the pointer resulting from @code{expr}.
@ -616,7 +616,7 @@ TCC includes its own x86 inline assembler with a @code{gas}-like (GNU
assembler) syntax. No intermediate files are generated. GCC 3.x named assembler) syntax. No intermediate files are generated. GCC 3.x named
operands are supported. operands are supported.
@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()} @item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()}
are supported. are supported.
@item @code{#pragma pack} is supported for win32 compatibility. @item @code{#pragma pack} is supported for win32 compatibility.
@ -681,7 +681,7 @@ same as C.
@item +, - @item +, -
@end enumerate @end enumerate
@item A value is either an absolute number or a label plus an offset. @item A value is either an absolute number or a label plus an offset.
All operators accept absolute values except '+' and '-'. '+' or '-' can be All operators accept absolute values except '+' and '-'. '+' or '-' can be
used to add an offset to a label. '-' supports two labels only if they used to add an offset to a label. '-' supports two labels only if they
are the same or if they are both defined and in the same section. are the same or if they are both defined and in the same section.
@ -694,7 +694,7 @@ are the same or if they are both defined and in the same section.
@item All labels are considered as local, except undefined ones. @item All labels are considered as local, except undefined ones.
@item Numeric labels can be used as local @code{gas}-like labels. @item Numeric labels can be used as local @code{gas}-like labels.
They can be defined several times in the same source. Use 'b' They can be defined several times in the same source. Use 'b'
(backward) or 'f' (forward) as suffix to reference them: (backward) or 'f' (forward) as suffix to reference them:
@ -901,7 +901,7 @@ Here are some examples of caught errors:
@chapter The @code{libtcc} library @chapter The @code{libtcc} library
The @code{libtcc} library enables you to use TCC as a backend for The @code{libtcc} library enables you to use TCC as a backend for
dynamic code generation. dynamic code generation.
Read the @file{libtcc.h} to have an overview of the API. Read Read the @file{libtcc.h} to have an overview of the API. Read
@file{libtcc_test.c} to have a very simple example. @file{libtcc_test.c} to have a very simple example.
@ -941,10 +941,10 @@ except:
@itemize @itemize
@item For initialized arrays with unknown size, a first pass @item For initialized arrays with unknown size, a first pass
is done to count the number of elements. is done to count the number of elements.
@item For architectures where arguments are evaluated in @item For architectures where arguments are evaluated in
reverse order, a first pass is done to reverse the argument order. reverse order, a first pass is done to reverse the argument order.
@end itemize @end itemize
@ -1156,7 +1156,7 @@ stack.
@item VT_CMP @item VT_CMP
indicates that the value is actually stored in the CPU flags (i.e. the indicates that the value is actually stored in the CPU flags (i.e. the
value is the consequence of a test). The value is either 0 or 1. The value is the consequence of a test). The value is either 0 or 1. The
actual CPU flags used is indicated in @code{SValue.c.i}. actual CPU flags used is indicated in @code{SValue.c.i}.
If any code is generated which destroys the CPU flags, this value MUST be If any code is generated which destroys the CPU flags, this value MUST be
put in a normal register. put in a normal register.
@ -1176,7 +1176,7 @@ taken.
@item VT_LVAL @item VT_LVAL
is a flag indicating that the value is actually an lvalue (left value of is a flag indicating that the value is actually an lvalue (left value of
an assignment). It means that the value stored is actually a pointer to an assignment). It means that the value stored is actually a pointer to
the wanted value. the wanted value.
Understanding the use @code{VT_LVAL} is very important if you want to Understanding the use @code{VT_LVAL} is very important if you want to
understand how TCC works. understand how TCC works.

View File

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or

View File

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -293,20 +293,20 @@
#define TARGET_DEFS_ONLY #define TARGET_DEFS_ONLY
#ifdef TCC_TARGET_I386 #ifdef TCC_TARGET_I386
# include "x86/i386-gen.c" # include "i386-gen.c"
#endif #endif
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
# include "x86/x86_64-gen.c" # include "x86_64-gen.c"
#endif #endif
#ifdef TCC_TARGET_ARM #ifdef TCC_TARGET_ARM
# include "arm/arm-gen.c" # include "arm-gen.c"
#endif #endif
#ifdef TCC_TARGET_ARM64 #ifdef TCC_TARGET_ARM64
# include "arm/arm64-gen.c" # include "arm64-gen.c"
#endif #endif
#ifdef TCC_TARGET_C67 #ifdef TCC_TARGET_C67
# include "coff.h" # include "coff.h"
# include "tms320c67c67-gen.c" # include "c67-gen.c"
#endif #endif
#undef TARGET_DEFS_ONLY #undef TARGET_DEFS_ONLY
@ -605,7 +605,7 @@ struct TCCState {
int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used. int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used.
Liuux 2.4.26 can't find initrd when compiled with a new algorithm */ Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
int dollars_in_identifiers; /* allows '$' char in indentifiers */ int dollars_in_identifiers; /* allows '$' char in indentifiers */
/* warning switches */ /* warning switches */
int warn_write_strings; int warn_write_strings;
int warn_unsupported; int warn_unsupported;
@ -631,7 +631,7 @@ struct TCCState {
char *init_symbol; /* symbols to call at load-time (not used currently) */ char *init_symbol; /* symbols to call at load-time (not used currently) */
char *fini_symbol; /* symbols to call at unload-time (not used currently) */ char *fini_symbol; /* symbols to call at unload-time (not used currently) */
#ifdef TCC_TARGET_I386 #ifdef TCC_TARGET_I386
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */ int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
#endif #endif
@ -885,7 +885,7 @@ struct TCCState {
#define TOK_SHL 0x01 /* shift left */ #define TOK_SHL 0x01 /* shift left */
#define TOK_SAR 0x02 /* signed shift right */ #define TOK_SAR 0x02 /* signed shift right */
/* assignement operators : normal operator or 0x80 */ /* assignement operators : normal operator or 0x80 */
#define TOK_A_MOD 0xa5 #define TOK_A_MOD 0xa5
#define TOK_A_AND 0xa6 #define TOK_A_AND 0xa6

View File

@ -1,6 +1,6 @@
/* /*
* GAS like assembler for TCC * GAS like assembler for TCC
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -92,10 +92,10 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
break; break;
case TOK_CCHAR: case TOK_CCHAR:
case TOK_LCHAR: case TOK_LCHAR:
pe->v = tokc.i; pe->v = tokc.i;
pe->sym = NULL; pe->sym = NULL;
next(); next();
break; break;
case '(': case '(':
next(); next();
asm_expr(s1, pe); asm_expr(s1, pe);
@ -125,7 +125,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
break; break;
} }
} }
static void asm_expr_prod(TCCState *s1, ExprValue *pe) static void asm_expr_prod(TCCState *s1, ExprValue *pe)
{ {
int op; int op;
@ -134,7 +134,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
asm_expr_unary(s1, pe); asm_expr_unary(s1, pe);
for(;;) { for(;;) {
op = tok; op = tok;
if (op != '*' && op != '/' && op != '%' && if (op != '*' && op != '/' && op != '%' &&
op != TOK_SHL && op != TOK_SAR) op != TOK_SHL && op != TOK_SAR)
break; break;
next(); next();
@ -145,14 +145,14 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
case '*': case '*':
pe->v *= e2.v; pe->v *= e2.v;
break; break;
case '/': case '/':
if (e2.v == 0) { if (e2.v == 0) {
div_error: div_error:
tcc_error("division by zero"); tcc_error("division by zero");
} }
pe->v /= e2.v; pe->v /= e2.v;
break; break;
case '%': case '%':
if (e2.v == 0) if (e2.v == 0)
goto div_error; goto div_error;
pe->v %= e2.v; pe->v %= e2.v;
@ -186,7 +186,7 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe)
case '&': case '&':
pe->v &= e2.v; pe->v &= e2.v;
break; break;
case '|': case '|':
pe->v |= e2.v; pe->v |= e2.v;
break; break;
default: default:
@ -224,7 +224,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
} else if (pe->sym && !e2.sym) { } else if (pe->sym && !e2.sym) {
/* OK */ /* OK */
} else if (pe->sym && e2.sym) { } else if (pe->sym && e2.sym) {
if (pe->sym == e2.sym) { if (pe->sym == e2.sym) {
/* OK */ /* OK */
} else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) { } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
/* we also accept defined symbols in the same section */ /* we also accept defined symbols in the same section */
@ -267,7 +267,7 @@ static void asm_new_label1(TCCState *s1, int label, int is_local,
if (sym->r) { if (sym->r) {
/* the label is already defined */ /* the label is already defined */
if (!is_local) { if (!is_local) {
tcc_error("assembler label '%s' already defined", tcc_error("assembler label '%s' already defined",
get_tok_str(label, NULL)); get_tok_str(label, NULL));
} else { } else {
/* redefinition of local labels is possible */ /* redefinition of local labels is possible */
@ -492,25 +492,25 @@ static void asm_parse_directive(TCCState *s1)
case TOK_ASM_global: case TOK_ASM_global:
case TOK_ASM_weak: case TOK_ASM_weak:
case TOK_ASM_hidden: case TOK_ASM_hidden:
tok1 = tok; tok1 = tok;
do { do {
Sym *sym; Sym *sym;
next(); next();
sym = label_find(tok); sym = label_find(tok);
if (!sym) { if (!sym) {
sym = label_push(&s1->asm_labels, tok, 0); sym = label_push(&s1->asm_labels, tok, 0);
sym->type.t = VT_VOID; sym->type.t = VT_VOID;
} }
if (tok1 != TOK_ASM_hidden) if (tok1 != TOK_ASM_hidden)
sym->type.t &= ~VT_STATIC; sym->type.t &= ~VT_STATIC;
if (tok1 == TOK_ASM_weak) if (tok1 == TOK_ASM_weak)
sym->type.t |= VT_WEAK; sym->type.t |= VT_WEAK;
else if (tok1 == TOK_ASM_hidden) else if (tok1 == TOK_ASM_hidden)
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT; sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
next(); next();
} while (tok == ','); } while (tok == ',');
break; break;
case TOK_ASM_string: case TOK_ASM_string:
case TOK_ASM_ascii: case TOK_ASM_ascii:
case TOK_ASM_asciz: case TOK_ASM_asciz:
@ -536,24 +536,24 @@ static void asm_parse_directive(TCCState *s1)
break; break;
} }
} }
} }
break; break;
case TOK_ASM_text: case TOK_ASM_text:
case TOK_ASM_data: case TOK_ASM_data:
case TOK_ASM_bss: case TOK_ASM_bss:
{ {
char sname[64]; char sname[64];
tok1 = tok; tok1 = tok;
n = 0; n = 0;
next(); next();
if (tok != ';' && tok != TOK_LINEFEED) { if (tok != ';' && tok != TOK_LINEFEED) {
n = asm_int_expr(s1); n = asm_int_expr(s1);
next(); next();
} }
sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
use_section(s1, sname); use_section(s1, sname);
} }
break; break;
case TOK_ASM_file: case TOK_ASM_file:
{ {
char filename[512]; char filename[512];
@ -591,7 +591,7 @@ static void asm_parse_directive(TCCState *s1)
} }
break; break;
case TOK_ASM_size: case TOK_ASM_size:
{ {
Sym *sym; Sym *sym;
next(); next();
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *s1)
} }
break; break;
case TOK_ASM_type: case TOK_ASM_type:
{ {
Sym *sym; Sym *sym;
const char *newtype; const char *newtype;
@ -637,7 +637,7 @@ static void asm_parse_directive(TCCState *s1)
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
} }
else if (s1->warn_unsupported) else if (s1->warn_unsupported)
tcc_warning("change type of '%s' from 0x%x to '%s' ignored", tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
get_tok_str(sym->v, NULL), sym->type.t, newtype); get_tok_str(sym->v, NULL), sym->type.t, newtype);
next(); next();
@ -669,7 +669,7 @@ static void asm_parse_directive(TCCState *s1)
} }
break; break;
case TOK_ASM_previous: case TOK_ASM_previous:
{ {
Section *sec; Section *sec;
next(); next();
if (!last_text_section) if (!last_text_section)
@ -830,7 +830,7 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
cur_text_section->data_offset = ind; cur_text_section->data_offset = ind;
free_defines(define_start); free_defines(define_start);
return ret; return ret;
} }
@ -863,7 +863,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len)
/* find a constraint by its number or id (gcc 3 extended /* find a constraint by its number or id (gcc 3 extended
syntax). return -1 if not found. Return in *pp in char after the syntax). return -1 if not found. Return in *pp in char after the
constraint */ constraint */
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
const char *name, const char **pp) const char *name, const char **pp)
{ {
int index; int index;
@ -901,7 +901,7 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
return index; return index;
} }
static void subst_asm_operands(ASMOperand *operands, int nb_operands, static void subst_asm_operands(ASMOperand *operands, int nb_operands,
int nb_outputs, int nb_outputs,
CString *out_str, CString *in_str) CString *out_str, CString *in_str)
{ {
@ -1052,12 +1052,12 @@ ST_FUNC void asm_instr(void)
token after the assembler parsing */ token after the assembler parsing */
if (tok != ';') if (tok != ';')
expect("';'"); expect("';'");
/* save all values in the memory */ /* save all values in the memory */
save_regs(0); save_regs(0);
/* compute constraints */ /* compute constraints */
asm_compute_constraints(operands, nb_operands, nb_outputs, asm_compute_constraints(operands, nb_operands, nb_outputs,
clobber_regs, &out_reg); clobber_regs, &out_reg);
/* substitute the operands in the asm string. No substitution is /* substitute the operands in the asm string. No substitution is
@ -1076,8 +1076,8 @@ ST_FUNC void asm_instr(void)
#endif #endif
/* generate loads */ /* generate loads */
asm_gen_code(operands, nb_operands, nb_outputs, 0, asm_gen_code(operands, nb_operands, nb_outputs, 0,
clobber_regs, out_reg); clobber_regs, out_reg);
/* assemble the string with tcc internal assembler */ /* assemble the string with tcc internal assembler */
tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1); tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
@ -1086,9 +1086,9 @@ ST_FUNC void asm_instr(void)
next(); next();
/* store the output values if needed */ /* store the output values if needed */
asm_gen_code(operands, nb_operands, nb_outputs, 1, asm_gen_code(operands, nb_operands, nb_outputs, 1,
clobber_regs, out_reg); clobber_regs, out_reg);
/* free everything */ /* free everything */
for(i=0;i<nb_operands;i++) { for(i=0;i<nb_operands;i++) {
ASMOperand *op; ASMOperand *op;
@ -1110,7 +1110,7 @@ ST_FUNC void asm_global_instr(void)
token after the assembler parsing */ token after the assembler parsing */
if (tok != ';') if (tok != ';')
expect("';'"); expect("';'");
#ifdef ASM_DEBUG #ifdef ASM_DEBUG
printf("asm_global: \"%s\"\n", (char *)astr.data); printf("asm_global: \"%s\"\n", (char *)astr.data);
#endif #endif
@ -1119,7 +1119,7 @@ ST_FUNC void asm_global_instr(void)
/* assemble the string with tcc internal assembler */ /* assemble the string with tcc internal assembler */
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1); tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
cur_text_section->data_offset = ind; cur_text_section->data_offset = ind;
/* restore the current C token */ /* restore the current C token */

948
tcccoff.c 100644
View File

@ -0,0 +1,948 @@
/*
* COFF file handling for TCC
*
* Copyright (c) 2003, 2004 TK
* Copyright (c) 2004 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tcc.h"
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
#define MAX_STR_TABLE 1000000
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
SCNHDR section_header[MAXNSCNS];
#define MAX_FUNCS 1000
#define MAX_FUNC_NAME_LENGTH 128
int nFuncs;
char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
int LineNoFilePtr[MAX_FUNCS];
int EndAddress[MAX_FUNCS];
int LastLineNo[MAX_FUNCS];
int FuncEntries[MAX_FUNCS];
int OutputTheSection(Section * sect);
short int GetCoffFlags(const char *s);
void SortSymbolTable(void);
Section *FindSection(TCCState * s1, const char *sname);
int C67_main_entry_point;
int FindCoffSymbolIndex(const char *func_name);
int nb_syms;
typedef struct {
long tag;
long size;
long fileptr;
long nextsym;
short int dummy;
} AUXFUNC;
typedef struct {
long regmask;
unsigned short lineno;
unsigned short nentries;
int localframe;
int nextentry;
short int dummy;
} AUXBF;
typedef struct {
long dummy;
unsigned short lineno;
unsigned short dummy1;
int dummy2;
int dummy3;
unsigned short dummy4;
} AUXEF;
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
{
Section *tcc_sect;
SCNHDR *coff_sec;
int file_pointer;
char *Coff_str_table, *pCoff_str_table;
int CoffTextSectionNo, coff_nb_syms;
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
Section *stext, *sdata, *sbss;
int i, NSectionsToOutput = 0;
Coff_str_table = pCoff_str_table = NULL;
stext = FindSection(s1, ".text");
sdata = FindSection(s1, ".data");
sbss = FindSection(s1, ".bss");
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
file_hdr.f_timdat = 0; /* time & date stamp */
file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
o_filehdr.magic = 0x0108; /* see magic.h */
o_filehdr.vstamp = 0x0190; /* version stamp */
o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
// create all the section headers
file_pointer = FILHSZ + sizeof(AOUTHDR);
CoffTextSectionNo = -1;
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
NSectionsToOutput++;
if (CoffTextSectionNo == -1 && tcc_sect == stext)
CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
coff_sec->s_size = tcc_sect->data_offset; /* section size */
coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
coff_sec->s_relptr = 0; /* file ptr to relocation */
coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
coff_sec->s_nreloc = 0; /* number of relocation entries */
coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
coff_sec->s_reserved = 0; /* reserved byte */
coff_sec->s_page = 0; /* memory page id */
file_pointer += sizeof(SCNHDR);
}
}
file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
// now loop through and determine file pointer locations
// for the raw data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
// put raw data
coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
file_pointer += coff_sec->s_size;
}
}
// now loop through and determine file pointer locations
// for the relocation data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
// put relocations data
if (coff_sec->s_nreloc > 0) {
coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
}
}
}
// now loop through and determine file pointer locations
// for the line number data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
coff_sec->s_nlnno = 0;
coff_sec->s_lnnoptr = 0;
if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data
// also find association between source file name and function
// so we can sort the symbol table
Stab_Sym *sym, *sym_end;
char func_name[MAX_FUNC_NAME_LENGTH],
last_func_name[MAX_FUNC_NAME_LENGTH];
unsigned long func_addr, last_pc, pc;
const char *incl_files[INCLUDE_STACK_SIZE];
int incl_index, len, last_line_num;
const char *str, *p;
coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
func_name[0] = '\0';
func_addr = 0;
incl_index = 0;
last_func_name[0] = '\0';
last_pc = 0xffffffff;
last_line_num = 1;
sym = (Stab_Sym *) stab_section->data + 1;
sym_end =
(Stab_Sym *) (stab_section->data +
stab_section->data_offset);
nFuncs = 0;
while (sym < sym_end) {
switch (sym->n_type) {
/* function start or end */
case N_FUN:
if (sym->n_strx == 0) {
// end of function
coff_sec->s_nlnno++;
file_pointer += LINESZ;
pc = sym->n_value + func_addr;
func_name[0] = '\0';
func_addr = 0;
EndAddress[nFuncs] = pc;
FuncEntries[nFuncs] =
(file_pointer -
LineNoFilePtr[nFuncs]) / LINESZ - 1;
LastLineNo[nFuncs++] = last_line_num + 1;
} else {
// beginning of function
LineNoFilePtr[nFuncs] = file_pointer;
coff_sec->s_nlnno++;
file_pointer += LINESZ;
str =
(const char *) stabstr_section->data +
sym->n_strx;
p = strchr(str, ':');
if (!p) {
pstrcpy(func_name, sizeof(func_name), str);
pstrcpy(Func[nFuncs], sizeof(func_name), str);
} else {
len = p - str;
if (len > sizeof(func_name) - 1)
len = sizeof(func_name) - 1;
memcpy(func_name, str, len);
memcpy(Func[nFuncs], str, len);
func_name[len] = '\0';
}
// save the file that it came in so we can sort later
pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
incl_files[incl_index - 1]);
func_addr = sym->n_value;
}
break;
/* line number info */
case N_SLINE:
pc = sym->n_value + func_addr;
last_pc = pc;
last_line_num = sym->n_desc;
/* XXX: slow! */
strcpy(last_func_name, func_name);
coff_sec->s_nlnno++;
file_pointer += LINESZ;
break;
/* include files */
case N_BINCL:
str =
(const char *) stabstr_section->data + sym->n_strx;
add_incl:
if (incl_index < INCLUDE_STACK_SIZE) {
incl_files[incl_index++] = str;
}
break;
case N_EINCL:
if (incl_index > 1)
incl_index--;
break;
case N_SO:
if (sym->n_strx == 0) {
incl_index = 0; /* end of translation unit */
} else {
str =
(const char *) stabstr_section->data +
sym->n_strx;
/* do not add path */
len = strlen(str);
if (len > 0 && str[len - 1] != '/')
goto add_incl;
}
break;
}
sym++;
}
}
}
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
if (s1->do_debug)
file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
else
file_hdr.f_nsyms = 0;
file_pointer += file_hdr.f_nsyms * SYMNMLEN;
// OK now we are all set to write the file
fwrite(&file_hdr, FILHSZ, 1, f);
fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
// write section headers
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
fwrite(coff_sec, sizeof(SCNHDR), 1, f);
}
}
// write raw data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
}
}
// write relocation data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (OutputTheSection(tcc_sect)) {
// put relocations data
if (coff_sec->s_nreloc > 0) {
fwrite(tcc_sect->reloc,
coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
}
}
}
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
if (s1->do_debug)
SortSymbolTable();
// write line no data
for (i = 1; i < s1->nb_sections; i++) {
coff_sec = &section_header[i];
tcc_sect = s1->sections[i];
if (s1->do_debug && tcc_sect == stext) {
// count how many line nos data
Stab_Sym *sym, *sym_end;
char func_name[128], last_func_name[128];
unsigned long func_addr, last_pc, pc;
const char *incl_files[INCLUDE_STACK_SIZE];
int incl_index, len, last_line_num;
const char *str, *p;
LINENO CoffLineNo;
func_name[0] = '\0';
func_addr = 0;
incl_index = 0;
last_func_name[0] = '\0';
last_pc = 0;
last_line_num = 1;
sym = (Stab_Sym *) stab_section->data + 1;
sym_end =
(Stab_Sym *) (stab_section->data +
stab_section->data_offset);
while (sym < sym_end) {
switch (sym->n_type) {
/* function start or end */
case N_FUN:
if (sym->n_strx == 0) {
// end of function
CoffLineNo.l_addr.l_paddr = last_pc;
CoffLineNo.l_lnno = last_line_num + 1;
fwrite(&CoffLineNo, 6, 1, f);
pc = sym->n_value + func_addr;
func_name[0] = '\0';
func_addr = 0;
} else {
// beginning of function
str =
(const char *) stabstr_section->data +
sym->n_strx;
p = strchr(str, ':');
if (!p) {
pstrcpy(func_name, sizeof(func_name), str);
} else {
len = p - str;
if (len > sizeof(func_name) - 1)
len = sizeof(func_name) - 1;
memcpy(func_name, str, len);
func_name[len] = '\0';
}
func_addr = sym->n_value;
last_pc = func_addr;
last_line_num = -1;
// output a function begin
CoffLineNo.l_addr.l_symndx =
FindCoffSymbolIndex(func_name);
CoffLineNo.l_lnno = 0;
fwrite(&CoffLineNo, 6, 1, f);
}
break;
/* line number info */
case N_SLINE:
pc = sym->n_value + func_addr;
/* XXX: slow! */
strcpy(last_func_name, func_name);
// output a line reference
CoffLineNo.l_addr.l_paddr = last_pc;
if (last_line_num == -1) {
CoffLineNo.l_lnno = sym->n_desc;
} else {
CoffLineNo.l_lnno = last_line_num + 1;
}
fwrite(&CoffLineNo, 6, 1, f);
last_pc = pc;
last_line_num = sym->n_desc;
break;
/* include files */
case N_BINCL:
str =
(const char *) stabstr_section->data + sym->n_strx;
add_incl2:
if (incl_index < INCLUDE_STACK_SIZE) {
incl_files[incl_index++] = str;
}
break;
case N_EINCL:
if (incl_index > 1)
incl_index--;
break;
case N_SO:
if (sym->n_strx == 0) {
incl_index = 0; /* end of translation unit */
} else {
str =
(const char *) stabstr_section->data +
sym->n_strx;
/* do not add path */
len = strlen(str);
if (len > 0 && str[len - 1] != '/')
goto add_incl2;
}
break;
}
sym++;
}
}
}
// write symbol table
if (s1->do_debug) {
int k;
struct syment csym;
AUXFUNC auxfunc;
AUXBF auxbf;
AUXEF auxef;
int i;
Elf32_Sym *p;
const char *name;
int nstr;
int n = 0;
Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
pCoff_str_table = Coff_str_table;
nstr = 0;
p = (Elf32_Sym *) symtab_section->data;
for (i = 0; i < nb_syms; i++) {
name = symtab_section->link->data + p->st_name;
for (k = 0; k < 8; k++)
csym._n._n_name[k] = 0;
if (strlen(name) <= 8) {
strcpy(csym._n._n_name, name);
} else {
if (pCoff_str_table - Coff_str_table + strlen(name) >
MAX_STR_TABLE - 1)
tcc_error("String table too large");
csym._n._n_n._n_zeroes = 0;
csym._n._n_n._n_offset =
pCoff_str_table - Coff_str_table + 4;
strcpy(pCoff_str_table, name);
pCoff_str_table += strlen(name) + 1; // skip over null
nstr++;
}
if (p->st_info == 4) {
// put a filename symbol
csym.n_value = 33; // ?????
csym.n_scnum = N_DEBUG;
csym.n_type = 0;
csym.n_sclass = C_FILE;
csym.n_numaux = 0;
fwrite(&csym, 18, 1, f);
n++;
} else if (p->st_info == 0x12) {
// find the function data
for (k = 0; k < nFuncs; k++) {
if (strcmp(name, Func[k]) == 0)
break;
}
if (k >= nFuncs) {
tcc_error("debug info can't find function: %s", name);
}
// put a Function Name
csym.n_value = p->st_value; // physical address
csym.n_scnum = CoffTextSectionNo;
csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
csym.n_sclass = C_EXT;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
// now put aux info
auxfunc.tag = 0;
auxfunc.size = EndAddress[k] - p->st_value;
auxfunc.fileptr = LineNoFilePtr[k];
auxfunc.nextsym = n + 6; // tktk
auxfunc.dummy = 0;
fwrite(&auxfunc, 18, 1, f);
// put a .bf
strcpy(csym._n._n_name, ".bf");
csym.n_value = p->st_value; // physical address
csym.n_scnum = CoffTextSectionNo;
csym.n_type = 0;
csym.n_sclass = C_FCN;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
// now put aux info
auxbf.regmask = 0;
auxbf.lineno = 0;
auxbf.nentries = FuncEntries[k];
auxbf.localframe = 0;
auxbf.nextentry = n + 6;
auxbf.dummy = 0;
fwrite(&auxbf, 18, 1, f);
// put a .ef
strcpy(csym._n._n_name, ".ef");
csym.n_value = EndAddress[k]; // physical address
csym.n_scnum = CoffTextSectionNo;
csym.n_type = 0;
csym.n_sclass = C_FCN;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
// now put aux info
auxef.dummy = 0;
auxef.lineno = LastLineNo[k];
auxef.dummy1 = 0;
auxef.dummy2 = 0;
auxef.dummy3 = 0;
auxef.dummy4 = 0;
fwrite(&auxef, 18, 1, f);
n += 6;
} else {
// try an put some type info
if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
csym.n_type = T_DOUBLE; // int
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
csym.n_type = T_FLOAT;
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_INT) {
csym.n_type = T_INT; // int
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
csym.n_type = T_SHORT;
csym.n_sclass = C_EXT;
} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
csym.n_type = T_CHAR;
csym.n_sclass = C_EXT;
} else {
csym.n_type = T_INT; // just mark as a label
csym.n_sclass = C_LABEL;
}
csym.n_value = p->st_value;
csym.n_scnum = 2;
csym.n_numaux = 1;
fwrite(&csym, 18, 1, f);
auxfunc.tag = 0;
auxfunc.size = 0x20;
auxfunc.fileptr = 0;
auxfunc.nextsym = 0;
auxfunc.dummy = 0;
fwrite(&auxfunc, 18, 1, f);
n++;
n++;
}
p++;
}
}
if (s1->do_debug) {
// write string table
// first write the size
i = pCoff_str_table - Coff_str_table;
fwrite(&i, 4, 1, f);
// then write the strings
fwrite(Coff_str_table, i, 1, f);
tcc_free(Coff_str_table);
}
return 0;
}
// group the symbols in order of filename, func1, func2, etc
// finally global symbols
void SortSymbolTable(void)
{
int i, j, k, n = 0;
Elf32_Sym *p, *p2, *NewTable;
char *name, *name2;
NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
p = (Elf32_Sym *) symtab_section->data;
// find a file symbol, copy it over
// then scan the whole symbol list and copy any function
// symbols that match the file association
for (i = 0; i < nb_syms; i++) {
if (p->st_info == 4) {
name = (char *) symtab_section->link->data + p->st_name;
// this is a file symbol, copy it over
NewTable[n++] = *p;
p2 = (Elf32_Sym *) symtab_section->data;
for (j = 0; j < nb_syms; j++) {
if (p2->st_info == 0x12) {
// this is a func symbol
name2 =
(char *) symtab_section->link->data + p2->st_name;
// find the function data index
for (k = 0; k < nFuncs; k++) {
if (strcmp(name2, Func[k]) == 0)
break;
}
if (k >= nFuncs) {
tcc_error("debug (sort) info can't find function: %s", name2);
}
if (strcmp(AssociatedFile[k], name) == 0) {
// yes they match copy it over
NewTable[n++] = *p2;
}
}
p2++;
}
}
p++;
}
// now all the filename and func symbols should have been copied over
// copy all the rest over (all except file and funcs)
p = (Elf32_Sym *) symtab_section->data;
for (i = 0; i < nb_syms; i++) {
if (p->st_info != 4 && p->st_info != 0x12) {
NewTable[n++] = *p;
}
p++;
}
if (n != nb_syms)
tcc_error("Internal Compiler error, debug info");
// copy it all back
p = (Elf32_Sym *) symtab_section->data;
for (i = 0; i < nb_syms; i++) {
*p++ = NewTable[i];
}
tcc_free(NewTable);
}
int FindCoffSymbolIndex(const char *func_name)
{
int i, n = 0;
Elf32_Sym *p;
char *name;
p = (Elf32_Sym *) symtab_section->data;
for (i = 0; i < nb_syms; i++) {
name = (char *) symtab_section->link->data + p->st_name;
if (p->st_info == 4) {
// put a filename symbol
n++;
} else if (p->st_info == 0x12) {
if (strcmp(func_name, name) == 0)
return n;
n += 6;
// put a Function Name
// now put aux info
// put a .bf
// now put aux info
// put a .ef
// now put aux info
} else {
n += 2;
}
p++;
}
return n; // total number of symbols
}
int OutputTheSection(Section * sect)
{
const char *s = sect->name;
if (!strcmp(s, ".text"))
return 1;
else if (!strcmp(s, ".data"))
return 1;
else
return 0;
}
short int GetCoffFlags(const char *s)
{
if (!strcmp(s, ".text"))
return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
else if (!strcmp(s, ".data"))
return STYP_DATA;
else if (!strcmp(s, ".bss"))
return STYP_BSS;
else if (!strcmp(s, ".stack"))
return STYP_BSS | STYP_ALIGN | 0x200;
else if (!strcmp(s, ".cinit"))
return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
else
return 0;
}
Section *FindSection(TCCState * s1, const char *sname)
{
Section *s;
int i;
for (i = 1; i < s1->nb_sections; i++) {
s = s1->sections[i];
if (!strcmp(sname, s->name))
return s;
}
tcc_error("could not find section %s", sname);
return 0;
}
ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
{
// tktk TokenSym *ts;
FILE *f;
unsigned int str_size;
char *Coff_str_table, *name;
int i, k;
struct syment csym;
char name2[9];
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
f = fdopen(fd, "rb");
if (!f) {
tcc_error("Unable to open .out file for input");
}
if (fread(&file_hdr, FILHSZ, 1, f) != 1)
tcc_error("error reading .out file for input");
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
tcc_error("error reading .out file for input");
// first read the string table
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
tcc_error("error reading .out file for input");
if (fread(&str_size, sizeof(int), 1, f) != 1)
tcc_error("error reading .out file for input");
Coff_str_table = (char *) tcc_malloc(str_size);
if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
tcc_error("error reading .out file for input");
// read/process all the symbols
// seek back to symbols
if (fseek(f, file_hdr.f_symptr, SEEK_SET))
tcc_error("error reading .out file for input");
for (i = 0; i < file_hdr.f_nsyms; i++) {
if (fread(&csym, SYMESZ, 1, f) != 1)
tcc_error("error reading .out file for input");
if (csym._n._n_n._n_zeroes == 0) {
name = Coff_str_table + csym._n._n_n._n_offset - 4;
} else {
name = csym._n._n_name;
if (name[7] != 0) {
for (k = 0; k < 8; k++)
name2[k] = name[k];
name2[8] = 0;
name = name2;
}
}
// if (strcmp("_DAC_Buffer",name)==0) // tktk
// name[0]=0;
if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
(csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
(csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
(csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
{
// strip off any leading underscore (except for other main routine)
if (name[0] == '_' && strcmp(name, "_main") != 0)
name++;
tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
}
// skip any aux records
if (csym.n_numaux == 1) {
if (fread(&csym, SYMESZ, 1, f) != 1)
tcc_error("error reading .out file for input");
i++;
}
}
return 0;
}

View File

@ -451,7 +451,7 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
if (addr) { if (addr) {
sym->st_value = (addr_t)addr; sym->st_value = (addr_t)addr;
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value); printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
#endif #endif
goto found; goto found;
} }
@ -580,10 +580,10 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
{ {
int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
x = (*(int *) ptr) & 0xffffff; x = (*(int *) ptr) & 0xffffff;
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)
val = s1->plt->sh_addr; val = s1->plt->sh_addr;
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
#endif #endif
(*(int *)ptr) &= 0xff000000; (*(int *)ptr) &= 0xff000000;
if (x & 0x800000) if (x & 0x800000)
@ -595,8 +595,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
x += val - addr; x += val - addr;
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf (" newx=0x%x name=%s\n", x, printf (" newx=0x%x name=%s\n", x,
(char *) symtab_section->link->data + sym->st_name); (char *) symtab_section->link->data + sym->st_name);
#endif #endif
h = x & 2; h = x & 2;
th_ko = (x & 3) && (!blx_avail || !is_call); th_ko = (x & 3) && (!blx_avail || !is_call);
@ -797,21 +797,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
break; break;
case R_AARCH64_JUMP26: case R_AARCH64_JUMP26:
case R_AARCH64_CALL26: case R_AARCH64_CALL26:
/* This check must match the one in build_got_entries, testing /* This check must match the one in build_got_entries, testing
if we really need a PLT slot. */ if we really need a PLT slot. */
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)
/* We've put the PLT slot offset into r_addend when generating /* We've put the PLT slot offset into r_addend when generating
it, and that's what we must use as relocation value (adjusted it, and that's what we must use as relocation value (adjusted
by section offset of course). */ by section offset of course). */
val = s1->plt->sh_addr + rel->r_addend; val = s1->plt->sh_addr + rel->r_addend;
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val, printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
(char *) symtab_section->link->data + sym->st_name); (char *) symtab_section->link->data + sym->st_name);
#endif #endif
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
{ {
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val); tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
} }
*(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 | *(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |
((val - addr) >> 2 & 0x3ffffff); ((val - addr) >> 2 & 0x3ffffff);
break; break;
@ -836,9 +836,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
case R_AARCH64_JUMP_SLOT: case R_AARCH64_JUMP_SLOT:
/* They don't need addend */ /* They don't need addend */
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
val - rel->r_addend, val - rel->r_addend,
(char *) symtab_section->link->data + sym->st_name); (char *) symtab_section->link->data + sym->st_name);
#endif #endif
*(addr_t *)ptr = val - rel->r_addend; *(addr_t *)ptr = val - rel->r_addend;
break; break;
@ -879,12 +879,12 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
qrel->r_offset = rel->r_offset; qrel->r_offset = rel->r_offset;
if (esym_index) { if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
qrel->r_addend = rel->r_addend; qrel->r_addend = rel->r_addend;
qrel++; qrel++;
break; break;
} else { } else {
qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
qrel->r_addend = *(long long *)ptr + val; qrel->r_addend = *(long long *)ptr + val;
qrel++; qrel++;
} }
} }
@ -917,21 +917,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
goto plt32pc32; goto plt32pc32;
case R_X86_64_PLT32: case R_X86_64_PLT32:
/* We've put the PLT slot offset into r_addend when generating /* We've put the PLT slot offset into r_addend when generating
it, and that's what we must use as relocation value (adjusted it, and that's what we must use as relocation value (adjusted
by section offset of course). */ by section offset of course). */
val = s1->plt->sh_addr + rel->r_addend; val = s1->plt->sh_addr + rel->r_addend;
/* fallthrough. */ /* fallthrough. */
plt32pc32: plt32pc32:
{ {
long long diff; long long diff;
diff = (long long)val - addr; diff = (long long)val - addr;
if (diff < -2147483648LL || diff > 2147483647LL) { if (diff < -2147483648LL || diff > 2147483647LL) {
tcc_error("internal error: relocation failed"); tcc_error("internal error: relocation failed");
}
*(int *)ptr += diff;
} }
*(int *)ptr += diff;
}
break; break;
case R_X86_64_GLOB_DAT: case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT: case R_X86_64_JUMP_SLOT:
@ -1080,8 +1080,8 @@ static void build_got(TCCState *s1)
and 'info' can be modifed if more precise info comes from the DLL. and 'info' can be modifed if more precise info comes from the DLL.
Returns offset of GOT or PLT slot. */ Returns offset of GOT or PLT slot. */
static unsigned long put_got_entry(TCCState *s1, static unsigned long put_got_entry(TCCState *s1,
int reloc_type, unsigned long size, int info, int reloc_type, unsigned long size, int info,
int sym_index) int sym_index)
{ {
int index, need_plt_entry; int index, need_plt_entry;
const char *name; const char *name;
@ -1107,18 +1107,18 @@ static unsigned long put_got_entry(TCCState *s1,
#endif #endif
if (need_plt_entry && !s1->plt) { if (need_plt_entry && !s1->plt) {
/* add PLT */ /* add PLT */
s1->plt = new_section(s1, ".plt", SHT_PROGBITS, s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
SHF_ALLOC | SHF_EXECINSTR); SHF_ALLOC | SHF_EXECINSTR);
s1->plt->sh_entsize = 4; s1->plt->sh_entsize = 4;
} }
/* If a got/plt entry already exists for that symbol, no need to add one */ /* If a got/plt entry already exists for that symbol, no need to add one */
if (sym_index < s1->nb_sym_attrs) { if (sym_index < s1->nb_sym_attrs) {
if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset) if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
return s1->sym_attrs[sym_index].plt_offset; return s1->sym_attrs[sym_index].plt_offset;
else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset) else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
return s1->sym_attrs[sym_index].got_offset; return s1->sym_attrs[sym_index].got_offset;
} }
symattr = alloc_sym_attr(s1, sym_index); symattr = alloc_sym_attr(s1, sym_index);
@ -1135,7 +1135,7 @@ static unsigned long put_got_entry(TCCState *s1,
Section *plt; Section *plt;
uint8_t *p; uint8_t *p;
int modrm; int modrm;
unsigned long relofs; unsigned long relofs;
#if defined(TCC_OUTPUT_DLL_WITH_PLT) #if defined(TCC_OUTPUT_DLL_WITH_PLT)
modrm = 0x25; modrm = 0x25;
@ -1160,10 +1160,10 @@ static unsigned long put_got_entry(TCCState *s1,
put32(p + 8, PTR_SIZE * 2); put32(p + 8, PTR_SIZE * 2);
} }
/* The PLT slot refers to the relocation entry it needs /* The PLT slot refers to the relocation entry it needs
via offset. The reloc entry is created below, so its via offset. The reloc entry is created below, so its
offset is the current data_offset. */ offset is the current data_offset. */
relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0; relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
symattr->plt_offset = plt->data_offset; symattr->plt_offset = plt->data_offset;
p = section_ptr_add(plt, 16); p = section_ptr_add(plt, 16);
p[0] = 0xff; /* jmp *(got + x) */ p[0] = 0xff; /* jmp *(got + x) */
@ -1171,20 +1171,20 @@ static unsigned long put_got_entry(TCCState *s1,
put32(p + 2, s1->got->data_offset); put32(p + 2, s1->got->data_offset);
p[6] = 0x68; /* push $xxx */ p[6] = 0x68; /* push $xxx */
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
/* On x86-64, the relocation is referred to by _index_. */ /* On x86-64, the relocation is referred to by _index_. */
put32(p + 7, relofs / sizeof (ElfW_Rel)); put32(p + 7, relofs / sizeof (ElfW_Rel));
#else #else
put32(p + 7, relofs); put32(p + 7, relofs);
#endif #endif
p[11] = 0xe9; /* jmp plt_start */ p[11] = 0xe9; /* jmp plt_start */
put32(p + 12, -(plt->data_offset)); put32(p + 12, -(plt->data_offset));
/* If this was an UNDEF symbol set the offset in the /* If this was an UNDEF symbol set the offset in the
dynsymtab to the PLT slot, so that PC32 relocs to it dynsymtab to the PLT slot, so that PC32 relocs to it
can be resolved. */ can be resolved. */
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)
offset = plt->data_offset - 16; offset = plt->data_offset - 16;
} }
#elif defined(TCC_TARGET_ARM) #elif defined(TCC_TARGET_ARM)
if (need_plt_entry) { if (need_plt_entry) {
Section *plt; Section *plt;
@ -1220,9 +1220,9 @@ static unsigned long put_got_entry(TCCState *s1,
/* the symbol is modified so that it will be relocated to /* the symbol is modified so that it will be relocated to
the PLT */ the PLT */
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)
offset = plt->data_offset - 16; offset = plt->data_offset - 16;
} }
#elif defined(TCC_TARGET_ARM64) #elif defined(TCC_TARGET_ARM64)
if (need_plt_entry) { if (need_plt_entry) {
Section *plt; Section *plt;
@ -1250,29 +1250,29 @@ static unsigned long put_got_entry(TCCState *s1,
#error unsupported CPU #error unsupported CPU
#endif #endif
if (s1->dynsym) { if (s1->dynsym) {
/* XXX This might generate multiple syms for name. */ /* XXX This might generate multiple syms for name. */
index = put_elf_sym(s1->dynsym, offset, index = put_elf_sym(s1->dynsym, offset,
size, info, 0, sym->st_shndx, name); size, info, 0, sym->st_shndx, name);
/* Create the relocation (it's against the GOT for PLT /* Create the relocation (it's against the GOT for PLT
and GOT relocs). */ and GOT relocs). */
put_elf_reloc(s1->dynsym, s1->got, put_elf_reloc(s1->dynsym, s1->got,
s1->got->data_offset, s1->got->data_offset,
reloc_type, index); reloc_type, index);
} else { } else {
/* Without .dynsym (i.e. static link or memory output) we /* Without .dynsym (i.e. static link or memory output) we
still need relocs against the generated got, so as to fill still need relocs against the generated got, so as to fill
the entries with the symbol values (determined later). */ the entries with the symbol values (determined later). */
put_elf_reloc(symtab_section, s1->got, put_elf_reloc(symtab_section, s1->got,
s1->got->data_offset, s1->got->data_offset,
reloc_type, sym_index); reloc_type, sym_index);
} }
/* And now create the GOT slot itself. */ /* And now create the GOT slot itself. */
ptr = section_ptr_add(s1->got, PTR_SIZE); ptr = section_ptr_add(s1->got, PTR_SIZE);
*ptr = 0; *ptr = 0;
if (need_plt_entry) if (need_plt_entry)
return symattr->plt_offset; return symattr->plt_offset;
else else
return symattr->got_offset; return symattr->got_offset;
} }
/* build GOT and PLT entries */ /* build GOT and PLT entries */
@ -1324,8 +1324,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
build_got(s1); build_got(s1);
sym_index = ELFW(R_SYM)(rel->r_info); sym_index = ELFW(R_SYM)(rel->r_info);
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
&& sym->st_shndx == SHN_UNDEF) { && sym->st_shndx == SHN_UNDEF) {
unsigned long ofs; unsigned long ofs;
/* look at the symbol got offset. If none, then add one */ /* look at the symbol got offset. If none, then add one */
if (type == R_ARM_GOT32) if (type == R_ARM_GOT32)
@ -1333,27 +1333,27 @@ ST_FUNC void build_got_entries(TCCState *s1)
else else
reloc_type = R_ARM_JUMP_SLOT; reloc_type = R_ARM_JUMP_SLOT;
ofs = put_got_entry(s1, reloc_type, sym->st_size, ofs = put_got_entry(s1, reloc_type, sym->st_size,
sym->st_info, sym_index); sym->st_info, sym_index);
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf("maybegot: %s, %d, %d --> ofs=0x%x\n", printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
(char *) symtab_section->link->data + sym->st_name, (char *) symtab_section->link->data + sym->st_name,
type, sym->st_shndx, ofs); type, sym->st_shndx, ofs);
#endif #endif
if (type != R_ARM_GOT32) { if (type != R_ARM_GOT32) {
addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
+ rel->r_offset); + rel->r_offset);
/* x must be signed! */ /* x must be signed! */
int x = *ptr & 0xffffff; int x = *ptr & 0xffffff;
x = (x << 8) >> 8; x = (x << 8) >> 8;
x <<= 2; x <<= 2;
x += ofs; x += ofs;
x >>= 2; x >>= 2;
#ifdef DEBUG_RELOC #ifdef DEBUG_RELOC
printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr, printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
(*ptr & 0xff000000) | x, x); (*ptr & 0xff000000) | x, x);
#endif #endif
*ptr = (*ptr & 0xff000000) | x; *ptr = (*ptr & 0xff000000) | x;
} }
} }
break; break;
case R_ARM_THM_JUMP24: case R_ARM_THM_JUMP24:
@ -1397,22 +1397,22 @@ ST_FUNC void build_got_entries(TCCState *s1)
sym_index); sym_index);
break; break;
case R_AARCH64_JUMP26: case R_AARCH64_JUMP26:
case R_AARCH64_CALL26: case R_AARCH64_CALL26:
if (!s1->got) if (!s1->got)
build_got(s1); build_got(s1);
sym_index = ELFW(R_SYM)(rel->r_info); sym_index = ELFW(R_SYM)(rel->r_info);
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if (sym->st_shndx == SHN_UNDEF) { if (sym->st_shndx == SHN_UNDEF) {
unsigned long ofs; unsigned long ofs;
reloc_type = R_AARCH64_JUMP_SLOT; reloc_type = R_AARCH64_JUMP_SLOT;
ofs = put_got_entry(s1, reloc_type, sym->st_size, ofs = put_got_entry(s1, reloc_type, sym->st_size,
sym->st_info, sym_index); sym->st_info, sym_index);
/* We store the place of the generated PLT slot /* We store the place of the generated PLT slot
in our addend. */ in our addend. */
rel->r_addend += ofs; rel->r_addend += ofs;
} }
break; break;
#elif defined(TCC_TARGET_C67) #elif defined(TCC_TARGET_C67)
case R_C60_GOT32: case R_C60_GOT32:
case R_C60_GOTOFF: case R_C60_GOTOFF:
@ -1439,29 +1439,29 @@ ST_FUNC void build_got_entries(TCCState *s1)
case R_X86_64_PLT32: case R_X86_64_PLT32:
sym_index = ELFW(R_SYM)(rel->r_info); sym_index = ELFW(R_SYM)(rel->r_info);
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if (type == R_X86_64_PLT32 && if (type == R_X86_64_PLT32 &&
ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
{ {
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32); rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
break; break;
} }
if (!s1->got) if (!s1->got)
build_got(s1); build_got(s1);
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
type == R_X86_64_PLT32) { type == R_X86_64_PLT32) {
unsigned long ofs; unsigned long ofs;
/* look at the symbol got offset. If none, then add one */ /* look at the symbol got offset. If none, then add one */
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL) if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
reloc_type = R_X86_64_GLOB_DAT; reloc_type = R_X86_64_GLOB_DAT;
else else
reloc_type = R_X86_64_JUMP_SLOT; reloc_type = R_X86_64_JUMP_SLOT;
ofs = put_got_entry(s1, reloc_type, sym->st_size, ofs = put_got_entry(s1, reloc_type, sym->st_size,
sym->st_info, sym_index); sym->st_info, sym_index);
if (type == R_X86_64_PLT32) if (type == R_X86_64_PLT32)
/* We store the place of the generated PLT slot /* We store the place of the generated PLT slot
in our addend. */ in our addend. */
rel->r_addend += ofs; rel->r_addend += ofs;
} }
break; break;
#else #else
@ -1546,21 +1546,21 @@ static int tcc_add_support(TCCState *s1, const char *filename)
snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path, snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path,
/* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */ /* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */
#ifdef TCC_TARGET_I386 #ifdef TCC_TARGET_I386
"i386" "i386"
#endif #endif
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
"x86_64" "x86-64"
#endif #endif
#ifdef TCC_TARGET_ARM #ifdef TCC_TARGET_ARM
"arm" "arm"
#endif #endif
#ifdef TCC_TARGET_ARM64 #ifdef TCC_TARGET_ARM64
"arm64" "arm64"
#endif #endif
#ifdef TCC_TARGET_C67 #ifdef TCC_TARGET_C67
"C67" "C67"
#endif #endif
, filename); ,filename);
return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY); return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY);
} }
@ -1587,17 +1587,17 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1)
when __bound_ptr_add, __bound_new_region, when __bound_ptr_add, __bound_new_region,
__bound_delete_region called */ __bound_delete_region called */
int sym_index = find_elf_sym(symtab_section, "__bound_init"); int sym_index = find_elf_sym(symtab_section, "__bound_init");
if (sym_index) { if (sym_index) {
Section *init_section = find_section(s1, ".init"); Section *init_section = find_section(s1, ".init");
unsigned char *pinit = section_ptr_add(init_section, 5); unsigned char *pinit = section_ptr_add(init_section, 5);
pinit[0] = 0xe8; pinit[0] = 0xe8;
put32(pinit + 1, -4); put32(pinit + 1, -4);
put_elf_reloc(symtab_section, init_section, put_elf_reloc(symtab_section, init_section,
init_section->data_offset - 4, R_386_PC32, sym_index); init_section->data_offset - 4, R_386_PC32, sym_index);
} }
else else
tcc_warning("__bound_init not defined"); tcc_warning("__bound_init not defined");
} }
#endif #endif
} }
@ -1905,11 +1905,11 @@ static void export_global_syms(TCCState *s1)
s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
name = (char *) symtab_section->link->data + sym->st_name; name = (char *) symtab_section->link->data + sym->st_name;
dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
sym->st_info, 0, sym->st_shndx, name); sym->st_info, 0, sym->st_shndx, name);
index = sym - (ElfW(Sym) *) symtab_section->data; index = sym - (ElfW(Sym) *) symtab_section->data;
s1->symtab_to_dynsym[index] = dynindex; s1->symtab_to_dynsym[index] = dynindex;
} }
} }
} }
@ -2179,15 +2179,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
file_offset += s->sh_size; file_offset += s->sh_size;
} }
} }
if (j == 0) { if (j == 0) {
/* Make the first PT_LOAD segment include the program /* Make the first PT_LOAD segment include the program
headers itself (and the ELF header as well), it'll headers itself (and the ELF header as well), it'll
come out with same memory use but will make various come out with same memory use but will make various
tools like binutils strip work better. */ tools like binutils strip work better. */
ph->p_offset &= ~(ph->p_align - 1); ph->p_offset &= ~(ph->p_align - 1);
ph->p_vaddr &= ~(ph->p_align - 1); ph->p_vaddr &= ~(ph->p_align - 1);
ph->p_paddr &= ~(ph->p_align - 1); ph->p_paddr &= ~(ph->p_align - 1);
} }
ph->p_filesz = file_offset - ph->p_offset; ph->p_filesz = file_offset - ph->p_offset;
ph->p_memsz = addr - ph->p_vaddr; ph->p_memsz = addr - ph->p_vaddr;
ph++; ph++;
@ -2662,10 +2662,10 @@ static int elf_output_file(TCCState *s1, const char *filename)
for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
if (sym->st_shndx == SHN_UNDEF) { if (sym->st_shndx == SHN_UNDEF) {
/* relocate to PLT if symbol corresponds to a PLT entry, /* relocate to PLT if symbol corresponds to a PLT entry,
but not if it's a weak symbol */ but not if it's a weak symbol */
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
sym->st_value = 0; sym->st_value = 0;
else if (sym->st_value) else if (sym->st_value)
sym->st_value += s1->plt->sh_addr; sym->st_value += s1->plt->sh_addr;
} else if (sym->st_shndx < SHN_LORESERVE) { } else if (sym->st_shndx < SHN_LORESERVE) {
/* do symbol relocation */ /* do symbol relocation */
@ -2690,14 +2690,14 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* Create the ELF file with name 'filename' */ /* Create the ELF file with name 'filename' */
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
if (s1->do_strip) { if (s1->do_strip) {
int rc; int rc;
const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers
const char *null_dev = " 2> /dev/null"; const char *null_dev = " 2> /dev/null";
char buf[1050]; char buf[1050];
snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev); snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev);
rc = system(buf); rc = system(buf);
if (rc) if (rc)
system(buf+1); // call a strip utility from binutils system(buf+1); // call a strip utility from binutils
} }
the_end: the_end:
tcc_free(s1->symtab_to_dynsym); tcc_free(s1->symtab_to_dynsym);

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* Simple libc header for TCC /* Simple libc header for TCC
* *
* Add any function you want from the libc there. This file is here * Add any function you want from the libc there. This file is here
* only for your convenience so that you do not need to put the whole * only for your convenience so that you do not need to put the whole
* glibc include files on your floppy disk * glibc include files on your floppy disk
*/ */
#ifndef _TCCLIB_H #ifndef _TCCLIB_H
#define _TCCLIB_H #define _TCCLIB_H

View File

@ -398,22 +398,22 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
s = pe_export_name(s1, sym); s = pe_export_name(s1, sym);
if (n) { if (n) {
/* second try: */ /* second try: */
if (sym->st_other & ST_PE_STDCALL) { if (sym->st_other & ST_PE_STDCALL) {
/* try w/0 stdcall deco (windows API convention) */ /* try w/0 stdcall deco (windows API convention) */
p = strrchr(s, '@'); p = strrchr(s, '@');
if (!p || s[0] != '_') if (!p || s[0] != '_')
break; break;
strcpy(buffer, s+1)[p-s-1] = 0; strcpy(buffer, s+1)[p-s-1] = 0;
} else if (s[0] != '_') { /* try non-ansi function */ } else if (s[0] != '_') { /* try non-ansi function */
buffer[0] = '_', strcpy(buffer + 1, s); buffer[0] = '_', strcpy(buffer + 1, s);
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */ } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
strcpy(buffer, s + 6); strcpy(buffer, s + 6);
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */ } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
strcpy(buffer, s + 6); strcpy(buffer, s + 6);
} else { } else {
break; break;
} }
s = buffer; s = buffer;
} }
sym_index = find_elf_sym(s1->dynsymtab_section, s); sym_index = find_elf_sym(s1->dynsymtab_section, s);
// printf("find (%d) %d %s\n", n, sym_index, s); // printf("find (%d) %d %s\n", n, sym_index, s);
@ -1266,7 +1266,7 @@ static int pe_check_symbols(struct pe_info *pe)
put_elf_reloc(symtab_section, text_section, put_elf_reloc(symtab_section, text_section,
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
#else #else
put_elf_reloc(symtab_section, text_section, put_elf_reloc(symtab_section, text_section,
offset + 2, R_XXX_THUNKFIX, is->iat_index); offset + 2, R_XXX_THUNKFIX, is->iat_index);
#endif #endif
is->thk_offset = offset; is->thk_offset = offset;
@ -1636,7 +1636,7 @@ quit:
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY #define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
#include "../win32/tools/tiny_impdef.c" #include "win32/tools/tiny_impdef.c"
static int pe_load_dll(TCCState *s1, const char *dllname, int fd) static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
{ {
@ -1841,13 +1841,13 @@ ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
pe.subsystem = s1->pe_subsystem; pe.subsystem = s1->pe_subsystem;
/* set default file/section alignment */ /* set default file/section alignment */
if (pe.subsystem == 1) { if (pe.subsystem == 1) {
pe.section_align = 0x20; pe.section_align = 0x20;
pe.file_align = 0x20; pe.file_align = 0x20;
} else { } else {
pe.section_align = 0x1000; pe.section_align = 0x1000;
pe.file_align = 0x200; pe.file_align = 0x200;
} }
if (s1->section_align != 0) if (s1->section_align != 0)
pe.section_align = s1->section_align; pe.section_align = s1->section_align;

View File

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -50,7 +50,7 @@ static unsigned char isidnum_table[256 - CH_EOF];
static TokenString *macro_stack; static TokenString *macro_stack;
static const char tcc_keywords[] = static const char tcc_keywords[] =
#define DEF(id, str) str "\0" #define DEF(id, str) str "\0"
#include "tcctok.h" #include "tcctok.h"
#undef DEF #undef DEF
@ -221,7 +221,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
TokenSym *ts, **ptable; TokenSym *ts, **ptable;
int i; int i;
if (tok_ident >= SYM_FIRST_ANOM) if (tok_ident >= SYM_FIRST_ANOM)
tcc_error("memory full (symbols)"); tcc_error("memory full (symbols)");
/* expand token table if needed */ /* expand token table if needed */
@ -255,7 +255,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len)
TokenSym *ts, **pts; TokenSym *ts, **pts;
int i; int i;
unsigned int h; unsigned int h;
h = TOK_HASH_INIT; h = TOK_HASH_INIT;
for(i=0;i<len;i++) for(i=0;i<len;i++)
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]); h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
@ -511,7 +511,7 @@ static int handle_stray1(uint8_t *p)
ST_FUNC void minp(void) ST_FUNC void minp(void)
{ {
inp(); inp();
if (ch == '\\') if (ch == '\\')
handle_stray(); handle_stray();
} }
@ -557,7 +557,7 @@ static uint8_t *parse_line_comment(uint8_t *p)
ST_FUNC uint8_t *parse_comment(uint8_t *p) ST_FUNC uint8_t *parse_comment(uint8_t *p)
{ {
int c; int c;
p++; p++;
for(;;) { for(;;) {
/* fast skip loop */ /* fast skip loop */
@ -635,13 +635,13 @@ static inline void skip_spaces(void)
cinp(); cinp();
} }
static inline int check_space(int t, int *spc) static inline int check_space(int t, int *spc)
{ {
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) { if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
if (*spc) if (*spc)
return 1; return 1;
*spc = 1; *spc = 1;
} else } else
*spc = 0; *spc = 0;
return 0; return 0;
} }
@ -774,7 +774,7 @@ redo_start:
file->buf_ptr = p; file->buf_ptr = p;
next_nomacro(); next_nomacro();
p = file->buf_ptr; p = file->buf_ptr;
if (a == 0 && if (a == 0 &&
(tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF)) (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
goto the_end; goto the_end;
if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF) if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
@ -786,7 +786,7 @@ redo_start:
else if (tok == TOK_LINEFEED) else if (tok == TOK_LINEFEED)
goto redo_start; goto redo_start;
} else if (parse_flags & PARSE_FLAG_ASM_FILE) } else if (parse_flags & PARSE_FLAG_ASM_FILE)
p = parse_line_comment(p); p = parse_line_comment(p);
break; break;
_default: _default:
default: default:
@ -930,7 +930,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
cstr->size = cv->cstr->size; cstr->size = cv->cstr->size;
cstr->data_allocated = NULL; cstr->data_allocated = NULL;
cstr->size_allocated = cstr->size; cstr->size_allocated = cstr->size;
memcpy((char *)cstr + sizeof(CString), memcpy((char *)cstr + sizeof(CString),
cv->cstr->data, cstr->size); cv->cstr->data, cstr->size);
len += nb_words; len += nb_words;
} }
@ -1253,14 +1253,14 @@ static int expr_preprocess(void)
{ {
int c, t; int c, t;
TokenString str; TokenString str;
tok_str_new(&str); tok_str_new(&str);
while (tok != TOK_LINEFEED && tok != TOK_EOF) { while (tok != TOK_LINEFEED && tok != TOK_EOF) {
next(); /* do macro subst */ next(); /* do macro subst */
if (tok == TOK_DEFINED) { if (tok == TOK_DEFINED) {
next_nomacro(); next_nomacro();
t = tok; t = tok;
if (t == '(') if (t == '(')
next_nomacro(); next_nomacro();
c = define_find(tok) != 0; c = define_find(tok) != 0;
if (t == '(') if (t == '(')
@ -1786,7 +1786,7 @@ _line_num:
total_lines += file->line_num - n; total_lines += file->line_num - n;
file->line_num = n; file->line_num = n;
if (s1->do_debug) if (s1->do_debug)
put_stabs(file->filename, N_BINCL, 0, 0, 0); put_stabs(file->filename, N_BINCL, 0, 0, 0);
break; break;
case TOK_ERROR: case TOK_ERROR:
case TOK_WARNING: case TOK_WARNING:
@ -1914,7 +1914,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
break; break;
case '\'': case '\'':
case '\"': case '\"':
case '\\': case '\\':
case '?': case '?':
break; break;
default: default:
@ -2070,7 +2070,7 @@ static void parse_number(const char *p)
*q = '\0'; *q = '\0';
if (b == 16) if (b == 16)
shift = 4; shift = 4;
else else
shift = 1; shift = 1;
bn_zero(bn); bn_zero(bn);
q = token_buf; q = token_buf;
@ -2126,7 +2126,7 @@ static void parse_number(const char *p)
ch = *p++; ch = *p++;
} }
exp_val = exp_val * s; exp_val = exp_val * s;
/* now we can generate the number */ /* now we can generate the number */
/* XXX: should patch directly float number */ /* XXX: should patch directly float number */
d = (double)bn[1] * 4294967296.0 + (double)bn[0]; d = (double)bn[1] * 4294967296.0 + (double)bn[0];
@ -2272,7 +2272,7 @@ static void parse_number(const char *p)
if (n & 0xffffffff00000000LL || must_64bit) { if (n & 0xffffffff00000000LL || must_64bit) {
tok = TOK_CLLONG; tok = TOK_CLLONG;
n1 = n >> 32; n1 = n >> 32;
} else { } else {
tok = TOK_CINT; tok = TOK_CINT;
n1 = n; n1 = n;
} }
@ -2363,7 +2363,7 @@ static inline void next_nomacro1(void)
} else { } else {
tok_flags &= ~TOK_FLAG_EOF; tok_flags &= ~TOK_FLAG_EOF;
/* pop include file */ /* pop include file */
/* test if previous '#endif' was after a #ifdef at /* test if previous '#endif' was after a #ifdef at
start of file */ start of file */
if (tok_flags & TOK_FLAG_ENDIF) { if (tok_flags & TOK_FLAG_ENDIF) {
@ -2400,7 +2400,7 @@ maybe_newline:
case '#': case '#':
/* XXX: simplify */ /* XXX: simplify */
PEEKC(c, p); PEEKC(c, p);
if ((tok_flags & TOK_FLAG_BOL) && if ((tok_flags & TOK_FLAG_BOL) &&
(parse_flags & PARSE_FLAG_PREPROCESS)) { (parse_flags & PARSE_FLAG_PREPROCESS)) {
file->buf_ptr = p; file->buf_ptr = p;
preprocess(tok_flags & TOK_FLAG_BOF); preprocess(tok_flags & TOK_FLAG_BOF);
@ -2420,7 +2420,7 @@ maybe_newline:
} }
} }
break; break;
/* dollar is allowed to start identifiers when not parsing asm */ /* dollar is allowed to start identifiers when not parsing asm */
case '$': case '$':
if (!(isidnum_table[c - CH_EOF] & IS_ID) if (!(isidnum_table[c - CH_EOF] & IS_ID)
@ -2433,14 +2433,14 @@ maybe_newline:
case 'm': case 'n': case 'o': case 'p': case 'm': case 'n': case 'o': case 'p':
case 'q': case 'r': case 's': case 't': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'A': case 'B': case 'C': case 'D':
case 'E': case 'F': case 'G': case 'H': case 'E': case 'F': case 'G': case 'H':
case 'I': case 'J': case 'K': case 'I': case 'J': case 'K':
case 'M': case 'N': case 'O': case 'P': case 'M': case 'N': case 'O': case 'P':
case 'Q': case 'R': case 'S': case 'T': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z': case 'Y': case 'Z':
case '_': case '_':
parse_ident_fast: parse_ident_fast:
p1 = p; p1 = p;
@ -2538,7 +2538,7 @@ maybe_newline:
} else if (c == '.') { } else if (c == '.') {
PEEKC(c, p); PEEKC(c, p);
if (c != '.') if (c != '.')
expect("'.'"); expect("'.'");
PEEKC(c, p); PEEKC(c, p);
tok = TOK_DOTS; tok = TOK_DOTS;
} else { } else {
@ -2594,7 +2594,7 @@ maybe_newline:
tok = TOK_GT; tok = TOK_GT;
} }
break; break;
case '&': case '&':
PEEKC(c, p); PEEKC(c, p);
if (c == '&') { if (c == '&') {
@ -2607,7 +2607,7 @@ maybe_newline:
tok = '&'; tok = '&';
} }
break; break;
case '|': case '|':
PEEKC(c, p); PEEKC(c, p);
if (c == '|') { if (c == '|') {
@ -2633,7 +2633,7 @@ maybe_newline:
tok = '+'; tok = '+';
} }
break; break;
case '-': case '-':
PEEKC(c, p); PEEKC(c, p);
if (c == '-') { if (c == '-') {
@ -2655,7 +2655,7 @@ maybe_newline:
PARSE2('*', '*', '=', TOK_A_MUL) PARSE2('*', '*', '=', TOK_A_MUL)
PARSE2('%', '%', '=', TOK_A_MOD) PARSE2('%', '%', '=', TOK_A_MOD)
PARSE2('^', '^', '=', TOK_A_XOR) PARSE2('^', '^', '=', TOK_A_XOR)
/* comments or operator */ /* comments or operator */
case '/': case '/':
PEEKC(c, p); PEEKC(c, p);
@ -2675,7 +2675,7 @@ maybe_newline:
tok = '/'; tok = '/';
} }
break; break;
/* simple tokens */ /* simple tokens */
case '(': case '(':
case ')': case ')':
@ -2730,7 +2730,7 @@ ST_FUNC void next_nomacro(void)
next_nomacro_spc(); next_nomacro_spc();
} while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC)); } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
} }
static void macro_subst( static void macro_subst(
TokenString *tok_str, TokenString *tok_str,
@ -2924,7 +2924,7 @@ static int macro_subst_tok(
CValue cval; CValue cval;
CString cstr; CString cstr;
char buf[32]; char buf[32];
/* if symbol is a macro, prepare substitution */ /* if symbol is a macro, prepare substitution */
/* special macros */ /* special macros */
if (tok == TOK___LINE__) { if (tok == TOK___LINE__) {
@ -2942,10 +2942,10 @@ static int macro_subst_tok(
time(&ti); time(&ti);
tm = localtime(&ti); tm = localtime(&ti);
if (tok == TOK___DATE__) { if (tok == TOK___DATE__) {
snprintf(buf, sizeof(buf), "%s %2d %d", snprintf(buf, sizeof(buf), "%s %2d %d",
ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900); ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
} else { } else {
snprintf(buf, sizeof(buf), "%02d:%02d:%02d", snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_hour, tm->tm_min, tm->tm_sec);
} }
cstrval = buf; cstrval = buf;
@ -3010,8 +3010,8 @@ static int macro_subst_tok(
tok_str_new(&str); tok_str_new(&str);
parlevel = spc = 0; parlevel = spc = 0;
/* NOTE: non zero sa->t indicates VA_ARGS */ /* NOTE: non zero sa->t indicates VA_ARGS */
while ((parlevel > 0 || while ((parlevel > 0 ||
(tok != ')' && (tok != ')' &&
(tok != ',' || sa->type.t)))) { (tok != ',' || sa->type.t)))) {
if (tok == TOK_EOF || tok == 0) if (tok == TOK_EOF || tok == 0)
break; break;
@ -3143,7 +3143,7 @@ static inline int *macro_twosharps(const int *ptr0)
/* given 'a##b', remove nosubsts preceding 'b' */ /* given 'a##b', remove nosubsts preceding 'b' */
while ((t1 = *++ptr) == TOK_NOSUBST) while ((t1 = *++ptr) == TOK_NOSUBST)
; ;
if (t1 && t1 != TOK_TWOSHARPS if (t1 && t1 != TOK_TWOSHARPS
&& t1 != ':') /* 'a##:' don't build a new token */ && t1 != ':') /* 'a##:' don't build a new token */
{ {
TOK_GET(&t1, &ptr, &cv1); TOK_GET(&t1, &ptr, &cv1);
@ -3181,7 +3181,7 @@ static void macro_subst(
int t, spc, nosubst; int t, spc, nosubst;
CValue cval; CValue cval;
int *macro_str1 = NULL; int *macro_str1 = NULL;
/* first scan for '##' operator handling */ /* first scan for '##' operator handling */
ptr = macro_str; ptr = macro_str;
spc = nosubst = 0; spc = nosubst = 0;
@ -3334,7 +3334,7 @@ ST_FUNC void preprocess_new(void)
: 0; : 0;
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
tok_ident = TOK_IDENT; tok_ident = TOK_IDENT;
p = tcc_keywords; p = tcc_keywords;
while (*p) { while (*p) {

View File

@ -127,7 +127,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
for (i=0; i<argc; ++i) for (i=0; i<argc; ++i)
bound_new_region(argv[i], strlen(argv[i])); bound_new_region(argv[i], strlen(argv[i]));
errno = 0; /* clean errno value */ errno = 0; /* clean errno value */
ret = (*prog_main)(argc, argv); ret = (*prog_main)(argc, argv);
/* unmark argv area */ /* unmark argv area */
@ -139,7 +139,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
} else } else
#endif #endif
{ {
errno = 0; /* clean errno value */ errno = 0; /* clean errno value */
ret = (*prog_main)(argc, argv); ret = (*prog_main)(argc, argv);
} }
return ret; return ret;
@ -652,7 +652,7 @@ static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
if (rt_bound_error_msg && *rt_bound_error_msg) if (rt_bound_error_msg && *rt_bound_error_msg)
rt_error(uc, *rt_bound_error_msg); rt_error(uc, *rt_bound_error_msg);
else else
rt_error(uc, "access violation"); rt_error(uc, "access violation");
break; break;
case EXCEPTION_STACK_OVERFLOW: case EXCEPTION_STACK_OVERFLOW:
rt_error(uc, "stack overflow"); rt_error(uc, "stack overflow");
@ -697,12 +697,12 @@ static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
fp = uc->Ebp; fp = uc->Ebp;
#endif #endif
if (level > 0) { if (level > 0) {
for(i = 1; i < level; i++) { for(i=1;i<level;i++) {
/* XXX: check address validity with program info */ /* XXX: check address validity with program info */
if (fp <= 0x1000 || fp >= 0xc0000000) if (fp <= 0x1000 || fp >= 0xc0000000)
return -1; return -1;
fp = ((addr_t*)fp)[0]; fp = ((addr_t*)fp)[0];
} }
pc = ((addr_t*)fp)[1]; pc = ((addr_t*)fp)[1];
} }
*paddr = pc; *paddr = pc;

View File

@ -36,7 +36,7 @@
DEF(TOK_RESTRICT2, "__restrict") DEF(TOK_RESTRICT2, "__restrict")
DEF(TOK_RESTRICT3, "__restrict__") DEF(TOK_RESTRICT3, "__restrict__")
DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */ DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
DEF(TOK_FLOAT, "float") DEF(TOK_FLOAT, "float")
DEF(TOK_DOUBLE, "double") DEF(TOK_DOUBLE, "double")
DEF(TOK_BOOL, "_Bool") DEF(TOK_BOOL, "_Bool")
@ -331,5 +331,5 @@
#endif #endif
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
#include "x86/i386-tok.h" #include "i386-tok.h"
#endif #endif

View File

@ -2,7 +2,7 @@
# Tiny C Compiler Makefile - tests # Tiny C Compiler Makefile - tests
# #
TOP = ../src TOP = ..
include $(TOP)/Makefile include $(TOP)/Makefile
SRCDIR = $(top_srcdir)/tests SRCDIR = $(top_srcdir)/tests
VPATH = $(SRCDIR) $(top_srcdir) VPATH = $(SRCDIR) $(top_srcdir)
@ -60,11 +60,11 @@ ifeq ($(TARGETOS),Darwin)
endif endif
# run local version of tcc with local libraries and includes # run local version of tcc with local libraries and includes
TCCFLAGS = -B$(TOP)/../lib -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/../include -L$(TOP) TCCFLAGS = -B$(TOP) -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include -L$(TOP)
ifdef CONFIG_WIN32 ifdef CONFIG_WIN32
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir) -I$(top_srcdir)/../include -L$(TOP) TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir) -I$(top_srcdir)/include -L$(TOP)
endif endif
XTCCFLAGS = -B$(TOP)/../lib -B$(top_srcdir)/win32 -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/../include XTCCFLAGS = -B$(TOP) -B$(top_srcdir)/win32 -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include
TCC = $(TOP)/tcc $(TCCFLAGS) TCC = $(TOP)/tcc $(TCCFLAGS)
RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(top_srcdir)/tcc.c $(TCCFLAGS) RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(top_srcdir)/tcc.c $(TCCFLAGS)
@ -73,7 +73,7 @@ DISAS = objdump -d
# libtcc test # libtcc test
ifdef LIBTCC1 ifdef LIBTCC1
LIBTCC1:=$(TOP)/lib/$(LIBTCC1) LIBTCC1:=$(TOP)/$(LIBTCC1)
endif endif
all test : $(TESTS) all test : $(TESTS)

View File

@ -41,7 +41,7 @@ static int run_callback(const char *src, callback_type callback) {
TCCState *s; TCCState *s;
int result; int result;
void *ptr; void *ptr;
s = tcc_new(); s = tcc_new();
if (!s) if (!s)
return -1; return -1;
@ -54,14 +54,14 @@ static int run_callback(const char *src, callback_type callback) {
return -1; return -1;
if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1) if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
return -1; return -1;
ptr = tcc_get_symbol(s, "f"); ptr = tcc_get_symbol(s, "f");
if (!ptr) if (!ptr)
return -1; return -1;
result = callback(ptr); result = callback(ptr);
tcc_delete(s); tcc_delete(s);
return result; return result;
} }
@ -89,7 +89,7 @@ RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
/* /*
* ret_2float_test: * ret_2float_test:
* *
* On x86-64, a struct with 2 floats should be packed into a single * On x86-64, a struct with 2 floats should be packed into a single
* SSE register (VT_DOUBLE is used for this purpose). * SSE register (VT_DOUBLE is used for this purpose).
*/ */
@ -117,7 +117,7 @@ static int ret_2float_test(void) {
/* /*
* ret_2double_test: * ret_2double_test:
* *
* On x86-64, a struct with 2 doubles should be passed in two SSE * On x86-64, a struct with 2 doubles should be passed in two SSE
* registers. * registers.
*/ */
@ -281,7 +281,7 @@ static int reg_pack_test(void) {
" reg_pack_test_type r = {a.x*5, a.y*3};\n" " reg_pack_test_type r = {a.x*5, a.y*3};\n"
" return r;\n" " return r;\n"
"}\n"; "}\n";
return run_callback(src, reg_pack_test_callback); return run_callback(src, reg_pack_test_callback);
} }
@ -307,7 +307,7 @@ static int reg_pack_longlong_test(void) {
" reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n" " reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
" return r;\n" " return r;\n"
"}\n"; "}\n";
return run_callback(src, reg_pack_longlong_test_callback); return run_callback(src, reg_pack_longlong_test_callback);
} }
@ -365,13 +365,13 @@ static int sret_test(void) {
" sret_test_type r = {x.a*35, x.b*19, x.c*21};\n" " sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
" return r;\n" " return r;\n"
"}\n"; "}\n";
return run_callback(src, sret_test_callback); return run_callback(src, sret_test_callback);
} }
/* /*
* one_member_union_test: * one_member_union_test:
* *
* In the x86-64 ABI a union should always be passed on the stack. However * In the x86-64 ABI a union should always be passed on the stack. However
* it appears that a single member union is treated by GCC as its member. * it appears that a single member union is treated by GCC as its member.
*/ */
@ -399,7 +399,7 @@ static int one_member_union_test(void) {
/* /*
* two_member_union_test: * two_member_union_test:
* *
* In the x86-64 ABI a union should always be passed on the stack. * In the x86-64 ABI a union should always be passed on the stack.
*/ */
typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type; typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
@ -430,7 +430,7 @@ static int two_member_union_test(void) {
typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type; typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type); typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
static int many_struct_test_callback(void *ptr) { static int many_struct_test_callback(void *ptr) {
many_struct_test_function_type f = (many_struct_test_function_type)ptr; many_struct_test_function_type f = (many_struct_test_function_type)ptr;
many_struct_test_type v = {1, 2, 3}; many_struct_test_type v = {1, 2, 3};
@ -457,7 +457,7 @@ static int many_struct_test(void) {
typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type; typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type); typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
static int many_struct_test_2_callback(void *ptr) { static int many_struct_test_2_callback(void *ptr) {
many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr; many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
many_struct_test_2_type v = {1,2}; many_struct_test_2_type v = {1,2};
@ -598,7 +598,7 @@ static int arg_align_test_callback(void *ptr) {
} }
static int arg_align_test(void) { static int arg_align_test(void) {
const char *src = const char *src =
"long double f(long double a, int b, long double c, int d, long double e) {\n" "long double f(long double a, int b, long double c, int d, long double e) {\n"
" return a + c + e;\n" " return a + c + e;\n"
"}\n"; "}\n";
@ -621,7 +621,7 @@ int main(int argc, char **argv) {
int i; int i;
const char *testname = NULL; const char *testname = NULL;
int retval = EXIT_SUCCESS; int retval = EXIT_SUCCESS;
/* if tcclib.h and libtcc1.a are not installed, where can we find them */ /* if tcclib.h and libtcc1.a are not installed, where can we find them */
for (i = 1; i < argc; ++i) { for (i = 1; i < argc; ++i) {
if (!memcmp(argv[i], "run_test=", 9)) if (!memcmp(argv[i], "run_test=", 9))

View File

@ -2,7 +2,7 @@
# credits: 01..13.c from the pcc cpp-tests suite # credits: 01..13.c from the pcc cpp-tests suite
# #
TCC = ../../src/tcc TCC = ../../tcc
TESTS = $(patsubst %.c,%.test,$(wildcard *.c)) TESTS = $(patsubst %.c,%.test,$(wildcard *.c))
all test : $(TESTS) all test : $(TESTS)

View File

@ -320,7 +320,7 @@ void macro_test(void)
#line 200 #line 200
printf("__LINE__=%d __FILE__=%s\n", printf("__LINE__=%d __FILE__=%s\n",
__LINE__, __FILE__); __LINE__, __FILE__);
#line 203 "test" #line 203 "test"
printf("__LINE__=%d __FILE__=%s\n", printf("__LINE__=%d __FILE__=%s\n",
__LINE__, __FILE__); __LINE__, __FILE__);
#line 227 "tcctest.c" #line 227 "tcctest.c"
@ -348,7 +348,7 @@ void macro_test(void)
glue(a <, <= 2); glue(a <, <= 2);
printf("a=%d\n", a); printf("a=%d\n", a);
} }
/* macro function with argument outside the macro string */ /* macro function with argument outside the macro string */
#define MF_s MF_hello #define MF_s MF_hello
#define MF_hello(msg) printf("%s\n",msg) #define MF_hello(msg) printf("%s\n",msg)
@ -357,7 +357,7 @@ void macro_test(void)
MF_s("hi"); MF_s("hi");
MF_t("hi"); MF_t("hi");
/* test macro substituion inside args (should not eat stream) */ /* test macro substituion inside args (should not eat stream) */
printf("qq=%d\n", qq(qq)(2)); printf("qq=%d\n", qq(qq)(2));
@ -398,7 +398,7 @@ void recursive_macro_test(void)
printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123))); printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
#define WRAP(x) x #define WRAP(x) x
#define print_num(x) print_num(__FILE__,__LINE__,x) #define print_num(x) print_num(__FILE__,__LINE__,x)
print_num(123); print_num(123);
WRAP(print_num(123)); WRAP(print_num(123));
@ -537,7 +537,7 @@ void goto_test()
/* This needs to parse as label, not as start of decl. */ /* This needs to parse as label, not as start of decl. */
typedef_and_label: typedef_and_label:
s_loop: s_loop:
if (i >= 10) if (i >= 10)
goto s_end; goto s_end;
printf("%d", i); printf("%d", i);
i++; i++;
@ -688,7 +688,7 @@ int main(int argc, char **argv)
callsave_test(); callsave_test();
builtin_frame_address_test(); builtin_frame_address_test();
intdiv_test(); intdiv_test();
return 0; return 0;
} }
int tab[3]; int tab[3];
@ -797,10 +797,10 @@ void expr_test()
printf("%d\n", ~12); printf("%d\n", ~12);
printf("%d\n", -12); printf("%d\n", -12);
printf("%d\n", +12); printf("%d\n", +12);
printf("%d %d %d %d\n", printf("%d %d %d %d\n",
isid('a'), isid('a'),
isid('g'), isid('g'),
isid('T'), isid('T'),
isid('(')); isid('('));
} }
@ -984,7 +984,7 @@ void struct_test()
sizeof(struct aligntest3), __alignof__(struct aligntest3)); sizeof(struct aligntest3), __alignof__(struct aligntest3));
printf("aligntest4 sizeof=%d alignof=%d\n", printf("aligntest4 sizeof=%d alignof=%d\n",
sizeof(struct aligntest4), __alignof__(struct aligntest4)); sizeof(struct aligntest4), __alignof__(struct aligntest4));
/* empty structures (GCC extension) */ /* empty structures (GCC extension) */
printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
@ -999,17 +999,17 @@ void char_short_test()
var1 = 0x01020304; var1 = 0x01020304;
var2 = 0xfffefdfc; var2 = 0xfffefdfc;
printf("s8=%d %d\n", printf("s8=%d %d\n",
*(char *)&var1, *(char *)&var2); *(char *)&var1, *(char *)&var2);
printf("u8=%d %d\n", printf("u8=%d %d\n",
*(unsigned char *)&var1, *(unsigned char *)&var2); *(unsigned char *)&var1, *(unsigned char *)&var2);
printf("s16=%d %d\n", printf("s16=%d %d\n",
*(short *)&var1, *(short *)&var2); *(short *)&var1, *(short *)&var2);
printf("u16=%d %d\n", printf("u16=%d %d\n",
*(unsigned short *)&var1, *(unsigned short *)&var2); *(unsigned short *)&var1, *(unsigned short *)&var2);
printf("s32=%d %d\n", printf("s32=%d %d\n",
*(int *)&var1, *(int *)&var2); *(int *)&var1, *(int *)&var2);
printf("u32=%d %d\n", printf("u32=%d %d\n",
*(unsigned int *)&var1, *(unsigned int *)&var2); *(unsigned int *)&var1, *(unsigned int *)&var2);
*(char *)&var1 = 0x08; *(char *)&var1 = 0x08;
printf("var1=%x\n", var1); printf("var1=%x\n", var1);
@ -1099,7 +1099,7 @@ void bool_test()
static int v1 = 34 ? : -1; /* constant case */ static int v1 = 34 ? : -1; /* constant case */
static int v2 = 0 ? : -1; /* constant case */ static int v2 = 0 ? : -1; /* constant case */
int a = 30; int a = 30;
printf("%d %d\n", v1, v2); printf("%d %d\n", v1, v2);
printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2); printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
} }
@ -1116,8 +1116,8 @@ static int tab_reinit[];
static int tab_reinit[10]; static int tab_reinit[10];
//int cinit1; /* a global variable can be defined several times without error ! */ //int cinit1; /* a global variable can be defined several times without error ! */
int cinit1; int cinit1;
int cinit1; int cinit1;
int cinit1 = 0; int cinit1 = 0;
int *cinit2 = (int []){3, 2, 1}; int *cinit2 = (int []){3, 2, 1};
@ -1157,7 +1157,7 @@ void compound_literal_test(void)
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
p = (int []){1, 2, 4 + i}; p = (int []){1, 2, 4 + i};
printf("%d %d %d\n", printf("%d %d %d\n",
p[0], p[0],
p[1], p[1],
p[2]); p[2]);
@ -1188,7 +1188,7 @@ kr_test()
void num(int n) void num(int n)
{ {
char *tab, *p; char *tab, *p;
tab = (char*)malloc(20); tab = (char*)malloc(20);
p = tab; p = tab;
while (1) { while (1) {
*p = 48 + (n % 10); *p = 48 + (n % 10);
@ -1231,7 +1231,7 @@ void struct_assign_test(void)
struct structa1 lsta1, lsta2; struct structa1 lsta1, lsta2;
int i; int i;
} s, *ps; } s, *ps;
ps = &s; ps = &s;
ps->i = 4; ps->i = 4;
#if 0 #if 0
@ -1247,7 +1247,7 @@ void struct_assign_test(void)
s.lsta2.f2 = 2; s.lsta2.f2 = 2;
#endif #endif
struct_assign_test1(ps->lsta2, 3, 4.5); struct_assign_test1(ps->lsta2, 3, 4.5);
printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2); printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i); ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2); printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
@ -1300,9 +1300,9 @@ void cast_test()
printf("%d\n", a); printf("%d\n", a);
a = (scast = 65536) + 1; a = (scast = 65536) + 1;
printf("%d\n", a); printf("%d\n", a);
printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c)); printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
/* test cast from unsigned to signed short to int */ /* test cast from unsigned to signed short to int */
b = 0xf000; b = 0xf000;
d = (short)b; d = (short)b;
@ -1310,7 +1310,7 @@ void cast_test()
b = 0xf0f0; b = 0xf0f0;
d = (char)b; d = (char)b;
printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d); printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
/* test implicit int casting for array accesses */ /* test implicit int casting for array accesses */
c = 0; c = 0;
tab[1] = 2; tab[1] = 2;
@ -1352,7 +1352,7 @@ char sinit8[] = "hello" "trala";
struct structinit1 sinit9 = { 1, 2, 3 }; struct structinit1 sinit9 = { 1, 2, 3 };
struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 }; struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
#ifdef ALL_ISOC99 #ifdef ALL_ISOC99
.farray[0] = 10, .farray[0] = 10,
.farray[1] = 11, .farray[1] = 11,
@ -1437,36 +1437,36 @@ void init_test(void)
int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, }; int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
int linit17 = sizeof(linit17); int linit17 = sizeof(linit17);
printf("init_test:\n"); printf("init_test:\n");
printf("sinit1=%d\n", sinit1); printf("sinit1=%d\n", sinit1);
printf("sinit2=%d\n", sinit2); printf("sinit2=%d\n", sinit2);
printf("sinit3=%d %d %d %d\n", printf("sinit3=%d %d %d %d\n",
sizeof(sinit3), sizeof(sinit3),
sinit3[0], sinit3[0],
sinit3[1], sinit3[1],
sinit3[2] sinit3[2]
); );
printf("sinit6=%d\n", sizeof(sinit6)); printf("sinit6=%d\n", sizeof(sinit6));
printf("sinit7=%d %d %d %d\n", printf("sinit7=%d %d %d %d\n",
sizeof(sinit7), sizeof(sinit7),
sinit7[0], sinit7[0],
sinit7[1], sinit7[1],
sinit7[2] sinit7[2]
); );
printf("sinit8=%s\n", sinit8); printf("sinit8=%s\n", sinit8);
printf("sinit9=%d %d %d\n", printf("sinit9=%d %d %d\n",
sinit9.f1, sinit9.f1,
sinit9.f2, sinit9.f2,
sinit9.f3 sinit9.f3
); );
printf("sinit10=%d %d %d\n", printf("sinit10=%d %d %d\n",
sinit10.f1, sinit10.f1,
sinit10.f2, sinit10.f2,
sinit10.f3 sinit10.f3
); );
printf("sinit11=%d %d %d %d %d %d\n", printf("sinit11=%d %d %d %d %d %d\n",
sinit11.f1, sinit11.f1,
sinit11.f2, sinit11.f2,
sinit11.f3, sinit11.f3,
@ -1477,7 +1477,7 @@ void init_test(void)
for(i=0;i<3;i++) for(i=0;i<3;i++)
for(j=0;j<2;j++) for(j=0;j<2;j++)
printf("[%d][%d] = %d %d %d\n", printf("[%d][%d] = %d %d %d\n",
i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]); i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
printf("linit1=%d\n", linit1); printf("linit1=%d\n", linit1);
printf("linit2=%d\n", linit2); printf("linit2=%d\n", linit2);
@ -1486,7 +1486,7 @@ void init_test(void)
printf("sinit12=%s\n", sinit12); printf("sinit12=%s\n", sinit12);
printf("sinit13=%d %s %s %s\n", printf("sinit13=%d %s %s %s\n",
sizeof(sinit13), sizeof(sinit13),
sinit13[0], sinit13[0],
sinit13[1], sinit13[1],
sinit13[2]); sinit13[2]);
@ -1500,7 +1500,7 @@ void init_test(void)
printf("\n"); printf("\n");
for(i=0;i<10;i++) printf(" %d", linit15[i]); for(i=0;i<10;i++) printf(" %d", linit15[i]);
printf("\n"); printf("\n");
printf("%d %d %d %d\n", printf("%d %d %d %d\n",
linit16.a1, linit16.a1,
linit16.a2, linit16.a2,
linit16.a3, linit16.a3,
@ -1599,13 +1599,13 @@ void bitfield_test(void)
printf("%d %d\n", sa, ca); printf("%d %d\n", sa, ca);
st1.f1 = 7; st1.f1 = 7;
if (st1.f1 == -1) if (st1.f1 == -1)
printf("st1.f1 == -1\n"); printf("st1.f1 == -1\n");
else else
printf("st1.f1 != -1\n"); printf("st1.f1 != -1\n");
if (st1.f2 == -1) if (st1.f2 == -1)
printf("st1.f2 == -1\n"); printf("st1.f2 == -1\n");
else else
printf("st1.f2 != -1\n"); printf("st1.f2 != -1\n");
/* bit sizes below must be bigger than 32 since GCC doesn't allow /* bit sizes below must be bigger than 32 since GCC doesn't allow
@ -1835,7 +1835,7 @@ void lloptest(long long a, long long b)
a + b, a + b,
a - b, a - b,
a * b); a * b);
if (b != 0) { if (b != 0) {
printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
a / b, a / b,
@ -1856,7 +1856,7 @@ void lloptest(long long a, long long b)
a > b, a > b,
a >= b, a >= b,
a <= b); a <= b);
printf("utest: %d %d %d %d %d %d\n", printf("utest: %d %d %d %d %d %d\n",
ua == ub, ua == ub,
ua != ub, ua != ub,
@ -1932,7 +1932,7 @@ long long llfunc1(int a)
} }
struct S { struct S {
int id; int id;
char item; char item;
}; };
@ -1953,8 +1953,8 @@ void longlong_test(void)
a = ia; a = ia;
b = ua; b = ua;
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
(long long)1, (long long)1,
(long long)-2, (long long)-2,
1LL, 1LL,
0x1234567812345679); 0x1234567812345679);
@ -2049,7 +2049,7 @@ void vprintf1(const char *fmt, ...)
va_start(aq, fmt); va_start(aq, fmt);
va_copy(ap, aq); va_copy(ap, aq);
p = fmt; p = fmt;
for(;;) { for(;;) {
c = *p; c = *p;
@ -2250,10 +2250,10 @@ void c99_vla_test(int size1, int size2)
int tab1[size][2], tab2[10][2]; int tab1[size][2], tab2[10][2];
void *tab1_ptr, *tab2_ptr, *bad_ptr; void *tab1_ptr, *tab2_ptr, *bad_ptr;
/* "size" should have been 'captured' at tab1 declaration, /* "size" should have been 'captured' at tab1 declaration,
so modifying it should have no effect on VLA behaviour. */ so modifying it should have no effect on VLA behaviour. */
size = size-1; size = size-1;
printf("Test C99 VLA 1 (sizeof): "); printf("Test C99 VLA 1 (sizeof): ");
printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED"); printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
tab1_ptr = tab1; tab1_ptr = tab1;
@ -2325,7 +2325,7 @@ void sizeof_test(void)
t <<= 16; t <<= 16;
t <<= 16; t <<= 16;
t++; t++;
/* This checks that sizeof really can be used to manipulate /* This checks that sizeof really can be used to manipulate
uintptr_t objects, without truncation. */ uintptr_t objects, without truncation. */
t2 = t & -sizeof(uintptr_t); t2 = t & -sizeof(uintptr_t);
printf ("%lu %lu\n", t, t2); printf ("%lu %lu\n", t, t2);
@ -2358,15 +2358,15 @@ void statement_expr_test(void)
a = 0; a = 0;
for(i=0;i<10;i++) { for(i=0;i<10;i++) {
a += 1 + a += 1 +
( { int b, j; ( { int b, j;
b = 0; b = 0;
for(j=0;j<5;j++) for(j=0;j<5;j++)
b += j; b; b += j; b;
} ); } );
} }
printf("a=%d\n", a); printf("a=%d\n", a);
} }
void local_label_test(void) void local_label_test(void)
@ -2589,7 +2589,7 @@ void builtin_test(void)
COMPAT_TYPE(char *, signed char *); COMPAT_TYPE(char *, signed char *);
COMPAT_TYPE(char *, char *); COMPAT_TYPE(char *, char *);
/* space is needed because tcc preprocessor introduces a space between each token */ /* space is needed because tcc preprocessor introduces a space between each token */
COMPAT_TYPE(char * *, void *); COMPAT_TYPE(char * *, void *);
#endif #endif
printf("res = %d\n", __builtin_constant_p(1)); printf("res = %d\n", __builtin_constant_p(1));
printf("res = %d\n", __builtin_constant_p(1 + 2)); printf("res = %d\n", __builtin_constant_p(1 + 2));
@ -2640,7 +2640,7 @@ void __attribute__((weak)) weak_test(void)
printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123); printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123); printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123); printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL); printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL); printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL); printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);

View File

@ -1,4 +1,4 @@
TOP = ../../src TOP = ../..
include $(TOP)/Makefile include $(TOP)/Makefile
# clear CFLAGS and LDFLAGS # clear CFLAGS and LDFLAGS
@ -6,9 +6,9 @@ CFLAGS :=
LDFLAGS := LDFLAGS :=
ifdef CONFIG_WIN32 ifdef CONFIG_WIN32
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir)/../include -L$(TOP) TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir)/include -L$(TOP)
else else
TCCFLAGS = -B$(TOP)/../lib -I$(top_srcdir)/../include -lm TCCFLAGS = -B$(TOP) -I$(top_srcdir)/include -lm
endif endif
ifeq ($(TARGETOS),Darwin) ifeq ($(TARGETOS),Darwin)

2
docs/texi2pod.pl → texi2pod.pl 100644 → 100755
View File

@ -229,7 +229,7 @@ while(<$inf>) {
$inf = gensym(); $inf = gensym();
# Try cwd and $ibase. # Try cwd and $ibase.
open($inf, "<" . $1) open($inf, "<" . $1)
or open($inf, "<" . $ibase . "/" . $1) or open($inf, "<" . $ibase . "/" . $1)
or die "cannot open $1 or $ibase/$1: $!\n"; or die "cannot open $1 or $ibase/$1: $!\n";
next; next;

View File

@ -21,7 +21,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../../src/elf.h" #include "../../elf.h"
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
# define ELFCLASSW ELFCLASS64 # define ELFCLASSW ELFCLASS64

View File

@ -136,7 +136,7 @@ enum {
/******************************************************/ /******************************************************/
#else /* ! TARGET_DEFS_ONLY */ #else /* ! TARGET_DEFS_ONLY */
/******************************************************/ /******************************************************/
#include "../tcc.h" #include "tcc.h"
#include <assert.h> #include <assert.h>
ST_DATA const int reg_classes[NB_REGS] = { ST_DATA const int reg_classes[NB_REGS] = {
@ -477,17 +477,18 @@ void load(int r, SValue *sv)
gen_modrm(r, VT_LOCAL, sv->sym, fc); gen_modrm(r, VT_LOCAL, sv->sym, fc);
} else if (v == VT_CMP) { } else if (v == VT_CMP) {
orex(0,r,0,0); orex(0,r,0,0);
if ((fc & ~0x100) != TOK_NE) if ((fc & ~0x100) != TOK_NE)
oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */ oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
else else
oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */ oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
if (fc & 0x100) { if (fc & 0x100)
/* This was a float compare. If the parity bit is {
* set the result was unordered, meaning false for everything /* This was a float compare. If the parity bit is
* except TOK_NE, and true for TOK_NE. */ set the result was unordered, meaning false for everything
fc &= ~0x100; except TOK_NE, and true for TOK_NE. */
o(0x037a + (REX_BASE(r) << 8)); fc &= ~0x100;
} o(0x037a + (REX_BASE(r) << 8));
}
orex(0,r,0, 0x0f); /* setxx %br */ orex(0,r,0, 0x0f); /* setxx %br */
o(fc); o(fc);
o(0xc0 + REG_VALUE(r)); o(0xc0 + REG_VALUE(r));
@ -618,7 +619,7 @@ static void gcall_or_jmp(int is_jmp)
{ {
int r; int r;
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) { ((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) {
/* constant case */ /* constant case */
if (vtop->r & VT_SYM) { if (vtop->r & VT_SYM) {
/* relocation case */ /* relocation case */
@ -680,7 +681,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
/* relocation offset of the bounding function call point */ /* relocation offset of the bounding function call point */
vtop->c.ull = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela))); vtop->c.ull = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
} }
/* patch pointer addition in vtop so that pointer dereferencing is /* patch pointer addition in vtop so that pointer dereferencing is
@ -822,7 +823,7 @@ void gfunc_call(int nb_args)
struct_size = args_size; struct_size = args_size;
for(i = 0; i < nb_args; i++) { for(i = 0; i < nb_args; i++) {
SValue *sv; SValue *sv;
--arg; --arg;
sv = &vtop[-i]; sv = &vtop[-i];
bt = (sv->type.t & VT_BTYPE); bt = (sv->type.t & VT_BTYPE);
@ -896,7 +897,7 @@ void gfunc_call(int nb_args)
vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
: size > 1 ? VT_SHORT : VT_BYTE; : size > 1 ? VT_SHORT : VT_BYTE;
} }
r = gv(RC_INT); r = gv(RC_INT);
if (arg >= REGN) { if (arg >= REGN) {
gen_offs_sp(0x89, r, arg*8); gen_offs_sp(0x89, r, arg*8);
@ -910,7 +911,7 @@ void gfunc_call(int nb_args)
vtop--; vtop--;
} }
save_regs(0); save_regs(0);
/* Copy R10 and R11 into RCX and RDX, respectively */ /* Copy R10 and R11 into RCX and RDX, respectively */
if (nb_args > 0) { if (nb_args > 0) {
o(0xd1894c); /* mov %r10, %rcx */ o(0xd1894c); /* mov %r10, %rcx */
@ -918,7 +919,7 @@ void gfunc_call(int nb_args)
o(0xda894c); /* mov %r11, %rdx */ o(0xda894c); /* mov %r11, %rdx */
} }
} }
gcall_or_jmp(0); gcall_or_jmp(0);
vtop--; vtop--;
} }
@ -1071,10 +1072,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
{ {
X86_64_Mode mode; X86_64_Mode mode;
Sym *f; Sym *f;
switch (ty->t & VT_BTYPE) { switch (ty->t & VT_BTYPE) {
case VT_VOID: return x86_64_mode_none; case VT_VOID: return x86_64_mode_none;
case VT_INT: case VT_INT:
case VT_BYTE: case VT_BYTE:
case VT_SHORT: case VT_SHORT:
@ -1083,12 +1084,12 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
case VT_PTR: case VT_PTR:
case VT_FUNC: case VT_FUNC:
case VT_ENUM: return x86_64_mode_integer; case VT_ENUM: return x86_64_mode_integer;
case VT_FLOAT: case VT_FLOAT:
case VT_DOUBLE: return x86_64_mode_sse; case VT_DOUBLE: return x86_64_mode_sse;
case VT_LDOUBLE: return x86_64_mode_x87; case VT_LDOUBLE: return x86_64_mode_x87;
case VT_STRUCT: case VT_STRUCT:
f = ty->ref; f = ty->ref;
@ -1097,10 +1098,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
if (f->c + offset >= start && f->c + offset < end) if (f->c + offset >= start && f->c + offset < end)
mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end)); mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end));
} }
return mode; return mode;
} }
assert(0); assert(0);
} }
@ -1304,7 +1305,7 @@ void gfunc_call(int nb_args)
args_size = 0; args_size = 0;
while (run_start != nb_args) { while (run_start != nb_args) {
int run_gen_reg = gen_reg, run_sse_reg = sse_reg; int run_gen_reg = gen_reg, run_sse_reg = sse_reg;
run_end = nb_args; run_end = nb_args;
stack_adjust = 0; stack_adjust = 0;
for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) { for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) {
@ -1318,10 +1319,10 @@ void gfunc_call(int nb_args)
stack_adjust += size; stack_adjust += size;
} }
} }
gen_reg = run_gen_reg; gen_reg = run_gen_reg;
sse_reg = run_sse_reg; sse_reg = run_sse_reg;
/* adjust stack to align SSE boundary */ /* adjust stack to align SSE boundary */
if (stack_adjust &= 15) { if (stack_adjust &= 15) {
/* fetch cpu flag before the following sub will change the value */ /* fetch cpu flag before the following sub will change the value */
@ -1333,7 +1334,7 @@ void gfunc_call(int nb_args)
oad(0xec81, stack_adjust); /* sub $xxx, %rsp */ oad(0xec81, stack_adjust); /* sub $xxx, %rsp */
args_size += stack_adjust; args_size += stack_adjust;
} }
for(i = run_start; i < run_end;) { for(i = run_start; i < run_end;) {
int arg_stored = regargs_nregs(&reg_args[i]) == 0; int arg_stored = regargs_nregs(&reg_args[i]) == 0;
SValue tmp; SValue tmp;
@ -1343,7 +1344,7 @@ void gfunc_call(int nb_args)
++i; ++i;
continue; continue;
} }
/* Swap argument to top, it will possibly be changed here, /* Swap argument to top, it will possibly be changed here,
and might use more temps. At the end of the loop we keep and might use more temps. At the end of the loop we keep
in on the stack and swap it back to its original position in on the stack and swap it back to its original position
@ -1351,7 +1352,7 @@ void gfunc_call(int nb_args)
tmp = vtop[0]; tmp = vtop[0];
vtop[0] = vtop[-i]; vtop[0] = vtop[-i];
vtop[-i] = tmp; vtop[-i] = tmp;
classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args); classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args);
switch (vtop->type.t & VT_BTYPE) { switch (vtop->type.t & VT_BTYPE) {
@ -1368,11 +1369,11 @@ void gfunc_call(int nb_args)
vstore(); vstore();
args_size += size; args_size += size;
break; break;
case VT_LDOUBLE: case VT_LDOUBLE:
assert(0); assert(0);
break; break;
case VT_FLOAT: case VT_FLOAT:
case VT_DOUBLE: case VT_DOUBLE:
r = gv(RC_FLOAT); r = gv(RC_FLOAT);
@ -1383,7 +1384,7 @@ void gfunc_call(int nb_args)
o(0x24); o(0x24);
args_size += size; args_size += size;
break; break;
default: default:
/* simple type */ /* simple type */
/* XXX: implicit cast ? */ /* XXX: implicit cast ? */
@ -1416,7 +1417,7 @@ void gfunc_call(int nb_args)
break; break;
vrotb(i+1); vrotb(i+1);
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
gv(RC_ST0); gv(RC_ST0);
oad(0xec8148, size); /* sub $xxx, %rsp */ oad(0xec8148, size); /* sub $xxx, %rsp */
@ -1439,7 +1440,7 @@ void gfunc_call(int nb_args)
vstore(); vstore();
args_size += size; args_size += size;
} }
vpop(); vpop();
memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args); memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args);
--nb_args; --nb_args;
@ -1697,14 +1698,14 @@ void gfunc_prolog(CType *func_type)
addr += size; addr += size;
} }
break; break;
case x86_64_mode_memory: case x86_64_mode_memory:
case x86_64_mode_x87: case x86_64_mode_x87:
addr = (addr + align - 1) & -align; addr = (addr + align - 1) & -align;
param_addr = addr; param_addr = addr;
addr += size; addr += size;
break; break;
default: break; /* nothing to be done for x86_64_mode_none */ default: break; /* nothing to be done for x86_64_mode_none */
} }
sym_push(sym->v & ~SYM_FIELD, type, sym_push(sym->v & ~SYM_FIELD, type,
VT_LOCAL | VT_LVAL, param_addr); VT_LOCAL | VT_LVAL, param_addr);
@ -1716,8 +1717,8 @@ void gfunc_prolog(CType *func_type)
func_bound_offset = lbounds_section->data_offset; func_bound_offset = lbounds_section->data_offset;
func_bound_ind = ind; func_bound_ind = ind;
oad(0xb8, 0); /* lbound section pointer */ oad(0xb8, 0); /* lbound section pointer */
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
oad(0xb8, 0); /* call to function */ oad(0xb8, 0); /* call to function */
} }
#endif #endif
} }
@ -1729,7 +1730,7 @@ void gfunc_epilog(void)
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
if (tcc_state->do_bounds_check if (tcc_state->do_bounds_check
&& func_bound_offset != lbounds_section->data_offset) && func_bound_offset != lbounds_section->data_offset)
{ {
addr_t saved_ind; addr_t saved_ind;
addr_t *bounds_ptr; addr_t *bounds_ptr;
@ -1753,7 +1754,7 @@ void gfunc_epilog(void)
o(0x5250); /* save returned value, if any */ o(0x5250); /* save returned value, if any */
greloc(cur_text_section, sym_data, ind + 1, R_386_32); greloc(cur_text_section, sym_data, ind + 1, R_386_32);
oad(0xb8, 0); /* mov xxx, %rax */ oad(0xb8, 0); /* mov xxx, %rax */
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
gen_static_call(TOK___bound_local_delete); gen_static_call(TOK___bound_local_delete);
o(0x585a); /* restore returned value, if any */ o(0x585a); /* restore returned value, if any */
} }
@ -1805,23 +1806,24 @@ int gtst(int inv, int t)
v = vtop->r & VT_VALMASK; v = vtop->r & VT_VALMASK;
if (v == VT_CMP) { if (v == VT_CMP) {
/* fast case : can jump directly since flags are set */ /* fast case : can jump directly since flags are set */
if (vtop->c.i & 0x100) if (vtop->c.i & 0x100)
{ {
/* This was a float compare. If the parity flag is set /* This was a float compare. If the parity flag is set
the result was unordered. For anything except != this the result was unordered. For anything except != this
means false and we don't jump (anding both conditions). means false and we don't jump (anding both conditions).
For != this means true (oring both). For != this means true (oring both).
Take care about inverting the test. We need to jump Take care about inverting the test. We need to jump
to our target if the result was unordered and test wasn't NE, to our target if the result was unordered and test wasn't NE,
otherwise if unordered we don't want to jump. */ otherwise if unordered we don't want to jump. */
vtop->c.i &= ~0x100; vtop->c.i &= ~0x100;
if (!inv == (vtop->c.i != TOK_NE)) if (!inv == (vtop->c.i != TOK_NE))
o(0x067a); /* jp +6 */ o(0x067a); /* jp +6 */
else { else
g(0x0f); {
t = psym(0x8a, t); /* jp t */ g(0x0f);
} t = psym(0x8a, t); /* jp t */
} }
}
g(0x0f); g(0x0f);
t = psym((vtop->c.i - 16) ^ inv, t); t = psym((vtop->c.i - 16) ^ inv, t);
} else if (v == VT_JMP || v == VT_JMPI) { } else if (v == VT_JMP || v == VT_JMPI) {
@ -2102,7 +2104,7 @@ void gen_opf(int op)
vswap(); vswap();
} }
assert(!(vtop[-1].r & VT_LVAL)); assert(!(vtop[-1].r & VT_LVAL));
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
o(0x66); o(0x66);
if (op == TOK_EQ || op == TOK_NE) if (op == TOK_EQ || op == TOK_NE)
@ -2139,7 +2141,7 @@ void gen_opf(int op)
ft = vtop->type.t; ft = vtop->type.t;
fc = vtop->c.ul; fc = vtop->c.ul;
assert((ft & VT_BTYPE) != VT_LDOUBLE); assert((ft & VT_BTYPE) != VT_LDOUBLE);
r = vtop->r; r = vtop->r;
/* if saved lvalue, then we must reload it */ /* if saved lvalue, then we must reload it */
if ((vtop->r & VT_VALMASK) == VT_LLOCAL) { if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
@ -2151,14 +2153,14 @@ void gen_opf(int op)
load(r, &v1); load(r, &v1);
fc = 0; fc = 0;
} }
assert(!(vtop[-1].r & VT_LVAL)); assert(!(vtop[-1].r & VT_LVAL));
if (swapped) { if (swapped) {
assert(vtop->r & VT_LVAL); assert(vtop->r & VT_LVAL);
gv(RC_FLOAT); gv(RC_FLOAT);
vswap(); vswap();
} }
if ((ft & VT_BTYPE) == VT_DOUBLE) { if ((ft & VT_BTYPE) == VT_DOUBLE) {
o(0xf2); o(0xf2);
} else { } else {
@ -2166,7 +2168,7 @@ void gen_opf(int op)
} }
o(0x0f); o(0x0f);
o(0x58 + a); o(0x58 + a);
if (vtop->r & VT_LVAL) { if (vtop->r & VT_LVAL) {
gen_modrm(vtop[-1].r, r, vtop->sym, fc); gen_modrm(vtop[-1].r, r, vtop->sym, fc);
} else { } else {
@ -2229,7 +2231,7 @@ void gen_cvt_ftof(int t)
ft = vtop->type.t; ft = vtop->type.t;
bt = ft & VT_BTYPE; bt = ft & VT_BTYPE;
tbt = t & VT_BTYPE; tbt = t & VT_BTYPE;
if (bt == VT_FLOAT) { if (bt == VT_FLOAT) {
gv(RC_FLOAT); gv(RC_FLOAT);
if (tbt == VT_DOUBLE) { if (tbt == VT_DOUBLE) {