Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/tcc-0.9.27
Files:
250 added
1 deleted
57 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/tcc-0.9.27/.cproject

    r279 r331  
    2020                                                        <builder buildPath="${workspace_loc:/tcc}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.1947549202" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
    2121                                                        <tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1351770923" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
    22                                                                 <option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.373654238" name="標準システム・ディレクトリーでヘッダー・ファイルを検索しない (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="false" valueType="boolean"/>
     22                                                                <option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.373654238" name="標準システム・ディレクトリーでヘッダー・ファイルを検索しない (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="true" valueType="boolean"/>
    2323                                                                <option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.1091726519" name="エンディアン" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
    2424                                                                <option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.1331241682" name="命令セット" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
     
    3030                                                                <option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.401098680" name="アーキテクチャー" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
    3131                                                                <option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.1123397289" name="CPU タイプ" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
    32                                                                 <option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1138208172" name="Decimal representation of '-Wsatck-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
     32                                                                <option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1138208172" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
    3333                                                                <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.276254572" name="インクルード・ファイル・ディレクトリー" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
    3434                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
     35                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
    3536                                                                </option>
    3637                                                                <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines.1180675084" name="マクロ定義" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines" valueType="definedSymbols">
     38                                                                        <listOptionValue builtIn="false" value="TCC_CPU_VERSION=7"/>
     39                                                                        <listOptionValue builtIn="false" value="TCC_MUSL"/>
    3740                                                                        <listOptionValue builtIn="false" value="TCC_TARGET_ARM"/>
    38                                                                         <listOptionValue builtIn="false" value="WITHOUT_LIBTCC"/>
     41                                                                        <listOptionValue builtIn="false" value="TCC_ARM_EABI"/>
     42                                                                        <listOptionValue builtIn="false" value="TCC_ARM_VFP"/>
     43                                                                        <listOptionValue builtIn="false" value="TCC_ARM_HARDFLOAT"/>
     44                                                                        <listOptionValue builtIn="false" value="ONE_SOURCE=0"/>
     45                                                                        <listOptionValue builtIn="false" value="CONFIG_TCC_STATIC"/>
    3946                                                                </option>
    4047                                                                <inputType id="%Base.Compiler.C.InputType.Id.1716911779" name="C å
     
    5764                                        </folderInfo>
    5865                                        <sourceEntries>
    59                                                 <entry excluding="tests|lib|examples|tccpe.c|tcccoff.c|x86_64-gen.c|x86_64-asm.h|il-opcodes.h|il-gen.c|i386-tok.h|i386-gen.c|i386-asm.h|i386-asm.c|c67-gen.c" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
     66                                                <entry excluding="lib/armeabi.c|lib/alloca-arm.S|tcctools.c|lib/va_list.c|lib/libtcc1.c|lib/lib-arm64.c|lib/bcheck.c|lib/alloca86-bt.S|lib/alloca86.S|lib/alloca86_64-bt.S|lib/alloca86_64.S|i386-link.c|conftest.c|c67-link.c|win32|x86_64-link.c|arm64-link.c|arm64-gen.c|tests|examples|tccpe.c|tcccoff.c|x86_64-gen.c|x86_64-asm.h|il-opcodes.h|il-gen.c|i386-tok.h|i386-gen.c|i386-asm.h|i386-asm.c|c67-gen.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
    6067                                        </sourceEntries>
    6168                                </configuration>
     
    7178        </storageModule>
    7279        <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
     80        <storageModule moduleId="refreshScope" versionNumber="2">
     81                <configuration configurationName="Debug">
     82                        <resource resourceType="PROJECT" workspacePath="/tcc-0.9.27"/>
     83                </configuration>
     84        </storageModule>
    7385</cproject>
  • EcnlProtoTool/trunk/tcc-0.9.27/.gitignore

    r279 r331  
     1*~
     2\#*
     3.#*
    14*.o
    25*.a
     6*.exe
     7*.dll
     8*.obj
     9*.pdb
     10*.lib
     11*.exp
     12*.log
     13*.bz2
     14*.zip
     15.gdb_history
     16a.out
    317tcc_g
    418tcc
    5 /*-tcc
    6 tc2.c
    7 doc
    8 tc3s.c
    9 p3.c
    10 tc1.c
    11 error.c
    12 i386-gen1.c
    13 test.out1
    14 test.out1b
    15 test.out2
    16 test.out2b
    17 test.out3
    18 test.out3b
    19 web.sh
    20 memdebug.c
    21 bench
    22 Makefile.uClibc
    23 boundtest
    24 prog.ref
    25 test.ref
    26 test.out
    27 tcc-doc.html
    28 ideas
    29 tcctest.ref
    30 linux.tcc
    31 ldtest
    32 libtcc_test
    33 instr.S
    34 p.c
    35 p2.c
    36 tcctest[1234]
    37 test[1234].out
    38 tests/tcclib.h
    39 tests/tcctest.gcc
    40 tests/weaktest.*.o.txt
    41 tests2/fred.txt
    42 .gdb_history
     19*-tcc
     20libtcc*.def
     21
     22config*.h
     23config*.mak
     24config.texi
     25conftest*
     26tags
     27TAGS
    4328tcc.1
    4429tcc.pod
    45 config.h
    46 config.mak
    47 config.texi
    48 tags
    49 .DS_Store
    50 *.swp
    51 lib/x86_64
    52 lib/i386
    53 lib/x86_64-win32
    54 lib/i386-win32
     30tcc-doc.html
    5531tcc-doc.info
    56 conftest*
    57 tiny_libmaker
    58 *.dSYM
     32
     33win32/doc
     34win32/libtcc
     35win32/lib/32
     36win32/lib/64
     37win32/include/float.h
     38win32/include/stdarg.h
     39win32/include/stdbool.h
     40win32/include/stddef.h
     41win32/include/varargs.h
     42win32/include/tcclib.h
     43
     44tests/tcctest[1234]
     45tests/tcctest.gcc
     46tests/*.out*
     47tests/*.ref
     48tests/*.txt
     49tests/*.gcc
     50tests/*-cc*
     51tests/*-tcc*
     52tests/libtcc_test
     53tests/asm-c-connect
     54tests/asm-c-connect-sep
     55tests/vla_test
     56tests/hello
     57tests/tests2/fred.txt
  • EcnlProtoTool/trunk/tcc-0.9.27/.info

    r279 r331  
    44GCC_STRING=5.2-GNUARM-NONE_v16.01
    55VERSION_IDE=
    6 E2STUDIO_VERSION=5.3.1.002
     6E2STUDIO_VERSION=5.4.0.018
    77ACTIVE_CONFIGURATION=Debug
  • EcnlProtoTool/trunk/tcc-0.9.27/.project

    r279 r331  
    11<?xml version="1.0" encoding="UTF-8"?>
    22<projectDescription>
    3         <name>tcc-0.9.26</name>
     3        <name>tcc-0.9.27</name>
    44        <comment></comment>
    55        <projects>
  • EcnlProtoTool/trunk/tcc-0.9.27/Changelog

    r279 r331  
     1Version 0.9.27:
     2
     3User interface:
     4- -x[c|a|n] filetype option (Sergey Korshunoff)
     5- -P[1], -dD, -dM preprocessor options (Sergey Korshunoff)
     6- -Wl,-(no-)whole-archive linker option (Reuben Thomas)
     7- -mms-bitfields option (David Mertens)
     8- -include <file> option (Michael Matz)
     9- -mno-sse on x86-64 disables use of SSE instructions
     10- @listfile support (Vlad Vissoultchev)
     11- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
     12- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
     13  (Andrew Aladjev, Urs Janssen)
     14
     15Platforms:
     16- new AARCH64 (arm64) target (Edmund Grimley Evans)
     17- vastly improved support for ARM hard float calling convention
     18   (Thomas Preud'homme, Daniel Gl旦ckner)
     19- provide a runtime library for ARM (Thomas Preud'homme)
     20- many x86_64 ABI fixes incl. XMM register passing and tests (James Lyon)
     21- ABI tests with native compiler using libtcc (James Lyon)
     22- UNICODE startup code supports wmain and wWinMain (YX Hao)
     23- shared libraries for x86_64 (Michael Matz)
     24- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
     25
     26Features:
     27- VLA (variable length array) improved (James Lyon, Pip Cet)
     28- import functions by ordinal in .def files on windows (YX Hao)
     29- x86/x86_64 assembler much improved (Michael Matz)
     30- simple dead code suppression (Edmund Grimley Evans, Michael Matz, grischka)
     31- implement round/fmin/fmax etc. math on windows (Avi Halachmi)
     32- #pragma once support (Sergey Korshunoff, Vlad Vissoultchev, ...)
     33- switch/case code improved (Zdenek Pavlas)
     34- ~15% faster by TinyAlloc fast memory allocator (Vlad Vissoultchev)
     35- standard conforming (and GCC compatible) struct initialization
     36   (Michael Matz)
     37- bit-field layout made compatible with GCC (Michael Matz)
     38- UTF8 in string literals supported (Zdenek Pavlas)
     39_ _Generic(...) supported (Matthias Gatto)
     40
     41Licensing:
     42- TinyCC partly relicensed to MIT license (See RELICENSING file).
     43
    144version 0.9.26:
    245
     
    1154- Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka)
    1255- x86-64 assembler (Frederic Feret)
    13 - Many improvements for ARM target (Daniel Glöckner, Thomas Preud'homme)
     56- Many improvements for ARM target (Daniel Glckner, Thomas Preud'homme)
    1457- Support WinCE PE ARM (Timo VJ Lahde)
    1558- Support ARM hardfloat calling convention (Thomas Preud'homme)
     
    3073
    3174- first support for x86-64 target (Shinichiro Hamaji)
    32 - support µClibc
     75- support Clibc
    3376- split tcc.c into tcc.h libtcc.c tccpp.c tccgen.c tcc.c
    3477- improved preprocess output with linenumbers and spaces preserved
    3578- tcc_relocate now copies code into user buffer
    3679- fix bitfields with non-int types and in unions
    37 - improve ARM cross-compiling (Daniel Glöckner)
     80- improve ARM cross-compiling (Daniel Glckner)
    3881- link stabstr sections from multiple objects
    3982- better (still limited) support for multiple TCCStates
     
    5295- Use _WIN32 for a windows hosted tcc and define it for the PE target,
    5396  otherwise define __unix / __linux (Detlef Riekenberg)
    54 - Import changesets (part 3) 409,410: ARM EABI by Daniel Glöckner
     97- Import changesets (part 3) 409,410: ARM EABI by Daniel Glckner
    5598- Some in-between fixes:
    5699  TCC -E no longer hangs with macro calls involving newlines.
     
    93136  420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
    94137  417: Make 'sizeof' unsigned (Rob Landley)
    95   397: Fix save_reg for longlongs (Daniel Glöckner)
     138  397: Fix save_reg for longlongs (Daniel Glckner)
    96139  396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
    97140
     
    135178version 0.9.21:
    136179
    137 - ARM target support (Daniel Glöckner)
     180- ARM target support (Daniel Glckner)
    138181- added '-funsigned-char, '-fsigned-char' and
    139182  '-Wimplicit-function-declaration'
  • EcnlProtoTool/trunk/tcc-0.9.27/Makefile

    r279 r331  
     1# --------------------------------------------------------------------------
    12#
    23# Tiny C Compiler Makefile
    34#
    45
    5 TOP ?= .
     6ifndef TOP
     7 TOP = .
     8 INCLUDED = no
     9endif
     10
    611include $(TOP)/config.mak
    7 VPATH = $(top_srcdir)
    8 
    9 CPPFLAGS = -I$(TOP) # for config.h
    10 
    11 ifeq (-$(findstring gcc,$(CC))-,-gcc-)
    12 ifeq (-$(findstring $(GCC_MAJOR),01)-,--)
    13 CFLAGS+=-fno-strict-aliasing
    14 ifeq (-$(findstring $(GCC_MAJOR),23)-,--)
    15 CFLAGS+=-Wno-pointer-sign -Wno-sign-compare
    16 ifeq (-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-4--)
    17 CFLAGS+=-D_FORTIFY_SOURCE=0
     12
     13ifeq (-$(CC)-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-gcc-4--)
     14 CFLAGS += -D_FORTIFY_SOURCE=0
     15endif
     16
     17LIBTCC = libtcc.a
     18LIBTCC1 = libtcc1.a
     19LINK_LIBTCC =
     20LIBS =
     21CFLAGS += -I$(TOP)
     22CFLAGS += $(CPPFLAGS)
     23VPATH = $(TOPSRC)
     24
     25ifdef CONFIG_WIN32
     26 ifneq ($(CONFIG_static),yes)
     27  LIBTCC = libtcc$(DLLSUF)
     28  LIBTCCDEF = libtcc.def
     29 endif
     30 CFGWIN = -win
     31 NATIVE_TARGET = $(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32)
    1832else
    19 CFLAGS+=-Wno-unused-result
    20 endif
    21 endif
    22 endif
    23 else # not GCC
    24 ifeq (-$(findstring clang,$(CC))-,-clang-)
    25 # make clang accept gnuisms in libtcc1.c
    26 CFLAGS+=-fheinous-gnu-extensions
    27 endif
    28 endif
    29 
    30 CPPFLAGS_P=$(CPPFLAGS) -DCONFIG_TCC_STATIC
    31 CFLAGS_P=$(CFLAGS) -pg -static
    32 LIBS_P=
    33 LDFLAGS_P=$(LDFLAGS)
    34 
    35 ifdef CONFIG_WIN64
    36 CONFIG_WIN32=yes
    37 endif
    38 
    39 ifndef CONFIG_WIN32
    40 LIBS=-lm
    41 ifndef CONFIG_NOLDL
    42 LIBS+=-ldl
    43 endif
    44 endif
    45 
    46 # make libtcc as static or dynamic library?
    47 ifdef DISABLE_STATIC
    48 LIBTCC=libtcc.so.1.0
    49 LINK_LIBTCC=-Wl,-rpath,"$(libdir)"
    50 ifdef DISABLE_RPATH
    51 LINK_LIBTCC=
    52 endif
    53 else
    54 LIBTCC=libtcc.a
    55 LINK_LIBTCC=
    56 endif
     33 LIBS=-lm
     34 ifneq ($(CONFIG_ldl),no)
     35  LIBS+=-ldl
     36 endif
     37 # make libtcc as static or dynamic library?
     38 ifeq ($(CONFIG_static),no)
     39  LIBTCC=libtcc$(DLLSUF)
     40  export LD_LIBRARY_PATH := $(CURDIR)/$(TOP)
     41  ifneq ($(CONFIG_rpath),no)
     42   LINK_LIBTCC += -Wl,-rpath,"$(libdir)"
     43  endif
     44 endif
     45 CFGWIN =-unx
     46 NATIVE_TARGET = $(ARCH)
     47 ifdef CONFIG_OSX
     48  NATIVE_TARGET = $(ARCH)-osx
     49  LDFLAGS += -flat_namespace -undefined warning
     50  export MACOSX_DEPLOYMENT_TARGET := 10.2
     51 endif
     52endif
     53
     54# run local version of tcc with local libraries and includes
     55TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
     56TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
     57TCCFLAGS = $(TCCFLAGS$(CFGWIN))
     58TCC = $(TOP)/tcc$(EXESUF) $(TCCFLAGS)
     59ifdef CONFIG_OSX
     60 TCCFLAGS += -D_ANSI_SOURCE
     61endif
     62
     63CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
     64LIBS_P = $(LIBS)
     65LDFLAGS_P = $(LDFLAGS)
    5766
    5867CONFIG_$(ARCH) = yes
    5968NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
    60 NATIVE_DEFINES_$(CONFIG_x86-64) += -DTCC_TARGET_X86_64
     69NATIVE_DEFINES_$(CONFIG_x86_64) += -DTCC_TARGET_X86_64
    6170NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
     71NATIVE_DEFINES_$(CONFIG_OSX) += -DTCC_TARGET_MACHO
    6272NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
    63 NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM -DWITHOUT_LIBTCC
     73NATIVE_DEFINES_$(CONFIG_musl) += -DTCC_MUSL
     74NATIVE_DEFINES_$(CONFIG_libgcc) += -DCONFIG_USE_LIBGCC
     75NATIVE_DEFINES_$(CONFIG_selinux) += -DHAVE_SELINUX
     76NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
    6477NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
    6578NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
    6679NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
     80NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
    6781NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
    6882
    69 ifeq ($(TOP),.)
    70 
    71 PROGS=tcc$(EXESUF)
    72 I386_CROSS = i386-tcc$(EXESUF)
    73 WIN32_CROSS = i386-win32-tcc$(EXESUF)
    74 WIN64_CROSS = x86_64-win32-tcc$(EXESUF)
    75 WINCE_CROSS = arm-win32-tcc$(EXESUF)
    76 X64_CROSS = x86_64-tcc$(EXESUF)
    77 ARM_FPA_CROSS = arm-fpa-tcc$(EXESUF)
    78 ARM_FPA_LD_CROSS = arm-fpa-ld-tcc$(EXESUF)
    79 ARM_VFP_CROSS = arm-vfp-tcc$(EXESUF)
    80 ARM_EABI_CROSS = arm-eabi-tcc$(EXESUF)
    81 ARM_CROSS = $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS)
    82 C67_CROSS = c67-tcc$(EXESUF)
    83 
    84 CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
     83ifeq ($(INCLUDED),no)
     84# --------------------------------------------------------------------------
     85# running top Makefile
     86
     87PROGS = tcc$(EXESUF)
     88TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCCDEF)
     89TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
     90
     91all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
     92
     93# cross compiler targets to build
     94TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
     95# TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi
     96
     97# cross libtcc1.a targets to build
     98LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
     99
     100PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
     101LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
     102
     103# build cross compilers & libs
     104cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
     105
     106# build specific cross compiler & lib
     107cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
     108
     109install: ; @$(MAKE) --no-print-directory install$(CFGWIN)
     110install-strip: ; @$(MAKE) --no-print-directory install$(CFGWIN) CONFIG_strip=yes
     111uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFGWIN)
     112
     113ifdef CONFIG_cross
     114all : cross
     115endif
     116
     117# --------------------------------------------
     118
     119T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
     120X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
     121
     122DEF-i386        = -DTCC_TARGET_I386
     123DEF-x86_64      = -DTCC_TARGET_X86_64
     124DEF-i386-win32  = -DTCC_TARGET_PE -DTCC_TARGET_I386
     125DEF-x86_64-win32= -DTCC_TARGET_PE -DTCC_TARGET_X86_64
     126DEF-x86_64-osx  = -DTCC_TARGET_MACHO -DTCC_TARGET_X86_64
     127DEF-arm-wince   = -DTCC_TARGET_PE -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP -DTCC_ARM_HARDFLOAT
     128DEF-arm64       = -DTCC_TARGET_ARM64
     129DEF-c67         = -DTCC_TARGET_C67 -w # disable warnigs
     130DEF-arm-fpa     = -DTCC_TARGET_ARM
     131DEF-arm-fpa-ld  = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
     132DEF-arm-vfp     = -DTCC_TARGET_ARM -DTCC_ARM_VFP
     133DEF-arm-eabi    = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
     134DEF-arm-eabihf  = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
     135DEF-arm         = $(DEF-arm-eabihf)
     136DEF-$(NATIVE_TARGET) = $(NATIVE_DEFINES)
     137
     138DEFINES += $(DEF-$T) $(DEF-all)
     139DEFINES += $(if $(ROOT-$T),-DCONFIG_SYSROOT="\"$(ROOT-$T)\"")
     140DEFINES += $(if $(CRT-$T),-DCONFIG_TCC_CRTPREFIX="\"$(CRT-$T)\"")
     141DEFINES += $(if $(LIB-$T),-DCONFIG_TCC_LIBPATHS="\"$(LIB-$T)\"")
     142DEFINES += $(if $(INC-$T),-DCONFIG_TCC_SYSINCLUDEPATHS="\"$(INC-$T)\"")
     143DEFINES += $(DEF-$(or $(findstring win,$T),unx))
     144
     145ifneq ($(X),)
     146ifeq ($(CONFIG_WIN32),yes)
     147DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
     148DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
     149else
     150DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
     151DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
     152endif
     153endif
     154
     155# include custom configuration (see make help)
     156-include config-extra.mak
     157
     158CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
    85159CORE_FILES += tcc.h config.h libtcc.h tcctok.h
    86 CORE_FILES += dummy.c
    87 I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h
    88 WIN32_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h tccpe.c
    89 WIN64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h tccpe.c
    90 WINCE_FILES = $(CORE_FILES) arm-gen.c tccpe.c
    91 X86_64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h
    92 ARM_FILES = $(CORE_FILES) arm-gen.c
    93 C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
    94 
    95 ifdef CONFIG_WIN64
    96 PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
    97 NATIVE_FILES=$(WIN64_FILES)
    98 PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
    99 LIBTCC1_CROSS=lib/i386-win32/libtcc1.a
    100 LIBTCC1=libtcc1.a
    101 else ifdef CONFIG_WIN32
    102 PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
    103 NATIVE_FILES=$(WIN32_FILES)
    104 PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
    105 LIBTCC1_CROSS=lib/x86_64-win32/libtcc1.a
    106 LIBTCC1=libtcc1.a
    107 else ifeq ($(ARCH),i386)
    108 NATIVE_FILES=$(I386_FILES)
    109 PROGS_CROSS=$(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
    110 LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a
    111 LIBTCC1=libtcc1.a
    112 else ifeq ($(ARCH),x86-64)
    113 NATIVE_FILES=$(X86_64_FILES)
    114 PROGS_CROSS=$(I386_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
    115 LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a lib/i386/libtcc1.a
    116 LIBTCC1=libtcc1.a
    117 else ifeq ($(ARCH),arm)
    118 NATIVE_FILES=$(ARM_FILES)
    119 PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(C67_CROSS)
    120 endif
    121 
    122 ifeq ($(TARGETOS),Darwin)
    123 PROGS+=tiny_libmaker$(EXESUF)
    124 endif
    125 
    126 ifdef CONFIG_USE_LIBGCC
    127 LIBTCC1=
    128 endif
    129 
    130 TCCLIBS = $(LIBTCC1) $(LIBTCC)
    131 TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
    132 
    133 ifdef CONFIG_CROSS
    134 PROGS+=$(PROGS_CROSS)
    135 TCCLIBS+=$(LIBTCC1_CROSS)
    136 endif
    137 
    138 all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
     160i386_FILES = $(CORE_FILES) i386-gen.c i386-link.c i386-asm.c i386-asm.h i386-tok.h
     161i386-win32_FILES = $(i386_FILES) tccpe.c
     162x86_64_FILES = $(CORE_FILES) x86_64-gen.c x86_64-link.c i386-asm.c x86_64-asm.h
     163x86_64-win32_FILES = $(x86_64_FILES) tccpe.c
     164x86_64-osx_FILES = $(x86_64_FILES)
     165arm_FILES = $(CORE_FILES) arm-gen.c arm-link.c arm-asm.c
     166arm-wince_FILES = $(arm_FILES) tccpe.c
     167arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c
     168c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c
     169
     170# libtcc sources
     171LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES)))
     172
     173ifeq ($(ONE_SOURCE),yes)
     174LIBTCC_OBJ = $(X)libtcc.o
     175LIBTCC_INC = $($T_FILES)
     176TCC_FILES = $(X)tcc.o
     177tcc.o : DEFINES += -DONE_SOURCE=0
     178else
     179LIBTCC_OBJ = $(patsubst %.c,$(X)%.o,$(LIBTCC_SRC))
     180LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES))
     181TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ)
     182$(TCC_FILES) : DEFINES += -DONE_SOURCE=0
     183endif
     184
     185# target specific object rule
     186$(X)%.o : %.c $(LIBTCC_INC)
     187        $(CC) -o $@ -c $< $(DEFINES) $(CFLAGS)
     188
     189# additional dependencies
     190$(X)tcc.o : tcctools.c
    139191
    140192# Host Tiny C Compiler
    141193tcc$(EXESUF): tcc.o $(LIBTCC)
    142         $(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
     194        $(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
    143195
    144196# Cross Tiny C Compilers
    145 %-tcc$(EXESUF): tcc.c
    146         $(CC) -o $@ $< -DONE_SOURCE $(DEFINES) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
     197%-tcc$(EXESUF): FORCE
     198        @$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
     199
     200$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
     201        $(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
    147202
    148203# profiling version
    149 tcc_p$(EXESUF): $(NATIVE_FILES)
    150         $(CC) -o $@ $< -DONE_SOURCE $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
    151 
    152 $(I386_CROSS): DEFINES = -DTCC_TARGET_I386 \
    153     -DCONFIG_TCCDIR="\"$(tccdir)/i386\""
    154 $(X64_CROSS): DEFINES = -DTCC_TARGET_X86_64
    155 $(WIN32_CROSS): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \
    156     -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
    157     -DCONFIG_TCC_LIBPATHS="\"{B}/lib/32;{B}/lib\""
    158 $(WIN64_CROSS): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \
    159     -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
    160     -DCONFIG_TCC_LIBPATHS="\"{B}/lib/64;{B}/lib\""
    161 $(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE
    162 $(C67_CROSS): DEFINES = -DTCC_TARGET_C67
    163 $(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM
    164 $(ARM_FPA_LD_CROSS)$(EXESUF): DEFINES = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
    165 $(ARM_VFP_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_VFP
    166 $(ARM_EABI_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_EABI
    167 
    168 $(I386_CROSS): $(I386_FILES)
    169 $(X64_CROSS): $(X86_64_FILES)
    170 $(WIN32_CROSS): $(WIN32_FILES)
    171 $(WIN64_CROSS): $(WIN64_FILES)
    172 $(WINCE_CROSS): $(WINCE_FILES)
    173 $(C67_CROSS): $(C67_FILES)
    174 $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS): $(ARM_FILES)
    175 
    176 # libtcc generation and test
    177 ifndef ONE_SOURCE
    178 LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
    179 LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
    180 else
    181 LIBTCC_OBJ = libtcc.o
    182 LIBTCC_INC = $(NATIVE_FILES)
    183 libtcc.o : NATIVE_DEFINES += -DONE_SOURCE
    184 endif
    185 
    186 $(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
    187         $(CC) -o $@ -c $< $(NATIVE_DEFINES) $(CPPFLAGS) $(CFLAGS)
    188 
     204tcc_p$(EXESUF): $($T_FILES)
     205        $(CC) -o $@ $< $(DEFINES) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
     206
     207# static libtcc library
    189208libtcc.a: $(LIBTCC_OBJ)
    190209        $(AR) rcs $@ $^
    191210
    192 libtcc.so.1.0: $(LIBTCC_OBJ)
     211# dynamic libtcc library
     212libtcc.so: $(LIBTCC_OBJ)
    193213        $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
    194214
    195 libtcc.so.1.0: CFLAGS+=-fPIC
    196 
    197 # windows utilities
    198 tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
    199         $(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
    200 tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
    201         $(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     215libtcc.so: CFLAGS+=-fPIC
     216libtcc.so: LDFLAGS+=-fPIC
     217
     218# windows dynamic libtcc library
     219libtcc.dll : $(LIBTCC_OBJ)
     220        $(CC) -shared -o $@ $^ $(LDFLAGS)
     221libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
     222
     223# import file for windows libtcc.dll
     224libtcc.def : libtcc.dll tcc$(EXESUF)
     225        $(XTCC) -impdef $< -o $@
     226XTCC ?= ./tcc$(EXESUF)
    202227
    203228# TinyCC runtime libraries
    204 libtcc1.a : FORCE
    205         $(MAKE) -C lib native
    206 lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
    207         $(MAKE) -C lib cross TARGET=$*
    208 
     229libtcc1.a : tcc$(EXESUF) FORCE
     230        @$(MAKE) -C lib DEFINES='$(DEF-$T)'
     231
     232# Cross libtcc1.a
     233%-libtcc1.a : %-tcc$(EXESUF) FORCE
     234        @$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
     235
     236.PRECIOUS: %-libtcc1.a
    209237FORCE:
    210238
    211 # install
    212 TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h tcclib.h
    213 INSTALL=install
    214 ifdef STRIP_BINARIES
    215 INSTALLBIN=$(INSTALL) -s
    216 else
    217 INSTALLBIN=$(INSTALL)
    218 endif
    219 
    220 ifndef CONFIG_WIN32
    221 install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
    222         mkdir -p "$(bindir)"
    223 ifeq ($(CC),tcc)
    224         $(INSTALL) -m755 $(PROGS) "$(bindir)"
    225 else
    226         $(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
    227 endif
    228         mkdir -p "$(mandir)/man1"
    229         -$(INSTALL) tcc.1 "$(mandir)/man1"
    230         mkdir -p "$(infodir)"
    231         -$(INSTALL) tcc-doc.info "$(infodir)"
    232         mkdir -p "$(tccdir)"
    233         mkdir -p "$(tccdir)/include"
    234 ifneq ($(LIBTCC1),)
    235         $(INSTALL) -m644 $(LIBTCC1) "$(tccdir)"
    236 endif
    237         $(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) "$(tccdir)/include"
    238         mkdir -p "$(libdir)"
    239         $(INSTALL) -m755 $(LIBTCC) "$(libdir)"
    240 ifdef DISABLE_STATIC
    241         ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so.1"
    242         ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so"
    243 endif
    244         mkdir -p "$(includedir)"
    245         $(INSTALL) -m644 $(top_srcdir)/libtcc.h "$(includedir)"
    246         mkdir -p "$(docdir)"
    247         -$(INSTALL) -m644 tcc-doc.html "$(docdir)"
    248 ifdef CONFIG_CROSS
    249         mkdir -p "$(tccdir)/win32/lib/32"
    250         mkdir -p "$(tccdir)/win32/lib/64"
    251 ifeq ($(ARCH),x86-64)
    252         mkdir -p "$(tccdir)/i386"
    253         $(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
    254         cp -r "$(tccdir)/include" "$(tccdir)/i386"
    255 endif
    256         $(INSTALL) -m644 win32/lib/*.def "$(tccdir)/win32/lib"
    257         $(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/win32/lib/32"
    258         $(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/win32/lib/64"
    259         cp -r win32/include/. "$(tccdir)/win32/include"
    260         cp -r include/. "$(tccdir)/win32/include"
    261 endif
    262 
    263 uninstall:
    264         rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
    265         rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
    266         rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
    267         rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
    268         rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
    269         rm -fv "$(libdir)/libtcc.so*"
    270         rm -rf "$(tccdir)/win32"
    271         -rmdir $(tccdir)/include
    272 ifeq ($(ARCH),x86-64)
    273         rm -rf "$(tccdir)/i386"
    274 endif
    275 else
    276 # on windows
    277 install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
    278         mkdir -p "$(tccdir)"
    279         mkdir -p "$(tccdir)/lib"
    280         mkdir -p "$(tccdir)/include"
    281         mkdir -p "$(tccdir)/examples"
    282         mkdir -p "$(tccdir)/doc"
    283         mkdir -p "$(tccdir)/libtcc"
    284         $(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
    285         $(INSTALL) -m644 $(LIBTCC1) win32/lib/*.def "$(tccdir)/lib"
    286         cp -r win32/include/. "$(tccdir)/include"
    287         cp -r win32/examples/. "$(tccdir)/examples"
    288         $(INSTALL) -m644 $(addprefix include/,$(TCC_INCLUDES)) "$(tccdir)/include"
    289         $(INSTALL) -m644 tcc-doc.html win32/tcc-win32.txt "$(tccdir)/doc"
    290         $(INSTALL) -m644 $(LIBTCC) libtcc.h "$(tccdir)/libtcc"
    291 ifdef CONFIG_CROSS
    292         mkdir -p "$(tccdir)/lib/32"
    293         mkdir -p "$(tccdir)/lib/64"
    294         -$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/lib/32"
    295         -$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/lib/64"
    296 endif
    297 
    298 uninstall:
    299         rm -rfv "$(tccdir)/*"
    300 endif
    301 
     239# --------------------------------------------------------------------------
    302240# documentation and man page
    303241tcc-doc.html: tcc-doc.texi
    304         -texi2html -monolithic -number $<
     242        makeinfo --no-split --html --number-sections -o $@ $< || true
    305243
    306244tcc.1: tcc-doc.texi
    307         -$(top_srcdir)/texi2pod.pl $< tcc.pod
    308         -pod2man --section=1 --center=" " --release=" " tcc.pod > $@
     245        $(TOPSRC)/texi2pod.pl $< tcc.pod \
     246        && pod2man --section=1 --center="Tiny C Compiler" --release="$(VERSION)" tcc.pod >tmp.1 \
     247        && mv tmp.1 $@ || rm -f tmp.1
    309248
    310249tcc-doc.info: tcc-doc.texi
    311         -makeinfo $<
    312 
    313 # in tests subdir
    314 export LIBTCC1
    315 
    316 %est:
    317         $(MAKE) -C tests $@
    318 
    319 clean:
    320         rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.exe libtcc_test$(EXESUF)
    321         $(MAKE) -C tests $@
    322 ifneq ($(LIBTCC1),)
    323         $(MAKE) -C lib $@
    324 endif
    325 
    326 distclean: clean
    327         rm -vf config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
    328 
    329 config.mak:
    330         @echo "Please run ./configure."
    331         @exit 1
     250        makeinfo $< || true
     251
     252# --------------------------------------------------------------------------
     253# install
     254
     255INSTALL = install -m644
     256INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip))
     257STRIP_yes = -s
     258
     259LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
     260LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
     261IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
     262IBw = $(call IB,$(wildcard $1),$2)
     263IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
     264IFw = $(call IF,$(wildcard $1),$2)
     265IR = mkdir -p $2 && cp -r $1/. $2
     266
     267# install progs & libs
     268install-unx:
     269        $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
     270        $(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")
     271        $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
     272        $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
     273        $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
     274        $(call IFw,tcc.1,"$(mandir)/man1")
     275        $(call IFw,tcc-doc.info,"$(infodir)")
     276        $(call IFw,tcc-doc.html,"$(docdir)")
     277ifneq "$(wildcard $(LIBTCC1_W))" ""
     278        $(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib")
     279        $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include")
     280        $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include")
     281endif
     282
     283# uninstall
     284uninstall-unx:
     285        @rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS),"$(bindir)/$P")
     286        @rm -fv "$(libdir)/libtcc.a" "$(libdir)/libtcc.so" "$(includedir)/libtcc.h"
     287        @rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
     288        @rm -fv "$(docdir)/tcc-doc.html"
     289        rm -r "$(tccdir)"
     290
     291# install progs & libs on windows
     292install-win:
     293        $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
     294        $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
     295        $(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")
     296        $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
     297        $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
     298        $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
     299        $(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples")
     300        $(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)")
     301        $(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)")
     302ifneq "$(wildcard $(LIBTCC1_U))" ""
     303        $(call IFw,$(LIBTCC1_U),"$(tccdir)/lib")
     304        $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
     305endif
     306
     307# the msys-git shell works to configure && make except it does not have install
     308ifeq "$(and $(CONFIG_WIN32),$(shell which install >/dev/null 2>&1 || echo no))" "no"
     309install-win : INSTALL = cp
     310install-win : INSTALLBIN = cp
     311endif
     312
     313# uninstall on windows
     314uninstall-win:
     315        @rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS) libtcc.dll,"$(bindir)/$P")
     316        @rm -fv $(foreach F,tcc-doc.html tcc-win32.txt,"$(docdir)/$F")
     317        @rm -fv $(foreach F,libtcc.h libtcc.def libtcc.a,"$(libdir)/$F")
     318        rm -r "$(tccdir)"
     319
     320# --------------------------------------------------------------------------
     321# other stuff
     322
     323TAGFILES = *.[ch] include/*.h lib/*.[chS]
     324tags : ; ctags $(TAGFILES)
     325# cannot have both tags and TAGS on windows
     326ETAGS : ; etags $(TAGFILES)
    332327
    333328# create release tarball from *current* git branch (including tcc-doc.html
    334329# and converting two files to CRLF)
    335 TCC-VERSION := tcc-$(shell cat $(top_srcdir)/VERSION)
     330TCC-VERSION = tcc-$(VERSION)
    336331tar:    tcc-doc.html
    337332        mkdir $(TCC-VERSION)
     
    345340        git reset
    346341
    347 
    348 .PHONY: all clean tar distclean install uninstall FORCE
    349 
    350 endif # ifeq ($(TOP),.)
     342config.mak:
     343        $(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
     344
     345# run all tests
     346test:
     347        $(MAKE) -C tests
     348# run test(s) from tests2 subdir (see make help)
     349tests2.%:
     350        $(MAKE) -C tests/tests2 $@
     351
     352clean:
     353        rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod
     354        rm -f  *~ *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS
     355        @$(MAKE) -C lib $@
     356        @$(MAKE) -C tests $@
     357
     358distclean: clean
     359        rm -f config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
     360
     361.PHONY: all clean test tar tags ETAGS distclean install uninstall FORCE
     362
     363help:
     364        @echo "make"
     365        @echo "   build native compiler (from separate objects)"
     366        @echo ""
     367        @echo "make cross"
     368        @echo "   build cross compilers (from one source)"
     369        @echo ""
     370        @echo "make ONE_SOURCE=yes / no"
     371        @echo "   force building from one source / separate objects"
     372        @echo ""
     373        @echo "make cross-TARGET"
     374        @echo "   build one specific cross compiler for 'TARGET', as in"
     375        @echo "   $(TCC_X)"
     376        @echo ""
     377        @echo "Custom configuration:"
     378        @echo "   The makefile includes a file 'config-extra.mak' if it is present."
     379        @echo "   This file may contain some custom configuration.  For example:"
     380        @echo ""
     381        @echo "      NATIVE_DEFINES += -D..."
     382        @echo ""
     383        @echo "   Or for example to configure the search paths for a cross-compiler"
     384        @echo "   that expects the linux files in <tccdir>/i386-linux:"
     385        @echo ""
     386        @echo "      ROOT-i386 = {B}/i386-linux"
     387        @echo "      CRT-i386  = {B}/i386-linux/usr/lib"
     388        @echo "      LIB-i386  = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
     389        @echo "      INC-i386  = {B}/lib/include:{B}/i386-linux/usr/include"
     390        @echo "      DEF-i386  += -D__linux__"
     391        @echo ""
     392        @echo "make test"
     393        @echo "   run all tests"
     394        @echo ""
     395        @echo "make tests2.all / make tests2.37 / make tests2.37+"
     396        @echo "   run all/single test(s) from tests2, optionally update .expect"
     397        @echo ""
     398        @echo "Other supported make targets:"
     399        @echo "   install install-strip tags ETAGS tar clean distclean help"
     400        @echo ""
     401
     402# --------------------------------------------------------------------------
     403endif # ($(INCLUDED),no)
  • EcnlProtoTool/trunk/tcc-0.9.27/README

    r279 r331  
    2929-------------
    3030
    31 1) Installation on a i386 Linux host (for Windows read tcc-win32.txt)
     311) Installation on a i386/x86_64/arm Linux/OSX/FreeBSD host
    3232
    3333   ./configure
     
    3636   make install
    3737
    38 Alternatively, out-of-tree builds are supported: you may use different
    39 directories to hold build objects, kept separate from your source tree:
     38   Notes: For OSX and FreeBSD, gmake should be used instead of make.
     39   For Windows read tcc-win32.txt.
    4040
    41    mkdir _build
    42    cd _build
    43    ../configure
    44    make
    45    make test
    46    make install
    47 
    48 By default, tcc is installed in /usr/local/bin.
    49 ./configure --help  shows configuration options.
     41makeinfo must be installed to compile the doc.  By default, tcc is
     42installed in /usr/local/bin.  ./configure --help  shows configuration
     43options.
    5044
    5145
  • EcnlProtoTool/trunk/tcc-0.9.27/TODO

    r279 r331  
    33Bugs:
    44
    5 - fix macro substitution with nested definitions (ShangHongzhang)
     5- i386 fastcall is mostly wrong
    66- FPU st(0) is left unclean (kwisatz haderach). Incompatible with
    77  optimized gcc/msc code
    8 
    9 - constructors
    10 - cast bug (Peter Wang)
    11 - define incomplete type if defined several times (Peter Wang).
    12 - configure --cc=tcc (still one bug in libtcc1.c)
    13 - test binutils/gcc compile
    14 - tci patch + argument.
    15 - see -lxxx bug (Michael Charity).
    168- see transparent union pb in /urs/include/sys/socket.h
    179- precise behaviour of typeof with arrays ? (__put_user macro)
     
    2214  (net/ipv4/ip_output.c)
    2315- fix function pointer type display
    24 - check lcc test suite -> fix bitfield binary operations
    2516- check section alignment in C
    2617- fix invalid cast in comparison 'if (v == (int8_t)v)'
     
    2819- fix static functions declared inside block
    2920- fix multiple unions init
    30 - sizeof, alignof, typeof can still generate code in some cases.
    31 - Fix the remaining libtcc memory leaks.
    3221- make libtcc fully reentrant (except for the compilation stage itself).
     22- struct/union/enum definitions in nested scopes (see also Debian bug #770657)
     23- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; }
     24- memory may be leaked after errors (longjmp).
     25
     26Portability:
     27
     28- it is assumed that int is 32-bit and sizeof(int) == 4
     29- int is used when host or target size_t would make more sense
     30- TCC handles target floating-point (fp) values using the host's fp
     31  arithmetic, which is simple and fast but may lead to exceptions
     32  and inaccuracy and wrong representations when cross-compiling
     33
     34Linking:
     35
     36- static linking (-static) does not work
    3337
    3438Bound checking:
    3539
    36 - '-b' bug.
    3740- fix bound exit on RedHat 7.3
    3841- setjmp is not supported properly in bound checking.
     
    4649- disable-asm and disable-bcheck options
    4750- __builtin_expect()
    48 - improve '-E' option.
    4951- atexit (Nigel Horne)
    50 - packed attribute
    5152- C99: add complex types (gcc 3.2 testsuite issue)
    5253- postfix compound literals (see 20010124-1.c)
     54- interactive mode / integrated debugger
    5355
    5456Optimizations:
     
    6668  boolean variable to tell if compound literal was already
    6769  initialized).
    68 - add PowerPC or ARM code generator and improve codegen for RISC (need
     70- add PowerPC generator and improve codegen for RISC (need
    6971  to suppress VT_LOCAL and use a base register instead).
    70 - interactive mode / integrated debugger
    7172- fix preprocessor symbol redefinition
    72 - better constant opt (&&, ||, ?:)
    7373- add portable byte code generator and interpreter for other
    7474  unsupported architectures.
     
    7777  check exception code (exception filter func).
    7878- handle void (__attribute__() *ptr)()
     79- VLAs are implemented in a way that is not compatible with signals:
     80  http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html
    7981
    8082Fixed (probably):
     
    9294- function pointers/lvalues in ? : (linux kernel net/core/dev.c)
    9395- win32: add __stdcall, check GetModuleHandle for dlls.
     96- macro substitution with nested definitions (ShangHongzhang)
     97- with "-run" and libtcc, a PLT is now built.
     98- '-E' option was improved
     99- packed attribute is now supported
     100- ARM and ARM64 code generators have been added.
  • EcnlProtoTool/trunk/tcc-0.9.27/VERSION

    r279 r331  
    1 0.9.26
     10.9.27
  • EcnlProtoTool/trunk/tcc-0.9.27/arm-gen.c

    r321 r331  
    11/*
    22 *  ARMv4 code generator for TCC
    3  * 
     3 *
    44 *  Copyright (c) 2003 Daniel Glöckner
    55 *  Copyright (c) 2012 Thomas Preud'homme
     
    2424#ifdef TARGET_DEFS_ONLY
    2525
    26 #ifdef TCC_ARM_EABI
    27 #ifndef TCC_ARM_VFP // Avoid useless warning
    28 #define TCC_ARM_VFP
    29 #endif
     26#if defined(TCC_ARM_EABI) && !defined(TCC_ARM_VFP)
     27#error "Currently TinyCC only supports float computation with VFP instructions"
    3028#endif
    3129
     
    3735#endif
    3836
    39 #ifndef TCC_ARM_VERSION
    40 # define TCC_ARM_VERSION 5
     37#ifndef TCC_CPU_VERSION
     38# define TCC_CPU_VERSION 5
    4139#endif
    4240
     
    4745#define RC_FLOAT   0x0002 /* generic float register */
    4846#define RC_R0      0x0004
    49 #define RC_R1      0x0008 
     47#define RC_R1      0x0008
    5048#define RC_R2      0x0010
    5149#define RC_R3      0x0020
     
    8280    TREG_F7,
    8381#endif
     82    TREG_SP = 13,
     83    TREG_LR,
    8484};
    8585
     
    105105/* defined if structures are passed as pointers. Otherwise structures
    106106   are directly pushed on stack. */
    107 //#define FUNC_STRUCT_PARAM_AS_PTR
     107/* #define FUNC_STRUCT_PARAM_AS_PTR */
    108108
    109109/* pointer size, in bytes */
     
    131131
    132132/******************************************************/
    133 /* ELF defines */
    134 
    135 #define EM_TCC_TARGET EM_ARM
    136 
    137 /* relocation type for 32 bit data relocation */
    138 #define R_DATA_32   R_ARM_ABS32
    139 #define R_DATA_PTR  R_ARM_ABS32
    140 #define R_JMP_SLOT  R_ARM_JUMP_SLOT
    141 #define R_COPY      R_ARM_COPY
    142 
    143 #define ELF_START_ADDR 0x00008000
    144 #define ELF_PAGE_SIZE  0x1000
    145 
    146 /******************************************************/
    147133#else /* ! TARGET_DEFS_ONLY */
    148134/******************************************************/
    149135#include "tcc.h"
     136
     137enum float_abi float_abi;
    150138
    151139ST_DATA const int reg_classes[NB_REGS] = {
     
    172160#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
    173161static CType float_type, double_type, func_float_type, func_double_type;
    174 ST_FUNC void arm_init_types(void)
     162ST_FUNC void arm_init(struct TCCState *s)
    175163{
    176164    float_type.t = VT_FLOAT;
     
    180168    func_double_type.t = VT_FUNC;
    181169    func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
     170
     171    float_abi = s->float_abi;
     172#ifndef TCC_ARM_HARDFLOAT
     173    tcc_warning("soft float ABI currently not supported: default to softfp");
     174#endif
    182175}
    183176#else
     
    185178#define func_double_type func_old_type
    186179#define func_ldouble_type func_old_type
    187 ST_FUNC void arm_init_types(void) {}
     180ST_FUNC void arm_init(struct TCCState *s)
     181{
     182#if 0
     183#if !defined (TCC_ARM_VFP)
     184    tcc_warning("Support for FPA is deprecated and will be removed in next"
     185                " release");
     186#endif
     187#if !defined (TCC_ARM_EABI)
     188    tcc_warning("Support for OABI is deprecated and will be removed in next"
     189                " release");
     190#endif
     191#endif
     192}
    188193#endif
    189194
     
    198203/******************************************************/
    199204
    200 void o(unsigned int i)
     205#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
     206const char *default_elfinterp(struct TCCState *s)
     207{
     208    if (s->float_abi == ARM_HARD_FLOAT)
     209        return "/lib/ld-linux-armhf.so.3";
     210    else
     211        return "/lib/ld-linux.so.3";
     212}
     213#endif
     214
     215void o(uint32_t i)
    201216{
    202217  /* this is a good place to start adding big-endian support*/
    203218  int ind1;
    204 
     219  if (nocode_wanted)
     220    return;
    205221  ind1 = ind + 4;
    206222  if (!cur_text_section)
     
    212228  i>>=8;
    213229  cur_text_section->data[ind++] = i&255;
    214   i>>=8; 
     230  i>>=8;
    215231  cur_text_section->data[ind++] = i&255;
    216232  i>>=8;
     
    328344}
    329345
    330 ST_FUNC uint32_t encbranch(int pos, int addr, int fail)
     346uint32_t encbranch(int pos, int addr, int fail)
    331347{
    332348  addr-=pos+8;
     
    377393  if(r<TREG_F0 || r>TREG_F7)
    378394    tcc_error("compiler error! register %i is no vfp register",r);
    379   return r-5;
     395  return r - TREG_F0;
    380396}
    381397#else
     
    384400  if(r<TREG_F0 || r>TREG_F3)
    385401    tcc_error("compiler error! register %i is no fpa register",r);
    386   return r-5;
     402  return r - TREG_F0;
    387403}
    388404#endif
     
    390406static uint32_t intr(int r)
    391407{
    392   if(r==4)
     408  if(r == TREG_R12)
    393409    return 12;
    394   if((r<0 || r>4) && r!=14)
    395     tcc_error("compiler error! register %i is no int register",r);
    396   return r;
     410  if(r >= TREG_R0 && r <= TREG_R3)
     411    return r - TREG_R0;
     412  if (r >= TREG_SP && r <= TREG_LR)
     413    return r + (13 - TREG_SP);
     414  tcc_error("compiler error! register %i is no int register",r);
    397415}
    398416
     
    499517  fr = sv->r;
    500518  ft = sv->type.t;
    501   fc = sv->c.ul;
     519  fc = sv->c.i;
    502520
    503521  if(fc>=0)
     
    507525    fc=-fc;
    508526  }
    509  
     527
    510528  v = fr & VT_VALMASK;
    511529  if (fr & VT_LVAL) {
     
    514532      v1.type.t = VT_PTR;
    515533      v1.r = VT_LOCAL | VT_LVAL;
    516       v1.c.ul = sv->c.ul;
    517       load(base=14 /* lr */, &v1);
     534      v1.c.i = sv->c.i;
     535      load(TREG_LR, &v1);
     536      base = 14; /* lr */
    518537      fc=sign=0;
    519538      v=VT_LOCAL;
     
    521540      v1.type.t = VT_PTR;
    522541      v1.r = fr&~VT_LVAL;
    523       v1.c.ul = sv->c.ul;
     542      v1.c.i = sv->c.i;
    524543      v1.sym=sv->sym;
    525       load(base=14, &v1);
     544      load(TREG_LR, &v1);
     545      base = 14; /* lr */
    526546      fc=sign=0;
    527547      v=VT_LOCAL;
     
    572592        if(!sign)
    573593          op|=0x800000;
    574         if ((ft & VT_BTYPE) == VT_BYTE)
     594        if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
    575595          op|=0x400000;
    576596        o(op|(intr(r)<<12)|fc|(base<<16));
     
    580600  } else {
    581601    if (v == VT_CONST) {
    582       op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul);
     602      op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);
    583603      if (fr & VT_SYM || !op) {
    584604        o(0xE59F0000|(intr(r)<<12));
     
    586606        if(fr & VT_SYM)
    587607          greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
    588         o(sv->c.ul);
     608        o(sv->c.i);
    589609      } else
    590610        o(op);
    591611      return;
    592612    } else if (v == VT_LOCAL) {
    593       op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul);
     613      op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);
    594614      if (fr & VT_SYM || !op) {
    595615        o(0xE59F0000|(intr(r)<<12));
     
    597617        if(fr & VT_SYM) // needed ?
    598618          greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
    599         o(sv->c.ul);
     619        o(sv->c.i);
    600620        o(0xE08B0000|(intr(r)<<12)|intr(r));
    601621      } else
     
    603623      return;
    604624    } else if(v == VT_CMP) {
    605       o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12));
    606       o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12));
     625      o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));
     626      o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));
    607627      return;
    608628    } else if (v == VT_JMP || v == VT_JMPI) {
     
    611631      o(0xE3A00000|(intr(r)<<12)|t);
    612632      o(0xEA000000);
    613       gsym(sv->c.ul);
     633      gsym(sv->c.i);
    614634      o(0xE3A00000|(intr(r)<<12)|(t^1));
    615635      return;
     
    638658  fr = sv->r;
    639659  ft = sv->type.t;
    640   fc = sv->c.ul;
     660  fc = sv->c.i;
    641661
    642662  if(fc>=0)
     
    646666    fc=-fc;
    647667  }
    648  
    649   v = fr & VT_VALMASK; 
     668
     669  v = fr & VT_VALMASK;
    650670  if (fr & VT_LVAL || fr == VT_LOCAL) {
    651     uint32_t base = 0xb;
     671    uint32_t base = 0xb; /* fp */
    652672    if(v < VT_CONST) {
    653673      base=intr(v);
     
    657677      v1.type.t = ft;
    658678      v1.r = fr&~VT_LVAL;
    659       v1.c.ul = sv->c.ul;
     679      v1.c.i = sv->c.i;
    660680      v1.sym=sv->sym;
    661       load(base=14, &v1);
     681      load(TREG_LR, &v1);
     682      base = 14; /* lr */
    662683      fc=sign=0;
    663       v=VT_LOCAL;   
     684      v=VT_LOCAL;
    664685    }
    665686    if(v == VT_LOCAL) {
     
    668689#ifdef TCC_ARM_VFP
    669690        op=0xED000A00; /* fsts */
    670         if(!sign) 
    671           op|=0x800000; 
    672         if ((ft & VT_BTYPE) != VT_FLOAT) 
     691        if(!sign)
     692          op|=0x800000;
     693        if ((ft & VT_BTYPE) != VT_FLOAT)
    673694          op|=0x100;   /* fsts -> fstd */
    674695        o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
     
    700721        if(!sign)
    701722          op|=0x800000;
    702         if ((ft & VT_BTYPE) == VT_BYTE)
     723        if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
    703724          op|=0x400000;
    704725        o(op|(intr(r)<<12)|fc|(base<<16));
     
    722743    uint32_t x;
    723744    /* constant case */
    724     x=encbranch(ind,ind+vtop->c.ul,0);
     745    x=encbranch(ind,ind+vtop->c.i,0);
    725746    if(x) {
    726747      if (vtop->r & VT_SYM) {
     
    736757      if (vtop->r & VT_SYM)
    737758        greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
    738       o(vtop->c.ul);
     759      o(vtop->c.i);
    739760    }
    740761  } else {
     
    747768}
    748769
    749 #ifdef TCC_ARM_HARDFLOAT
    750 static int is_float_hgen_aggr(CType *type)
     770static int unalias_ldbl(int btype)
     771{
     772#if LDOUBLE_SIZE == 8
     773    if (btype == VT_LDOUBLE)
     774      btype = VT_DOUBLE;
     775#endif
     776    return btype;
     777}
     778
     779/* Return whether a structure is an homogeneous float aggregate or not.
     780   The answer is true if all the elements of the structure are of the same
     781   primitive float type and there is less than 4 elements.
     782
     783   type: the type corresponding to the structure to be tested */
     784static int is_hgen_float_aggr(CType *type)
    751785{
    752786  if ((type->t & VT_BTYPE) == VT_STRUCT) {
     
    754788    int btype, nb_fields = 0;
    755789
    756     ref = type->ref;
    757     btype = ref->type.t & VT_BTYPE;
     790    ref = type->ref->next;
     791    btype = unalias_ldbl(ref->type.t & VT_BTYPE);
    758792    if (btype == VT_FLOAT || btype == VT_DOUBLE) {
    759       for(; ref && btype == (ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
     793      for(; ref && btype == unalias_ldbl(ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
    760794      return !ref && nb_fields <= 4;
    761795    }
     
    765799
    766800struct avail_regs {
    767   /* worst case: f(float, double, 3 float struct, double, 3 float struct, double) */
    768   signed char avail[3];
    769   int first_hole;
    770   int last_hole;
    771   int first_free_reg;
     801  signed char avail[3]; /* 3 holes max with only float and double alignments */
     802  int first_hole; /* first available hole */
     803  int last_hole; /* last available hole (none if equal to first_hole) */
     804  int first_free_reg; /* next free register in the sequence, hole excluded */
    772805};
    773806
    774807#define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 }
    775808
    776 /* Assign a register for a CPRC param with correct size and alignment
    777  * size and align are in bytes, as returned by type_size */
    778 int assign_fpreg(struct avail_regs *avregs, int align, int size)
     809/* Find suitable registers for a VFP Co-Processor Register Candidate (VFP CPRC
     810   param) according to the rules described in the procedure call standard for
     811   the ARM architecture (AAPCS). If found, the registers are assigned to this
     812   VFP CPRC parameter. Registers are allocated in sequence unless a hole exists
     813   and the parameter is a single float.
     814
     815   avregs: opaque structure to keep track of available VFP co-processor regs
     816   align: alignment constraints for the param, as returned by type_size()
     817   size: size of the parameter, as returned by type_size() */
     818int assign_vfpreg(struct avail_regs *avregs, int align, int size)
    779819{
    780820  int first_reg = 0;
     
    782822  if (avregs->first_free_reg == -1)
    783823    return -1;
    784   if (align >> 3) { // alignment needed (base type: double)
     824  if (align >> 3) { /* double alignment */
    785825    first_reg = avregs->first_free_reg;
     826    /* alignment constraint not respected so use next reg and record hole */
    786827    if (first_reg & 1)
    787828      avregs->avail[avregs->last_hole++] = first_reg++;
    788   } else {
     829  } else { /* no special alignment (float or array of float) */
     830    /* if single float and a hole is available, assign the param to it */
    789831    if (size == 4 && avregs->first_hole != avregs->last_hole)
    790832      return avregs->avail[avregs->first_hole++];
     
    799841  return -1;
    800842}
    801 #endif
    802 
    803 /* Generate function call. The function address is pushed first, then
    804    all the parameters in call order. This functions pops all the
    805    parameters and the function address. */
    806 void gfunc_call(int nb_args)
    807 {
    808   int size, align, r, args_size, i, ncrn, ncprn, argno, vfp_argno;
    809   signed char plan[4][2]={{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
    810   SValue *before_stack = NULL; /* SValue before first on stack argument */
    811   SValue *before_vfpreg_hfa = NULL; /* SValue before first in VFP reg hfa argument */
    812 #ifdef TCC_ARM_HARDFLOAT
     843
     844/* Returns whether all params need to be passed in core registers or not.
     845   This is the case for function part of the runtime ABI. */
     846int floats_in_core_regs(SValue *sval)
     847{
     848  if (!sval->sym)
     849    return 0;
     850
     851  switch (sval->sym->v) {
     852    case TOK___floatundisf:
     853    case TOK___floatundidf:
     854    case TOK___fixunssfdi:
     855    case TOK___fixunsdfdi:
     856#ifndef TCC_ARM_VFP
     857    case TOK___fixunsxfdi:
     858#endif
     859    case TOK___floatdisf:
     860    case TOK___floatdidf:
     861    case TOK___fixsfdi:
     862    case TOK___fixdfdi:
     863      return 1;
     864
     865    default:
     866      return 0;
     867  }
     868}
     869
     870/* Return the number of registers needed to return the struct, or 0 if
     871   returning via struct pointer. */
     872ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
     873#ifdef TCC_ARM_EABI
     874    int size, align;
     875    size = type_size(vt, &align);
     876    if (float_abi == ARM_HARD_FLOAT && !variadic &&
     877        (is_float(vt->t) || is_hgen_float_aggr(vt))) {
     878        *ret_align = 8;
     879        *regsize = 8;
     880        ret->ref = NULL;
     881        ret->t = VT_DOUBLE;
     882        return (size + 7) >> 3;
     883    } else if (size <= 4) {
     884        *ret_align = 4;
     885        *regsize = 4;
     886        ret->ref = NULL;
     887        ret->t = VT_INT;
     888        return 1;
     889    } else
     890        return 0;
     891#else
     892    return 0;
     893#endif
     894}
     895
     896/* Parameters are classified according to how they are copied to their final
     897   destination for the function call. Because the copying is performed class
     898   after class according to the order in the union below, it is important that
     899   some constraints about the order of the members of this union are respected:
     900   - CORE_STRUCT_CLASS must come after STACK_CLASS;
     901   - CORE_CLASS must come after STACK_CLASS, CORE_STRUCT_CLASS and
     902     VFP_STRUCT_CLASS;
     903   - VFP_STRUCT_CLASS must come after VFP_CLASS.
     904   See the comment for the main loop in copy_params() for the reason. */
     905enum reg_class {
     906        STACK_CLASS = 0,
     907        CORE_STRUCT_CLASS,
     908        VFP_CLASS,
     909        VFP_STRUCT_CLASS,
     910        CORE_CLASS,
     911        NB_CLASSES
     912};
     913
     914struct param_plan {
     915    int start; /* first reg or addr used depending on the class */
     916    int end; /* last reg used or next free addr depending on the class */
     917    SValue *sval; /* pointer to SValue on the value stack */
     918    struct param_plan *prev; /*  previous element in this class */
     919};
     920
     921struct plan {
     922    struct param_plan *pplans; /* array of all the param plans */
     923    struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */
     924};
     925
     926#define add_param_plan(plan,pplan,class)                        \
     927    do {                                                        \
     928        pplan.prev = plan->clsplans[class];                     \
     929        plan->pplans[plan ## _nb] = pplan;                      \
     930        plan->clsplans[class] = &plan->pplans[plan ## _nb++];   \
     931    } while(0)
     932
     933/* Assign parameters to registers and stack with alignment according to the
     934   rules in the procedure call standard for the ARM architecture (AAPCS).
     935   The overall assignment is recorded in an array of per parameter structures
     936   called parameter plans. The parameter plans are also further organized in a
     937   number of linked lists, one per class of parameter (see the comment for the
     938   definition of union reg_class).
     939
     940   nb_args: number of parameters of the function for which a call is generated
     941   float_abi: float ABI in use for this function call
     942   plan: the structure where the overall assignment is recorded
     943   todo: a bitmap that record which core registers hold a parameter
     944
     945   Returns the amount of stack space needed for parameter passing
     946
     947   Note: this function allocated an array in plan->pplans with tcc_malloc. It
     948   is the responsibility of the caller to free this array once used (ie not
     949   before copy_params). */
     950static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
     951{
     952  int i, size, align;
     953  int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
     954  int plan_nb = 0;
     955  struct param_plan pplan;
    813956  struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
    814   signed char vfp_plan[16];
    815   int plan2[4+16];
    816   int variadic;
    817 #else
    818   int plan2[4]={0,0,0,0};
    819 #endif
    820   int vfp_todo=0;
    821   int todo=0, keep;
    822 
    823 #ifdef TCC_ARM_HARDFLOAT
    824   memset(vfp_plan, -1, sizeof(vfp_plan));
    825   memset(plan2, 0, sizeof(plan2));
    826   variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS);
    827 #endif
    828   r = vtop->r & VT_VALMASK;
    829   if (r == VT_CMP || (r & ~1) == VT_JMP)
    830     gv(RC_INT);
    831 #ifdef TCC_ARM_EABI
    832   if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT
    833      && type_size(&vtop[-nb_args].type.ref->type, &align) <= 4) {
    834     SValue tmp;
    835     tmp=vtop[-nb_args];
    836     vtop[-nb_args]=vtop[-nb_args+1];
    837     vtop[-nb_args+1]=tmp;
    838     --nb_args;
    839   }
    840  
    841   vpushi(0), nb_args++;
    842   vtop->type.t = VT_LLONG;
    843 #endif
    844   ncrn = ncprn = argno = vfp_argno = args_size = 0;
    845   /* Assign argument to registers and stack with alignment.
    846      If, considering alignment constraints, enough registers of the correct type
    847      (core or VFP) are free for the current argument, assign them to it, else
    848      allocate on stack with correct alignment. Whenever a structure is allocated
    849      in registers or on stack, it is always put on the stack at this stage. The
    850      stack is divided in 3 zones. The zone are, from low addresses to high
    851      addresses: structures to be loaded in core registers, structures to be
    852      loaded in VFP registers, argument allocated to stack. SValue's representing
    853      structures in the first zone are moved just after the SValue pointed by
    854      before_vfpreg_hfa. SValue's representing structures in the second zone are
    855      moved just after the SValue pointer by before_stack. */
     957
     958  ncrn = nsaa = 0;
     959  *todo = 0;
     960  plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
     961  memset(plan->clsplans, 0, sizeof(plan->clsplans));
    856962  for(i = nb_args; i-- ;) {
    857     int j, assigned_vfpreg = 0;
    858     size = type_size(&vtop[-i].type, &align);
     963    int j, start_vfpreg = 0;
     964    CType type = vtop[-i].type;
     965    type.t &= ~VT_ARRAY;
     966    size = type_size(&type, &align);
     967    size = (size + 3) & ~3;
     968    align = (align + 3) & ~3;
    859969    switch(vtop[-i].type.t & VT_BTYPE) {
    860970      case VT_STRUCT:
     
    862972      case VT_DOUBLE:
    863973      case VT_LDOUBLE:
    864 #ifdef TCC_ARM_HARDFLOAT
    865       if (!variadic) {
    866         int hfa = 0; /* Homogeneous float aggregate */
     974      if (float_abi == ARM_HARD_FLOAT) {
     975        int is_hfa = 0; /* Homogeneous float aggregate */
    867976
    868977        if (is_float(vtop[-i].type.t)
    869             || (hfa = is_float_hgen_aggr(&vtop[-i].type))) {
    870           int end_reg;
    871 
    872           assigned_vfpreg = assign_fpreg(&avregs, align, size);
    873           end_reg = assigned_vfpreg + (size - 1) / 4;
    874           if (assigned_vfpreg >= 0) {
    875             vfp_plan[vfp_argno++]=TREG_F0 + assigned_vfpreg/2;
    876             if (hfa) {
    877               /* before_stack can only have been set because all core registers
    878                  are assigned, so no need to care about before_vfpreg_hfa if
    879                  before_stack is set */
    880               if (before_stack) {
    881                 vrote(&vtop[-i], &vtop[-i] - before_stack);
    882                 before_stack++;
    883               } else if (!before_vfpreg_hfa)
    884                 before_vfpreg_hfa = &vtop[-i-1];
    885               for (j = assigned_vfpreg; j <= end_reg; j++)
    886                 vfp_todo|=(1<<j);
    887             }
     978            || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
     979          int end_vfpreg;
     980
     981          start_vfpreg = assign_vfpreg(&avregs, align, size);
     982          end_vfpreg = start_vfpreg + ((size - 1) >> 2);
     983          if (start_vfpreg >= 0) {
     984            pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]};
     985            if (is_hfa)
     986              add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
     987            else
     988              add_param_plan(plan, pplan, VFP_CLASS);
    888989            continue;
    889           } else {
    890             if (!hfa)
    891               vfp_argno++;
    892             /* No need to update before_stack as no more hfa can be allocated in
    893                VFP regs */
    894             if (!before_vfpreg_hfa)
    895               before_vfpreg_hfa = &vtop[-i-1];
     990          } else
    896991            break;
    897           }
    898992        }
    899993      }
    900 #endif
    901       ncrn = (ncrn + (align-1)/4) & -(align/4);
    902       size = (size + 3) & -4;
    903       if (ncrn + size/4 <= 4 || (ncrn < 4 && assigned_vfpreg != -1)) {
    904         /* Either there is HFA in VFP registers, or there is arguments on stack,
    905            it cannot be both. Hence either before_stack already points after
    906            the slot where the vtop[-i] SValue is moved, or before_stack will not
    907            be used */
    908         if (before_vfpreg_hfa) {
    909           vrote(&vtop[-i], &vtop[-i] - before_vfpreg_hfa);
    910           before_vfpreg_hfa++;
    911         }
     994      ncrn = (ncrn + (align-1)/4) & ~((align/4) - 1);
     995      if (ncrn + size/4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
     996        /* The parameter is allocated both in core register and on stack. As
     997         * such, it can be of either class: it would either be the last of
     998         * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
    912999        for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
    913           todo|=(1<<j);
    914         ncrn+=size/4;
    915         if (ncrn > 4) {
    916           args_size = (ncrn - 4) * 4;
    917           if (!before_stack)
    918             before_stack = &vtop[-i-1];
    919         }
    920       }
    921       else {
     1000          *todo|=(1<<j);
     1001        pplan = (struct param_plan) {ncrn, j, &vtop[-i]};
     1002        add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
     1003        ncrn += size/4;
     1004        if (ncrn > 4)
     1005          nsaa = (ncrn - 4) * 4;
     1006      } else {
    9221007        ncrn = 4;
    923         /* No need to set before_vfpreg_hfa if not set since there will no
    924            longer be any structure assigned to core registers */
    925         if (!before_stack)
    926           before_stack = &vtop[-i-1];
    9271008        break;
    9281009      }
    9291010      continue;
    9301011      default:
    931 #ifdef TCC_ARM_EABI
    932       if (!i) {
    933         break;
    934       }
    935 #endif
    9361012      if (ncrn < 4) {
    9371013        int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
     
    9391015        if (is_long) {
    9401016          ncrn = (ncrn + 1) & -2;
    941           if (ncrn == 4) {
    942             argno++;
     1017          if (ncrn == 4)
    9431018            break;
     1019        }
     1020        pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]};
     1021        ncrn++;
     1022        if (is_long)
     1023          pplan.end = ncrn++;
     1024        add_param_plan(plan, pplan, CORE_CLASS);
     1025        continue;
     1026      }
     1027    }
     1028    nsaa = (nsaa + (align - 1)) & ~(align - 1);
     1029    pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]};
     1030    add_param_plan(plan, pplan, STACK_CLASS);
     1031    nsaa += size; /* size already rounded up before */
     1032  }
     1033  return nsaa;
     1034}
     1035
     1036#undef add_param_plan
     1037
     1038/* Copy parameters to their final destination (core reg, VFP reg or stack) for
     1039   function call.
     1040
     1041   nb_args: number of parameters the function take
     1042   plan: the overall assignment plan for parameters
     1043   todo: a bitmap indicating what core reg will hold a parameter
     1044
     1045   Returns the number of SValue added by this function on the value stack */
     1046static int copy_params(int nb_args, struct plan *plan, int todo)
     1047{
     1048  int size, align, r, i, nb_extra_sval = 0;
     1049  struct param_plan *pplan;
     1050  int pass = 0;
     1051
     1052   /* Several constraints require parameters to be copied in a specific order:
     1053      - structures are copied to the stack before being loaded in a reg;
     1054      - floats loaded to an odd numbered VFP reg are first copied to the
     1055        preceding even numbered VFP reg and then moved to the next VFP reg.
     1056
     1057      It is thus important that:
     1058      - structures assigned to core regs must be copied after parameters
     1059        assigned to the stack but before structures assigned to VFP regs because
     1060        a structure can lie partly in core registers and partly on the stack;
     1061      - parameters assigned to the stack and all structures be copied before
     1062        parameters assigned to a core reg since copying a parameter to the stack
     1063        require using a core reg;
     1064      - parameters assigned to VFP regs be copied before structures assigned to
     1065        VFP regs as the copy might use an even numbered VFP reg that already
     1066        holds part of a structure. */
     1067again:
     1068  for(i = 0; i < NB_CLASSES; i++) {
     1069    for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
     1070
     1071      if (pass
     1072          && (i != CORE_CLASS || pplan->sval->r < VT_CONST))
     1073        continue;
     1074
     1075      vpushv(pplan->sval);
     1076      pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
     1077      switch(i) {
     1078        case STACK_CLASS:
     1079        case CORE_STRUCT_CLASS:
     1080        case VFP_STRUCT_CLASS:
     1081          if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
     1082            int padding = 0;
     1083            size = type_size(&pplan->sval->type, &align);
     1084            /* align to stack align size */
     1085            size = (size + 3) & ~3;
     1086            if (i == STACK_CLASS && pplan->prev)
     1087              padding = pplan->start - pplan->prev->end;
     1088            size += padding; /* Add padding if any */
     1089            /* allocate the necessary size on stack */
     1090            gadd_sp(-size);
     1091            /* generate structure store */
     1092            r = get_reg(RC_INT);
     1093            o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
     1094            vset(&vtop->type, r | VT_LVAL, 0);
     1095            vswap();
     1096            vstore(); /* memcpy to current sp + potential padding */
     1097
     1098            /* Homogeneous float aggregate are loaded to VFP registers
     1099               immediately since there is no way of loading data in multiple
     1100               non consecutive VFP registers as what is done for other
     1101               structures (see the use of todo). */
     1102            if (i == VFP_STRUCT_CLASS) {
     1103              int first = pplan->start, nb = pplan->end - first + 1;
     1104              /* vpop.32 {pplan->start, ..., pplan->end} */
     1105              o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
     1106              /* No need to write the register used to a SValue since VFP regs
     1107                 cannot be used for gcall_or_jmp */
     1108            }
     1109          } else {
     1110            if (is_float(pplan->sval->type.t)) {
     1111#ifdef TCC_ARM_VFP
     1112              r = vfpr(gv(RC_FLOAT)) << 12;
     1113              if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
     1114                size = 4;
     1115              else {
     1116                size = 8;
     1117                r |= 0x101; /* vpush.32 -> vpush.64 */
     1118              }
     1119              o(0xED2D0A01 + r); /* vpush */
     1120#else
     1121              r = fpr(gv(RC_FLOAT)) << 12;
     1122              if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
     1123                size = 4;
     1124              else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
     1125                size = 8;
     1126              else
     1127                size = LDOUBLE_SIZE;
     1128
     1129              if (size == 12)
     1130                r |= 0x400000;
     1131              else if(size == 8)
     1132                r|=0x8000;
     1133
     1134              o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
     1135#endif
     1136            } else {
     1137              /* simple type (currently always same size) */
     1138              /* XXX: implicit cast ? */
     1139              size=4;
     1140              if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
     1141                lexpand_nr();
     1142                size = 8;
     1143                r = gv(RC_INT);
     1144                o(0xE52D0004|(intr(r)<<12)); /* push r */
     1145                vtop--;
     1146              }
     1147              r = gv(RC_INT);
     1148              o(0xE52D0004|(intr(r)<<12)); /* push r */
     1149            }
     1150            if (i == STACK_CLASS && pplan->prev)
     1151              gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
    9441152          }
     1153          break;
     1154
     1155        case VFP_CLASS:
     1156          gv(regmask(TREG_F0 + (pplan->start >> 1)));
     1157          if (pplan->start & 1) { /* Must be in upper part of double register */
     1158            o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
     1159            vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
     1160          }
     1161          break;
     1162
     1163        case CORE_CLASS:
     1164          if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
     1165            lexpand_nr();
     1166            gv(regmask(pplan->end));
     1167            pplan->sval->r2 = vtop->r;
     1168            vtop--;
     1169          }
     1170          gv(regmask(pplan->start));
     1171          /* Mark register as used so that gcall_or_jmp use another one
     1172             (regs >=4 are free as never used to pass parameters) */
     1173          pplan->sval->r = vtop->r;
     1174          break;
     1175      }
     1176      vtop--;
     1177    }
     1178  }
     1179
     1180  /* second pass to restore registers that were saved on stack by accident.
     1181     Maybe redundant after the "lvalue_save" patch in tccgen.c:gv() */
     1182  if (++pass < 2)
     1183    goto again;
     1184
     1185  /* Manually free remaining registers since next parameters are loaded
     1186   * manually, without the help of gv(int). */
     1187  save_regs(nb_args);
     1188
     1189  if(todo) {
     1190    o(0xE8BD0000|todo); /* pop {todo} */
     1191    for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
     1192      int r;
     1193      pplan->sval->r = pplan->start;
     1194      /* An SValue can only pin 2 registers at best (r and r2) but a structure
     1195         can occupy more than 2 registers. Thus, we need to push on the value
     1196         stack some fake parameter to have on SValue for each registers used
     1197         by a structure (r2 is not used). */
     1198      for (r = pplan->start + 1; r <= pplan->end; r++) {
     1199        if (todo & (1 << r)) {
     1200          nb_extra_sval++;
     1201          vpushi(0);
     1202          vtop->r = r;
    9451203        }
    946         plan[argno++][0]=ncrn++;
    947         if (is_long) {
    948           plan[argno-1][1]=ncrn++;
    949         }
    950         continue;
    951       }
    952       argno++;
    953     }
     1204      }
     1205    }
     1206  }
     1207  return nb_extra_sval;
     1208}
     1209
     1210/* Generate function call. The function address is pushed first, then
     1211   all the parameters in call order. This functions pops all the
     1212   parameters and the function address. */
     1213void gfunc_call(int nb_args)
     1214{
     1215  int r, args_size;
     1216  int def_float_abi = float_abi;
     1217  int todo;
     1218  struct plan plan;
     1219
    9541220#ifdef TCC_ARM_EABI
    955     if(args_size & (align-1)) {
    956       vpushi(0);
    957       vtop->type.t = VT_VOID; /* padding */
    958       vrott(i+2);
    959       args_size += 4;
    960       nb_args++;
    961       argno++;
    962     }
    963 #endif
    964     args_size += (size + 3) & -4;
    965   }
     1221  int variadic;
     1222
     1223  if (float_abi == ARM_HARD_FLOAT) {
     1224    variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
     1225    if (variadic || floats_in_core_regs(&vtop[-nb_args]))
     1226      float_abi = ARM_SOFTFP_FLOAT;
     1227  }
     1228#endif
     1229  /* cannot let cpu flags if other instruction are generated. Also avoid leaving
     1230     VT_JMP anywhere except on the top of the stack because it would complicate
     1231     the code generator. */
     1232  r = vtop->r & VT_VALMASK;
     1233  if (r == VT_CMP || (r & ~1) == VT_JMP)
     1234    gv(RC_INT);
     1235
     1236  args_size = assign_regs(nb_args, float_abi, &plan, &todo);
     1237
    9661238#ifdef TCC_ARM_EABI
    967   vtop--, nb_args--;
    968 #endif
    969   args_size = keep = 0;
    970   for(i = 0;i < nb_args; i++) {
    971     vrotb(keep+1);
    972     if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
    973       size = type_size(&vtop->type, &align);
    974       /* align to stack align size */
    975       size = (size + 3) & -4;
    976       /* allocate the necessary size on stack */
    977       gadd_sp(-size);
    978       /* generate structure store */
    979       r = get_reg(RC_INT);
    980       o(0xE1A0000D|(intr(r)<<12));
    981       vset(&vtop->type, r | VT_LVAL, 0);
    982       vswap();
    983       vstore();
    984       vtop--;
    985       args_size += size;
    986     } else if (is_float(vtop->type.t)) {
    987 #ifdef TCC_ARM_HARDFLOAT
    988       if (!variadic && --vfp_argno<16 && vfp_plan[vfp_argno]!=-1) {
    989         plan2[keep++]=vfp_plan[vfp_argno];
    990         continue;
    991       }
    992 #endif
    993 #ifdef TCC_ARM_VFP
    994       r=vfpr(gv(RC_FLOAT))<<12;
    995       size=4;
    996       if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
    997       {
    998         size=8;
    999         r|=0x101; /* fstms -> fstmd */
    1000       }
    1001       o(0xED2D0A01+r);
    1002 #else
    1003       r=fpr(gv(RC_FLOAT))<<12;
    1004       if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
    1005         size = 4;
    1006       else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
    1007         size = 8;
    1008       else
    1009         size = LDOUBLE_SIZE;
    1010      
    1011       if (size == 12)
    1012         r|=0x400000;
    1013       else if(size == 8)
    1014         r|=0x8000;
    1015 
    1016       o(0xED2D0100|r|(size>>2));
    1017 #endif
    1018       vtop--;
    1019       args_size += size;
    1020     } else {
    1021       int s;
    1022       /* simple type (currently always same size) */
    1023       /* XXX: implicit cast ? */
    1024       size=4;
    1025       if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
    1026         lexpand_nr();
    1027         s=-1;
    1028         if(--argno<4 && plan[argno][1]!=-1)
    1029           s=plan[argno][1];
    1030         argno++;
    1031         size = 8;
    1032         if(s==-1) {
    1033           r = gv(RC_INT);
    1034           o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
    1035           vtop--;
    1036         } else {
    1037           size=0;
    1038           plan2[keep]=s;
    1039           keep++;
    1040           vswap();
    1041         }
    1042       }
    1043       s=-1;
    1044       if(--argno<4 && plan[argno][0]!=-1)
    1045         s=plan[argno][0];
    1046 #ifdef TCC_ARM_EABI
    1047       if(vtop->type.t == VT_VOID) {
    1048         if(s == -1)
    1049           o(0xE24DD004); /* sub sp,sp,#4 */
    1050         vtop--;
    1051       } else
    1052 #endif
    1053       if(s == -1) {
    1054         r = gv(RC_INT);
    1055         o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
    1056         vtop--;
    1057       } else {
    1058         size=0;
    1059         plan2[keep]=s;
    1060         keep++;
    1061       }
    1062       args_size += size;
    1063     }
    1064   }
    1065   for(i = 0; i < keep; i++) {
    1066     vrotb(keep);
    1067     gv(regmask(plan2[i]));
    1068 #ifdef TCC_ARM_HARDFLOAT
    1069     /* arg is in s(2d+1): plan2[i]<plan2[i+1] => alignment occured (ex f,d,f) */
    1070     if (i < keep - 1 && is_float(vtop->type.t) && (plan2[i] <= plan2[i + 1])) {
    1071       o(0xEEF00A40|(vfpr(plan2[i])<<12)|vfpr(plan2[i]));
    1072     }
    1073 #endif
    1074   }
    1075 save_regs(keep); /* save used temporary registers */
    1076   keep++;
    1077   if(ncrn) {
    1078     int nb_regs=0;
    1079     if (ncrn>4)
    1080       ncrn=4;
    1081     todo&=((1<<ncrn)-1);
    1082     if(todo) {
    1083       int i;
    1084       o(0xE8BD0000|todo);
    1085       for(i=0;i<4;i++)
    1086         if(todo&(1<<i)) {
    1087           vpushi(0);
    1088           vtop->r=i;
    1089           keep++;
    1090           nb_regs++;
    1091         }
    1092     }
    1093     args_size-=nb_regs*4;
    1094   }
    1095   if(vfp_todo) {
    1096     int nb_fregs=0;
    1097 
    1098     for(i=0;i<16;i++)
    1099       if(vfp_todo&(1<<i)) {
    1100         o(0xED9D0A00|(i&1)<<22|(i>>1)<<12|nb_fregs);
    1101         vpushi(0);
    1102         /* There might be 2 floats in a double VFP reg but that doesn't seem
    1103            to matter */
    1104         if (!(i%2))
    1105           vtop->r=TREG_F0+i/2;
    1106         keep++;
    1107         nb_fregs++;
    1108       }
    1109     if (nb_fregs) {
    1110       gadd_sp(nb_fregs*4);
    1111       args_size-=nb_fregs*4;
    1112     }
    1113   }
    1114   vrotb(keep);
     1239  if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
     1240    args_size = (args_size + 7) & ~7;
     1241    o(0xE24DD004); /* sub sp, sp, #4 */
     1242  }
     1243#endif
     1244
     1245  nb_args += copy_params(nb_args, &plan, todo);
     1246  tcc_free(plan.pplans);
     1247
     1248  /* Move fct SValue on top as required by gcall_or_jmp */
     1249  vrotb(nb_args + 1);
    11151250  gcall_or_jmp(0);
    11161251  if (args_size)
    1117       gadd_sp(args_size);
    1118 #ifdef TCC_ARM_EABI
    1119   if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT
    1120      && type_size(&vtop->type.ref->type, &align) <= 4)
    1121   {
    1122     store(REG_IRET,vtop-keep);
    1123     ++keep;
    1124   }
    1125 #ifdef TCC_ARM_VFP
    1126 #ifdef TCC_ARM_HARDFLOAT
    1127   else if(variadic && is_float(vtop->type.ref->type.t)) {
    1128 #else
    1129   else if(is_float(vtop->type.ref->type.t)) {
    1130 #endif
     1252      gadd_sp(args_size); /* pop all parameters passed on the stack */
     1253#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
     1254  if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
    11311255    if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
    1132       o(0xEE000A10); /* fmsr s0,r0 */
     1256      o(0xEE000A10); /*vmov s0, r0 */
    11331257    } else {
    1134       o(0xEE000B10); /* fmdlr d0,r0 */
    1135       o(0xEE201B10); /* fmdhr d0,r1 */
    1136     }
    1137   }
    1138 #endif
    1139 #endif
    1140   vtop-=keep;
    1141   leaffunc = 0;
     1258      o(0xEE000B10); /* vmov.32 d0[0], r0 */
     1259      o(0xEE201B10); /* vmov.32 d0[1], r1 */
     1260    }
     1261  }
     1262#endif
     1263  vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
     1264  leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
     1265  float_abi = def_float_abi;
    11421266}
    11431267
     
    11461270{
    11471271  Sym *sym,*sym2;
    1148   int n,nf,size,align, variadic, struct_ret = 0;
    1149 #ifdef TCC_ARM_HARDFLOAT
     1272  int n, nf, size, align, rs, struct_ret = 0;
     1273  int addr, pn, sn; /* pn=core, sn=stack */
     1274  CType ret_type;
     1275
     1276#ifdef TCC_ARM_EABI
    11501277  struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
    11511278#endif
     
    11531280  sym = func_type->ref;
    11541281  func_vt = sym->type;
     1282  func_var = (func_type->ref->f.func_type == FUNC_ELLIPSIS);
    11551283
    11561284  n = nf = 0;
    1157   variadic = (func_type->ref->c == FUNC_ELLIPSIS);
    1158   if((func_vt.t & VT_BTYPE) == VT_STRUCT
    1159      && type_size(&func_vt,&align) > 4)
     1285  if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
     1286      !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))
    11601287  {
    11611288    n++;
     
    11631290    func_vc = 12; /* Offset from fp of the place to store the result */
    11641291  }
    1165   for(sym2=sym->next;sym2 && (n<4 || nf<16);sym2=sym2->next) {
     1292  for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
    11661293    size = type_size(&sym2->type, &align);
    1167 #ifdef TCC_ARM_HARDFLOAT
    1168     if (!variadic && (is_float(sym2->type.t)
    1169         || is_float_hgen_aggr(&sym2->type))) {
    1170       int tmpnf = assign_fpreg(&avregs, align, size) + 1;
     1294#ifdef TCC_ARM_EABI
     1295    if (float_abi == ARM_HARD_FLOAT && !func_var &&
     1296        (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
     1297      int tmpnf = assign_vfpreg(&avregs, align, size);
     1298      tmpnf += (size + 3) / 4;
    11711299      nf = (tmpnf > nf) ? tmpnf : nf;
    11721300    } else
     
    11761304  }
    11771305  o(0xE1A0C00D); /* mov ip,sp */
    1178   if(variadic)
     1306  if (func_var)
    11791307    n=4;
    1180   if(n) {
     1308  if (n) {
    11811309    if(n>4)
    11821310      n=4;
     
    11951323  o(0xE1A0B00D); /* mov fp, sp */
    11961324  func_sub_sp_offset = ind;
    1197   o(0xE1A00000); /* nop, leave space for stack adjustment in epilogue */
    1198   {
    1199     int addr, pn = struct_ret, sn = 0; /* pn=core, sn=stack */
    1200 
    1201 #ifdef TCC_ARM_HARDFLOAT
     1325  o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
     1326
     1327#ifdef TCC_ARM_EABI
     1328  if (float_abi == ARM_HARD_FLOAT) {
     1329    func_vc += nf * 4;
    12021330    avregs = AVAIL_REGS_INITIALIZER;
    1203 #endif
    1204     while ((sym = sym->next)) {
    1205       CType *type;
    1206       type = &sym->type;
    1207       size = type_size(type, &align);
    1208       size = (size + 3) >> 2;
    1209       align = (align + 3) & ~3;
    1210 #ifdef TCC_ARM_HARDFLOAT
    1211       if (!variadic && (is_float(sym->type.t)
    1212           || is_float_hgen_aggr(&sym->type))) {
    1213         int fpn = assign_fpreg(&avregs, align, size << 2);
    1214         if (fpn >= 0) {
    1215           addr = fpn * 4;
    1216         } else
    1217           goto from_stack;
    1218       } else
    1219 #endif
    1220       if (pn < 4) {
     1331  }
     1332#endif
     1333  pn = struct_ret, sn = 0;
     1334  while ((sym = sym->next)) {
     1335    CType *type;
     1336    type = &sym->type;
     1337    size = type_size(type, &align);
     1338    size = (size + 3) >> 2;
     1339    align = (align + 3) & ~3;
     1340#ifdef TCC_ARM_EABI
     1341    if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
     1342        || is_hgen_float_aggr(&sym->type))) {
     1343      int fpn = assign_vfpreg(&avregs, align, size << 2);
     1344      if (fpn >= 0)
     1345        addr = fpn * 4;
     1346      else
     1347        goto from_stack;
     1348    } else
     1349#endif
     1350    if (pn < 4) {
    12211351#ifdef TCC_ARM_EABI
    12221352        pn = (pn + (align-1)/4) & -(align/4);
    12231353#endif
    1224         addr = (nf + pn) * 4;
    1225         pn += size;
    1226         if (!sn && pn > 4)
    1227           sn = (pn - 4);
    1228       } else {
    1229 #ifdef TCC_ARM_HARDFLOAT
     1354      addr = (nf + pn) * 4;
     1355      pn += size;
     1356      if (!sn && pn > 4)
     1357        sn = (pn - 4);
     1358    } else {
     1359#ifdef TCC_ARM_EABI
    12301360from_stack:
    1231 #endif
    1232 #ifdef TCC_ARM_EABI
    12331361        sn = (sn + (align-1)/4) & -(align/4);
    12341362#endif
    1235         addr = (n + nf + sn) * 4;
    1236         sn += size;
    1237       }
    1238       sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr+12);
    1239     }
     1363      addr = (n + nf + sn) * 4;
     1364      sn += size;
     1365    }
     1366    sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
     1367             addr + 12);
    12401368  }
    12411369  last_itod_magic=0;
     
    12491377  uint32_t x;
    12501378  int diff;
    1251 #ifdef TCC_ARM_EABI
    1252   /* Useless but harmless copy of the float result into main register(s) in case
    1253      of variadic function in the hardfloat variant */
    1254   if(is_float(func_vt.t)) {
     1379  /* Copy float return value to core register if base standard is used and
     1380     float computation is made with VFP */
     1381#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
     1382  if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
    12551383    if((func_vt.t & VT_BTYPE) == VT_FLOAT)
    12561384      o(0xEE100A10); /* fmrs r0, s0 */
     
    12871415{
    12881416  int r;
     1417  if (nocode_wanted)
     1418    return t;
    12891419  r=ind;
    12901420  o(0xE0000000|encbranch(r,t,1));
     
    13031433  int v, r;
    13041434  uint32_t op;
     1435
    13051436  v = vtop->r & VT_VALMASK;
    13061437  r=ind;
    1307   if (v == VT_CMP) {
     1438
     1439  if (nocode_wanted) {
     1440    ;
     1441  } else if (v == VT_CMP) {
    13081442    op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
    13091443    op|=encbranch(r,t,1);
     
    13321466      gsym(vtop->c.i);
    13331467    }
    1334   } else {
    1335     if (is_float(vtop->type.t)) {
    1336       r=gv(RC_FLOAT);
    1337 #ifdef TCC_ARM_VFP
    1338       o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */
    1339       o(0xEEF1FA10); /* fmstat */
    1340 #else
    1341       o(0xEE90F118|(fpr(r)<<16));
    1342 #endif
    1343       vtop->r = VT_CMP;
    1344       vtop->c.i = TOK_NE;
    1345       return gtst(inv, t);
    1346     } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    1347       /* constant jmp optimization */
    1348       if ((vtop->c.i != 0) != inv)
    1349         t = gjmp(t);
    1350     } else {
    1351       v = gv(RC_INT);
    1352       o(0xE3300000|(intr(v)<<16));
    1353       vtop->r = VT_CMP;
    1354       vtop->c.i = TOK_NE;
    1355       return gtst(inv, t);
    1356     }   
    13571468  }
    13581469  vtop--;
     
    15431654
    15441655/* generate a floating point operation 'v = t1 op t2' instruction. The
    1545  *    two operands are guaranted to have the same floating point type */
     1656 *    two operands are guaranteed to have the same floating point type */
    15461657void gen_opf(int op)
    15471658{
     
    16121723        case TOK_UGT: op=TOK_GT; break;
    16131724      }
    1614      
     1725
    16151726      vtop->r = VT_CMP;
    16161727      vtop->c.i = op;
     
    16731784
    16741785/* generate a floating point operation 'v = t1 op t2' instruction. The
    1675    two operands are guaranted to have the same floating point type */
     1786   two operands are guaranteed to have the same floating point type */
    16761787void gen_opf(int op)
    16771788{
     
    17631874        vswap();
    17641875        r2=fpr(gv(RC_FLOAT));
    1765       }     
     1876      }
    17661877      break;
    17671878    default:
     
    17751886          case TOK_ULE:
    17761887          case TOK_UGT:
    1777             tcc_error("unsigned comparision on floats?");
     1888            tcc_error("unsigned comparison on floats?");
    17781889            break;
    17791890          case TOK_LT:
     
    20002111}
    20012112
     2113/* Save the stack pointer onto the stack and return the location of its address */
     2114ST_FUNC void gen_vla_sp_save(int addr) {
     2115    SValue v;
     2116    v.type.t = VT_PTR;
     2117    v.r = VT_LOCAL | VT_LVAL;
     2118    v.c.i = addr;
     2119    store(TREG_SP, &v);
     2120}
     2121
     2122/* Restore the SP from a location on the stack */
     2123ST_FUNC void gen_vla_sp_restore(int addr) {
     2124    SValue v;
     2125    v.type.t = VT_PTR;
     2126    v.r = VT_LOCAL | VT_LVAL;
     2127    v.c.i = addr;
     2128    load(TREG_SP, &v);
     2129}
     2130
     2131/* Subtract from the stack pointer, and push the resulting value onto the stack */
     2132ST_FUNC void gen_vla_alloc(CType *type, int align) {
     2133    int r = intr(gv(RC_INT));
     2134    o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
     2135#ifdef TCC_ARM_EABI
     2136    if (align < 8)
     2137        align = 8;
     2138#else
     2139    if (align < 4)
     2140        align = 4;
     2141#endif
     2142    if (align & (align - 1))
     2143        tcc_error("alignment is not a power of 2: %i", align);
     2144    o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
     2145    vpop();
     2146}
     2147
    20022148/* end of ARM code generator */
    20032149/*************************************************************/
  • EcnlProtoTool/trunk/tcc-0.9.27/c67-gen.c

    r321 r331  
    2121#ifdef TARGET_DEFS_ONLY
    2222
    23 //#define ASSEMBLY_LISTING_C67
     23/* #define ASSEMBLY_LISTING_C67 */
    2424
    2525/* number of available registers */
     
    9494
    9595/* defined if function parameters must be evaluated in reverse order */
    96 //#define INVERT_FUNC_PARAMS
     96/* #define INVERT_FUNC_PARAMS */
    9797
    9898/* defined if structures are passed as pointers. Otherwise structures
    9999   are directly pushed on stack. */
    100 //#define FUNC_STRUCT_PARAM_AS_PTR
     100/* #define FUNC_STRUCT_PARAM_AS_PTR */
    101101
    102102/* pointer size, in bytes */
     
    108108/* maximum alignment (for aligned attribute support) */
    109109#define MAX_ALIGN     8
    110 
    111 /******************************************************/
    112 /* ELF defines */
    113 
    114 #define EM_TCC_TARGET EM_C60
    115 
    116 /* relocation type for 32 bit data relocation */
    117 #define R_DATA_32   R_C60_32
    118 #define R_DATA_PTR  R_C60_32
    119 #define R_JMP_SLOT  R_C60_JMP_SLOT
    120 #define R_COPY      R_C60_COPY
    121 
    122 #define ELF_START_ADDR 0x00000400
    123 #define ELF_PAGE_SIZE  0x1000
    124110
    125111/******************************************************/
     
    197183{
    198184    int ind1;
    199 
     185    if (nocode_wanted)
     186        return;
    200187#ifdef ASSEMBLY_LISTING_C67
    201188    fprintf(f, " %08X", c);
     
    246233
    247234// these are regs that tcc doesn't really know about,
    248 // but asign them unique values so the mapping routines
    249 // can distinquish them
     235// but assign them unique values so the mapping routines
     236// can distinguish them
    250237
    251238#define C67_A0 105
     
    254241#define C67_FP 108
    255242#define C67_B2 109
    256 #define C67_CREG_ZERO -1        // Special code for no condition reg test
     243#define C67_CREG_ZERO -1        /* Special code for no condition reg test */
    257244
    258245
     
    15681555    fr = sv->r;
    15691556    ft = sv->type.t;
    1570     fc = sv->c.ul;
     1557    fc = sv->c.i;
    15711558
    15721559    v = fr & VT_VALMASK;
     
    15751562            v1.type.t = VT_INT;
    15761563            v1.r = VT_LOCAL | VT_LVAL;
    1577             v1.c.ul = fc;
     1564            v1.c.i = fc;
    15781565            load(r, &v1);
    15791566            fr = r;
     
    17271714
    17281715    ft = v->type.t;
    1729     fc = v->c.ul;
     1716    fc = v->c.i;
    17301717    fr = v->r & VT_VALMASK;
    17311718    bt = ft & VT_BTYPE;
     
    18801867}
    18811868
     1869/* Return the number of registers needed to return the struct, or 0 if
     1870   returning via struct pointer. */
     1871ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
     1872    *ret_align = 1; // Never have to re-align return values for x86-64
     1873    return 0;
     1874}
     1875
    18821876/* generate function call with address in (vtop->t, vtop->c) and free function
    18831877   context. Stack entry is popped */
     
    18941888    for (i = 0; i < nb_args; i++) {
    18951889        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
    1896             ALWAYS_ASSERT(FALSE);
    1897         } else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
    18981890            ALWAYS_ASSERT(FALSE);
    18991891        } else {
     
    19601952
    19611953    sym = func_type->ref;
    1962     func_call = sym->r;
     1954    func_call = sym->f.func_call;
    19631955    addr = 8;
    19641956    /* if the function returns a structure, then add an
    19651957       implicit pointer parameter */
    19661958    func_vt = sym->type;
     1959    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
    19671960    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
    19681961        func_vc = addr;
     
    20472040{
    20482041    int ind1 = ind;
     2042    if (nocode_wanted)
     2043        return t;
    20492044
    20502045    C67_MVKL(C67_A0, t);        //r=reg to load,  constant
     
    20792074
    20802075    v = vtop->r & VT_VALMASK;
    2081     if (v == VT_CMP) {
     2076    if (nocode_wanted) {
     2077        ;
     2078    } else if (v == VT_CMP) {
    20822079        /* fast case : can jump directly since flags are set */
    20832080        // C67 uses B2 sort of as flags register
     
    21012098        if ((v & 1) == inv) {
    21022099            /* insert vtop->c jump list in t */
    2103             p = &vtop->c.i;
    21042100
    21052101            // I guess the idea is to traverse to the
     
    21072103            // there
    21082104
    2109             n = *p;
     2105            n = vtop->c.i;
    21102106            while (n != 0) {
    21112107                p = (int *) (cur_text_section->data + n);
     
    21222118            t = gjmp(t);
    21232119            gsym(vtop->c.i);
    2124         }
    2125     } else {
    2126         if (is_float(vtop->type.t)) {
    2127             vpushi(0);
    2128             gen_op(TOK_NE);
    2129         }
    2130         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    2131             /* constant jmp optimization */
    2132             if ((vtop->c.i != 0) != inv)
    2133                 t = gjmp(t);
    2134         } else {
    2135             // I think we need to get the value on the stack
    2136             // into a register, test it, and generate a branch
    2137             // return the address of the branch, so it can be
    2138             // later patched
    2139 
    2140             v = gv(RC_INT);     // get value into a reg
    2141             ind1 = ind;
    2142             C67_MVKL(C67_A0, t);        //r=reg to load, constant
    2143             C67_MVKH(C67_A0, t);        //r=reg to load, constant
    2144 
    2145             if (v != TREG_EAX &&        // check if not already in a conditional test reg
    2146                 v != TREG_EDX && v != TREG_ST0 && v != C67_B2) {
    2147                 C67_MV(v, C67_B2);
    2148                 v = C67_B2;
    2149             }
    2150 
    2151             C67_IREG_B_REG(inv, v, C67_A0);     // [!R] B.S2x  A0
    2152             C67_NOP(5);
    2153             t = ind1;           //return where we need to patch
    2154             ind1 = ind;
    21552120        }
    21562121    }
     
    22612226        fr = vtop[0].r;
    22622227        vtop--;
    2263         C67_MPYI(fr, r);        // 32 bit bultiply  fr,r,fr
     2228        C67_MPYI(fr, r);        // 32 bit multiply  fr,r,fr
    22642229        C67_NOP(8);             // NOP 8 for worst case
    22652230        break;
     
    23182283
    23192284/* generate a floating point operation 'v = t1 op t2' instruction. The
    2320    two operands are guaranted to have the same floating point type */
     2285   two operands are guaranteed to have the same floating point type */
    23212286/* XXX: need to use ST1 too */
    23222287void gen_opf(int op)
     
    23302295
    23312296    ft = vtop->type.t;
    2332     fc = vtop->c.ul;
     2297    fc = vtop->c.i;
    23332298    r = vtop->r;
    23342299    fr = vtop[-1].r;
     
    25552520}
    25562521
     2522/* Save the stack pointer onto the stack and return the location of its address */
     2523ST_FUNC void gen_vla_sp_save(int addr) {
     2524    tcc_error("variable length arrays unsupported for this target");
     2525}
     2526
     2527/* Restore the SP from a location on the stack */
     2528ST_FUNC void gen_vla_sp_restore(int addr) {
     2529    tcc_error("variable length arrays unsupported for this target");
     2530}
     2531
     2532/* Subtract from the stack pointer, and push the resulting value onto the stack */
     2533ST_FUNC void gen_vla_alloc(CType *type, int align) {
     2534    tcc_error("variable length arrays unsupported for this target");
     2535}
     2536
    25572537/* end of C67 code generator */
    25582538/*************************************************************/
  • EcnlProtoTool/trunk/tcc-0.9.27/coff.h

    r321 r331  
    2323#define  F_RELFLG   0x01       /* relocation info stripped from file       */
    2424#define  F_EXEC     0x02       /* file is executable (no unresolved refs)  */
    25 #define  F_LNNO     0x04       /* line nunbers stripped from file          */
     25#define  F_LNNO     0x04       /* line numbers stripped from file          */
    2626#define  F_LSYMS    0x08       /* local symbols stripped from file         */
    2727#define  F_GSP10    0x10       /* 34010 version                            */
     
    3838#define FILHDR  struct filehdr
    3939
    40 //#define FILHSZ  sizeof(FILHDR)
    41 #define FILHSZ  22                // above rounds to align on 4 bytes which causes problems
     40/* #define FILHSZ  sizeof(FILHDR)  */
     41#define FILHSZ  22                /* above rounds to align on 4 bytes which causes problems */
    4242
    4343#define COFF_C67_MAGIC 0x00c2
     
    154154/* Define constants for names of "special" sections                       */
    155155/*------------------------------------------------------------------------*/
    156 //#define _TEXT    ".text"
     156/* #define _TEXT    ".text" */
    157157#define _DATA    ".data"
    158158#define _BSS     ".bss"
  • EcnlProtoTool/trunk/tcc-0.9.27/config.h

    r321 r331  
    11/* Automatically generated by configure - do not modify */
    22#ifndef CONFIG_TCCDIR
    3 # define CONFIG_TCCDIR "0:/lib/tcc"
     3# define CONFIG_TCCDIR "1:/lib"
    44#endif
    5 #define GCC_MAJOR
    6 #define GCC_MINOR
    7 #define HOST_ARM 1
    8 #define TCC_ARM_VERSION 7
    9 #define TCC_VERSION "0.9.26"
    10 #define CONFIG_TCC_STATIC
     5#define CONFIG_TCC_CRTPREFIX "1:/lib"
     6#define CONFIG_TCC_SYSINCLUDEPATHS "1:/include"
     7#define TCC_VERSION "0.9.27"
  • EcnlProtoTool/trunk/tcc-0.9.27/config.mak

    r279 r331  
    11# Automatically generated by configure - do not modify
    2 prefix=0:
    3 bindir=$(DESTDIR)0:/bin
    4 tccdir=$(DESTDIR)0:/lib/tcc
    5 libdir=$(DESTDIR)0:/lib
    6 ln_libdir=0:/lib
    7 includedir=$(DESTDIR)0:/include
    8 mandir=$(DESTDIR)0:/share/man
    9 infodir=$(DESTDIR)0:/share/info
    10 docdir=$(DESTDIR)0:/share/doc/tcc
     2prefix=1:
     3bindir=$(DESTDIR)1:
     4tccdir=$(DESTDIR)1:
     5libdir=$(DESTDIR)1:/libtcc
     6includedir=$(DESTDIR)
     7mandir=$(DESTDIR)
     8infodir=$(DESTDIR)
     9docdir=$(DESTDIR)1:/doc
    1110CC=arm-none-eabi-gcc
    12 GCC_MAJOR=
    13 GCC_MINOR=
    14 HOST_CC=gcc
     11GCC_MAJOR=0
     12GCC_MINOR=0
    1513AR=arm-none-eabi-ar
    1614STRIP=arm-none-eabi-strip -s -R .comment -R .note
    17 CFLAGS=-Wall -g -O2
    18 LDFLAGS=
     15CFLAGS=-Wall -g -Og -nostdinc -I$(TOP)/../musl-1.1.18/include -mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfp -Dtcc_main=main -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result
     16LDFLAGS=-Wl,-e_start_c -nostdlib $(TOP)/../musl-1.1.18/lib/crtn.o $(TOP)/../musl-1.1.18/lib/crti.o $(TOP)/../musl-1.1.18/lib/rcrt1.o -L$(TOP)/../musl-1.1.18/lib -L. -lc -lgcc
    1917LIBSUF=.a
    20 EXESUF=
     18EXESUF=.elf
     19DLLSUF=.so
     20NATIVE_DEFINES+=-DTCC_CPU_VERSION=7
    2121ARCH=arm
    2222TARGETOS=
    23 VERSION=0.9.26
    24 SRC_PATH=.
    25 top_srcdir=$(TOP)
    26 top_builddir=$(TOP)
    27 CONFIG_NOLDL=yes
     23#CONFIG_libgcc=yes
     24CONFIG_musl=yes
     25VERSION = 0.9.27
     26TOPSRC=$(TOP)
     27arm-libtcc1-usegcc=yes
  • EcnlProtoTool/trunk/tcc-0.9.27/config.texi

    r279 r331  
    1 @set VERSION 0.9.26
     1@set VERSION 0.9.27
  • EcnlProtoTool/trunk/tcc-0.9.27/configure

    r279 r331  
    1818
    1919# default parameters
    20 build_cross="no"
    21 use_libgcc="no"
    2220prefix=""
    2321execprefix=""
     
    3129cross_prefix=""
    3230cc="gcc"
    33 host_cc="gcc"
    3431ar="ar"
    3532strip="strip"
    36 cygwin="no"
    37 gprof="no"
    3833bigendian="no"
    3934mingw32="no"
    4035LIBSUF=".a"
    4136EXESUF=""
     37DLLSUF=".so"
    4238tcc_sysincludepaths=""
    4339tcc_libpaths=""
    4440tcc_crtprefix=""
    4541tcc_elfinterp=""
     42triplet=
    4643tcc_lddir=
    4744confvars=
    48 
    49 #cpu=`uname -m`
    50 cpu="armv7a"
     45suggest="yes"
     46cpu=
     47cpuver=
     48gcc_major=0
     49gcc_minor=0
    5150
    5251# OS specific
    53 #targetos=`uname -s`
    54 targetos=""
     52targetos=`uname`
    5553case $targetos in
    56   MINGW32*)  mingw32=yes;;
    57   DragonFly) noldl=yes;;
    58   OpenBSD)   noldl=yes;;
    59   *) ;;
     54  Darwin)
     55    confvars="$confvars OSX"
     56    DLLSUF=".dylib"
     57    ;;
     58  MINGW*|MSYS*|CYGWIN*)
     59    mingw32=yes
     60    ;;
     61  DragonFly|OpenBSD|FreeBSD|NetBSD)
     62    confvars="$confvars ldl=no"
     63    ;;
     64  *)
     65    ;;
    6066esac
    6167
    6268# find source path
    63 # XXX: we assume an absolute path is given when launching configure,
    64 # except in './configure' case.
    6569source_path=${0%configure}
    6670source_path=${source_path%/}
     
    7175fi
    7276
    73 case "$cpu" in
    74   i386|i486|i586|i686|i86pc|BePC|i686-AT386)
    75     cpu="x86"
    76   ;;
    77   x86_64)
    78     cpu="x86-64"
    79   ;;
    80   arm*)
    81     case "$cpu" in
    82       arm|armv4l)
    83         cpuver=4
    84       ;;
    85       armv5tel|armv5tejl)
    86         cpuver=5
    87       ;;
    88       armv6j|armv6l)
    89         cpuver=6
    90       ;;
    91       armv7a|armv7l)
    92         cpuver=7
    93       ;;
    94     esac
    95     cpu="armv4l"
    96   ;;
    97   alpha)
    98     cpu="alpha"
    99   ;;
    100   "Power Macintosh"|ppc|ppc64)
    101     cpu="powerpc"
    102   ;;
    103   mips)
    104     cpu="mips"
    105   ;;
    106   s390)
    107     cpu="s390"
    108   ;;
    109   *)
    110     cpu="unknown"
    111   ;;
    112 esac
    113 
    11477for opt do
    11578  eval opt=\"$opt\"
     
    143106  --cc=*) cc=`echo $opt | cut -d '=' -f 2`
    144107  ;;
     108  --ar=*) ar=`echo $opt | cut -d '=' -f 2`
     109  ;;
    145110  --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
    146111  ;;
    147112  --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
    148113  ;;
    149   --extra-libs=*) extralibs=${opt#--extra-libs=}
     114  --extra-libs=*) extralibs="${opt#--extra-libs=}"
    150115  ;;
    151116  --sysincludepaths=*) tcc_sysincludepaths=`echo $opt | cut -d '=' -f 2`
     
    157122  --elfinterp=*) tcc_elfinterp=`echo $opt | cut -d '=' -f 2`
    158123  ;;
     124  --triplet=*) triplet=`echo $opt | cut -d '=' -f 2`
     125  ;;
    159126  --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
    160127  ;;
    161   --enable-gprof) gprof="yes"
    162   ;;
    163   --enable-mingw32) mingw32="yes" ; cross_prefix="i686-pc-mingw32-" ; cpu=x86
    164   ;;
    165   --enable-cygwin) mingw32="yes" ; cygwin="yes" ; cross_prefix="mingw32-" ; cpu=x86
    166   ;;
    167   --enable-cross) build_cross="yes"
    168   ;;
    169   --disable-static) disable_static="yes"
    170   ;;
    171   --disable-rpath) disable_rpath="yes"
    172   ;;
    173   --strip-binaries) strip_binaries="yes"
    174   ;;
    175   --with-libgcc) use_libgcc="yes"
    176   ;;
    177   --with-selinux) have_selinux="yes"
     128  --enable-cross) confvars="$confvars cross"
     129  ;;
     130  --disable-static) confvars="$confvars static=no"
     131  ;;
     132  --enable-static) confvars="$confvars static"
     133  ;;
     134  --disable-rpath) confvars="$confvars rpath=no"
     135  ;;
     136  --strip-binaries) confvars="$confvars strip"
     137  ;;
     138  --with-libgcc) confvars="$confvars libgcc"
     139  ;;
     140  --with-selinux) confvars="$confvars selinux"
     141  ;;
     142  --config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2)
     143  ;;
     144  --config-*) confvars="$confvars ${opt#--config-}"; suggest="no"
    178145  ;;
    179146  --help|-h) show_help="yes"
     
    183150  esac
    184151done
     152
     153if test -z "$cpu" ; then
     154    if test -n "$ARCH" ; then
     155        cpu="$ARCH"
     156    else
     157        cpu=`uname -m`
     158    fi
     159fi
     160
     161case "$cpu" in
     162  x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
     163    cpu="i386"
     164  ;;
     165  x86_64|amd64|x86-64)
     166    cpu="x86_64"
     167  ;;
     168  arm*)
     169    case "$cpu" in
     170      arm|armv4l)
     171        cpuver=4
     172      ;;
     173      armv5tel|armv5tejl)
     174        cpuver=5
     175      ;;
     176      armv6j|armv6l)
     177        cpuver=6
     178      ;;
     179      armv7a|armv7l)
     180        cpuver=7
     181      ;;
     182    esac
     183    cpu="arm"
     184  ;;
     185  aarch64)
     186    cpu="aarch64"
     187  ;;
     188  alpha)
     189    cpu="alpha"
     190  ;;
     191  "Power Macintosh"|ppc|ppc64)
     192    cpu="ppc"
     193  ;;
     194  mips)
     195    cpu="mips"
     196  ;;
     197  s390)
     198    cpu="s390"
     199  ;;
     200  *)
     201    echo "Unsupported CPU"
     202    exit 1
     203  ;;
     204esac
    185205
    186206# Checking for CFLAGS
     
    190210
    191211if test "$mingw32" = "yes" ; then
    192     if test x"$tccdir" = x""; then
    193     tccdir="tcc"
    194     fi
    195     if test -z "$prefix" ; then
    196     prefix="C:/Program Files/${tccdir}"
    197     fi
    198     if test -z "$sharedir" ; then
    199     sharedir="${prefix}"
    200     fi
    201     execprefix="$prefix"
    202     bindir="${prefix}"
    203     tccdir="${prefix}"
    204     libdir="${prefix}/lib"
    205     docdir="${sharedir}/doc"
    206     mandir="${sharedir}/man"
    207     infodir="${sharedir}/info"
     212    if test "$source_path_used" = "no"; then
     213      source_path="."
     214    fi
     215    if test "$cc" = gcc; then
     216      test -z "$LDFLAGS" && LDFLAGS="-static"
     217    fi
     218    test -z "$prefix" && prefix="C:/Program Files/tcc"
     219    test -z "$tccdir" && tccdir="${prefix}"
     220    test -z "$bindir" && bindir="${tccdir}"
     221    test -z "$docdir" && docdir="${tccdir}/doc"
     222    test -z "$libdir" && libdir="${tccdir}/libtcc"
     223    confvars="$confvars WIN32"
    208224    LIBSUF=".lib"
    209225    EXESUF=".exe"
     226    DLLSUF=".dll"
    210227else
    211228    if test -z "$prefix" ; then
    212     prefix="/usr/local"
     229      prefix="/usr/local"
    213230    fi
    214231    if test -z "$sharedir" ; then
    215     sharedir="${prefix}/share"
     232      sharedir="${prefix}/share"
    216233    fi
    217234    if test x"$execprefix" = x""; then
    218     execprefix="${prefix}"
     235      execprefix="${prefix}"
    219236    fi
    220237    if test x"$libdir" = x""; then
    221     libdir="${execprefix}/lib"
     238      libdir="${execprefix}/lib"
    222239    fi
    223240    if test x"$bindir" = x""; then
    224     bindir="${execprefix}/bin"
     241      bindir="${execprefix}/bin"
     242    fi
     243    if test x"$docdir" = x""; then
     244      docdir="${sharedir}/doc"
     245    fi
     246    if test x"$mandir" = x""; then
     247      mandir="${sharedir}/man"
     248    fi
     249    if test x"$infodir" = x""; then
     250      infodir="${sharedir}/info"
    225251    fi
    226252    if test x"$tccdir" = x""; then
    227     tccdir="tcc"
    228     fi
    229     if test x"$docdir" = x""; then
    230     docdir="${sharedir}/doc/${tccdir}"
    231     fi
    232     if test x"$mandir" = x""; then
    233     mandir="${sharedir}/man"
    234     fi
    235     if test x"$infodir" = x""; then
    236     infodir="${sharedir}/info"
    237     fi
    238     tccdir="${libdir}/${tccdir}"
     253      tccdir="${libdir}/tcc"
     254    fi
     255    if test x"$includedir" = x""; then
     256      includedir="${prefix}/include"
     257    fi
    239258fi # mingw32
    240 
    241 if test x"$includedir" = x""; then
    242 includedir="${prefix}/include"
    243 fi
    244259
    245260if test x"$show_help" = "xyes" ; then
     
    252267  --prefix=PREFIX          install in PREFIX [$prefix]
    253268  --exec-prefix=EPREFIX    install architecture-dependent files in EPREFIX
    254                            [same as prefix]
     269                           [same as prefix]
    255270  --bindir=DIR             user executables in DIR [EPREFIX/bin]
    256271  --libdir=DIR             object code libraries in DIR [EPREFIX/lib]
     
    267282  --sysroot=PREFIX         prepend PREFIX to library/include paths []
    268283  --cc=CC                  use C compiler CC [$cc]
     284  --ar=AR                  create archives using AR [$ar]
    269285  --extra-cflags=          specify compiler flags [$CFLAGS]
    270286  --extra-ldflags=         specify linker options []
     287  --cpu=CPU                CPU [$cpu]
    271288  --strip-binaries         strip symbol tables from resulting binaries
    272289  --disable-static         make libtcc.so instead of libtcc.a
     290  --enable-static          make libtcc.a instead of libtcc.dll (win32)
    273291  --disable-rpath          disable use of -rpath with the above
    274   --with-libgcc            use /lib/libgcc_s.so.1 instead of libtcc.a
    275   --enable-mingw32         build windows version on linux with mingw32
    276   --enable-cygwin          build windows version on windows with cygwin
     292  --with-libgcc            use libgcc_s.so.1 instead of libtcc1.a
    277293  --enable-cross           build cross compilers
    278   --with-selinux           use mmap for exec mem [needs writable /tmp]
     294  --with-selinux           use mmap for executable memory (with tcc -run)
    279295  --sysincludepaths=...    specify system include paths, colon separated
    280296  --libpaths=...           specify system library paths, colon separated
    281297  --crtprefix=...          specify locations of crt?.o, colon separated
    282298  --elfinterp=...          specify elf interpreter
     299  --triplet=...            specify system library/include directory triplet
     300  --config-uClibc,-musl,-mingw32... enable system specific configurations
    283301EOF
    284302#echo "NOTE: The object files are build at the place where configure is launched"
     
    290308strip="${cross_prefix}${strip}"
    291309
    292 CONFTEST=./conftest$EXESUF
    293 
    294310if test -z "$cross_prefix" ; then
     311  CONFTEST=./conftest$EXESUF
    295312  if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
    296313    echo "configure: error: '$cc' failed to compile conftest.c."
    297314  else
    298     bigendian="$($CONFTEST bigendian)"
    299315    gcc_major="$($CONFTEST version)"
    300316    gcc_minor="$($CONFTEST minor)"
    301     if test "$mingw32" = "no" ; then
    302       triplet="$($CONFTEST triplet)"
    303       if test -f "/usr/lib/$triplet/crti.o" ; then
    304         tcc_lddir="lib/$triplet"
    305         multiarch_triplet="$triplet"
    306       elif test -f "/usr/lib64/crti.o" ; then
    307         tcc_lddir="lib64"
    308       fi
    309 
    310       if test "$cpu" = "armv4l" ; then
    311         if test "${triplet%eabihf}" != "$triplet" ; then
    312            confvars="$confvars arm_eabihf"
    313         elif test "${triplet%eabi}" != "$triplet" ; then
    314            confvars="$confvars arm_eabi"
    315         fi
    316         if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
    317            confvars="$confvars arm_vfp"
     317  fi
     318  bigendian="$($CONFTEST bigendian)"
     319  if test "$mingw32" = "no" ; then
     320
     321      if test -z "$triplet"; then
     322        tt="$($CONFTEST triplet)"
     323        if test -n "$tt" -a -f "/usr/lib/$tt/crti.o" ; then
     324          triplet="$tt"
    318325        fi
    319326      fi
    320327
    321 #      multiarch_triplet=${libc_dir#*/}
    322 #      multiarch_triplet=${multiarch_triplet%/}
    323 #      tcc_lddir="${libc_dir%%/*}"
    324 #      if test -n "$multiarch_triplet" ; then
    325 #        tcc_lddir="$tcc_lddir/$multiarch_triplet"
    326 #      fi
    327 
    328       if test -f "/lib/ld-uClibc.so.0" ; then
    329         confvars="$confvars uClibc"
     328      if test -z "$triplet"; then
     329        if test $cpu = "x86_64" -o $cpu = "aarch64" ; then
     330          if test -f "/usr/lib64/crti.o" ; then
     331            tcc_lddir="lib64"
     332          fi
     333        fi
    330334      fi
    331 # gr: maybe for after the release:
    332 #       tcc_elfinterp="$(ldd $CONFTEST | grep 'ld.*.so' | sed 's,\s*\(\S\+\).*,\1,')"
    333        # echo "elfinterp           $tcc_elfinterp"
    334 
    335     fi
     335
     336      if test "$cpu" = "arm" ; then
     337        if test "${triplet%eabihf}" != "$triplet" ; then
     338           confvars="$confvars arm_eabihf"
     339        elif test "${triplet%eabi}" != "$triplet" ; then
     340           confvars="$confvars arm_eabi"
     341        fi
     342        if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
     343           confvars="$confvars arm_vfp"
     344        fi
     345      fi
     346
     347      if test "$suggest" = "yes"; then
     348        if test -f "/lib/ld-uClibc.so.0" ; then
     349          echo "Perhaps you want ./configure --config-uClibc"
     350        fi
     351        if test -f "/lib/ld-musl-$cpu.so.1"; then
     352          echo "Perhaps you want ./configure --config-musl"
     353        fi
     354      fi
    336355  fi
    337356else
    338357  # if cross compiling, cannot launch a program, so make a static guess
    339358  case $cpu in
    340     powerpc|mips|s390)  bigendian=yes;;
     359    ppc|mips|s390)  bigendian=yes;;
    341360  esac
    342361fi
    343362
    344 cat <<EOF
    345 Binary  directory   $bindir
    346 TinyCC directory    $tccdir
    347 Library directory   $libdir
    348 Include directory   $includedir
    349 Manual directory    $mandir
    350 Info directory      $infodir
    351 Doc directory       $docdir
    352 Target root prefix  $sysroot
    353 Source path      $source_path
    354 C compiler       $cc
    355 Target OS        $targetos
    356 CPU              $cpu
    357 Big Endian       $bigendian
    358 gprof enabled    $gprof
    359 cross compilers  $build_cross
    360 use libgcc       $use_libgcc
    361 EOF
    362 
     363if test "$bigendian" = "yes" ; then
     364  confvars="$confvars BIGENDIAN"
     365fi
     366
     367# a final configuration tuning
     368if ! echo "$cc" | grep -q "tcc"; then
     369  OPT1="-Wdeclaration-after-statement -fno-strict-aliasing"
     370  # we want -Wno- but gcc does not always reject unknown -Wno- options
     371  OPT2="-Wpointer-sign -Wsign-compare -Wunused-result"
     372  if echo "$cc" | grep -q "clang"; then
     373    OPT1="$OPT1 -fheinous-gnu-extensions"
     374    OPT2="$OPT2 -Wstring-plus-int"
     375  fi
     376  $cc $OPT1 $OPT2 -o a.out -c -xc - < /dev/null > cc_msg.txt 2>&1
     377  for o in $OPT1; do # enable these options
     378    if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS $o"; fi
     379  done
     380  for o in $OPT2; do # disable these options
     381    if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS -Wno-${o#-W*}"; fi
     382  done
     383  # cat cc_msg.txt
     384  # echo $CFLAGS
     385  rm -f cc_msg.txt a.out
     386fi
     387
     388fcho() { if test -n "$2"; then echo "$1$2"; fi }
     389
     390fcho "Binary directory    " "$bindir"
     391fcho "TinyCC directory    " "$tccdir"
     392fcho "Library directory   " "$libdir"
     393fcho "Include directory   " "$includedir"
     394fcho "Manual directory    " "$mandir"
     395fcho "Info directory      " "$infodir"
     396fcho "Doc directory       " "$docdir"
     397fcho "Target root prefix  " "$sysroot"
     398echo "Source path         $source_path"
     399echo "C compiler          $cc ($gcc_major.$gcc_minor)"
     400echo "Target OS           $targetos"
     401echo "CPU                 $cpu"
     402fcho "Triplet             " "$triplet"
     403fcho "Config              " "${confvars# }"
    363404echo "Creating config.mak and config.h"
    364405
     
    369410tccdir=\$(DESTDIR)$tccdir
    370411libdir=\$(DESTDIR)$libdir
    371 ln_libdir=$libdir
    372412includedir=\$(DESTDIR)$includedir
    373413mandir=\$(DESTDIR)$mandir
     
    377417GCC_MAJOR=$gcc_major
    378418GCC_MINOR=$gcc_minor
    379 HOST_CC=$host_cc
    380419AR=$ar
    381420STRIP=$strip -s -R .comment -R .note
     
    384423LIBSUF=$LIBSUF
    385424EXESUF=$EXESUF
     425DLLSUF=$DLLSUF
    386426EOF
    387427
     
    393433  fi
    394434}
     435
    395436print_mak() {
    396437  if test -n "$2"; then
    397438    echo "NATIVE_DEFINES+=-D$1=\"\\\"$2\\\"\"" >> config.mak
     439  fi
     440}
     441
     442print_mak_int() {
     443  if test -n "$2"; then
     444    echo "NATIVE_DEFINES+=-D$1=$2" >> config.mak
    398445  fi
    399446}
     
    408455print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp"
    409456print_mak CONFIG_LDDIR "$tcc_lddir"
    410 print_mak CONFIG_MULTIARCHDIR "$multiarch_triplet"
    411 
    412 echo "#define GCC_MAJOR $gcc_major" >> $TMPH
    413 echo "#define GCC_MINOR $gcc_minor" >> $TMPH
    414 
    415 if test "$cpu" = "x86" ; then
    416   echo "ARCH=i386" >> config.mak
    417   echo "#define HOST_I386 1" >> $TMPH
    418 elif test "$cpu" = "x86-64" ; then
    419   echo "ARCH=x86-64" >> config.mak
    420   echo "#define HOST_X86_64 1" >> $TMPH
    421 elif test "$cpu" = "armv4l" ; then
    422   echo "ARCH=arm" >> config.mak
    423   echo "#define HOST_ARM 1" >> $TMPH
    424   echo "#define TCC_ARM_VERSION $cpuver" >> $TMPH
    425 elif test "$cpu" = "powerpc" ; then
    426   echo "ARCH=ppc" >> config.mak
    427   echo "#define HOST_PPC 1" >> $TMPH
    428 elif test "$cpu" = "mips" ; then
    429   echo "ARCH=mips" >> config.mak
    430   echo "#define HOST_MIPS 1" >> $TMPH
    431 elif test "$cpu" = "s390" ; then
    432   echo "ARCH=s390" >> config.mak
    433   echo "#define HOST_S390 1" >> $TMPH
    434 elif test "$cpu" = "alpha" ; then
    435   echo "ARCH=alpha" >> config.mak
    436   echo "#define HOST_ALPHA 1" >> $TMPH
     457print_mak CONFIG_TRIPLET "$triplet"
     458print_mak_int TCC_CPU_VERSION "$cpuver"
     459
     460if test "$cpu" = "aarch64" ; then
     461  echo "ARCH=arm64" >> config.mak
    437462else
    438   echo "Unsupported CPU"
    439   exit 1
    440 fi
    441 
     463  echo "ARCH=$cpu" >> config.mak
     464fi
    442465echo "TARGETOS=$targetos" >> config.mak
    443466
    444467for v in $confvars ; do
    445   echo "CONFIG_$v=yes" >> config.mak
     468  if test "${v%=*}" = "$v"; then
     469    echo "CONFIG_$v=yes" >> config.mak
     470  else
     471    echo "CONFIG_$v" >> config.mak
     472  fi
    446473done
    447 if test "$noldl" = "yes" ; then
    448   echo "CONFIG_NOLDL=yes" >> config.mak
    449 fi
    450 if test "$mingw32" = "yes" ; then
    451   echo "CONFIG_WIN32=yes" >> config.mak
    452   echo "#define CONFIG_WIN32 1" >> $TMPH
    453 fi
    454 if test "$cygwin" = "yes" ; then
    455   echo "#ifndef _WIN32" >> $TMPH
    456   echo "# define _WIN32" >> $TMPH
    457   echo "#endif" >> $TMPH
    458   echo "AR=ar" >> config.mak
    459 fi
    460 if test "$bigendian" = "yes" ; then
    461   echo "WORDS_BIGENDIAN=yes" >> config.mak
    462   echo "#define WORDS_BIGENDIAN 1" >> $TMPH
    463 fi
    464 if test "$gprof" = "yes" ; then
    465   echo "TARGET_GPROF=yes" >> config.mak
    466   echo "#define HAVE_GPROF 1" >> $TMPH
    467 fi
    468 if test "$build_cross" = "yes" ; then
    469   echo "CONFIG_CROSS=yes" >> config.mak
    470 fi
    471 if test "$disable_static" = "yes" ; then
    472   echo "DISABLE_STATIC=yes" >> config.mak
    473 fi
    474 if test "$disable_rpath" = "yes" ; then
    475   echo "DISABLE_RPATH=yes" >> config.mak
    476 fi
    477 if test "$strip_binaries" = "yes" ; then
    478   echo "STRIP_BINARIES=yes" >> config.mak
    479 fi
    480 if test "$use_libgcc" = "yes" ; then
    481   echo "#define CONFIG_USE_LIBGCC" >> $TMPH
    482   echo "CONFIG_USE_LIBGCC=yes" >> config.mak
    483 fi
    484 if test "$have_selinux" = "yes" ; then
    485   echo "#define HAVE_SELINUX" >> $TMPH
    486   echo "HAVE_SELINUX=yes" >> config.mak
    487 fi
    488474
    489475version=`head $source_path/VERSION`
    490 echo "VERSION=$version" >>config.mak
     476echo "VERSION = $version" >> config.mak
    491477echo "#define TCC_VERSION \"$version\"" >> $TMPH
    492478echo "@set VERSION $version" > config.texi
    493 echo "SRC_PATH=$source_path" >>config.mak
    494479
    495480if test "$source_path_used" = "yes" ; then
    496481    case $source_path in
    497        /*) echo "top_srcdir=$source_path";;
    498         *) echo "top_srcdir=\$(TOP)/$source_path";;
     482       /*) echo "TOPSRC=$source_path";;
     483        *) echo "TOPSRC=\$(TOP)/$source_path";;
    499484     esac >>config.mak
    500485else
    501      echo 'top_srcdir=$(TOP)' >>config.mak
    502 fi
    503 echo 'top_builddir=$(TOP)' >>config.mak
     486     echo 'TOPSRC=$(TOP)' >>config.mak
     487fi
    504488
    505489diff $TMPH config.h >/dev/null 2>&1
     
    520504    case $2 in
    521505    */*) dn=${2%/*}
    522         test -d $dn || mkdir -p $dn
    523         case $1 in
    524         /*) ;;
    525           *) while test $dn ; do
    526                 tgt=../$tgt; dn=${dn#${dn%%/*}}; dn=${dn#/}
    527              done
    528              ;;
    529         esac
    530         ;;
     506        test -d $dn || mkdir -p $dn
     507        case $1 in
     508        /*) ;;
     509          *) while test $dn ; do
     510                tgt=../$tgt; dn=${dn#${dn%%/*}}; dn=${dn#/}
     511             done
     512             ;;
     513        esac
     514        ;;
    531515    esac
    532     ln -sfn $tgt $2
     516
     517    ln -sfn $tgt $2 || ( echo "ln failed. Using cp instead."; cp -f $1/$2 $2 )
    533518}
    534519
    535520if test "$source_path_used" = "yes" ; then
    536   FILES="Makefile lib/Makefile tests/Makefile tests/tests2/Makefile"
     521  FILES="Makefile lib/Makefile tests/Makefile tests/tests2/Makefile tests/pp/Makefile"
    537522  for f in $FILES ; do
    538523    fn_makelink $source_path $f
  • EcnlProtoTool/trunk/tcc-0.9.27/conftest.c

    r321 r331  
    22
    33/* Define architecture */
    4 #if defined(__i386__)
     4#if defined(__i386__) || defined _M_IX86
    55# define TRIPLET_ARCH "i386"
    6 #elif defined(__x86_64__)
     6#elif defined(__x86_64__) || defined _M_AMD64
    77# define TRIPLET_ARCH "x86_64"
    88#elif defined(__arm__)
    99# define TRIPLET_ARCH "arm"
     10#elif defined(__aarch64__)
     11# define TRIPLET_ARCH "aarch64"
    1012#else
    1113# define TRIPLET_ARCH "unknown"
     
    1719#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
    1820# define TRIPLET_OS "kfreebsd"
     21#elif defined _WIN32
     22# define TRIPLET_OS "win32"
    1923#elif !defined (__GNU__)
    2024# define TRIPLET_OS "unknown"
     
    3236#endif
    3337
    34 #ifdef __GNU__
     38#if defined _WIN32
     39# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS
     40#elif defined __GNU__
    3541# define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI
    3642#else
    3743# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
     44#endif
     45
     46#if defined(_WIN32)
     47int _CRT_glob = 0;
    3848#endif
    3949
     
    5464            printf("%d\n", __GNUC__);
    5565            break;
     66#elif defined __TINYC__
     67        case 'v':
     68            puts("0");
     69            break;
     70        case 'm':
     71            printf("%d\n", __TINYC__);
     72            break;
    5673#else
    5774        case 'm':
     
    6380            puts(TRIPLET);
    6481            break;
    65         case -1:
    66             /* to test -Wno-unused-result */
    67             fread(NULL, 1, 1, NULL);
     82
     83        default:
    6884            break;
    6985    }
  • EcnlProtoTool/trunk/tcc-0.9.27/elf.h

    r321 r331  
    11/* This file defines standard ELF types, structures, and macros.
    2    Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
     2   Copyright (C) 1995-2012 Free Software Foundation, Inc.
    33   This file is part of the GNU C Library.
    4    Contributed by Ian Lance Taylor <ian@cygnus.com>.
    54
    65   The GNU C Library is free software; you can redistribute it and/or
    7    modify it under the terms of the GNU Library General Public License as
    8    published by the Free Software Foundation; either version 2 of the
    9    License, or (at your option) any later version.
     6   modify it under the terms of the GNU Lesser General Public
     7   License as published by the Free Software Foundation; either
     8   version 2.1 of the License, or (at your option) any later version.
    109
    1110   The GNU C Library is distributed in the hope that it will be useful,
    1211   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1312   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    14    Library General Public License for more details.
    15 
    16    You should have received a copy of the GNU Library General Public
    17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    19    Boston, MA 02111-1307, USA.  */
     13   Lesser General Public License for more details.
     14
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with the GNU C Library; if not, see
     17   <http://www.gnu.org/licenses/>.  */
    2018
    2119#ifndef _ELF_H
    22 #define _ELF_H 1
     20#define _ELF_H 1
    2321
    2422#ifndef _WIN32
     
    3129typedef int int32_t;
    3230typedef long long int int64_t;
    33 #endif
    34 
    3531typedef unsigned char           uint8_t;
    3632typedef unsigned short int      uint16_t;
     
    3834typedef unsigned long long int  uint64_t;
    3935#endif
     36#endif
    4037
    4138/* Standard ELF types.  */
     
    4744/* Types for signed and unsigned 32-bit quantities.  */
    4845typedef uint32_t Elf32_Word;
    49 typedef int32_t  Elf32_Sword;
     46typedef int32_t  Elf32_Sword;
    5047typedef uint32_t Elf64_Word;
    51 typedef int32_t  Elf64_Sword;
     48typedef int32_t  Elf64_Sword;
    5249
    5350/* Types for signed and unsigned 64-bit quantities.  */
    5451typedef uint64_t Elf32_Xword;
    55 typedef int64_t  Elf32_Sxword;
     52typedef int64_t  Elf32_Sxword;
    5653typedef uint64_t Elf64_Xword;
    57 typedef int64_t  Elf64_Sxword;
     54typedef int64_t  Elf64_Sxword;
    5855
    5956/* Type of addresses.  */
     
    6966typedef uint16_t Elf64_Section;
    7067
    71 /* Type of symbol indices.  */
    72 typedef uint32_t Elf32_Symndx;
    73 typedef uint64_t Elf64_Symndx;
     68/* Type for version symbol information.  */
     69typedef Elf32_Half Elf32_Versym;
     70typedef Elf64_Half Elf64_Versym;
    7471
    7572
     
    8077typedef struct
    8178{
    82   unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
    83   Elf32_Half    e_type;                 /* Object file type */
    84   Elf32_Half    e_machine;              /* Architecture */
    85   Elf32_Word    e_version;              /* Object file version */
    86   Elf32_Addr    e_entry;                /* Entry point virtual address */
    87   Elf32_Off     e_phoff;                /* Program header table file offset */
    88   Elf32_Off     e_shoff;                /* Section header table file offset */
    89   Elf32_Word    e_flags;                /* Processor-specific flags */
    90   Elf32_Half    e_ehsize;               /* ELF header size in bytes */
    91   Elf32_Half    e_phentsize;            /* Program header table entry size */
    92   Elf32_Half    e_phnum;                /* Program header table entry count */
    93   Elf32_Half    e_shentsize;            /* Section header table entry size */
    94   Elf32_Half    e_shnum;                /* Section header table entry count */
    95   Elf32_Half    e_shstrndx;             /* Section header string table index */
    96 } Elf32_Ehdr;
    97 
    98 typedef struct
    99 {
    100   unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
    101   Elf64_Half    e_type;                 /* Object file type */
    102   Elf64_Half    e_machine;              /* Architecture */
    103   Elf64_Word    e_version;              /* Object file version */
    104   Elf64_Addr    e_entry;                /* Entry point virtual address */
    105   Elf64_Off     e_phoff;                /* Program header table file offset */
    106   Elf64_Off     e_shoff;                /* Section header table file offset */
    107   Elf64_Word    e_flags;                /* Processor-specific flags */
    108   Elf64_Half    e_ehsize;               /* ELF header size in bytes */
    109   Elf64_Half    e_phentsize;            /* Program header table entry size */
    110   Elf64_Half    e_phnum;                /* Program header table entry count */
    111   Elf64_Half    e_shentsize;            /* Section header table entry size */
    112   Elf64_Half    e_shnum;                /* Section header table entry count */
    113   Elf64_Half    e_shstrndx;             /* Section header string table index */
    114 } Elf64_Ehdr;
     79  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
     80  Elf32_Half    e_type;                 /* Object file type */
     81  Elf32_Half    e_machine;              /* Architecture */
     82  Elf32_Word    e_version;              /* Object file version */
     83  Elf32_Addr    e_entry;                /* Entry point virtual address */
     84  Elf32_Off     e_phoff;                /* Program header table file offset */
     85  Elf32_Off     e_shoff;                /* Section header table file offset */
     86  Elf32_Word    e_flags;                /* Processor-specific flags */
     87  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
     88  Elf32_Half    e_phentsize;            /* Program header table entry size */
     89  Elf32_Half    e_phnum;                /* Program header table entry count */
     90  Elf32_Half    e_shentsize;            /* Section header table entry size */
     91  Elf32_Half    e_shnum;                /* Section header table entry count */
     92  Elf32_Half    e_shstrndx;             /* Section header string table index */
     93} __attribute__((packed)) Elf32_Ehdr;
     94
     95typedef struct
     96{
     97  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
     98  Elf64_Half    e_type;                 /* Object file type */
     99  Elf64_Half    e_machine;              /* Architecture */
     100  Elf64_Word    e_version;              /* Object file version */
     101  Elf64_Addr    e_entry;                /* Entry point virtual address */
     102  Elf64_Off     e_phoff;                /* Program header table file offset */
     103  Elf64_Off     e_shoff;                /* Section header table file offset */
     104  Elf64_Word    e_flags;                /* Processor-specific flags */
     105  Elf64_Half    e_ehsize;               /* ELF header size in bytes */
     106  Elf64_Half    e_phentsize;            /* Program header table entry size */
     107  Elf64_Half    e_phnum;                /* Program header table entry count */
     108  Elf64_Half    e_shentsize;            /* Section header table entry size */
     109  Elf64_Half    e_shnum;                /* Section header table entry count */
     110  Elf64_Half    e_shstrndx;             /* Section header string table index */
     111} __attribute__((packed)) Elf64_Ehdr;
    115112
    116113/* Fields in the e_ident array.  The EI_* macros are indices into the
     
    118115   may have.  */
    119116
    120 #define EI_MAG0         0               /* File identification byte 0 index */
    121 #define ELFMAG0         0x7f            /* Magic number byte 0 */
    122 
    123 #define EI_MAG1         1               /* File identification byte 1 index */
    124 #define ELFMAG1         'E'             /* Magic number byte 1 */
    125 
    126 #define EI_MAG2         2               /* File identification byte 2 index */
    127 #define ELFMAG2         'L'             /* Magic number byte 2 */
    128 
    129 #define EI_MAG3         3               /* File identification byte 3 index */
    130 #define ELFMAG3         'F'             /* Magic number byte 3 */
     117#define EI_MAG0         0               /* File identification byte 0 index */
     118#define ELFMAG0         0x7f            /* Magic number byte 0 */
     119
     120#define EI_MAG1         1               /* File identification byte 1 index */
     121#define ELFMAG1         'E'             /* Magic number byte 1 */
     122
     123#define EI_MAG2         2               /* File identification byte 2 index */
     124#define ELFMAG2         'L'             /* Magic number byte 2 */
     125
     126#define EI_MAG3         3               /* File identification byte 3 index */
     127#define ELFMAG3         'F'             /* Magic number byte 3 */
    131128
    132129/* Conglomeration of the identification bytes, for easy testing as a word.  */
    133 #define ELFMAG          "\177ELF"
    134 #define SELFMAG         4
    135 
    136 #define EI_CLASS        4               /* File class byte index */
    137 #define ELFCLASSNONE    0               /* Invalid class */
    138 #define ELFCLASS32      1               /* 32-bit objects */
    139 #define ELFCLASS64      2               /* 64-bit objects */
    140 #define ELFCLASSNUM     3
    141 
    142 #define EI_DATA         5               /* Data encoding byte index */
    143 #define ELFDATANONE     0               /* Invalid data encoding */
    144 #define ELFDATA2LSB     1               /* 2's complement, little endian */
    145 #define ELFDATA2MSB     2               /* 2's complement, big endian */
    146 #define ELFDATANUM      3
    147 
    148 #define EI_VERSION      6               /* File version byte index */
    149                                         /* Value must be EV_CURRENT */
    150 
    151 #define EI_OSABI        7               /* OS ABI identification */
    152 #define ELFOSABI_SYSV           0       /* UNIX System V ABI */
    153 #define ELFOSABI_HPUX           1       /* HP-UX */
    154 #define ELFOSABI_FREEBSD        9       /* Free BSD */
    155 #define ELFOSABI_ARM            97      /* ARM */
    156 #define ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
    157 
    158 #define EI_ABIVERSION   8               /* ABI version */
    159 
    160 #define EI_PAD          9               /* Byte index of padding bytes */
     130#define ELFMAG          "\177ELF"
     131#define SELFMAG         4
     132
     133#define EI_CLASS        4               /* File class byte index */
     134#define ELFCLASSNONE    0               /* Invalid class */
     135#define ELFCLASS32      1               /* 32-bit objects */
     136#define ELFCLASS64      2               /* 64-bit objects */
     137#define ELFCLASSNUM     3
     138
     139#define EI_DATA         5               /* Data encoding byte index */
     140#define ELFDATANONE     0               /* Invalid data encoding */
     141#define ELFDATA2LSB     1               /* 2's complement, little endian */
     142#define ELFDATA2MSB     2               /* 2's complement, big endian */
     143#define ELFDATANUM      3
     144
     145#define EI_VERSION      6               /* File version byte index */
     146                                        /* Value must be EV_CURRENT */
     147
     148#define EI_OSABI        7               /* OS ABI identification */
     149#define ELFOSABI_NONE           0       /* UNIX System V ABI */
     150#define ELFOSABI_SYSV           0       /* Alias.  */
     151#define ELFOSABI_HPUX           1       /* HP-UX */
     152#define ELFOSABI_NETBSD         2       /* NetBSD.  */
     153#define ELFOSABI_GNU            3       /* Object uses GNU ELF extensions.  */
     154#define ELFOSABI_LINUX          ELFOSABI_GNU /* Compatibility alias.  */
     155#define ELFOSABI_SOLARIS        6       /* Sun Solaris.  */
     156#define ELFOSABI_AIX            7       /* IBM AIX.  */
     157#define ELFOSABI_IRIX           8       /* SGI Irix.  */
     158#define ELFOSABI_FREEBSD        9       /* FreeBSD.  */
     159#define ELFOSABI_TRU64          10      /* Compaq TRU64 UNIX.  */
     160#define ELFOSABI_MODESTO        11      /* Novell Modesto.  */
     161#define ELFOSABI_OPENBSD        12      /* OpenBSD.  */
     162#define ELFOSABI_ARM_AEABI      64      /* ARM EABI */
     163#define ELFOSABI_ARM            97      /* ARM */
     164#define ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
     165
     166#define EI_ABIVERSION   8               /* ABI version */
     167
     168#define EI_PAD          9               /* Byte index of padding bytes */
    161169
    162170/* Legal values for e_type (object file type).  */
    163171
    164 #define ET_NONE         0               /* No file type */
    165 #define ET_REL          1               /* Relocatable file */
    166 #define ET_EXEC         2               /* Executable file */
    167 #define ET_DYN          3               /* Shared object file */
    168 #define ET_CORE         4               /* Core file */
    169 #define ET_NUM          5               /* Number of defined types */
    170 #define ET_LOPROC       0xff00          /* Processor-specific */
    171 #define ET_HIPROC       0xffff          /* Processor-specific */
     172#define ET_NONE         0               /* No file type */
     173#define ET_REL          1               /* Relocatable file */
     174#define ET_EXEC         2               /* Executable file */
     175#define ET_DYN          3               /* Shared object file */
     176#define ET_CORE         4               /* Core file */
     177#define ET_NUM          5               /* Number of defined types */
     178#define ET_LOOS         0xfe00          /* OS-specific range start */
     179#define ET_HIOS         0xfeff          /* OS-specific range end */
     180#define ET_LOPROC       0xff00          /* Processor-specific range start */
     181#define ET_HIPROC       0xffff          /* Processor-specific range end */
    172182
    173183/* Legal values for e_machine (architecture).  */
    174184
    175 #define EM_NONE          0              /* No machine */
    176 #define EM_M32           1              /* AT&T WE 32100 */
    177 #define EM_SPARC         2              /* SUN SPARC */
    178 #define EM_386           3              /* Intel 80386 */
    179 #define EM_68K           4              /* Motorola m68k family */
    180 #define EM_88K           5              /* Motorola m88k family */
    181 #define EM_486           6              /* Intel 80486 */
    182 #define EM_860           7              /* Intel 80860 */
    183 #define EM_MIPS          8              /* MIPS R3000 big-endian */
    184 #define EM_S370          9              /* Amdahl */
    185 #define EM_MIPS_RS4_BE  10              /* MIPS R4000 big-endian */
    186 #define EM_RS6000       11              /* RS6000 */
    187 
    188 #define EM_PARISC       15              /* HPPA */
    189 #define EM_nCUBE        16              /* nCUBE */
    190 #define EM_VPP500       17              /* Fujitsu VPP500 */
    191 #define EM_SPARC32PLUS  18              /* Sun's "v8plus" */
    192 #define EM_960          19              /* Intel 80960 */
    193 #define EM_PPC          20              /* PowerPC */
    194 
    195 #define EM_V800         36              /* NEC V800 series */
    196 #define EM_FR20         37              /* Fujitsu FR20 */
    197 #define EM_RH32         38              /* TRW RH32 */
    198 #define EM_RCE          39              /* Motorola RCE */
    199 #define EM_ARM          40              /* ARM */
    200 #define EM_FAKE_ALPHA   41              /* Digital Alpha */
    201 #define EM_SH           42              /* Hitachi SH */
    202 #define EM_SPARCV9      43              /* SPARC v9 64-bit */
    203 #define EM_TRICORE      44              /* Siemens Tricore */
    204 #define EM_ARC          45              /* Argonaut RISC Core */
    205 #define EM_H8_300       46              /* Hitachi H8/300 */
    206 #define EM_H8_300H      47              /* Hitachi H8/300H */
    207 #define EM_H8S          48              /* Hitachi H8S */
    208 #define EM_H8_500       49              /* Hitachi H8/500 */
    209 #define EM_IA_64        50              /* Intel Merced */
    210 #define EM_MIPS_X       51              /* Stanford MIPS-X */
    211 #define EM_COLDFIRE     52              /* Motorola Coldfire */
    212 #define EM_68HC12       53              /* Motorola M68HC12 */
    213 #define EM_MMA          54              /* Fujitsu MMA Multimedia Accelerator*/
    214 #define EM_PCP          55              /* Siemens PCP */
    215 #define EM_NCPU         56              /* Sony nCPU embeeded RISC */
    216 #define EM_NDR1         57              /* Denso NDR1 microprocessor */
    217 #define EM_STARCORE     58              /* Motorola Start*Core processor */
    218 #define EM_ME16         59              /* Toyota ME16 processor */
    219 #define EM_ST100        60              /* STMicroelectronic ST100 processor */
    220 #define EM_TINYJ        61              /* Advanced Logic Corp. Tinyj emb.fam*/
    221 #define EM_X86_64       62              /* AMD x86-64 architecture */
    222 #define EM_PDSP         63              /* Sony DSP Processor */
    223 #define EM_FX66         66              /* Siemens FX66 microcontroller */
    224 #define EM_ST9PLUS      67              /* STMicroelectronics ST9+ 8/16 mc */
    225 #define EM_ST7          68              /* STmicroelectronics ST7 8 bit mc */
    226 #define EM_68HC16       69              /* Motorola MC68HC16 microcontroller */
    227 #define EM_68HC11       70              /* Motorola MC68HC11 microcontroller */
    228 #define EM_68HC08       71              /* Motorola MC68HC08 microcontroller */
    229 #define EM_68HC05       72              /* Motorola MC68HC05 microcontroller */
    230 #define EM_SVX          73              /* Silicon Graphics SVx */
    231 #define EM_ST19         74              /* STMicroelectronics ST19 8 bit mc */
    232 #define EM_VAX          75              /* Digital VAX */
    233 #define EM_CRIS         76              /* Axis Communications 32-bit embedded processor */
    234 #define EM_JAVELIN      77              /* Infineon Technologies 32-bit embedded processor */
    235 #define EM_FIREPATH     78              /* Element 14 64-bit DSP Processor */
    236 #define EM_ZSP          79              /* LSI Logic 16-bit DSP Processor */
    237 #define EM_MMIX         80              /* Donald Knuth's educational 64-bit processor */
    238 #define EM_HUANY        81              /* Harvard University machine-independent object files */
    239 #define EM_PRISM        82              /* SiTera Prism */
    240 #define EM_AVR          83              /* Atmel AVR 8-bit microcontroller */
    241 #define EM_FR30         84              /* Fujitsu FR30 */
    242 #define EM_D10V         85              /* Mitsubishi D10V */
    243 #define EM_D30V         86              /* Mitsubishi D30V */
    244 #define EM_V850         87              /* NEC v850 */
    245 #define EM_M32R         88              /* Mitsubishi M32R */
    246 #define EM_MN10300      89              /* Matsushita MN10300 */
    247 #define EM_MN10200      90              /* Matsushita MN10200 */
    248 #define EM_PJ           91              /* picoJava */
    249 #define EM_OPENRISC     92              /* OpenRISC 32-bit embedded processor */
    250 #define EM_ARC_A5       93              /* ARC Cores Tangent-A5 */
    251 #define EM_XTENSA       94              /* Tensilica Xtensa Architecture */
    252 #define EM_NUM          95
     185#define EM_NONE          0              /* No machine */
     186#define EM_M32           1              /* AT&T WE 32100 */
     187#define EM_SPARC         2              /* SUN SPARC */
     188#define EM_386           3              /* Intel 80386 */
     189#define EM_68K           4              /* Motorola m68k family */
     190#define EM_88K           5              /* Motorola m88k family */
     191#define EM_860           7              /* Intel 80860 */
     192#define EM_MIPS          8              /* MIPS R3000 big-endian */
     193#define EM_S370          9              /* IBM System/370 */
     194#define EM_MIPS_RS3_LE  10              /* MIPS R3000 little-endian */
     195
     196#define EM_PARISC       15              /* HPPA */
     197#define EM_VPP500       17              /* Fujitsu VPP500 */
     198#define EM_SPARC32PLUS  18              /* Sun's "v8plus" */
     199#define EM_960          19              /* Intel 80960 */
     200#define EM_PPC          20              /* PowerPC */
     201#define EM_PPC64        21              /* PowerPC 64-bit */
     202#define EM_S390         22              /* IBM S390 */
     203
     204#define EM_V800         36              /* NEC V800 series */
     205#define EM_FR20         37              /* Fujitsu FR20 */
     206#define EM_RH32         38              /* TRW RH-32 */
     207#define EM_RCE          39              /* Motorola RCE */
     208#define EM_ARM          40              /* ARM */
     209#define EM_FAKE_ALPHA   41              /* Digital Alpha */
     210#define EM_SH           42              /* Hitachi SH */
     211#define EM_SPARCV9      43              /* SPARC v9 64-bit */
     212#define EM_TRICORE      44              /* Siemens Tricore */
     213#define EM_ARC          45              /* Argonaut RISC Core */
     214#define EM_H8_300       46              /* Hitachi H8/300 */
     215#define EM_H8_300H      47              /* Hitachi H8/300H */
     216#define EM_H8S          48              /* Hitachi H8S */
     217#define EM_H8_500       49              /* Hitachi H8/500 */
     218#define EM_IA_64        50              /* Intel Merced */
     219#define EM_MIPS_X       51              /* Stanford MIPS-X */
     220#define EM_COLDFIRE     52              /* Motorola Coldfire */
     221#define EM_68HC12       53              /* Motorola M68HC12 */
     222#define EM_MMA          54              /* Fujitsu MMA Multimedia Accelerator*/
     223#define EM_PCP          55              /* Siemens PCP */
     224#define EM_NCPU         56              /* Sony nCPU embedded RISC */
     225#define EM_NDR1         57              /* Denso NDR1 microprocessor */
     226#define EM_STARCORE     58              /* Motorola Start*Core processor */
     227#define EM_ME16         59              /* Toyota ME16 processor */
     228#define EM_ST100        60              /* STMicroelectronic ST100 processor */
     229#define EM_TINYJ        61              /* Advanced Logic Corp. Tinyj emb.fam*/
     230#define EM_X86_64       62              /* AMD x86-64 architecture */
     231#define EM_PDSP         63              /* Sony DSP Processor */
     232
     233#define EM_FX66         66              /* Siemens FX66 microcontroller */
     234#define EM_ST9PLUS      67              /* STMicroelectronics ST9+ 8/16 mc */
     235#define EM_ST7          68              /* STMicroelectronics ST7 8 bit mc */
     236#define EM_68HC16       69              /* Motorola MC68HC16 microcontroller */
     237#define EM_68HC11       70              /* Motorola MC68HC11 microcontroller */
     238#define EM_68HC08       71              /* Motorola MC68HC08 microcontroller */
     239#define EM_68HC05       72              /* Motorola MC68HC05 microcontroller */
     240#define EM_SVX          73              /* Silicon Graphics SVx */
     241#define EM_ST19         74              /* STMicroelectronics ST19 8 bit mc */
     242#define EM_VAX          75              /* Digital VAX */
     243#define EM_CRIS         76              /* Axis Communications 32-bit embedded processor */
     244#define EM_JAVELIN      77              /* Infineon Technologies 32-bit embedded processor */
     245#define EM_FIREPATH     78              /* Element 14 64-bit DSP Processor */
     246#define EM_ZSP          79              /* LSI Logic 16-bit DSP Processor */
     247#define EM_MMIX         80              /* Donald Knuth's educational 64-bit processor */
     248#define EM_HUANY        81              /* Harvard University machine-independent object files */
     249#define EM_PRISM        82              /* SiTera Prism */
     250#define EM_AVR          83              /* Atmel AVR 8-bit microcontroller */
     251#define EM_FR30         84              /* Fujitsu FR30 */
     252#define EM_D10V         85              /* Mitsubishi D10V */
     253#define EM_D30V         86              /* Mitsubishi D30V */
     254#define EM_V850         87              /* NEC v850 */
     255#define EM_M32R         88              /* Mitsubishi M32R */
     256#define EM_MN10300      89              /* Matsushita MN10300 */
     257#define EM_MN10200      90              /* Matsushita MN10200 */
     258#define EM_PJ           91              /* picoJava */
     259#define EM_OPENRISC     92              /* OpenRISC 32-bit embedded processor */
     260#define EM_ARC_A5       93              /* ARC Cores Tangent-A5 */
     261#define EM_XTENSA       94              /* Tensilica Xtensa Architecture */
     262#define EM_AARCH64      183             /* ARM AARCH64 */
     263#define EM_TILEPRO      188             /* Tilera TILEPro */
     264#define EM_TILEGX       191             /* Tilera TILE-Gx */
     265#define EM_NUM          192
    253266
    254267/* If it is necessary to assign new unofficial EM_* values, please
     
    256269   chances of collision with official or non-GNU unofficial values.  */
    257270
    258 #define EM_ALPHA        0x9026
    259 #define EM_C60          0x9c60
     271#define EM_ALPHA        0x9026
     272#define EM_C60          0x9c60
    260273
    261274/* Legal values for e_version (version).  */
    262275
    263 #define EV_NONE         0               /* Invalid ELF version */
    264 #define EV_CURRENT      1               /* Current version */
    265 #define EV_NUM          2
     276#define EV_NONE         0               /* Invalid ELF version */
     277#define EV_CURRENT      1               /* Current version */
     278#define EV_NUM          2
    266279
    267280/* Section header.  */
     
    269282typedef struct
    270283{
    271   Elf32_Word    sh_name;                /* Section name (string tbl index) */
    272   Elf32_Word    sh_type;                /* Section type */
    273   Elf32_Word    sh_flags;               /* Section flags */
    274   Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
    275   Elf32_Off     sh_offset;              /* Section file offset */
    276   Elf32_Word    sh_size;                /* Section size in bytes */
    277   Elf32_Word    sh_link;                /* Link to another section */
    278   Elf32_Word    sh_info;                /* Additional section information */
    279   Elf32_Word    sh_addralign;           /* Section alignment */
    280   Elf32_Word    sh_entsize;             /* Entry size if section holds table */
    281 } Elf32_Shdr;
    282 
    283 typedef struct
    284 {
    285   Elf64_Word    sh_name;                /* Section name (string tbl index) */
    286   Elf64_Word    sh_type;                /* Section type */
    287   Elf64_Xword   sh_flags;               /* Section flags */
    288   Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
    289   Elf64_Off     sh_offset;              /* Section file offset */
    290   Elf64_Xword   sh_size;                /* Section size in bytes */
    291   Elf64_Word    sh_link;                /* Link to another section */
    292   Elf64_Word    sh_info;                /* Additional section information */
    293   Elf64_Xword   sh_addralign;           /* Section alignment */
    294   Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
    295 } Elf64_Shdr;
     284  Elf32_Word    sh_name;                /* Section name (string tbl index) */
     285  Elf32_Word    sh_type;                /* Section type */
     286  Elf32_Word    sh_flags;               /* Section flags */
     287  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
     288  Elf32_Off     sh_offset;              /* Section file offset */
     289  Elf32_Word    sh_size;                /* Section size in bytes */
     290  Elf32_Word    sh_link;                /* Link to another section */
     291  Elf32_Word    sh_info;                /* Additional section information */
     292  Elf32_Word    sh_addralign;           /* Section alignment */
     293  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
     294} __attribute__((packed)) Elf32_Shdr;
     295
     296typedef struct
     297{
     298  Elf64_Word    sh_name;                /* Section name (string tbl index) */
     299  Elf64_Word    sh_type;                /* Section type */
     300  Elf64_Xword   sh_flags;               /* Section flags */
     301  Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
     302  Elf64_Off     sh_offset;              /* Section file offset */
     303  Elf64_Xword   sh_size;                /* Section size in bytes */
     304  Elf64_Word    sh_link;                /* Link to another section */
     305  Elf64_Word    sh_info;                /* Additional section information */
     306  Elf64_Xword   sh_addralign;           /* Section alignment */
     307  Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
     308} __attribute__((packed)) Elf64_Shdr;
    296309
    297310/* Special section indices.  */
    298311
    299 #define SHN_UNDEF       0               /* Undefined section */
    300 #define SHN_LORESERVE   0xff00          /* Start of reserved indices */
    301 #define SHN_LOPROC      0xff00          /* Start of processor-specific */
    302 #define SHN_HIPROC      0xff1f          /* End of processor-specific */
    303 #define SHN_ABS         0xfff1          /* Associated symbol is absolute */
    304 #define SHN_COMMON      0xfff2          /* Associated symbol is common */
    305 #define SHN_HIRESERVE   0xffff          /* End of reserved indices */
     312#define SHN_UNDEF       0               /* Undefined section */
     313#define SHN_LORESERVE   0xff00          /* Start of reserved indices */
     314#define SHN_LOPROC      0xff00          /* Start of processor-specific */
     315#define SHN_BEFORE      0xff00          /* Order section before all others
     316                                           (Solaris).  */
     317#define SHN_AFTER       0xff01          /* Order section after all others
     318                                           (Solaris).  */
     319#define SHN_HIPROC      0xff1f          /* End of processor-specific */
     320#define SHN_LOOS        0xff20          /* Start of OS-specific */
     321#define SHN_HIOS        0xff3f          /* End of OS-specific */
     322#define SHN_ABS         0xfff1          /* Associated symbol is absolute */
     323#define SHN_COMMON      0xfff2          /* Associated symbol is common */
     324#define SHN_XINDEX      0xffff          /* Index is in extra table.  */
     325#define SHN_HIRESERVE   0xffff          /* End of reserved indices */
    306326
    307327/* Legal values for sh_type (section type).  */
    308328
    309 #define SHT_NULL         0              /* Section header table entry unused */
    310 #define SHT_PROGBITS     1              /* Program data */
    311 #define SHT_SYMTAB       2              /* Symbol table */
    312 #define SHT_STRTAB       3              /* String table */
    313 #define SHT_RELA         4              /* Relocation entries with addends */
    314 #define SHT_HASH         5              /* Symbol hash table */
    315 #define SHT_DYNAMIC      6              /* Dynamic linking information */
    316 #define SHT_NOTE         7              /* Notes */
    317 #define SHT_NOBITS       8              /* Program space with no data (bss) */
    318 #define SHT_REL          9              /* Relocation entries, no addends */
    319 #define SHT_SHLIB        10             /* Reserved */
    320 #define SHT_DYNSYM       11             /* Dynamic linker symbol table */
    321 #define SHT_INIT_ARRAY   14             /* Array of constructors */
    322 #define SHT_FINI_ARRAY   15             /* Array of destructors */
    323 #define SHT_PREINIT_ARRAY 16            /* Array of pre-constructors */
    324 #define SHT_GROUP        17             /* Section group */
    325 #define SHT_SYMTAB_SHNDX 18             /* Extended section indices */
    326 #define SHT_NUM          19             /* Number of defined types.  */
    327 #define SHT_LOOS         0x60000000     /* Start OS-specific */
    328 #define SHT_LOSUNW       0x6ffffffb     /* Sun-specific low bound.  */
    329 #define SHT_SUNW_COMDAT  0x6ffffffb
    330 #define SHT_SUNW_syminfo 0x6ffffffc
    331 #define SHT_GNU_verdef   0x6ffffffd     /* Version definition section.  */
    332 #define SHT_GNU_verneed  0x6ffffffe     /* Version needs section.  */
    333 #define SHT_GNU_versym   0x6fffffff     /* Version symbol table.  */
    334 #define SHT_HISUNW       0x6fffffff     /* Sun-specific high bound.  */
    335 #define SHT_HIOS         0x6fffffff     /* End OS-specific type */
    336 #define SHT_LOPROC       0x70000000     /* Start of processor-specific */
    337 #define SHT_ARM_EXIDX    0x70000001     /* Exception Index table */
    338 #define SHT_ARM_PREEMPTMAP 0x70000002   /* dynamic linking pre-emption map */
    339 #define SHT_ARM_ATTRIBUTES 0x70000003   /* Object file compatibility attrs */
    340 #define SHT_HIPROC       0x7fffffff     /* End of processor-specific */
    341 #define SHT_LOUSER       0x80000000     /* Start of application-specific */
    342 #define SHT_HIUSER       0x8fffffff     /* End of application-specific */
     329#define SHT_NULL          0             /* Section header table entry unused */
     330#define SHT_PROGBITS      1             /* Program data */
     331#define SHT_SYMTAB        2             /* Symbol table */
     332#define SHT_STRTAB        3             /* String table */
     333#define SHT_RELA          4             /* Relocation entries with addends */
     334#define SHT_HASH          5             /* Symbol hash table */
     335#define SHT_DYNAMIC       6             /* Dynamic linking information */
     336#define SHT_NOTE          7             /* Notes */
     337#define SHT_NOBITS        8             /* Program space with no data (bss) */
     338#define SHT_REL           9             /* Relocation entries, no addends */
     339#define SHT_SHLIB         10            /* Reserved */
     340#define SHT_DYNSYM        11            /* Dynamic linker symbol table */
     341#define SHT_INIT_ARRAY    14            /* Array of constructors */
     342#define SHT_FINI_ARRAY    15            /* Array of destructors */
     343#define SHT_PREINIT_ARRAY 16            /* Array of pre-constructors */
     344#define SHT_GROUP         17            /* Section group */
     345#define SHT_SYMTAB_SHNDX  18            /* Extended section indices */
     346#define SHT_NUM           19            /* Number of defined types.  */
     347#define SHT_LOOS          0x60000000    /* Start OS-specific.  */
     348#define SHT_GNU_ATTRIBUTES 0x6ffffff5   /* Object attributes.  */
     349#define SHT_GNU_HASH      0x6ffffff6    /* GNU-style hash table.  */
     350#define SHT_GNU_LIBLIST   0x6ffffff7    /* Prelink library list */
     351#define SHT_CHECKSUM      0x6ffffff8    /* Checksum for DSO content.  */
     352#define SHT_LOSUNW        0x6ffffffa    /* Sun-specific low bound.  */
     353#define SHT_SUNW_move     0x6ffffffa
     354#define SHT_SUNW_COMDAT   0x6ffffffb
     355#define SHT_SUNW_syminfo  0x6ffffffc
     356#define SHT_GNU_verdef    0x6ffffffd    /* Version definition section.  */
     357#define SHT_GNU_verneed   0x6ffffffe    /* Version needs section.  */
     358#define SHT_GNU_versym    0x6fffffff    /* Version symbol table.  */
     359#define SHT_HISUNW        0x6fffffff    /* Sun-specific high bound.  */
     360#define SHT_HIOS          0x6fffffff    /* End OS-specific type */
     361#define SHT_LOPROC        0x70000000    /* Start of processor-specific */
     362#define SHT_HIPROC        0x7fffffff    /* End of processor-specific */
     363#define SHT_LOUSER        0x80000000    /* Start of application-specific */
     364#define SHT_HIUSER        0x8fffffff    /* End of application-specific */
    343365
    344366/* Legal values for sh_flags (section flags).  */
    345367
    346 #define SHF_WRITE       (1 << 0)        /* Writable */
    347 #define SHF_ALLOC       (1 << 1)        /* Occupies memory during execution */
    348 #define SHF_EXECINSTR   (1 << 2)        /* Executable */
    349 #define SHF_MASKPROC    0xf0000000      /* Processor-specific */
    350 
    351 #define SHF_MERGE       0x10
    352 #define SHF_STRINGS     0x20
    353 #define SHF_INFO_LINK   0x40
    354 #define SHF_LINK_ORDER  0x80
    355 #define SHF_OS_NONCONFORMING 0x100
    356 #define SHF_GROUP       0x200
    357 #define SHF_TLS         0x400
    358 #define SHF_MASKOS      0x0ff00000
    359 #define SHF_ORDERED     0x40000000
    360 #define SHF_EXCLUDE     0x80000000
     368#define SHF_WRITE            (1 << 0)   /* Writable */
     369#define SHF_ALLOC            (1 << 1)   /* Occupies memory during execution */
     370#define SHF_EXECINSTR        (1 << 2)   /* Executable */
     371#define SHF_MERGE            (1 << 4)   /* Might be merged */
     372#define SHF_STRINGS          (1 << 5)   /* Contains nul-terminated strings */
     373#define SHF_INFO_LINK        (1 << 6)   /* `sh_info' contains SHT index */
     374#define SHF_LINK_ORDER       (1 << 7)   /* Preserve order after combining */
     375#define SHF_OS_NONCONFORMING (1 << 8)   /* Non-standard OS specific handling
     376                                           required */
     377#define SHF_GROUP            (1 << 9)   /* Section is member of a group.  */
     378#define SHF_TLS              (1 << 10)  /* Section hold thread-local data.  */
     379#define SHF_COMPRESSED       (1 << 11)  /* Section with compressed data. */
     380#define SHF_MASKOS           0x0ff00000 /* OS-specific.  */
     381#define SHF_MASKPROC         0xf0000000 /* Processor-specific */
     382#define SHF_ORDERED          (1 << 30)  /* Special ordering requirement
     383                                           (Solaris).  */
     384#define SHF_EXCLUDE          (1 << 31)  /* Section is excluded unless
     385                                           referenced or allocated (Solaris).*/
     386
     387/* Section group handling.  */
     388#define GRP_COMDAT      0x1             /* Mark group as COMDAT.  */
    361389
    362390/* Symbol table entry.  */
     
    364392typedef struct
    365393{
    366   Elf32_Word    st_name;                /* Symbol name (string tbl index) */
    367   Elf32_Addr    st_value;               /* Symbol value */
    368   Elf32_Word    st_size;                /* Symbol size */
    369   unsigned char st_info;                /* Symbol type and binding */
    370   unsigned char st_other;               /* No defined meaning, 0 */
    371   Elf32_Section st_shndx;               /* Section index */
    372 } Elf32_Sym;
    373 
    374 typedef struct
    375 {
    376   Elf64_Word    st_name;                /* Symbol name (string tbl index) */
    377   unsigned char st_info;                /* Symbol type and binding */
    378   unsigned char st_other;               /* No defined meaning, 0 */
    379   Elf64_Section st_shndx;               /* Section index */
    380   Elf64_Addr    st_value;               /* Symbol value */
    381   Elf64_Xword   st_size;                /* Symbol size */
    382 } Elf64_Sym;
     394  Elf32_Word    st_name;                /* Symbol name (string tbl index) */
     395  Elf32_Addr    st_value;               /* Symbol value */
     396  Elf32_Word    st_size;                /* Symbol size */
     397  unsigned char st_info;                /* Symbol type and binding */
     398  unsigned char st_other;               /* Symbol visibility */
     399  Elf32_Section st_shndx;               /* Section index */
     400} __attribute__((packed)) Elf32_Sym;
     401
     402typedef struct
     403{
     404  Elf64_Word    st_name;                /* Symbol name (string tbl index) */
     405  unsigned char st_info;                /* Symbol type and binding */
     406  unsigned char st_other;               /* Symbol visibility */
     407  Elf64_Section st_shndx;               /* Section index */
     408  Elf64_Addr    st_value;               /* Symbol value */
     409  Elf64_Xword   st_size;                /* Symbol size */
     410} __attribute__((packed)) Elf64_Sym;
    383411
    384412/* The syminfo section if available contains additional information about
     
    387415typedef struct
    388416{
    389   Elf32_Half si_boundto;                /* Direct bindings, symbol bound to */
    390   Elf32_Half si_flags;                  /* Per symbol flags */
    391 } Elf32_Syminfo;
    392 
    393 typedef struct
    394 {
    395   Elf64_Half si_boundto;                /* Direct bindings, symbol bound to */
    396   Elf64_Half si_flags;                  /* Per symbol flags */
    397 } Elf64_Syminfo;
     417  Elf32_Half si_boundto;                /* Direct bindings, symbol bound to */
     418  Elf32_Half si_flags;                  /* Per symbol flags */
     419} __attribute__((packed)) Elf32_Syminfo;
     420
     421typedef struct
     422{
     423  Elf64_Half si_boundto;                /* Direct bindings, symbol bound to */
     424  Elf64_Half si_flags;                  /* Per symbol flags */
     425} __attribute__((packed)) Elf64_Syminfo;
    398426
    399427/* Possible values for si_boundto.  */
    400 #define SYMINFO_BT_SELF         0xffff  /* Symbol bound to self */
    401 #define SYMINFO_BT_PARENT       0xfffe  /* Symbol bound to parent */
    402 #define SYMINFO_BT_LOWRESERVE   0xff00  /* Beginning of reserved entries */
     428#define SYMINFO_BT_SELF         0xffff  /* Symbol bound to self */
     429#define SYMINFO_BT_PARENT       0xfffe  /* Symbol bound to parent */
     430#define SYMINFO_BT_LOWRESERVE   0xff00  /* Beginning of reserved entries */
    403431
    404432/* Possible bitmasks for si_flags.  */
    405 #define SYMINFO_FLG_DIRECT      0x0001  /* Direct bound symbol */
    406 #define SYMINFO_FLG_PASSTHRU    0x0002  /* Pass-thru symbol for translator */
    407 #define SYMINFO_FLG_COPY        0x0004  /* Symbol is a copy-reloc */
    408 #define SYMINFO_FLG_LAZYLOAD    0x0008  /* Symbol bound to object to be lazy
    409                                            loaded */
     433#define SYMINFO_FLG_DIRECT      0x0001  /* Direct bound symbol */
     434#define SYMINFO_FLG_PASSTHRU    0x0002  /* Pass-thru symbol for translator */
     435#define SYMINFO_FLG_COPY        0x0004  /* Symbol is a copy-reloc */
     436#define SYMINFO_FLG_LAZYLOAD    0x0008  /* Symbol bound to object to be lazy
     437                                           loaded */
    410438/* Syminfo version values.  */
    411 #define SYMINFO_NONE            0
    412 #define SYMINFO_CURRENT         1
    413 #define SYMINFO_NUM             2
    414 
    415 
    416 /* Special section index.  */
    417 
    418 #define SHN_UNDEF       0               /* No section, undefined symbol.  */
     439#define SYMINFO_NONE            0
     440#define SYMINFO_CURRENT         1
     441#define SYMINFO_NUM             2
     442
    419443
    420444/* How to extract and insert information held in the st_info field.  */
    421445
    422 #define ELF32_ST_BIND(val)              (((unsigned char) (val)) >> 4)
    423 #define ELF32_ST_TYPE(val)              ((val) & 0xf)
    424 #define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
     446#define ELF32_ST_BIND(val)              (((unsigned char) (val)) >> 4)
     447#define ELF32_ST_TYPE(val)              ((val) & 0xf)
     448#define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
    425449
    426450/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
    427 #define ELF64_ST_BIND(val)              ELF32_ST_BIND (val)
    428 #define ELF64_ST_TYPE(val)              ELF32_ST_TYPE (val)
    429 #define ELF64_ST_INFO(bind, type)       ELF32_ST_INFO ((bind), (type))
     451#define ELF64_ST_BIND(val)              ELF32_ST_BIND (val)
     452#define ELF64_ST_TYPE(val)              ELF32_ST_TYPE (val)
     453#define ELF64_ST_INFO(bind, type)       ELF32_ST_INFO ((bind), (type))
    430454
    431455/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
    432456
    433 #define STB_LOCAL       0               /* Local symbol */
    434 #define STB_GLOBAL      1               /* Global symbol */
    435 #define STB_WEAK        2               /* Weak symbol */
    436 #define STB_NUM         3               /* Number of defined types.  */
    437 #define STB_LOOS        10              /* Start of OS-specific */
    438 #define STB_HIOS        12              /* End of OS-specific */
    439 #define STB_LOPROC      13              /* Start of processor-specific */
    440 #define STB_HIPROC      15              /* End of processor-specific */
     457#define STB_LOCAL       0               /* Local symbol */
     458#define STB_GLOBAL      1               /* Global symbol */
     459#define STB_WEAK        2               /* Weak symbol */
     460#define STB_NUM         3               /* Number of defined types.  */
     461#define STB_LOOS        10              /* Start of OS-specific */
     462#define STB_GNU_UNIQUE  10              /* Unique symbol.  */
     463#define STB_HIOS        12              /* End of OS-specific */
     464#define STB_LOPROC      13              /* Start of processor-specific */
     465#define STB_HIPROC      15              /* End of processor-specific */
    441466
    442467/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
    443468
    444 #define STT_NOTYPE      0               /* Symbol type is unspecified */
    445 #define STT_OBJECT      1               /* Symbol is a data object */
    446 #define STT_FUNC        2               /* Symbol is a code object */
    447 #define STT_SECTION     3               /* Symbol associated with a section */
    448 #define STT_FILE        4               /* Symbol's name is file name */
    449 #define STT_NUM         5               /* Number of defined types.  */
    450 #define STT_GNU_IFUNC   10              /* Symbol is a indirect code object */
    451 #define STT_LOOS        11              /* Start of OS-specific */
    452 #define STT_HIOS        12              /* End of OS-specific */
    453 #define STT_LOPROC      13              /* Start of processor-specific */
    454 #define STT_HIPROC      15              /* End of processor-specific */
     469#define STT_NOTYPE      0               /* Symbol type is unspecified */
     470#define STT_OBJECT      1               /* Symbol is a data object */
     471#define STT_FUNC        2               /* Symbol is a code object */
     472#define STT_SECTION     3               /* Symbol associated with a section */
     473#define STT_FILE        4               /* Symbol's name is file name */
     474#define STT_COMMON      5               /* Symbol is a common data object */
     475#define STT_TLS         6               /* Symbol is thread-local data object*/
     476#define STT_NUM         7               /* Number of defined types.  */
     477#define STT_LOOS        10              /* Start of OS-specific */
     478#define STT_GNU_IFUNC   10              /* Symbol is indirect code object */
     479#define STT_HIOS        12              /* End of OS-specific */
     480#define STT_LOPROC      13              /* Start of processor-specific */
     481#define STT_HIPROC      15              /* End of processor-specific */
    455482
    456483
     
    459486   the end of a chain, meaning no further symbols are found in that bucket.  */
    460487
    461 #define STN_UNDEF       0               /* End of a chain.  */
     488#define STN_UNDEF       0               /* End of a chain.  */
    462489
    463490
    464491/* How to extract and insert information held in the st_other field.  */
    465492
    466 #define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
     493#define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
    467494
    468495/* For ELF64 the definitions are the same.  */
    469 #define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
     496#define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
    470497
    471498/* Symbol visibility specification encoded in the st_other field.  */
    472 #define STV_DEFAULT     0               /* Default symbol visibility rules */
    473 #define STV_INTERNAL    1               /* Processor specific hidden class */
    474 #define STV_HIDDEN      2               /* Sym unavailable in other modules */
    475 #define STV_PROTECTED   3               /* Not preemptible, not exported */
     499#define STV_DEFAULT     0               /* Default symbol visibility rules */
     500#define STV_INTERNAL    1               /* Processor specific hidden class */
     501#define STV_HIDDEN      2               /* Sym unavailable in other modules */
     502#define STV_PROTECTED   3               /* Not preemptible, not exported */
    476503
    477504
     
    480507typedef struct
    481508{
    482   Elf32_Addr    r_offset;               /* Address */
    483   Elf32_Word    r_info;                 /* Relocation type and symbol index */
    484 } Elf32_Rel;
     509  Elf32_Addr    r_offset;               /* Address */
     510  Elf32_Word    r_info;                 /* Relocation type and symbol index */
     511} __attribute__((packed)) Elf32_Rel;
    485512
    486513/* I have seen two different definitions of the Elf64_Rel and
     
    491518typedef struct
    492519{
    493   Elf64_Addr    r_offset;               /* Address */
    494   Elf64_Xword   r_info;                 /* Relocation type and symbol index */
    495 } Elf64_Rel;
     520  Elf64_Addr    r_offset;               /* Address */
     521  Elf64_Xword   r_info;                 /* Relocation type and symbol index */
     522} __attribute__((packed)) Elf64_Rel;
    496523
    497524/* Relocation table entry with addend (in section of type SHT_RELA).  */
     
    499526typedef struct
    500527{
    501   Elf32_Addr    r_offset;               /* Address */
    502   Elf32_Word    r_info;                 /* Relocation type and symbol index */
    503   Elf32_Sword   r_addend;               /* Addend */
    504 } Elf32_Rela;
    505 
    506 typedef struct
    507 {
    508   Elf64_Addr    r_offset;               /* Address */
    509   Elf64_Xword   r_info;                 /* Relocation type and symbol index */
    510   Elf64_Sxword  r_addend;               /* Addend */
    511 } Elf64_Rela;
     528  Elf32_Addr    r_offset;               /* Address */
     529  Elf32_Word    r_info;                 /* Relocation type and symbol index */
     530  Elf32_Sword   r_addend;               /* Addend */
     531} __attribute__((packed)) Elf32_Rela;
     532
     533typedef struct
     534{
     535  Elf64_Addr    r_offset;               /* Address */
     536  Elf64_Xword   r_info;                 /* Relocation type and symbol index */
     537  Elf64_Sxword  r_addend;               /* Addend */
     538} __attribute__((packed)) Elf64_Rela;
    512539
    513540/* How to extract and insert information held in the r_info field.  */
    514541
    515 #define ELF32_R_SYM(val)                ((val) >> 8)
    516 #define ELF32_R_TYPE(val)               ((val) & 0xff)
    517 #define ELF32_R_INFO(sym, type)         (((sym) << 8) + ((type) & 0xff))
    518 
    519 #define ELF64_R_SYM(i)                  ((i) >> 32)
    520 #define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
    521 #define ELF64_R_INFO(sym,type)          ((((Elf64_Xword)(sym)) << 32) + (type))
     542#define ELF32_R_SYM(val)                ((val) >> 8)
     543#define ELF32_R_TYPE(val)               ((val) & 0xff)
     544#define ELF32_R_INFO(sym, type)         (((sym) << 8) + ((type) & 0xff))
     545
     546#define ELF64_R_SYM(i)                  ((i) >> 32)
     547#define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
     548#define ELF64_R_INFO(sym,type)          ((((Elf64_Xword) (sym)) << 32) + (type))
    522549
    523550/* Program segment header.  */
     
    525552typedef struct
    526553{
    527   Elf32_Word    p_type;                 /* Segment type */
    528   Elf32_Off     p_offset;               /* Segment file offset */
    529   Elf32_Addr    p_vaddr;                /* Segment virtual address */
    530   Elf32_Addr    p_paddr;                /* Segment physical address */
    531   Elf32_Word    p_filesz;               /* Segment size in file */
    532   Elf32_Word    p_memsz;                /* Segment size in memory */
    533   Elf32_Word    p_flags;                /* Segment flags */
    534   Elf32_Word    p_align;                /* Segment alignment */
    535 } Elf32_Phdr;
    536 
    537 typedef struct
    538 {
    539   Elf64_Word    p_type;                 /* Segment type */
    540   Elf64_Word    p_flags;                /* Segment flags */
    541   Elf64_Off     p_offset;               /* Segment file offset */
    542   Elf64_Addr    p_vaddr;                /* Segment virtual address */
    543   Elf64_Addr    p_paddr;                /* Segment physical address */
    544   Elf64_Xword   p_filesz;               /* Segment size in file */
    545   Elf64_Xword   p_memsz;                /* Segment size in memory */
    546   Elf64_Xword   p_align;                /* Segment alignment */
    547 } Elf64_Phdr;
     554  Elf32_Word    p_type;                 /* Segment type */
     555  Elf32_Off     p_offset;               /* Segment file offset */
     556  Elf32_Addr    p_vaddr;                /* Segment virtual address */
     557  Elf32_Addr    p_paddr;                /* Segment physical address */
     558  Elf32_Word    p_filesz;               /* Segment size in file */
     559  Elf32_Word    p_memsz;                /* Segment size in memory */
     560  Elf32_Word    p_flags;                /* Segment flags */
     561  Elf32_Word    p_align;                /* Segment alignment */
     562} __attribute__((packed)) Elf32_Phdr;
     563
     564typedef struct
     565{
     566  Elf64_Word    p_type;                 /* Segment type */
     567  Elf64_Word    p_flags;                /* Segment flags */
     568  Elf64_Off     p_offset;               /* Segment file offset */
     569  Elf64_Addr    p_vaddr;                /* Segment virtual address */
     570  Elf64_Addr    p_paddr;                /* Segment physical address */
     571  Elf64_Xword   p_filesz;               /* Segment size in file */
     572  Elf64_Xword   p_memsz;                /* Segment size in memory */
     573  Elf64_Xword   p_align;                /* Segment alignment */
     574} __attribute__((packed)) Elf64_Phdr;
     575
     576/* Special value for e_phnum.  This indicates that the real number of
     577   program headers is too large to fit into e_phnum.  Instead the real
     578   value is in the field sh_info of section 0.  */
     579
     580#define PN_XNUM         0xffff
    548581
    549582/* Legal values for p_type (segment type).  */
    550583
    551 #define PT_NULL         0               /* Program header table entry unused */
    552 #define PT_LOAD         1               /* Loadable program segment */
    553 #define PT_DYNAMIC      2               /* Dynamic linking information */
    554 #define PT_INTERP       3               /* Program interpreter */
    555 #define PT_NOTE         4               /* Auxiliary information */
    556 #define PT_SHLIB        5               /* Reserved */
    557 #define PT_PHDR         6               /* Entry for header table itself */
    558 #define PT_NUM          7               /* Number of defined types.  */
    559 #define PT_LOOS         0x60000000      /* Start of OS-specific */
    560 #define PT_HIOS         0x6fffffff      /* End of OS-specific */
    561 #define PT_LOPROC       0x70000000      /* Start of processor-specific */
    562 #define PT_HIPROC       0x7fffffff      /* End of processor-specific */
     584#define PT_NULL         0               /* Program header table entry unused */
     585#define PT_LOAD         1               /* Loadable program segment */
     586#define PT_DYNAMIC      2               /* Dynamic linking information */
     587#define PT_INTERP       3               /* Program interpreter */
     588#define PT_NOTE         4               /* Auxiliary information */
     589#define PT_SHLIB        5               /* Reserved */
     590#define PT_PHDR         6               /* Entry for header table itself */
     591#define PT_TLS          7               /* Thread-local storage segment */
     592#define PT_NUM          8               /* Number of defined types */
     593#define PT_LOOS         0x60000000      /* Start of OS-specific */
     594#define PT_GNU_EH_FRAME 0x6474e550      /* GCC .eh_frame_hdr segment */
     595#define PT_GNU_STACK    0x6474e551      /* Indicates stack executability */
     596#define PT_GNU_RELRO    0x6474e552      /* Read-only after relocation */
     597#define PT_LOSUNW       0x6ffffffa
     598#define PT_SUNWBSS      0x6ffffffa      /* Sun Specific segment */
     599#define PT_SUNWSTACK    0x6ffffffb      /* Stack segment */
     600#define PT_HISUNW       0x6fffffff
     601#define PT_HIOS         0x6fffffff      /* End of OS-specific */
     602#define PT_LOPROC       0x70000000      /* Start of processor-specific */
     603#define PT_HIPROC       0x7fffffff      /* End of processor-specific */
    563604
    564605/* Legal values for p_flags (segment flags).  */
    565606
    566 #define PF_X            (1 << 0)        /* Segment is executable */
    567 #define PF_W            (1 << 1)        /* Segment is writable */
    568 #define PF_R            (1 << 2)        /* Segment is readable */
    569 #define PF_MASKPROC     0xf0000000      /* Processor-specific */
     607#define PF_X            (1 << 0)        /* Segment is executable */
     608#define PF_W            (1 << 1)        /* Segment is writable */
     609#define PF_R            (1 << 2)        /* Segment is readable */
     610#define PF_MASKOS       0x0ff00000      /* OS-specific */
     611#define PF_MASKPROC     0xf0000000      /* Processor-specific */
    570612
    571613/* Legal values for note segment descriptor types for core files. */
    572614
    573 #define NT_PRSTATUS     1               /* Contains copy of prstatus struct */
    574 #define NT_FPREGSET     2               /* Contains copy of fpregset struct */
    575 #define NT_PRPSINFO     3               /* Contains copy of prpsinfo struct */
    576 #define NT_PRXREG       4               /* Contains copy of prxregset struct */
    577 #define NT_PLATFORM     5               /* String from sysinfo(SI_PLATFORM) */
    578 #define NT_AUXV         6               /* Contains copy of auxv array */
    579 #define NT_GWINDOWS     7               /* Contains copy of gwindows struct */
    580 #define NT_PSTATUS      10              /* Contains copy of pstatus struct */
    581 #define NT_PSINFO       13              /* Contains copy of psinfo struct */
    582 #define NT_PRCRED       14              /* Contains copy of prcred struct */
    583 #define NT_UTSNAME      15              /* Contains copy of utsname struct */
    584 #define NT_LWPSTATUS    16              /* Contains copy of lwpstatus struct */
    585 #define NT_LWPSINFO     17              /* Contains copy of lwpinfo struct */
    586 
    587 /* Legal values for the  note segment descriptor types for object files.  */
    588 
    589 #define NT_VERSION      1               /* Contains a version string.  */
     615#define NT_PRSTATUS     1               /* Contains copy of prstatus struct */
     616#define NT_FPREGSET     2               /* Contains copy of fpregset struct */
     617#define NT_PRPSINFO     3               /* Contains copy of prpsinfo struct */
     618#define NT_PRXREG       4               /* Contains copy of prxregset struct */
     619#define NT_TASKSTRUCT   4               /* Contains copy of task structure */
     620#define NT_PLATFORM     5               /* String from sysinfo(SI_PLATFORM) */
     621#define NT_AUXV         6               /* Contains copy of auxv array */
     622#define NT_GWINDOWS     7               /* Contains copy of gwindows struct */
     623#define NT_ASRS         8               /* Contains copy of asrset struct */
     624#define NT_PSTATUS      10              /* Contains copy of pstatus struct */
     625#define NT_PSINFO       13              /* Contains copy of psinfo struct */
     626#define NT_PRCRED       14              /* Contains copy of prcred struct */
     627#define NT_UTSNAME      15              /* Contains copy of utsname struct */
     628#define NT_LWPSTATUS    16              /* Contains copy of lwpstatus struct */
     629#define NT_LWPSINFO     17              /* Contains copy of lwpinfo struct */
     630#define NT_PRFPXREG     20              /* Contains copy of fprxregset struct */
     631#define NT_PRXFPREG     0x46e62b7f      /* Contains copy of user_fxsr_struct */
     632#define NT_PPC_VMX      0x100           /* PowerPC Altivec/VMX registers */
     633#define NT_PPC_SPE      0x101           /* PowerPC SPE/EVR registers */
     634#define NT_PPC_VSX      0x102           /* PowerPC VSX registers */
     635#define NT_386_TLS      0x200           /* i386 TLS slots (struct user_desc) */
     636#define NT_386_IOPERM   0x201           /* x86 io permission bitmap (1=deny) */
     637#define NT_X86_XSTATE   0x202           /* x86 extended state using xsave */
     638#define NT_S390_HIGH_GPRS       0x300   /* s390 upper register halves */
     639#define NT_S390_TIMER   0x301           /* s390 timer register */
     640#define NT_S390_TODCMP  0x302           /* s390 TOD clock comparator register */
     641#define NT_S390_TODPREG 0x303           /* s390 TOD programmable register */
     642#define NT_S390_CTRS    0x304           /* s390 control registers */
     643#define NT_S390_PREFIX  0x305           /* s390 prefix register */
     644#define NT_S390_LAST_BREAK      0x306   /* s390 breaking event address */
     645#define NT_S390_SYSTEM_CALL     0x307   /* s390 system call restart data */
     646#define NT_ARM_VFP      0x400           /* ARM VFP/NEON registers */
     647#define NT_ARM_TLS      0x401           /* ARM TLS register */
     648#define NT_ARM_HW_BREAK 0x402           /* ARM hardware breakpoint registers */
     649#define NT_ARM_HW_WATCH 0x403           /* ARM hardware watchpoint registers */
     650
     651/* Legal values for the note segment descriptor types for object files.  */
     652
     653#define NT_VERSION      1               /* Contains a version string.  */
    590654
    591655
     
    594658typedef struct
    595659{
    596   Elf32_Sword   d_tag;                  /* Dynamic entry type */
     660  Elf32_Sword   d_tag;                  /* Dynamic entry type */
    597661  union
    598662    {
    599       Elf32_Word d_val;                 /* Integer value */
    600       Elf32_Addr d_ptr;                 /* Address value */
     663      Elf32_Word d_val;                 /* Integer value */
     664      Elf32_Addr d_ptr;                 /* Address value */
    601665    } d_un;
    602 } Elf32_Dyn;
    603 
    604 typedef struct
    605 {
    606   Elf64_Sxword  d_tag;                  /* Dynamic entry type */
     666} __attribute__((packed)) Elf32_Dyn;
     667
     668typedef struct
     669{
     670  Elf64_Sxword  d_tag;                  /* Dynamic entry type */
    607671  union
    608672    {
    609       Elf64_Xword d_val;                /* Integer value */
    610       Elf64_Addr d_ptr;                 /* Address value */
     673      Elf64_Xword d_val;                /* Integer value */
     674      Elf64_Addr d_ptr;                 /* Address value */
    611675    } d_un;
    612 } Elf64_Dyn;
     676} __attribute__((packed)) Elf64_Dyn;
    613677
    614678/* Legal values for d_tag (dynamic entry type).  */
    615679
    616 #define DT_NULL         0               /* Marks end of dynamic section */
    617 #define DT_NEEDED       1               /* Name of needed library */
    618 #define DT_PLTRELSZ     2               /* Size in bytes of PLT relocs */
    619 #define DT_PLTGOT       3               /* Processor defined value */
    620 #define DT_HASH         4               /* Address of symbol hash table */
    621 #define DT_STRTAB       5               /* Address of string table */
    622 #define DT_SYMTAB       6               /* Address of symbol table */
    623 #define DT_RELA         7               /* Address of Rela relocs */
    624 #define DT_RELASZ       8               /* Total size of Rela relocs */
    625 #define DT_RELAENT      9               /* Size of one Rela reloc */
    626 #define DT_STRSZ        10              /* Size of string table */
    627 #define DT_SYMENT       11              /* Size of one symbol table entry */
    628 #define DT_INIT         12              /* Address of init function */
    629 #define DT_FINI         13              /* Address of termination function */
    630 #define DT_SONAME       14              /* Name of shared object */
    631 #define DT_RPATH        15              /* Library search path */
    632 #define DT_SYMBOLIC     16              /* Start symbol search here */
    633 #define DT_REL          17              /* Address of Rel relocs */
    634 #define DT_RELSZ        18              /* Total size of Rel relocs */
    635 #define DT_RELENT       19              /* Size of one Rel reloc */
    636 #define DT_PLTREL       20              /* Type of reloc in PLT */
    637 #define DT_DEBUG        21              /* For debugging; unspecified */
    638 #define DT_TEXTREL      22              /* Reloc might modify .text */
    639 #define DT_JMPREL       23              /* Address of PLT relocs */
    640 #define DT_BIND_NOW     24              /* Process relocations of object */
    641 #define DT_INIT_ARRAY   25              /* Array with addresses of init fct */
    642 #define DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
    643 #define DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
    644 #define DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
    645 #define DT_NUM          29              /* Number used */
    646 #define DT_LOOS         0x60000000      /* Start of OS-specific */
    647 #define DT_HIOS         0x6fffffff      /* End of OS-specific */
    648 #define DT_LOPROC       0x70000000      /* Start of processor-specific */
    649 #define DT_HIPROC       0x7fffffff      /* End of processor-specific */
    650 #define DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
     680#define DT_NULL         0               /* Marks end of dynamic section */
     681#define DT_NEEDED       1               /* Name of needed library */
     682#define DT_PLTRELSZ     2               /* Size in bytes of PLT relocs */
     683#define DT_PLTGOT       3               /* Processor defined value */
     684#define DT_HASH         4               /* Address of symbol hash table */
     685#define DT_STRTAB       5               /* Address of string table */
     686#define DT_SYMTAB       6               /* Address of symbol table */
     687#define DT_RELA         7               /* Address of Rela relocs */
     688#define DT_RELASZ       8               /* Total size of Rela relocs */
     689#define DT_RELAENT      9               /* Size of one Rela reloc */
     690#define DT_STRSZ        10              /* Size of string table */
     691#define DT_SYMENT       11              /* Size of one symbol table entry */
     692#define DT_INIT         12              /* Address of init function */
     693#define DT_FINI         13              /* Address of termination function */
     694#define DT_SONAME       14              /* Name of shared object */
     695#define DT_RPATH        15              /* Library search path (deprecated) */
     696#define DT_SYMBOLIC     16              /* Start symbol search here */
     697#define DT_REL          17              /* Address of Rel relocs */
     698#define DT_RELSZ        18              /* Total size of Rel relocs */
     699#define DT_RELENT       19              /* Size of one Rel reloc */
     700#define DT_PLTREL       20              /* Type of reloc in PLT */
     701#define DT_DEBUG        21              /* For debugging; unspecified */
     702#define DT_TEXTREL      22              /* Reloc might modify .text */
     703#define DT_JMPREL       23              /* Address of PLT relocs */
     704#define DT_BIND_NOW     24              /* Process relocations of object */
     705#define DT_INIT_ARRAY   25              /* Array with addresses of init fct */
     706#define DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
     707#define DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
     708#define DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
     709#define DT_RUNPATH      29              /* Library search path */
     710#define DT_FLAGS        30              /* Flags for the object being loaded */
     711#define DT_ENCODING     32              /* Start of encoded range */
     712#define DT_PREINIT_ARRAY 32             /* Array with addresses of preinit fct*/
     713#define DT_PREINIT_ARRAYSZ 33           /* size in bytes of DT_PREINIT_ARRAY */
     714#define DT_NUM          34              /* Number used */
     715#define DT_LOOS         0x6000000d      /* Start of OS-specific */
     716#define DT_HIOS         0x6ffff000      /* End of OS-specific */
     717#define DT_LOPROC       0x70000000      /* Start of processor-specific */
     718#define DT_HIPROC       0x7fffffff      /* End of processor-specific */
     719#define DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
    651720
    652721/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
    653722   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
    654723   approach.  */
    655 #define DT_VALRNGLO     0x6ffffd00
    656 #define DT_POSFLAG_1    0x6ffffdfd      /* Flags for DT_* entries, effecting
    657                                            the following DT_* entry.  */
    658 #define DT_SYMINSZ      0x6ffffdfe      /* Size of syminfo table (in bytes) */
    659 #define DT_SYMINENT     0x6ffffdff      /* Entry size of syminfo */
    660 #define DT_VALRNGHI     0x6ffffdff
     724#define DT_VALRNGLO     0x6ffffd00
     725#define DT_GNU_PRELINKED 0x6ffffdf5     /* Prelinking timestamp */
     726#define DT_GNU_CONFLICTSZ 0x6ffffdf6    /* Size of conflict section */
     727#define DT_GNU_LIBLISTSZ 0x6ffffdf7     /* Size of library list */
     728#define DT_CHECKSUM     0x6ffffdf8
     729#define DT_PLTPADSZ     0x6ffffdf9
     730#define DT_MOVEENT      0x6ffffdfa
     731#define DT_MOVESZ       0x6ffffdfb
     732#define DT_FEATURE_1    0x6ffffdfc      /* Feature selection (DTF_*).  */
     733#define DT_POSFLAG_1    0x6ffffdfd      /* Flags for DT_* entries, effecting
     734                                           the following DT_* entry.  */
     735#define DT_SYMINSZ      0x6ffffdfe      /* Size of syminfo table (in bytes) */
     736#define DT_SYMINENT     0x6ffffdff      /* Entry size of syminfo */
     737#define DT_VALRNGHI     0x6ffffdff
     738#define DT_VALTAGIDX(tag)       (DT_VALRNGHI - (tag))   /* Reverse order! */
     739#define DT_VALNUM 12
    661740
    662741/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
     
    665744   If any adjustment is made to the ELF object after it has been
    666745   built these entries will need to be adjusted.  */
    667 #define DT_ADDRRNGLO    0x6ffffe00
    668 #define DT_SYMINFO      0x6ffffeff      /* syminfo table */
    669 #define DT_ADDRRNGHI    0x6ffffeff
     746#define DT_ADDRRNGLO    0x6ffffe00
     747#define DT_GNU_HASH     0x6ffffef5      /* GNU-style hash table.  */
     748#define DT_TLSDESC_PLT  0x6ffffef6
     749#define DT_TLSDESC_GOT  0x6ffffef7
     750#define DT_GNU_CONFLICT 0x6ffffef8      /* Start of conflict section */
     751#define DT_GNU_LIBLIST  0x6ffffef9      /* Library list */
     752#define DT_CONFIG       0x6ffffefa      /* Configuration information.  */
     753#define DT_DEPAUDIT     0x6ffffefb      /* Dependency auditing.  */
     754#define DT_AUDIT        0x6ffffefc      /* Object auditing.  */
     755#define DT_PLTPAD       0x6ffffefd      /* PLT padding.  */
     756#define DT_MOVETAB      0x6ffffefe      /* Move table.  */
     757#define DT_SYMINFO      0x6ffffeff      /* Syminfo table.  */
     758#define DT_ADDRRNGHI    0x6ffffeff
     759#define DT_ADDRTAGIDX(tag)      (DT_ADDRRNGHI - (tag))  /* Reverse order! */
     760#define DT_ADDRNUM 11
    670761
    671762/* The versioning entry types.  The next are defined as part of the
    672763   GNU extension.  */
    673 #define DT_VERSYM       0x6ffffff0
     764#define DT_VERSYM       0x6ffffff0
     765
     766#define DT_RELACOUNT    0x6ffffff9
     767#define DT_RELCOUNT     0x6ffffffa
    674768
    675769/* These were chosen by Sun.  */
    676 #define DT_FLAGS_1      0x6ffffffb      /* State flags, see DF_1_* below.  */
    677 #define DT_VERDEF       0x6ffffffc      /* Address of version definition
    678                                            table */
    679 #define DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
    680 #define DT_VERNEED      0x6ffffffe      /* Address of table with needed
    681                                            versions */
    682 #define DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
    683 #define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
     770#define DT_FLAGS_1      0x6ffffffb      /* State flags, see DF_1_* below.  */
     771#define DT_VERDEF       0x6ffffffc      /* Address of version definition
     772                                           table */
     773#define DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
     774#define DT_VERNEED      0x6ffffffe      /* Address of table with needed
     775                                           versions */
     776#define DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
     777#define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
    684778#define DT_VERSIONTAGNUM 16
    685779
     
    688782#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
    689783#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
    690 #define DT_EXTRATAGIDX(tag)     ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
    691 #define DT_EXTRANUM     3
     784#define DT_EXTRATAGIDX(tag)     ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
     785#define DT_EXTRANUM     3
     786
     787/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
     788#define DF_ORIGIN       0x00000001      /* Object may use DF_ORIGIN */
     789#define DF_SYMBOLIC     0x00000002      /* Symbol resolutions starts here */
     790#define DF_TEXTREL      0x00000004      /* Object contains text relocations */
     791#define DF_BIND_NOW     0x00000008      /* No lazy binding for this object */
     792#define DF_STATIC_TLS   0x00000010      /* Module uses the static TLS model */
    692793
    693794/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
    694795   entry in the dynamic section.  */
    695 #define DF_1_NOW        0x00000001      /* Set RTLD_NOW for this object.  */
    696 #define DF_1_GLOBAL     0x00000002      /* Set RTLD_GLOBAL for this object.  */
    697 #define DF_1_GROUP      0x00000004      /* Set RTLD_GROUP for this object.  */
    698 #define DF_1_NODELETE   0x00000008      /* Set RTLD_NODELETE for this object.*/
    699 #define DF_1_LOADFLTR   0x00000010      /* Trigger filtee loading at runtime.*/
    700 #define DF_1_INITFIRST  0x00000020      /* Set RTLD_INITFIRST for this object*/
    701 #define DF_1_NOOPEN     0x00000040      /* Set RTLD_NOOPEN for this object.  */
     796#define DF_1_NOW        0x00000001      /* Set RTLD_NOW for this object.  */
     797#define DF_1_GLOBAL     0x00000002      /* Set RTLD_GLOBAL for this object.  */
     798#define DF_1_GROUP      0x00000004      /* Set RTLD_GROUP for this object.  */
     799#define DF_1_NODELETE   0x00000008      /* Set RTLD_NODELETE for this object.*/
     800#define DF_1_LOADFLTR   0x00000010      /* Trigger filtee loading at runtime.*/
     801#define DF_1_INITFIRST  0x00000020      /* Set RTLD_INITFIRST for this object*/
     802#define DF_1_NOOPEN     0x00000040      /* Set RTLD_NOOPEN for this object.  */
     803#define DF_1_ORIGIN     0x00000080      /* $ORIGIN must be handled.  */
     804#define DF_1_DIRECT     0x00000100      /* Direct binding enabled.  */
     805#define DF_1_TRANS      0x00000200
     806#define DF_1_INTERPOSE  0x00000400      /* Object is used to interpose.  */
     807#define DF_1_NODEFLIB   0x00000800      /* Ignore default lib search path.  */
     808#define DF_1_NODUMP     0x00001000      /* Object can't be dldump'ed.  */
     809#define DF_1_CONFALT    0x00002000      /* Configuration alternative created.*/
     810#define DF_1_ENDFILTEE  0x00004000      /* Filtee terminates filters search. */
     811#define DF_1_DISPRELDNE 0x00008000      /* Disp reloc applied at build time. */
     812#define DF_1_DISPRELPND 0x00010000      /* Disp reloc applied at run-time.  */
     813#define DF_1_NODIRECT   0x00020000      /* Object has no-direct binding. */
     814#define DF_1_IGNMULDEF  0x00040000
     815#define DF_1_NOKSYMS    0x00080000
     816#define DF_1_NOHDR      0x00100000
     817#define DF_1_EDITED     0x00200000      /* Object is modified after built.  */
     818#define DF_1_NORELOC    0x00400000
     819#define DF_1_SYMINTPOSE 0x00800000      /* Object has individual interposers.  */
     820#define DF_1_GLOBAUDIT  0x01000000      /* Global auditing required.  */
     821#define DF_1_SINGLETON  0x02000000      /* Singleton symbols are used.  */
     822
     823/* Flags for the feature selection in DT_FEATURE_1.  */
     824#define DTF_1_PARINIT   0x00000001
     825#define DTF_1_CONFEXP   0x00000002
     826
     827/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
     828#define DF_P1_LAZYLOAD  0x00000001      /* Lazyload following object.  */
     829#define DF_P1_GROUPPERM 0x00000002      /* Symbols from next object are not
     830                                           generally available.  */
    702831
    703832/* Version definition sections.  */
     
    705834typedef struct
    706835{
    707   Elf32_Half    vd_version;             /* Version revision */
    708   Elf32_Half    vd_flags;               /* Version information */
    709   Elf32_Half    vd_ndx;                 /* Version Index */
    710   Elf32_Half    vd_cnt;                 /* Number of associated aux entries */
    711   Elf32_Word    vd_hash;                /* Version name hash value */
    712   Elf32_Word    vd_aux;                 /* Offset in bytes to verdaux array */
    713   Elf32_Word    vd_next;                /* Offset in bytes to next verdef
    714                                            entry */
    715 } Elf32_Verdef;
    716 
    717 typedef struct
    718 {
    719   Elf64_Half    vd_version;             /* Version revision */
    720   Elf64_Half    vd_flags;               /* Version information */
    721   Elf64_Half    vd_ndx;                 /* Version Index */
    722   Elf64_Half    vd_cnt;                 /* Number of associated aux entries */
    723   Elf64_Word    vd_hash;                /* Version name hash value */
    724   Elf64_Word    vd_aux;                 /* Offset in bytes to verdaux array */
    725   Elf64_Word    vd_next;                /* Offset in bytes to next verdef
    726                                            entry */
    727 } Elf64_Verdef;
     836  Elf32_Half    vd_version;             /* Version revision */
     837  Elf32_Half    vd_flags;               /* Version information */
     838  Elf32_Half    vd_ndx;                 /* Version Index */
     839  Elf32_Half    vd_cnt;                 /* Number of associated aux entries */
     840  Elf32_Word    vd_hash;                /* Version name hash value */
     841  Elf32_Word    vd_aux;                 /* Offset in bytes to verdaux array */
     842  Elf32_Word    vd_next;                /* Offset in bytes to next verdef
     843                                           entry */
     844} __attribute__((packed)) Elf32_Verdef;
     845
     846typedef struct
     847{
     848  Elf64_Half    vd_version;             /* Version revision */
     849  Elf64_Half    vd_flags;               /* Version information */
     850  Elf64_Half    vd_ndx;                 /* Version Index */
     851  Elf64_Half    vd_cnt;                 /* Number of associated aux entries */
     852  Elf64_Word    vd_hash;                /* Version name hash value */
     853  Elf64_Word    vd_aux;                 /* Offset in bytes to verdaux array */
     854  Elf64_Word    vd_next;                /* Offset in bytes to next verdef
     855                                           entry */
     856} __attribute__((packed)) Elf64_Verdef;
    728857
    729858
    730859/* Legal values for vd_version (version revision).  */
    731 #define VER_DEF_NONE    0               /* No version */
    732 #define VER_DEF_CURRENT 1               /* Current version */
    733 #define VER_DEF_NUM     2               /* Given version number */
     860#define VER_DEF_NONE    0               /* No version */
     861#define VER_DEF_CURRENT 1               /* Current version */
     862#define VER_DEF_NUM     2               /* Given version number */
    734863
    735864/* Legal values for vd_flags (version information flags).  */
    736 #define VER_FLG_BASE    0x1             /* Version definition of file itself */
    737 #define VER_FLG_WEAK    0x2             /* Weak version identifier */
    738 
    739 /* Auxialiary version information.  */
    740 
    741 typedef struct
    742 {
    743   Elf32_Word    vda_name;               /* Version or dependency names */
    744   Elf32_Word    vda_next;               /* Offset in bytes to next verdaux
    745                                            entry */
    746 } Elf32_Verdaux;
    747 
    748 typedef struct
    749 {
    750   Elf64_Word    vda_name;               /* Version or dependency names */
    751   Elf64_Word    vda_next;               /* Offset in bytes to next verdaux
    752                                            entry */
    753 } Elf64_Verdaux;
     865#define VER_FLG_BASE    0x1             /* Version definition of file itself */
     866#define VER_FLG_WEAK    0x2             /* Weak version identifier */
     867
     868/* Versym symbol index values.  */
     869#define VER_NDX_LOCAL           0       /* Symbol is local.  */
     870#define VER_NDX_GLOBAL          1       /* Symbol is global.  */
     871#define VER_NDX_LORESERVE       0xff00  /* Beginning of reserved entries.  */
     872#define VER_NDX_ELIMINATE       0xff01  /* Symbol is to be eliminated.  */
     873
     874/* Auxiliary version information.  */
     875
     876typedef struct
     877{
     878  Elf32_Word    vda_name;               /* Version or dependency names */
     879  Elf32_Word    vda_next;               /* Offset in bytes to next verdaux
     880                                           entry */
     881} __attribute__((packed)) Elf32_Verdaux;
     882
     883typedef struct
     884{
     885  Elf64_Word    vda_name;               /* Version or dependency names */
     886  Elf64_Word    vda_next;               /* Offset in bytes to next verdaux
     887                                           entry */
     888} __attribute__((packed)) Elf64_Verdaux;
    754889
    755890
     
    758893typedef struct
    759894{
    760   Elf32_Half    vn_version;             /* Version of structure */
    761   Elf32_Half    vn_cnt;                 /* Number of associated aux entries */
    762   Elf32_Word    vn_file;                /* Offset of filename for this
    763                                            dependency */
    764   Elf32_Word    vn_aux;                 /* Offset in bytes to vernaux array */
    765   Elf32_Word    vn_next;                /* Offset in bytes to next verneed
    766                                            entry */
    767 } Elf32_Verneed;
    768 
    769 typedef struct
    770 {
    771   Elf64_Half    vn_version;             /* Version of structure */
    772   Elf64_Half    vn_cnt;                 /* Number of associated aux entries */
    773   Elf64_Word    vn_file;                /* Offset of filename for this
    774                                            dependency */
    775   Elf64_Word    vn_aux;                 /* Offset in bytes to vernaux array */
    776   Elf64_Word    vn_next;                /* Offset in bytes to next verneed
    777                                            entry */
    778 } Elf64_Verneed;
     895  Elf32_Half    vn_version;             /* Version of structure */
     896  Elf32_Half    vn_cnt;                 /* Number of associated aux entries */
     897  Elf32_Word    vn_file;                /* Offset of filename for this
     898                                           dependency */
     899  Elf32_Word    vn_aux;                 /* Offset in bytes to vernaux array */
     900  Elf32_Word    vn_next;                /* Offset in bytes to next verneed
     901                                           entry */
     902} __attribute__((packed)) Elf32_Verneed;
     903
     904typedef struct
     905{
     906  Elf64_Half    vn_version;             /* Version of structure */
     907  Elf64_Half    vn_cnt;                 /* Number of associated aux entries */
     908  Elf64_Word    vn_file;                /* Offset of filename for this
     909                                           dependency */
     910  Elf64_Word    vn_aux;                 /* Offset in bytes to vernaux array */
     911  Elf64_Word    vn_next;                /* Offset in bytes to next verneed
     912                                           entry */
     913} __attribute__((packed)) Elf64_Verneed;
    779914
    780915
    781916/* Legal values for vn_version (version revision).  */
    782 #define VER_NEED_NONE    0              /* No version */
    783 #define VER_NEED_CURRENT 1              /* Current version */
    784 #define VER_NEED_NUM     2              /* Given version number */
     917#define VER_NEED_NONE    0              /* No version */
     918#define VER_NEED_CURRENT 1              /* Current version */
     919#define VER_NEED_NUM     2              /* Given version number */
    785920
    786921/* Auxiliary needed version information.  */
     
    788923typedef struct
    789924{
    790   Elf32_Word    vna_hash;               /* Hash value of dependency name */
    791   Elf32_Half    vna_flags;              /* Dependency specific information */
    792   Elf32_Half    vna_other;              /* Unused */
    793   Elf32_Word    vna_name;               /* Dependency name string offset */
    794   Elf32_Word    vna_next;               /* Offset in bytes to next vernaux
    795                                            entry */
    796 } Elf32_Vernaux;
    797 
    798 typedef struct
    799 {
    800   Elf64_Word    vna_hash;               /* Hash value of dependency name */
    801   Elf64_Half    vna_flags;              /* Dependency specific information */
    802   Elf64_Half    vna_other;              /* Unused */
    803   Elf64_Word    vna_name;               /* Dependency name string offset */
    804   Elf64_Word    vna_next;               /* Offset in bytes to next vernaux
    805                                            entry */
    806 } Elf64_Vernaux;
     925  Elf32_Word    vna_hash;               /* Hash value of dependency name */
     926  Elf32_Half    vna_flags;              /* Dependency specific information */
     927  Elf32_Half    vna_other;              /* Unused */
     928  Elf32_Word    vna_name;               /* Dependency name string offset */
     929  Elf32_Word    vna_next;               /* Offset in bytes to next vernaux
     930                                           entry */
     931} __attribute__((packed)) Elf32_Vernaux;
     932
     933typedef struct
     934{
     935  Elf64_Word    vna_hash;               /* Hash value of dependency name */
     936  Elf64_Half    vna_flags;              /* Dependency specific information */
     937  Elf64_Half    vna_other;              /* Unused */
     938  Elf64_Word    vna_name;               /* Dependency name string offset */
     939  Elf64_Word    vna_next;               /* Offset in bytes to next vernaux
     940                                           entry */
     941} __attribute__((packed)) Elf64_Vernaux;
    807942
    808943
    809944/* Legal values for vna_flags.  */
    810 #define VER_FLG_WEAK    0x2             /* Weak version identifier */
     945#define VER_FLG_WEAK    0x2             /* Weak version identifier */
    811946
    812947
     
    822957typedef struct
    823958{
    824   int a_type;                   /* Entry type */
     959  uint32_t a_type;              /* Entry type */
    825960  union
    826961    {
    827       long int a_val;           /* Integer value */
    828       void *a_ptr;              /* Pointer value */
    829       void (*a_fcn) (void);     /* Function pointer value */
     962      uint32_t a_val;           /* Integer value */
     963      /* We use to have pointer elements added here.  We cannot do that,
     964         though, since it does not work when using 32-bit definitions
     965         on 64-bit platforms and vice versa.  */
    830966    } a_un;
    831 } Elf32_auxv_t;
    832 
    833 typedef struct
    834 {
    835   long int a_type;              /* Entry type */
     967} __attribute__((packed)) Elf32_auxv_t;
     968
     969typedef struct
     970{
     971  uint64_t a_type;              /* Entry type */
    836972  union
    837973    {
    838       long int a_val;           /* Integer value */
    839       void *a_ptr;              /* Pointer value */
    840       void (*a_fcn) (void);     /* Function pointer value */
     974      uint64_t a_val;           /* Integer value */
     975      /* We use to have pointer elements added here.  We cannot do that,
     976         though, since it does not work when using 32-bit definitions
     977         on 64-bit platforms and vice versa.  */
    841978    } a_un;
    842 } Elf64_auxv_t;
     979} __attribute__((packed)) Elf64_auxv_t;
    843980
    844981/* Legal values for a_type (entry type).  */
    845982
    846 #define AT_NULL         0               /* End of vector */
    847 #define AT_IGNORE       1               /* Entry should be ignored */
    848 #define AT_EXECFD       2               /* File descriptor of program */
    849 #define AT_PHDR         3               /* Program headers for program */
    850 #define AT_PHENT        4               /* Size of program header entry */
    851 #define AT_PHNUM        5               /* Number of program headers */
    852 #define AT_PAGESZ       6               /* System page size */
    853 #define AT_BASE         7               /* Base address of interpreter */
    854 #define AT_FLAGS        8               /* Flags */
    855 #define AT_ENTRY        9               /* Entry point of program */
    856 #define AT_NOTELF       10              /* Program is not ELF */
    857 #define AT_UID          11              /* Real uid */
    858 #define AT_EUID         12              /* Effective uid */
    859 #define AT_GID          13              /* Real gid */
    860 #define AT_EGID         14              /* Effective gid */
     983#define AT_NULL         0               /* End of vector */
     984#define AT_IGNORE       1               /* Entry should be ignored */
     985#define AT_EXECFD       2               /* File descriptor of program */
     986#define AT_PHDR         3               /* Program headers for program */
     987#define AT_PHENT        4               /* Size of program header entry */
     988#define AT_PHNUM        5               /* Number of program headers */
     989#define AT_PAGESZ       6               /* System page size */
     990#define AT_BASE         7               /* Base address of interpreter */
     991#define AT_FLAGS        8               /* Flags */
     992#define AT_ENTRY        9               /* Entry point of program */
     993#define AT_NOTELF       10              /* Program is not ELF */
     994#define AT_UID          11              /* Real uid */
     995#define AT_EUID         12              /* Effective uid */
     996#define AT_GID          13              /* Real gid */
     997#define AT_EGID         14              /* Effective gid */
     998#define AT_CLKTCK       17              /* Frequency of times() */
    861999
    8621000/* Some more special a_type values describing the hardware.  */
    863 #define AT_PLATFORM     15              /* String identifying platform.  */
    864 #define AT_HWCAP        16              /* Machine dependent hints about
    865                                            processor capabilities.  */
     1001#define AT_PLATFORM     15              /* String identifying platform.  */
     1002#define AT_HWCAP        16              /* Machine dependent hints about
     1003                                           processor capabilities.  */
    8661004
    8671005/* This entry gives some information about the FPU initialization
    8681006   performed by the kernel.  */
    869 #define AT_FPUCW        17              /* Used FPU control word.  */
    870 
     1007#define AT_FPUCW        18              /* Used FPU control word.  */
     1008
     1009/* Cache block sizes.  */
     1010#define AT_DCACHEBSIZE  19              /* Data cache block size.  */
     1011#define AT_ICACHEBSIZE  20              /* Instruction cache block size.  */
     1012#define AT_UCACHEBSIZE  21              /* Unified cache block size.  */
     1013
     1014/* A special ignored value for PPC, used by the kernel to control the
     1015   interpretation of the AUXV. Must be > 16.  */
     1016#define AT_IGNOREPPC    22              /* Entry should be ignored.  */
     1017
     1018#define AT_SECURE       23              /* Boolean, was exec setuid-like?  */
     1019
     1020#define AT_BASE_PLATFORM 24             /* String identifying real platforms.*/
     1021
     1022#define AT_RANDOM       25              /* Address of 16 random bytes.  */
     1023
     1024#define AT_EXECFN       31              /* Filename of executable.  */
     1025
     1026/* Pointer to the global system page used for system calls and other
     1027   nice things.  */
     1028#define AT_SYSINFO      32
     1029#define AT_SYSINFO_EHDR 33
     1030
     1031/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
     1032   log2 of line size; mask those to get cache size.  */
     1033#define AT_L1I_CACHESHAPE       34
     1034#define AT_L1D_CACHESHAPE       35
     1035#define AT_L2_CACHESHAPE        36
     1036#define AT_L3_CACHESHAPE        37
    8711037
    8721038/* Note section contents.  Each entry in the note section begins with
     
    8751041typedef struct
    8761042{
    877   Elf32_Word n_namesz;                  /* Length of the note's name.  */
    878   Elf32_Word n_descsz;                  /* Length of the note's descriptor.  */
    879   Elf32_Word n_type;                    /* Type of the note.  */
    880 } Elf32_Nhdr;
    881 
    882 typedef struct
    883 {
    884   Elf64_Word n_namesz;                  /* Length of the note's name.  */
    885   Elf64_Word n_descsz;                  /* Length of the note's descriptor.  */
    886   Elf64_Word n_type;                    /* Type of the note.  */
    887 } Elf64_Nhdr;
     1043  Elf32_Word n_namesz;                  /* Length of the note's name.  */
     1044  Elf32_Word n_descsz;                  /* Length of the note's descriptor.  */
     1045  Elf32_Word n_type;                    /* Type of the note.  */
     1046} __attribute__((packed)) Elf32_Nhdr;
     1047
     1048typedef struct
     1049{
     1050  Elf64_Word n_namesz;                  /* Length of the note's name.  */
     1051  Elf64_Word n_descsz;                  /* Length of the note's descriptor.  */
     1052  Elf64_Word n_type;                    /* Type of the note.  */
     1053} __attribute__((packed)) Elf64_Nhdr;
    8881054
    8891055/* Known names of notes.  */
    8901056
    8911057/* Solaris entries in the note section have this name.  */
    892 #define ELF_NOTE_SOLARIS        "SUNW Solaris"
     1058#define ELF_NOTE_SOLARIS        "SUNW Solaris"
    8931059
    8941060/* Note entries for GNU systems have this name.  */
    895 #define ELF_NOTE_GNU            "GNU"
     1061#define ELF_NOTE_GNU            "GNU"
    8961062
    8971063
     
    8991065
    9001066/* Value of descriptor (one word) is desired pagesize for the binary.  */
    901 #define ELF_NOTE_PAGESIZE_HINT  1
     1067#define ELF_NOTE_PAGESIZE_HINT  1
    9021068
    9031069
     
    9101076   word 3: subminor version of the ABI
    9111077*/
    912 #define ELF_NOTE_ABI            1
    913 
    914 /* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
    915    note section entry.  */
    916 #define ELF_NOTE_OS_LINUX       0
    917 #define ELF_NOTE_OS_GNU         1
    918 #define ELF_NOTE_OS_SOLARIS2    2
     1078#define NT_GNU_ABI_TAG  1
     1079#define ELF_NOTE_ABI    NT_GNU_ABI_TAG /* Old name.  */
     1080
     1081/* Known OSes.  These values can appear in word 0 of an
     1082   NT_GNU_ABI_TAG note section entry.  */
     1083#define ELF_NOTE_OS_LINUX       0
     1084#define ELF_NOTE_OS_GNU         1
     1085#define ELF_NOTE_OS_SOLARIS2    2
     1086#define ELF_NOTE_OS_FREEBSD     3
     1087
     1088/* Synthetic hwcap information.  The descriptor begins with two words:
     1089   word 0: number of entries
     1090   word 1: bitmask of enabled entries
     1091   Then follow variable-length entries, one byte followed by a
     1092   '\0'-terminated hwcap name string.  The byte gives the bit
     1093   number to test if enabled, (1U << bit) & bitmask.  */
     1094#define NT_GNU_HWCAP    2
     1095
     1096/* Build ID bits as generated by ld --build-id.
     1097   The descriptor consists of any nonzero number of bytes.  */
     1098#define NT_GNU_BUILD_ID 3
     1099
     1100/* Version note generated by GNU gold containing a version string.  */
     1101#define NT_GNU_GOLD_VERSION     4
     1102
     1103
     1104/* Move records.  */
     1105typedef struct
     1106{
     1107  Elf32_Xword m_value;          /* Symbol value.  */
     1108  Elf32_Word m_info;            /* Size and index.  */
     1109  Elf32_Word m_poffset;         /* Symbol offset.  */
     1110  Elf32_Half m_repeat;          /* Repeat count.  */
     1111  Elf32_Half m_stride;          /* Stride info.  */
     1112} __attribute__((packed)) Elf32_Move;
     1113
     1114typedef struct
     1115{
     1116  Elf64_Xword m_value;          /* Symbol value.  */
     1117  Elf64_Xword m_info;           /* Size and index.  */
     1118  Elf64_Xword m_poffset;        /* Symbol offset.  */
     1119  Elf64_Half m_repeat;          /* Repeat count.  */
     1120  Elf64_Half m_stride;          /* Stride info.  */
     1121} __attribute__((packed)) Elf64_Move;
     1122
     1123/* Macro to construct move records.  */
     1124#define ELF32_M_SYM(info)       ((info) >> 8)
     1125#define ELF32_M_SIZE(info)      ((unsigned char) (info))
     1126#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
     1127
     1128#define ELF64_M_SYM(info)       ELF32_M_SYM (info)
     1129#define ELF64_M_SIZE(info)      ELF32_M_SIZE (info)
     1130#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
    9191131
    9201132
    9211133/* Motorola 68k specific definitions.  */
    9221134
     1135/* Values for Elf32_Ehdr.e_flags.  */
     1136#define EF_CPU32        0x00810000
     1137
    9231138/* m68k relocs.  */
    9241139
    925 #define R_68K_NONE      0               /* No reloc */
    926 #define R_68K_32        1               /* Direct 32 bit  */
    927 #define R_68K_16        2               /* Direct 16 bit  */
    928 #define R_68K_8         3               /* Direct 8 bit  */
    929 #define R_68K_PC32      4               /* PC relative 32 bit */
    930 #define R_68K_PC16      5               /* PC relative 16 bit */
    931 #define R_68K_PC8       6               /* PC relative 8 bit */
    932 #define R_68K_GOT32     7               /* 32 bit PC relative GOT entry */
    933 #define R_68K_GOT16     8               /* 16 bit PC relative GOT entry */
    934 #define R_68K_GOT8      9               /* 8 bit PC relative GOT entry */
    935 #define R_68K_GOT32O    10              /* 32 bit GOT offset */
    936 #define R_68K_GOT16O    11              /* 16 bit GOT offset */
    937 #define R_68K_GOT8O     12              /* 8 bit GOT offset */
    938 #define R_68K_PLT32     13              /* 32 bit PC relative PLT address */
    939 #define R_68K_PLT16     14              /* 16 bit PC relative PLT address */
    940 #define R_68K_PLT8      15              /* 8 bit PC relative PLT address */
    941 #define R_68K_PLT32O    16              /* 32 bit PLT offset */
    942 #define R_68K_PLT16O    17              /* 16 bit PLT offset */
    943 #define R_68K_PLT8O     18              /* 8 bit PLT offset */
    944 #define R_68K_COPY      19              /* Copy symbol at runtime */
    945 #define R_68K_GLOB_DAT  20              /* Create GOT entry */
    946 #define R_68K_JMP_SLOT  21              /* Create PLT entry */
    947 #define R_68K_RELATIVE  22              /* Adjust by program base */
     1140#define R_68K_NONE      0               /* No reloc */
     1141#define R_68K_32        1               /* Direct 32 bit  */
     1142#define R_68K_16        2               /* Direct 16 bit  */
     1143#define R_68K_8         3               /* Direct 8 bit  */
     1144#define R_68K_PC32      4               /* PC relative 32 bit */
     1145#define R_68K_PC16      5               /* PC relative 16 bit */
     1146#define R_68K_PC8       6               /* PC relative 8 bit */
     1147#define R_68K_GOT32     7               /* 32 bit PC relative GOT entry */
     1148#define R_68K_GOT16     8               /* 16 bit PC relative GOT entry */
     1149#define R_68K_GOT8      9               /* 8 bit PC relative GOT entry */
     1150#define R_68K_GOT32O    10              /* 32 bit GOT offset */
     1151#define R_68K_GOT16O    11              /* 16 bit GOT offset */
     1152#define R_68K_GOT8O     12              /* 8 bit GOT offset */
     1153#define R_68K_PLT32     13              /* 32 bit PC relative PLT address */
     1154#define R_68K_PLT16     14              /* 16 bit PC relative PLT address */
     1155#define R_68K_PLT8      15              /* 8 bit PC relative PLT address */
     1156#define R_68K_PLT32O    16              /* 32 bit PLT offset */
     1157#define R_68K_PLT16O    17              /* 16 bit PLT offset */
     1158#define R_68K_PLT8O     18              /* 8 bit PLT offset */
     1159#define R_68K_COPY      19              /* Copy symbol at runtime */
     1160#define R_68K_GLOB_DAT  20              /* Create GOT entry */
     1161#define R_68K_JMP_SLOT  21              /* Create PLT entry */
     1162#define R_68K_RELATIVE  22              /* Adjust by program base */
     1163#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
     1164#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
     1165#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
     1166#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
     1167#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
     1168#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
     1169#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
     1170#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
     1171#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
     1172#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
     1173#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
     1174#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
     1175#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
     1176                                           static TLS block */
     1177#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
     1178                                           static TLS block */
     1179#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
     1180                                           static TLS block */
     1181#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
     1182#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
     1183#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
    9481184/* Keep this the last entry.  */
    949 #define R_68K_NUM       23
     1185#define R_68K_NUM       43
    9501186
    9511187/* Intel 80386 specific definitions.  */
     
    9531189/* i386 relocs.  */
    9541190
    955 #define R_386_NONE      0               /* No reloc */
    956 #define R_386_32        1               /* Direct 32 bit  */
    957 #define R_386_PC32      2               /* PC relative 32 bit */
    958 #define R_386_GOT32     3               /* 32 bit GOT entry */
    959 #define R_386_PLT32     4               /* 32 bit PLT address */
    960 #define R_386_COPY      5               /* Copy symbol at runtime */
    961 #define R_386_GLOB_DAT  6               /* Create GOT entry */
    962 #define R_386_JMP_SLOT  7               /* Create PLT entry */
    963 #define R_386_RELATIVE  8               /* Adjust by program base */
    964 #define R_386_GOTOFF    9               /* 32 bit offset to GOT */
    965 #define R_386_GOTPC     10              /* 32 bit PC relative offset to GOT */
     1191#define R_386_NONE         0            /* No reloc */
     1192#define R_386_32           1            /* Direct 32 bit  */
     1193#define R_386_PC32         2            /* PC relative 32 bit */
     1194#define R_386_GOT32        3            /* 32 bit GOT entry */
     1195#define R_386_PLT32        4            /* 32 bit PLT address */
     1196#define R_386_COPY         5            /* Copy symbol at runtime */
     1197#define R_386_GLOB_DAT     6            /* Create GOT entry */
     1198#define R_386_JMP_SLOT     7            /* Create PLT entry */
     1199#define R_386_RELATIVE     8            /* Adjust by program base */
     1200#define R_386_GOTOFF       9            /* 32 bit offset to GOT */
     1201#define R_386_GOTPC        10           /* 32 bit PC relative offset to GOT */
     1202#define R_386_32PLT        11
     1203#define R_386_TLS_TPOFF    14           /* Offset in static TLS block */
     1204#define R_386_TLS_IE       15           /* Address of GOT entry for static TLS
     1205                                           block offset */
     1206#define R_386_TLS_GOTIE    16           /* GOT entry for static TLS block
     1207                                           offset */
     1208#define R_386_TLS_LE       17           /* Offset relative to static TLS
     1209                                           block */
     1210#define R_386_TLS_GD       18           /* Direct 32 bit for GNU version of
     1211                                           general dynamic thread local data */
     1212#define R_386_TLS_LDM      19           /* Direct 32 bit for GNU version of
     1213                                           local dynamic thread local data
     1214                                           in LE code */
     1215#define R_386_16           20
     1216#define R_386_PC16         21
     1217#define R_386_8            22
     1218#define R_386_PC8          23
     1219#define R_386_TLS_GD_32    24           /* Direct 32 bit for general dynamic
     1220                                           thread local data */
     1221#define R_386_TLS_GD_PUSH  25           /* Tag for pushl in GD TLS code */
     1222#define R_386_TLS_GD_CALL  26           /* Relocation for call to
     1223                                           __tls_get_addr() */
     1224#define R_386_TLS_GD_POP   27           /* Tag for popl in GD TLS code */
     1225#define R_386_TLS_LDM_32   28           /* Direct 32 bit for local dynamic
     1226                                           thread local data in LE code */
     1227#define R_386_TLS_LDM_PUSH 29           /* Tag for pushl in LDM TLS code */
     1228#define R_386_TLS_LDM_CALL 30           /* Relocation for call to
     1229                                           __tls_get_addr() in LDM code */
     1230#define R_386_TLS_LDM_POP  31           /* Tag for popl in LDM TLS code */
     1231#define R_386_TLS_LDO_32   32           /* Offset relative to TLS block */
     1232#define R_386_TLS_IE_32    33           /* GOT entry for negated static TLS
     1233                                           block offset */
     1234#define R_386_TLS_LE_32    34           /* Negated offset relative to static
     1235                                           TLS block */
     1236#define R_386_TLS_DTPMOD32 35           /* ID of module containing symbol */
     1237#define R_386_TLS_DTPOFF32 36           /* Offset in TLS block */
     1238#define R_386_TLS_TPOFF32  37           /* Negated offset in static TLS block */
     1239/* 38? */
     1240#define R_386_TLS_GOTDESC  39           /* GOT offset for TLS descriptor.  */
     1241#define R_386_TLS_DESC_CALL 40          /* Marker of call through TLS
     1242                                           descriptor for
     1243                                           relaxation.  */
     1244#define R_386_TLS_DESC     41           /* TLS descriptor containing
     1245                                           pointer to code and to
     1246                                           argument, returning the TLS
     1247                                           offset for the symbol.  */
     1248#define R_386_IRELATIVE    42           /* Adjust indirectly by program base */
     1249#define R_386_GOT32X       43           /* 32 bit GOT entry, relaxable */
    9661250/* Keep this the last entry.  */
    967 #define R_386_NUM       11
    968 
    969 /* TCC-specific 16-bit relocs. */
    970 #define R_386_16        12              /* Direct 16 bit  */
    971 #define R_386_PC16      13              /* PC relative 16 bit */
     1251#define R_386_NUM          44
    9721252
    9731253/* SUN SPARC specific definitions.  */
    9741254
     1255/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
     1256
     1257#define STT_SPARC_REGISTER      13      /* Global register reserved to app. */
     1258
    9751259/* Values for Elf64_Ehdr.e_flags.  */
    9761260
    977 #define EF_SPARCV9_MM           3
    978 #define EF_SPARCV9_TSO          0
    979 #define EF_SPARCV9_PSO          1
    980 #define EF_SPARCV9_RMO          2
    981 #define EF_SPARC_EXT_MASK       0xFFFF00
    982 #define EF_SPARC_SUN_US1        0x000200
    983 #define EF_SPARC_HAL_R1         0x000400
     1261#define EF_SPARCV9_MM           3
     1262#define EF_SPARCV9_TSO          0
     1263#define EF_SPARCV9_PSO          1
     1264#define EF_SPARCV9_RMO          2
     1265#define EF_SPARC_LEDATA         0x800000 /* little endian data */
     1266#define EF_SPARC_EXT_MASK       0xFFFF00
     1267#define EF_SPARC_32PLUS         0x000100 /* generic V8+ features */
     1268#define EF_SPARC_SUN_US1        0x000200 /* Sun UltraSPARC1 extensions */
     1269#define EF_SPARC_HAL_R1         0x000400 /* HAL R1 extensions */
     1270#define EF_SPARC_SUN_US3        0x000800 /* Sun UltraSPARCIII extensions */
    9841271
    9851272/* SPARC relocs.  */
    9861273
    987 #define R_SPARC_NONE    0               /* No reloc */
    988 #define R_SPARC_8       1               /* Direct 8 bit */
    989 #define R_SPARC_16      2               /* Direct 16 bit */
    990 #define R_SPARC_32      3               /* Direct 32 bit */
    991 #define R_SPARC_DISP8   4               /* PC relative 8 bit */
    992 #define R_SPARC_DISP16  5               /* PC relative 16 bit */
    993 #define R_SPARC_DISP32  6               /* PC relative 32 bit */
    994 #define R_SPARC_WDISP30 7               /* PC relative 30 bit shifted */
    995 #define R_SPARC_WDISP22 8               /* PC relative 22 bit shifted */
    996 #define R_SPARC_HI22    9               /* High 22 bit */
    997 #define R_SPARC_22      10              /* Direct 22 bit */
    998 #define R_SPARC_13      11              /* Direct 13 bit */
    999 #define R_SPARC_LO10    12              /* Truncated 10 bit */
    1000 #define R_SPARC_GOT10   13              /* Truncated 10 bit GOT entry */
    1001 #define R_SPARC_GOT13   14              /* 13 bit GOT entry */
    1002 #define R_SPARC_GOT22   15              /* 22 bit GOT entry shifted */
    1003 #define R_SPARC_PC10    16              /* PC relative 10 bit truncated */
    1004 #define R_SPARC_PC22    17              /* PC relative 22 bit shifted */
    1005 #define R_SPARC_WPLT30  18              /* 30 bit PC relative PLT address */
    1006 #define R_SPARC_COPY    19              /* Copy symbol at runtime */
    1007 #define R_SPARC_GLOB_DAT 20             /* Create GOT entry */
    1008 #define R_SPARC_JMP_SLOT 21             /* Create PLT entry */
    1009 #define R_SPARC_RELATIVE 22             /* Adjust by program base */
    1010 #define R_SPARC_UA32    23              /* Direct 32 bit unaligned */
     1274#define R_SPARC_NONE            0       /* No reloc */
     1275#define R_SPARC_8               1       /* Direct 8 bit */
     1276#define R_SPARC_16              2       /* Direct 16 bit */
     1277#define R_SPARC_32              3       /* Direct 32 bit */
     1278#define R_SPARC_DISP8           4       /* PC relative 8 bit */
     1279#define R_SPARC_DISP16          5       /* PC relative 16 bit */
     1280#define R_SPARC_DISP32          6       /* PC relative 32 bit */
     1281#define R_SPARC_WDISP30         7       /* PC relative 30 bit shifted */
     1282#define R_SPARC_WDISP22         8       /* PC relative 22 bit shifted */
     1283#define R_SPARC_HI22            9       /* High 22 bit */
     1284#define R_SPARC_22              10      /* Direct 22 bit */
     1285#define R_SPARC_13              11      /* Direct 13 bit */
     1286#define R_SPARC_LO10            12      /* Truncated 10 bit */
     1287#define R_SPARC_GOT10           13      /* Truncated 10 bit GOT entry */
     1288#define R_SPARC_GOT13           14      /* 13 bit GOT entry */
     1289#define R_SPARC_GOT22           15      /* 22 bit GOT entry shifted */
     1290#define R_SPARC_PC10            16      /* PC relative 10 bit truncated */
     1291#define R_SPARC_PC22            17      /* PC relative 22 bit shifted */
     1292#define R_SPARC_WPLT30          18      /* 30 bit PC relative PLT address */
     1293#define R_SPARC_COPY            19      /* Copy symbol at runtime */
     1294#define R_SPARC_GLOB_DAT        20      /* Create GOT entry */
     1295#define R_SPARC_JMP_SLOT        21      /* Create PLT entry */
     1296#define R_SPARC_RELATIVE        22      /* Adjust by program base */
     1297#define R_SPARC_UA32            23      /* Direct 32 bit unaligned */
    10111298
    10121299/* Additional Sparc64 relocs.  */
    10131300
    1014 #define R_SPARC_PLT32   24              /* Direct 32 bit ref to PLT entry */
    1015 #define R_SPARC_HIPLT22 25              /* High 22 bit PLT entry */
    1016 #define R_SPARC_LOPLT10 26              /* Truncated 10 bit PLT entry */
    1017 #define R_SPARC_PCPLT32 27              /* PC rel 32 bit ref to PLT entry */
    1018 #define R_SPARC_PCPLT22 28              /* PC rel high 22 bit PLT entry */
    1019 #define R_SPARC_PCPLT10 29              /* PC rel trunc 10 bit PLT entry */
    1020 #define R_SPARC_10      30              /* Direct 10 bit */
    1021 #define R_SPARC_11      31              /* Direct 11 bit */
    1022 #define R_SPARC_64      32              /* Direct 64 bit */
    1023 #define R_SPARC_OLO10   33              /* ?? */
    1024 #define R_SPARC_HH22    34              /* Top 22 bits of direct 64 bit */
    1025 #define R_SPARC_HM10    35              /* High middle 10 bits of ... */
    1026 #define R_SPARC_LM22    36              /* Low middle 22 bits of ... */
    1027 #define R_SPARC_PC_HH22 37              /* Top 22 bits of pc rel 64 bit */
    1028 #define R_SPARC_PC_HM10 38              /* High middle 10 bit of ... */
    1029 #define R_SPARC_PC_LM22 39              /* Low miggle 22 bits of ... */
    1030 #define R_SPARC_WDISP16 40              /* PC relative 16 bit shifted */
    1031 #define R_SPARC_WDISP19 41              /* PC relative 19 bit shifted */
    1032 #define R_SPARC_7       43              /* Direct 7 bit */
    1033 #define R_SPARC_5       44              /* Direct 5 bit */
    1034 #define R_SPARC_6       45              /* Direct 6 bit */
    1035 #define R_SPARC_DISP64  46              /* PC relative 64 bit */
    1036 #define R_SPARC_PLT64   47              /* Direct 64 bit ref to PLT entry */
    1037 #define R_SPARC_HIX22   48              /* High 22 bit complemented */
    1038 #define R_SPARC_LOX10   49              /* Truncated 11 bit complemented */
    1039 #define R_SPARC_H44     50              /* Direct high 12 of 44 bit */
    1040 #define R_SPARC_M44     51              /* Direct mid 22 of 44 bit */
    1041 #define R_SPARC_L44     52              /* Direct low 10 of 44 bit */
    1042 #define R_SPARC_REGISTER 53             /* Global register usage */
    1043 #define R_SPARC_UA64    54              /* Direct 64 bit unaligned */
    1044 #define R_SPARC_UA16    55              /* Direct 16 bit unaligned */
     1301#define R_SPARC_PLT32           24      /* Direct 32 bit ref to PLT entry */
     1302#define R_SPARC_HIPLT22         25      /* High 22 bit PLT entry */
     1303#define R_SPARC_LOPLT10         26      /* Truncated 10 bit PLT entry */
     1304#define R_SPARC_PCPLT32         27      /* PC rel 32 bit ref to PLT entry */
     1305#define R_SPARC_PCPLT22         28      /* PC rel high 22 bit PLT entry */
     1306#define R_SPARC_PCPLT10         29      /* PC rel trunc 10 bit PLT entry */
     1307#define R_SPARC_10              30      /* Direct 10 bit */
     1308#define R_SPARC_11              31      /* Direct 11 bit */
     1309#define R_SPARC_64              32      /* Direct 64 bit */
     1310#define R_SPARC_OLO10           33      /* 10bit with secondary 13bit addend */
     1311#define R_SPARC_HH22            34      /* Top 22 bits of direct 64 bit */
     1312#define R_SPARC_HM10            35      /* High middle 10 bits of ... */
     1313#define R_SPARC_LM22            36      /* Low middle 22 bits of ... */
     1314#define R_SPARC_PC_HH22         37      /* Top 22 bits of pc rel 64 bit */
     1315#define R_SPARC_PC_HM10         38      /* High middle 10 bit of ... */
     1316#define R_SPARC_PC_LM22         39      /* Low middle 22 bits of ... */
     1317#define R_SPARC_WDISP16         40      /* PC relative 16 bit shifted */
     1318#define R_SPARC_WDISP19         41      /* PC relative 19 bit shifted */
     1319#define R_SPARC_GLOB_JMP        42      /* was part of v9 ABI but was removed */
     1320#define R_SPARC_7               43      /* Direct 7 bit */
     1321#define R_SPARC_5               44      /* Direct 5 bit */
     1322#define R_SPARC_6               45      /* Direct 6 bit */
     1323#define R_SPARC_DISP64          46      /* PC relative 64 bit */
     1324#define R_SPARC_PLT64           47      /* Direct 64 bit ref to PLT entry */
     1325#define R_SPARC_HIX22           48      /* High 22 bit complemented */
     1326#define R_SPARC_LOX10           49      /* Truncated 11 bit complemented */
     1327#define R_SPARC_H44             50      /* Direct high 12 of 44 bit */
     1328#define R_SPARC_M44             51      /* Direct mid 22 of 44 bit */
     1329#define R_SPARC_L44             52      /* Direct low 10 of 44 bit */
     1330#define R_SPARC_REGISTER        53      /* Global register usage */
     1331#define R_SPARC_UA64            54      /* Direct 64 bit unaligned */
     1332#define R_SPARC_UA16            55      /* Direct 16 bit unaligned */
     1333#define R_SPARC_TLS_GD_HI22     56
     1334#define R_SPARC_TLS_GD_LO10     57
     1335#define R_SPARC_TLS_GD_ADD      58
     1336#define R_SPARC_TLS_GD_CALL     59
     1337#define R_SPARC_TLS_LDM_HI22    60
     1338#define R_SPARC_TLS_LDM_LO10    61
     1339#define R_SPARC_TLS_LDM_ADD     62
     1340#define R_SPARC_TLS_LDM_CALL    63
     1341#define R_SPARC_TLS_LDO_HIX22   64
     1342#define R_SPARC_TLS_LDO_LOX10   65
     1343#define R_SPARC_TLS_LDO_ADD     66
     1344#define R_SPARC_TLS_IE_HI22     67
     1345#define R_SPARC_TLS_IE_LO10     68
     1346#define R_SPARC_TLS_IE_LD       69
     1347#define R_SPARC_TLS_IE_LDX      70
     1348#define R_SPARC_TLS_IE_ADD      71
     1349#define R_SPARC_TLS_LE_HIX22    72
     1350#define R_SPARC_TLS_LE_LOX10    73
     1351#define R_SPARC_TLS_DTPMOD32    74
     1352#define R_SPARC_TLS_DTPMOD64    75
     1353#define R_SPARC_TLS_DTPOFF32    76
     1354#define R_SPARC_TLS_DTPOFF64    77
     1355#define R_SPARC_TLS_TPOFF32     78
     1356#define R_SPARC_TLS_TPOFF64     79
     1357#define R_SPARC_GOTDATA_HIX22   80
     1358#define R_SPARC_GOTDATA_LOX10   81
     1359#define R_SPARC_GOTDATA_OP_HIX22        82
     1360#define R_SPARC_GOTDATA_OP_LOX10        83
     1361#define R_SPARC_GOTDATA_OP      84
     1362#define R_SPARC_H34             85
     1363#define R_SPARC_SIZE32          86
     1364#define R_SPARC_SIZE64          87
     1365#define R_SPARC_WDISP10         88
     1366#define R_SPARC_JMP_IREL        248
     1367#define R_SPARC_IRELATIVE       249
     1368#define R_SPARC_GNU_VTINHERIT   250
     1369#define R_SPARC_GNU_VTENTRY     251
     1370#define R_SPARC_REV32           252
    10451371/* Keep this the last entry.  */
    1046 #define R_SPARC_NUM     56
     1372#define R_SPARC_NUM             253
     1373
     1374/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
     1375
     1376#define DT_SPARC_REGISTER 0x70000001
     1377#define DT_SPARC_NUM    2
     1378
     1379/* MIPS R3000 specific definitions.  */
     1380
     1381/* Legal values for e_flags field of Elf32_Ehdr.  */
     1382
     1383#define EF_MIPS_NOREORDER   1           /* A .noreorder directive was used */
     1384#define EF_MIPS_PIC         2           /* Contains PIC code */
     1385#define EF_MIPS_CPIC        4           /* Uses PIC calling sequence */
     1386#define EF_MIPS_XGOT        8
     1387#define EF_MIPS_64BIT_WHIRL 16
     1388#define EF_MIPS_ABI2        32
     1389#define EF_MIPS_ABI_ON32    64
     1390#define EF_MIPS_ARCH        0xf0000000  /* MIPS architecture level */
     1391
     1392/* Legal values for MIPS architecture level.  */
     1393
     1394#define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
     1395#define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
     1396#define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
     1397#define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
     1398#define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
     1399#define EF_MIPS_ARCH_32     0x60000000  /* MIPS32 code.  */
     1400#define EF_MIPS_ARCH_64     0x70000000  /* MIPS64 code.  */
     1401
     1402/* The following are non-official names and should not be used.  */
     1403
     1404#define E_MIPS_ARCH_1     0x00000000    /* -mips1 code.  */
     1405#define E_MIPS_ARCH_2     0x10000000    /* -mips2 code.  */
     1406#define E_MIPS_ARCH_3     0x20000000    /* -mips3 code.  */
     1407#define E_MIPS_ARCH_4     0x30000000    /* -mips4 code.  */
     1408#define E_MIPS_ARCH_5     0x40000000    /* -mips5 code.  */
     1409#define E_MIPS_ARCH_32    0x60000000    /* MIPS32 code.  */
     1410#define E_MIPS_ARCH_64    0x70000000    /* MIPS64 code.  */
     1411
     1412/* Special section indices.  */
     1413
     1414#define SHN_MIPS_ACOMMON    0xff00      /* Allocated common symbols */
     1415#define SHN_MIPS_TEXT       0xff01      /* Allocated test symbols.  */
     1416#define SHN_MIPS_DATA       0xff02      /* Allocated data symbols.  */
     1417#define SHN_MIPS_SCOMMON    0xff03      /* Small common symbols */
     1418#define SHN_MIPS_SUNDEFINED 0xff04      /* Small undefined symbols */
     1419
     1420/* Legal values for sh_type field of Elf32_Shdr.  */
     1421
     1422#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
     1423#define SHT_MIPS_MSYM          0x70000001
     1424#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
     1425#define SHT_MIPS_GPTAB         0x70000003 /* Global data area sizes */
     1426#define SHT_MIPS_UCODE         0x70000004 /* Reserved for SGI/MIPS compilers */
     1427#define SHT_MIPS_DEBUG         0x70000005 /* MIPS ECOFF debugging information*/
     1428#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
     1429#define SHT_MIPS_PACKAGE       0x70000007
     1430#define SHT_MIPS_PACKSYM       0x70000008
     1431#define SHT_MIPS_RELD          0x70000009
     1432#define SHT_MIPS_IFACE         0x7000000b
     1433#define SHT_MIPS_CONTENT       0x7000000c
     1434#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
     1435#define SHT_MIPS_SHDR          0x70000010
     1436#define SHT_MIPS_FDESC         0x70000011
     1437#define SHT_MIPS_EXTSYM        0x70000012
     1438#define SHT_MIPS_DENSE         0x70000013
     1439#define SHT_MIPS_PDESC         0x70000014
     1440#define SHT_MIPS_LOCSYM        0x70000015
     1441#define SHT_MIPS_AUXSYM        0x70000016
     1442#define SHT_MIPS_OPTSYM        0x70000017
     1443#define SHT_MIPS_LOCSTR        0x70000018
     1444#define SHT_MIPS_LINE          0x70000019
     1445#define SHT_MIPS_RFDESC        0x7000001a
     1446#define SHT_MIPS_DELTASYM      0x7000001b
     1447#define SHT_MIPS_DELTAINST     0x7000001c
     1448#define SHT_MIPS_DELTACLASS    0x7000001d
     1449#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
     1450#define SHT_MIPS_DELTADECL     0x7000001f
     1451#define SHT_MIPS_SYMBOL_LIB    0x70000020
     1452#define SHT_MIPS_EVENTS        0x70000021 /* Event section.  */
     1453#define SHT_MIPS_TRANSLATE     0x70000022
     1454#define SHT_MIPS_PIXIE         0x70000023
     1455#define SHT_MIPS_XLATE         0x70000024
     1456#define SHT_MIPS_XLATE_DEBUG   0x70000025
     1457#define SHT_MIPS_WHIRL         0x70000026
     1458#define SHT_MIPS_EH_REGION     0x70000027
     1459#define SHT_MIPS_XLATE_OLD     0x70000028
     1460#define SHT_MIPS_PDR_EXCEPTION 0x70000029
     1461
     1462/* Legal values for sh_flags field of Elf32_Shdr.  */
     1463
     1464#define SHF_MIPS_GPREL   0x10000000     /* Must be part of global data area */
     1465#define SHF_MIPS_MERGE   0x20000000
     1466#define SHF_MIPS_ADDR    0x40000000
     1467#define SHF_MIPS_STRINGS 0x80000000
     1468#define SHF_MIPS_NOSTRIP 0x08000000
     1469#define SHF_MIPS_LOCAL   0x04000000
     1470#define SHF_MIPS_NAMES   0x02000000
     1471#define SHF_MIPS_NODUPE  0x01000000
     1472
     1473
     1474/* Symbol tables.  */
     1475
     1476/* MIPS specific values for `st_other'.  */
     1477#define STO_MIPS_DEFAULT                0x0
     1478#define STO_MIPS_INTERNAL               0x1
     1479#define STO_MIPS_HIDDEN                 0x2
     1480#define STO_MIPS_PROTECTED              0x3
     1481#define STO_MIPS_PLT                    0x8
     1482#define STO_MIPS_SC_ALIGN_UNUSED        0xff
     1483
     1484/* MIPS specific values for `st_info'.  */
     1485#define STB_MIPS_SPLIT_COMMON           13
     1486
     1487/* Entries found in sections of type SHT_MIPS_GPTAB.  */
     1488
     1489typedef union
     1490{
     1491  struct
     1492    {
     1493      Elf32_Word gt_current_g_value;    /* -G value used for compilation */
     1494      Elf32_Word gt_unused;             /* Not used */
     1495    } gt_header;                        /* First entry in section */
     1496  struct
     1497    {
     1498      Elf32_Word gt_g_value;            /* If this value were used for -G */
     1499      Elf32_Word gt_bytes;              /* This many bytes would be used */
     1500    } gt_entry;                         /* Subsequent entries in section */
     1501} __attribute__((packed)) Elf32_gptab;
     1502
     1503/* Entry found in sections of type SHT_MIPS_REGINFO.  */
     1504
     1505typedef struct
     1506{
     1507  Elf32_Word    ri_gprmask;             /* General registers used */
     1508  Elf32_Word    ri_cprmask[4];          /* Coprocessor registers used */
     1509  Elf32_Sword   ri_gp_value;            /* $gp register value */
     1510} __attribute__((packed)) Elf32_RegInfo;
     1511
     1512/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
     1513
     1514typedef struct
     1515{
     1516  unsigned char kind;           /* Determines interpretation of the
     1517                                   variable part of descriptor.  */
     1518  unsigned char size;           /* Size of descriptor, including header.  */
     1519  Elf32_Section section;        /* Section header index of section affected,
     1520                                   0 for global options.  */
     1521  Elf32_Word info;              /* Kind-specific information.  */
     1522} __attribute__((packed)) Elf_Options;
     1523
     1524/* Values for `kind' field in Elf_Options.  */
     1525
     1526#define ODK_NULL        0       /* Undefined.  */
     1527#define ODK_REGINFO     1       /* Register usage information.  */
     1528#define ODK_EXCEPTIONS  2       /* Exception processing options.  */
     1529#define ODK_PAD         3       /* Section padding options.  */
     1530#define ODK_HWPATCH     4       /* Hardware workarounds performed */
     1531#define ODK_FILL        5       /* record the fill value used by the linker. */
     1532#define ODK_TAGS        6       /* reserve space for desktop tools to write. */
     1533#define ODK_HWAND       7       /* HW workarounds.  'AND' bits when merging. */
     1534#define ODK_HWOR        8       /* HW workarounds.  'OR' bits when merging.  */
     1535
     1536/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
     1537
     1538#define OEX_FPU_MIN     0x1f    /* FPE's which MUST be enabled.  */
     1539#define OEX_FPU_MAX     0x1f00  /* FPE's which MAY be enabled.  */
     1540#define OEX_PAGE0       0x10000 /* page zero must be mapped.  */
     1541#define OEX_SMM         0x20000 /* Force sequential memory mode?  */
     1542#define OEX_FPDBUG      0x40000 /* Force floating point debug mode?  */
     1543#define OEX_PRECISEFP   OEX_FPDBUG
     1544#define OEX_DISMISS     0x80000 /* Dismiss invalid address faults?  */
     1545
     1546#define OEX_FPU_INVAL   0x10
     1547#define OEX_FPU_DIV0    0x08
     1548#define OEX_FPU_OFLO    0x04
     1549#define OEX_FPU_UFLO    0x02
     1550#define OEX_FPU_INEX    0x01
     1551
     1552/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
     1553
     1554#define OHW_R4KEOP      0x1     /* R4000 end-of-page patch.  */
     1555#define OHW_R8KPFETCH   0x2     /* may need R8000 prefetch patch.  */
     1556#define OHW_R5KEOP      0x4     /* R5000 end-of-page patch.  */
     1557#define OHW_R5KCVTL     0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
     1558
     1559#define OPAD_PREFIX     0x1
     1560#define OPAD_POSTFIX    0x2
     1561#define OPAD_SYMBOL     0x4
     1562
     1563/* Entry found in `.options' section.  */
     1564
     1565typedef struct
     1566{
     1567  Elf32_Word hwp_flags1;        /* Extra flags.  */
     1568  Elf32_Word hwp_flags2;        /* Extra flags.  */
     1569} __attribute__((packed)) Elf_Options_Hw;
     1570
     1571/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
     1572
     1573#define OHWA0_R4KEOP_CHECKED    0x00000001
     1574#define OHWA1_R4KEOP_CLEAN      0x00000002
     1575
     1576/* MIPS relocs.  */
     1577
     1578#define R_MIPS_NONE             0       /* No reloc */
     1579#define R_MIPS_16               1       /* Direct 16 bit */
     1580#define R_MIPS_32               2       /* Direct 32 bit */
     1581#define R_MIPS_REL32            3       /* PC relative 32 bit */
     1582#define R_MIPS_26               4       /* Direct 26 bit shifted */
     1583#define R_MIPS_HI16             5       /* High 16 bit */
     1584#define R_MIPS_LO16             6       /* Low 16 bit */
     1585#define R_MIPS_GPREL16          7       /* GP relative 16 bit */
     1586#define R_MIPS_LITERAL          8       /* 16 bit literal entry */
     1587#define R_MIPS_GOT16            9       /* 16 bit GOT entry */
     1588#define R_MIPS_PC16             10      /* PC relative 16 bit */
     1589#define R_MIPS_CALL16           11      /* 16 bit GOT entry for function */
     1590#define R_MIPS_GPREL32          12      /* GP relative 32 bit */
     1591
     1592#define R_MIPS_SHIFT5           16
     1593#define R_MIPS_SHIFT6           17
     1594#define R_MIPS_64               18
     1595#define R_MIPS_GOT_DISP         19
     1596#define R_MIPS_GOT_PAGE         20
     1597#define R_MIPS_GOT_OFST         21
     1598#define R_MIPS_GOT_HI16         22
     1599#define R_MIPS_GOT_LO16         23
     1600#define R_MIPS_SUB              24
     1601#define R_MIPS_INSERT_A         25
     1602#define R_MIPS_INSERT_B         26
     1603#define R_MIPS_DELETE           27
     1604#define R_MIPS_HIGHER           28
     1605#define R_MIPS_HIGHEST          29
     1606#define R_MIPS_CALL_HI16        30
     1607#define R_MIPS_CALL_LO16        31
     1608#define R_MIPS_SCN_DISP         32
     1609#define R_MIPS_REL16            33
     1610#define R_MIPS_ADD_IMMEDIATE    34
     1611#define R_MIPS_PJUMP            35
     1612#define R_MIPS_RELGOT           36
     1613#define R_MIPS_JALR             37
     1614#define R_MIPS_TLS_DTPMOD32     38      /* Module number 32 bit */
     1615#define R_MIPS_TLS_DTPREL32     39      /* Module-relative offset 32 bit */
     1616#define R_MIPS_TLS_DTPMOD64     40      /* Module number 64 bit */
     1617#define R_MIPS_TLS_DTPREL64     41      /* Module-relative offset 64 bit */
     1618#define R_MIPS_TLS_GD           42      /* 16 bit GOT offset for GD */
     1619#define R_MIPS_TLS_LDM          43      /* 16 bit GOT offset for LDM */
     1620#define R_MIPS_TLS_DTPREL_HI16  44      /* Module-relative offset, high 16 bits */
     1621#define R_MIPS_TLS_DTPREL_LO16  45      /* Module-relative offset, low 16 bits */
     1622#define R_MIPS_TLS_GOTTPREL     46      /* 16 bit GOT offset for IE */
     1623#define R_MIPS_TLS_TPREL32      47      /* TP-relative offset, 32 bit */
     1624#define R_MIPS_TLS_TPREL64      48      /* TP-relative offset, 64 bit */
     1625#define R_MIPS_TLS_TPREL_HI16   49      /* TP-relative offset, high 16 bits */
     1626#define R_MIPS_TLS_TPREL_LO16   50      /* TP-relative offset, low 16 bits */
     1627#define R_MIPS_GLOB_DAT         51
     1628#define R_MIPS_COPY             126
     1629#define R_MIPS_JUMP_SLOT        127
     1630/* Keep this the last entry.  */
     1631#define R_MIPS_NUM              128
     1632
     1633/* Legal values for p_type field of Elf32_Phdr.  */
     1634
     1635#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
     1636#define PT_MIPS_RTPROC  0x70000001      /* Runtime procedure table. */
     1637#define PT_MIPS_OPTIONS 0x70000002
     1638
     1639/* Special program header types.  */
     1640
     1641#define PF_MIPS_LOCAL   0x10000000
     1642
     1643/* Legal values for d_tag field of Elf32_Dyn.  */
     1644
     1645#define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime linker interface version */
     1646#define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
     1647#define DT_MIPS_ICHECKSUM    0x70000003 /* Checksum */
     1648#define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
     1649#define DT_MIPS_FLAGS        0x70000005 /* Flags */
     1650#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
     1651#define DT_MIPS_MSYM         0x70000007
     1652#define DT_MIPS_CONFLICT     0x70000008 /* Address of CONFLICT section */
     1653#define DT_MIPS_LIBLIST      0x70000009 /* Address of LIBLIST section */
     1654#define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local GOT entries */
     1655#define DT_MIPS_CONFLICTNO   0x7000000b /* Number of CONFLICT entries */
     1656#define DT_MIPS_LIBLISTNO    0x70000010 /* Number of LIBLIST entries */
     1657#define DT_MIPS_SYMTABNO     0x70000011 /* Number of DYNSYM entries */
     1658#define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
     1659#define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in DYNSYM */
     1660#define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
     1661#define DT_MIPS_RLD_MAP      0x70000016 /* Address of run time loader map.  */
     1662#define DT_MIPS_DELTA_CLASS  0x70000017 /* Delta C++ class definition.  */
     1663#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
     1664                                                DT_MIPS_DELTA_CLASS.  */
     1665#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
     1666#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
     1667                                                DT_MIPS_DELTA_INSTANCE.  */
     1668#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
     1669#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
     1670                                             DT_MIPS_DELTA_RELOC.  */
     1671#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
     1672                                           relocations refer to.  */
     1673#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
     1674                                           DT_MIPS_DELTA_SYM.  */
     1675#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
     1676                                             class declaration.  */
     1677#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
     1678                                                DT_MIPS_DELTA_CLASSSYM.  */
     1679#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
     1680#define DT_MIPS_PIXIE_INIT   0x70000023
     1681#define DT_MIPS_SYMBOL_LIB   0x70000024
     1682#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
     1683#define DT_MIPS_LOCAL_GOTIDX 0x70000026
     1684#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
     1685#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
     1686#define DT_MIPS_OPTIONS      0x70000029 /* Address of .options.  */
     1687#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
     1688#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
     1689#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
     1690#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
     1691                                                    function stored in GOT.  */
     1692#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
     1693                                           by rld on dlopen() calls.  */
     1694#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
     1695#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
     1696#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
     1697/* The address of .got.plt in an executable using the new non-PIC ABI.  */
     1698#define DT_MIPS_PLTGOT       0x70000032
     1699/* The base of the PLT in an executable using the new non-PIC ABI if that
     1700   PLT is writable.  For a non-writable PLT, this is omitted or has a zero
     1701   value.  */
     1702#define DT_MIPS_RWPLT        0x70000034
     1703#define DT_MIPS_NUM          0x35
     1704
     1705/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
     1706
     1707#define RHF_NONE                   0            /* No flags */
     1708#define RHF_QUICKSTART             (1 << 0)     /* Use quickstart */
     1709#define RHF_NOTPOT                 (1 << 1)     /* Hash size not power of 2 */
     1710#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)     /* Ignore LD_LIBRARY_PATH */
     1711#define RHF_NO_MOVE                (1 << 3)
     1712#define RHF_SGI_ONLY               (1 << 4)
     1713#define RHF_GUARANTEE_INIT         (1 << 5)
     1714#define RHF_DELTA_C_PLUS_PLUS      (1 << 6)
     1715#define RHF_GUARANTEE_START_INIT   (1 << 7)
     1716#define RHF_PIXIE                  (1 << 8)
     1717#define RHF_DEFAULT_DELAY_LOAD     (1 << 9)
     1718#define RHF_REQUICKSTART           (1 << 10)
     1719#define RHF_REQUICKSTARTED         (1 << 11)
     1720#define RHF_CORD                   (1 << 12)
     1721#define RHF_NO_UNRES_UNDEF         (1 << 13)
     1722#define RHF_RLD_ORDER_SAFE         (1 << 14)
     1723
     1724/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
     1725
     1726typedef struct
     1727{
     1728  Elf32_Word l_name;            /* Name (string table index) */
     1729  Elf32_Word l_time_stamp;      /* Timestamp */
     1730  Elf32_Word l_checksum;        /* Checksum */
     1731  Elf32_Word l_version;         /* Interface version */
     1732  Elf32_Word l_flags;           /* Flags */
     1733} __attribute__((packed)) Elf32_Lib;
     1734
     1735typedef struct
     1736{
     1737  Elf64_Word l_name;            /* Name (string table index) */
     1738  Elf64_Word l_time_stamp;      /* Timestamp */
     1739  Elf64_Word l_checksum;        /* Checksum */
     1740  Elf64_Word l_version;         /* Interface version */
     1741  Elf64_Word l_flags;           /* Flags */
     1742} __attribute__((packed)) Elf64_Lib;
     1743
     1744
     1745/* Legal values for l_flags.  */
     1746
     1747#define LL_NONE           0
     1748#define LL_EXACT_MATCH    (1 << 0)      /* Require exact match */
     1749#define LL_IGNORE_INT_VER (1 << 1)      /* Ignore interface version */
     1750#define LL_REQUIRE_MINOR  (1 << 2)
     1751#define LL_EXPORTS        (1 << 3)
     1752#define LL_DELAY_LOAD     (1 << 4)
     1753#define LL_DELTA          (1 << 5)
     1754
     1755/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
     1756
     1757typedef Elf32_Addr Elf32_Conflict;
     1758
     1759
     1760/* HPPA specific definitions.  */
     1761
     1762/* Legal values for e_flags field of Elf32_Ehdr.  */
     1763
     1764#define EF_PARISC_TRAPNIL       0x00010000 /* Trap nil pointer dereference.  */
     1765#define EF_PARISC_EXT           0x00020000 /* Program uses arch. extensions. */
     1766#define EF_PARISC_LSB           0x00040000 /* Program expects little endian. */
     1767#define EF_PARISC_WIDE          0x00080000 /* Program expects wide mode.  */
     1768#define EF_PARISC_NO_KABP       0x00100000 /* No kernel assisted branch
     1769                                              prediction.  */
     1770#define EF_PARISC_LAZYSWAP      0x00400000 /* Allow lazy swapping.  */
     1771#define EF_PARISC_ARCH          0x0000ffff /* Architecture version.  */
     1772
     1773/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
     1774
     1775#define EFA_PARISC_1_0              0x020b /* PA-RISC 1.0 big-endian.  */
     1776#define EFA_PARISC_1_1              0x0210 /* PA-RISC 1.1 big-endian.  */
     1777#define EFA_PARISC_2_0              0x0214 /* PA-RISC 2.0 big-endian.  */
     1778
     1779/* Additional section indices.  */
     1780
     1781#define SHN_PARISC_ANSI_COMMON  0xff00     /* Section for tentatively declared
     1782                                              symbols in ANSI C.  */
     1783#define SHN_PARISC_HUGE_COMMON  0xff01     /* Common blocks in huge model.  */
     1784
     1785/* Legal values for sh_type field of Elf32_Shdr.  */
     1786
     1787#define SHT_PARISC_EXT          0x70000000 /* Contains product specific ext. */
     1788#define SHT_PARISC_UNWIND       0x70000001 /* Unwind information.  */
     1789#define SHT_PARISC_DOC          0x70000002 /* Debug info for optimized code. */
     1790
     1791/* Legal values for sh_flags field of Elf32_Shdr.  */
     1792
     1793#define SHF_PARISC_SHORT        0x20000000 /* Section with short addressing. */
     1794#define SHF_PARISC_HUGE         0x40000000 /* Section far from gp.  */
     1795#define SHF_PARISC_SBP          0x80000000 /* Static branch prediction code. */
     1796
     1797/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
     1798
     1799#define STT_PARISC_MILLICODE    13      /* Millicode function entry point.  */
     1800
     1801#define STT_HP_OPAQUE           (STT_LOOS + 0x1)
     1802#define STT_HP_STUB             (STT_LOOS + 0x2)
     1803
     1804/* HPPA relocs.  */
     1805
     1806#define R_PARISC_NONE           0       /* No reloc.  */
     1807#define R_PARISC_DIR32          1       /* Direct 32-bit reference.  */
     1808#define R_PARISC_DIR21L         2       /* Left 21 bits of eff. address.  */
     1809#define R_PARISC_DIR17R         3       /* Right 17 bits of eff. address.  */
     1810#define R_PARISC_DIR17F         4       /* 17 bits of eff. address.  */
     1811#define R_PARISC_DIR14R         6       /* Right 14 bits of eff. address.  */
     1812#define R_PARISC_PCREL32        9       /* 32-bit rel. address.  */
     1813#define R_PARISC_PCREL21L       10      /* Left 21 bits of rel. address.  */
     1814#define R_PARISC_PCREL17R       11      /* Right 17 bits of rel. address.  */
     1815#define R_PARISC_PCREL17F       12      /* 17 bits of rel. address.  */
     1816#define R_PARISC_PCREL14R       14      /* Right 14 bits of rel. address.  */
     1817#define R_PARISC_DPREL21L       18      /* Left 21 bits of rel. address.  */
     1818#define R_PARISC_DPREL14R       22      /* Right 14 bits of rel. address.  */
     1819#define R_PARISC_GPREL21L       26      /* GP-relative, left 21 bits.  */
     1820#define R_PARISC_GPREL14R       30      /* GP-relative, right 14 bits.  */
     1821#define R_PARISC_LTOFF21L       34      /* LT-relative, left 21 bits.  */
     1822#define R_PARISC_LTOFF14R       38      /* LT-relative, right 14 bits.  */
     1823#define R_PARISC_SECREL32       41      /* 32 bits section rel. address.  */
     1824#define R_PARISC_SEGBASE        48      /* No relocation, set segment base.  */
     1825#define R_PARISC_SEGREL32       49      /* 32 bits segment rel. address.  */
     1826#define R_PARISC_PLTOFF21L      50      /* PLT rel. address, left 21 bits.  */
     1827#define R_PARISC_PLTOFF14R      54      /* PLT rel. address, right 14 bits.  */
     1828#define R_PARISC_LTOFF_FPTR32   57      /* 32 bits LT-rel. function pointer. */
     1829#define R_PARISC_LTOFF_FPTR21L  58      /* LT-rel. fct ptr, left 21 bits. */
     1830#define R_PARISC_LTOFF_FPTR14R  62      /* LT-rel. fct ptr, right 14 bits. */
     1831#define R_PARISC_FPTR64         64      /* 64 bits function address.  */
     1832#define R_PARISC_PLABEL32       65      /* 32 bits function address.  */
     1833#define R_PARISC_PLABEL21L      66      /* Left 21 bits of fdesc address.  */
     1834#define R_PARISC_PLABEL14R      70      /* Right 14 bits of fdesc address.  */
     1835#define R_PARISC_PCREL64        72      /* 64 bits PC-rel. address.  */
     1836#define R_PARISC_PCREL22F       74      /* 22 bits PC-rel. address.  */
     1837#define R_PARISC_PCREL14WR      75      /* PC-rel. address, right 14 bits.  */
     1838#define R_PARISC_PCREL14DR      76      /* PC rel. address, right 14 bits.  */
     1839#define R_PARISC_PCREL16F       77      /* 16 bits PC-rel. address.  */
     1840#define R_PARISC_PCREL16WF      78      /* 16 bits PC-rel. address.  */
     1841#define R_PARISC_PCREL16DF      79      /* 16 bits PC-rel. address.  */
     1842#define R_PARISC_DIR64          80      /* 64 bits of eff. address.  */
     1843#define R_PARISC_DIR14WR        83      /* 14 bits of eff. address.  */
     1844#define R_PARISC_DIR14DR        84      /* 14 bits of eff. address.  */
     1845#define R_PARISC_DIR16F         85      /* 16 bits of eff. address.  */
     1846#define R_PARISC_DIR16WF        86      /* 16 bits of eff. address.  */
     1847#define R_PARISC_DIR16DF        87      /* 16 bits of eff. address.  */
     1848#define R_PARISC_GPREL64        88      /* 64 bits of GP-rel. address.  */
     1849#define R_PARISC_GPREL14WR      91      /* GP-rel. address, right 14 bits.  */
     1850#define R_PARISC_GPREL14DR      92      /* GP-rel. address, right 14 bits.  */
     1851#define R_PARISC_GPREL16F       93      /* 16 bits GP-rel. address.  */
     1852#define R_PARISC_GPREL16WF      94      /* 16 bits GP-rel. address.  */
     1853#define R_PARISC_GPREL16DF      95      /* 16 bits GP-rel. address.  */
     1854#define R_PARISC_LTOFF64        96      /* 64 bits LT-rel. address.  */
     1855#define R_PARISC_LTOFF14WR      99      /* LT-rel. address, right 14 bits.  */
     1856#define R_PARISC_LTOFF14DR      100     /* LT-rel. address, right 14 bits.  */
     1857#define R_PARISC_LTOFF16F       101     /* 16 bits LT-rel. address.  */
     1858#define R_PARISC_LTOFF16WF      102     /* 16 bits LT-rel. address.  */
     1859#define R_PARISC_LTOFF16DF      103     /* 16 bits LT-rel. address.  */
     1860#define R_PARISC_SECREL64       104     /* 64 bits section rel. address.  */
     1861#define R_PARISC_SEGREL64       112     /* 64 bits segment rel. address.  */
     1862#define R_PARISC_PLTOFF14WR     115     /* PLT-rel. address, right 14 bits.  */
     1863#define R_PARISC_PLTOFF14DR     116     /* PLT-rel. address, right 14 bits.  */
     1864#define R_PARISC_PLTOFF16F      117     /* 16 bits LT-rel. address.  */
     1865#define R_PARISC_PLTOFF16WF     118     /* 16 bits PLT-rel. address.  */
     1866#define R_PARISC_PLTOFF16DF     119     /* 16 bits PLT-rel. address.  */
     1867#define R_PARISC_LTOFF_FPTR64   120     /* 64 bits LT-rel. function ptr.  */
     1868#define R_PARISC_LTOFF_FPTR14WR 123     /* LT-rel. fct. ptr., right 14 bits. */
     1869#define R_PARISC_LTOFF_FPTR14DR 124     /* LT-rel. fct. ptr., right 14 bits. */
     1870#define R_PARISC_LTOFF_FPTR16F  125     /* 16 bits LT-rel. function ptr.  */
     1871#define R_PARISC_LTOFF_FPTR16WF 126     /* 16 bits LT-rel. function ptr.  */
     1872#define R_PARISC_LTOFF_FPTR16DF 127     /* 16 bits LT-rel. function ptr.  */
     1873#define R_PARISC_LORESERVE      128
     1874#define R_PARISC_COPY           128     /* Copy relocation.  */
     1875#define R_PARISC_IPLT           129     /* Dynamic reloc, imported PLT */
     1876#define R_PARISC_EPLT           130     /* Dynamic reloc, exported PLT */
     1877#define R_PARISC_TPREL32        153     /* 32 bits TP-rel. address.  */
     1878#define R_PARISC_TPREL21L       154     /* TP-rel. address, left 21 bits.  */
     1879#define R_PARISC_TPREL14R       158     /* TP-rel. address, right 14 bits.  */
     1880#define R_PARISC_LTOFF_TP21L    162     /* LT-TP-rel. address, left 21 bits. */
     1881#define R_PARISC_LTOFF_TP14R    166     /* LT-TP-rel. address, right 14 bits.*/
     1882#define R_PARISC_LTOFF_TP14F    167     /* 14 bits LT-TP-rel. address.  */
     1883#define R_PARISC_TPREL64        216     /* 64 bits TP-rel. address.  */
     1884#define R_PARISC_TPREL14WR      219     /* TP-rel. address, right 14 bits.  */
     1885#define R_PARISC_TPREL14DR      220     /* TP-rel. address, right 14 bits.  */
     1886#define R_PARISC_TPREL16F       221     /* 16 bits TP-rel. address.  */
     1887#define R_PARISC_TPREL16WF      222     /* 16 bits TP-rel. address.  */
     1888#define R_PARISC_TPREL16DF      223     /* 16 bits TP-rel. address.  */
     1889#define R_PARISC_LTOFF_TP64     224     /* 64 bits LT-TP-rel. address.  */
     1890#define R_PARISC_LTOFF_TP14WR   227     /* LT-TP-rel. address, right 14 bits.*/
     1891#define R_PARISC_LTOFF_TP14DR   228     /* LT-TP-rel. address, right 14 bits.*/
     1892#define R_PARISC_LTOFF_TP16F    229     /* 16 bits LT-TP-rel. address.  */
     1893#define R_PARISC_LTOFF_TP16WF   230     /* 16 bits LT-TP-rel. address.  */
     1894#define R_PARISC_LTOFF_TP16DF   231     /* 16 bits LT-TP-rel. address.  */
     1895#define R_PARISC_GNU_VTENTRY    232
     1896#define R_PARISC_GNU_VTINHERIT  233
     1897#define R_PARISC_TLS_GD21L      234     /* GD 21-bit left.  */
     1898#define R_PARISC_TLS_GD14R      235     /* GD 14-bit right.  */
     1899#define R_PARISC_TLS_GDCALL     236     /* GD call to __t_g_a.  */
     1900#define R_PARISC_TLS_LDM21L     237     /* LD module 21-bit left.  */
     1901#define R_PARISC_TLS_LDM14R     238     /* LD module 14-bit right.  */
     1902#define R_PARISC_TLS_LDMCALL    239     /* LD module call to __t_g_a.  */
     1903#define R_PARISC_TLS_LDO21L     240     /* LD offset 21-bit left.  */
     1904#define R_PARISC_TLS_LDO14R     241     /* LD offset 14-bit right.  */
     1905#define R_PARISC_TLS_DTPMOD32   242     /* DTP module 32-bit.  */
     1906#define R_PARISC_TLS_DTPMOD64   243     /* DTP module 64-bit.  */
     1907#define R_PARISC_TLS_DTPOFF32   244     /* DTP offset 32-bit.  */
     1908#define R_PARISC_TLS_DTPOFF64   245     /* DTP offset 32-bit.  */
     1909#define R_PARISC_TLS_LE21L      R_PARISC_TPREL21L
     1910#define R_PARISC_TLS_LE14R      R_PARISC_TPREL14R
     1911#define R_PARISC_TLS_IE21L      R_PARISC_LTOFF_TP21L
     1912#define R_PARISC_TLS_IE14R      R_PARISC_LTOFF_TP14R
     1913#define R_PARISC_TLS_TPREL32    R_PARISC_TPREL32
     1914#define R_PARISC_TLS_TPREL64    R_PARISC_TPREL64
     1915#define R_PARISC_HIRESERVE      255
     1916
     1917/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
     1918
     1919#define PT_HP_TLS               (PT_LOOS + 0x0)
     1920#define PT_HP_CORE_NONE         (PT_LOOS + 0x1)
     1921#define PT_HP_CORE_VERSION      (PT_LOOS + 0x2)
     1922#define PT_HP_CORE_KERNEL       (PT_LOOS + 0x3)
     1923#define PT_HP_CORE_COMM         (PT_LOOS + 0x4)
     1924#define PT_HP_CORE_PROC         (PT_LOOS + 0x5)
     1925#define PT_HP_CORE_LOADABLE     (PT_LOOS + 0x6)
     1926#define PT_HP_CORE_STACK        (PT_LOOS + 0x7)
     1927#define PT_HP_CORE_SHM          (PT_LOOS + 0x8)
     1928#define PT_HP_CORE_MMF          (PT_LOOS + 0x9)
     1929#define PT_HP_PARALLEL          (PT_LOOS + 0x10)
     1930#define PT_HP_FASTBIND          (PT_LOOS + 0x11)
     1931#define PT_HP_OPT_ANNOT         (PT_LOOS + 0x12)
     1932#define PT_HP_HSL_ANNOT         (PT_LOOS + 0x13)
     1933#define PT_HP_STACK             (PT_LOOS + 0x14)
     1934
     1935#define PT_PARISC_ARCHEXT       0x70000000
     1936#define PT_PARISC_UNWIND        0x70000001
     1937
     1938/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
     1939
     1940#define PF_PARISC_SBP           0x08000000
     1941
     1942#define PF_HP_PAGE_SIZE         0x00100000
     1943#define PF_HP_FAR_SHARED        0x00200000
     1944#define PF_HP_NEAR_SHARED       0x00400000
     1945#define PF_HP_CODE              0x01000000
     1946#define PF_HP_MODIFY            0x02000000
     1947#define PF_HP_LAZYSWAP          0x04000000
     1948#define PF_HP_SBP               0x08000000
     1949
     1950
     1951/* Alpha specific definitions.  */
     1952
     1953/* Legal values for e_flags field of Elf64_Ehdr.  */
     1954
     1955#define EF_ALPHA_32BIT          1       /* All addresses must be < 2GB.  */
     1956#define EF_ALPHA_CANRELAX       2       /* Relocations for relaxing exist.  */
     1957
     1958/* Legal values for sh_type field of Elf64_Shdr.  */
     1959
     1960/* These two are primarily concerned with ECOFF debugging info.  */
     1961#define SHT_ALPHA_DEBUG         0x70000001
     1962#define SHT_ALPHA_REGINFO       0x70000002
     1963
     1964/* Legal values for sh_flags field of Elf64_Shdr.  */
     1965
     1966#define SHF_ALPHA_GPREL         0x10000000
     1967
     1968/* Legal values for st_other field of Elf64_Sym.  */
     1969#define STO_ALPHA_NOPV          0x80    /* No PV required.  */
     1970#define STO_ALPHA_STD_GPLOAD    0x88    /* PV only used for initial ldgp.  */
     1971
     1972/* Alpha relocs.  */
     1973
     1974#define R_ALPHA_NONE            0       /* No reloc */
     1975#define R_ALPHA_REFLONG         1       /* Direct 32 bit */
     1976#define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
     1977#define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
     1978#define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
     1979#define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
     1980#define R_ALPHA_GPDISP          6       /* Add displacement to GP */
     1981#define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
     1982#define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
     1983#define R_ALPHA_SREL16          9       /* PC relative 16 bit */
     1984#define R_ALPHA_SREL32          10      /* PC relative 32 bit */
     1985#define R_ALPHA_SREL64          11      /* PC relative 64 bit */
     1986#define R_ALPHA_GPRELHIGH       17      /* GP relative 32 bit, high 16 bits */
     1987#define R_ALPHA_GPRELLOW        18      /* GP relative 32 bit, low 16 bits */
     1988#define R_ALPHA_GPREL16         19      /* GP relative 16 bit */
     1989#define R_ALPHA_COPY            24      /* Copy symbol at runtime */
     1990#define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
     1991#define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
     1992#define R_ALPHA_RELATIVE        27      /* Adjust by program base */
     1993#define R_ALPHA_TLS_GD_HI       28
     1994#define R_ALPHA_TLSGD           29
     1995#define R_ALPHA_TLS_LDM         30
     1996#define R_ALPHA_DTPMOD64        31
     1997#define R_ALPHA_GOTDTPREL       32
     1998#define R_ALPHA_DTPREL64        33
     1999#define R_ALPHA_DTPRELHI        34
     2000#define R_ALPHA_DTPRELLO        35
     2001#define R_ALPHA_DTPREL16        36
     2002#define R_ALPHA_GOTTPREL        37
     2003#define R_ALPHA_TPREL64         38
     2004#define R_ALPHA_TPRELHI         39
     2005#define R_ALPHA_TPRELLO         40
     2006#define R_ALPHA_TPREL16         41
     2007/* Keep this the last entry.  */
     2008#define R_ALPHA_NUM             46
     2009
     2010/* Magic values of the LITUSE relocation addend.  */
     2011#define LITUSE_ALPHA_ADDR       0
     2012#define LITUSE_ALPHA_BASE       1
     2013#define LITUSE_ALPHA_BYTOFF     2
     2014#define LITUSE_ALPHA_JSR        3
     2015#define LITUSE_ALPHA_TLS_GD     4
     2016#define LITUSE_ALPHA_TLS_LDM    5
     2017
     2018/* Legal values for d_tag of Elf64_Dyn.  */
     2019#define DT_ALPHA_PLTRO          (DT_LOPROC + 0)
     2020#define DT_ALPHA_NUM            1
     2021
     2022/* PowerPC specific declarations */
     2023
     2024/* Values for Elf32/64_Ehdr.e_flags.  */
     2025#define EF_PPC_EMB              0x80000000      /* PowerPC embedded flag */
     2026
     2027/* Cygnus local bits below */
     2028#define EF_PPC_RELOCATABLE      0x00010000      /* PowerPC -mrelocatable flag*/
     2029#define EF_PPC_RELOCATABLE_LIB  0x00008000      /* PowerPC -mrelocatable-lib
     2030                                                   flag */
     2031
     2032/* PowerPC relocations defined by the ABIs */
     2033#define R_PPC_NONE              0
     2034#define R_PPC_ADDR32            1       /* 32bit absolute address */
     2035#define R_PPC_ADDR24            2       /* 26bit address, 2 bits ignored.  */
     2036#define R_PPC_ADDR16            3       /* 16bit absolute address */
     2037#define R_PPC_ADDR16_LO         4       /* lower 16bit of absolute address */
     2038#define R_PPC_ADDR16_HI         5       /* high 16bit of absolute address */
     2039#define R_PPC_ADDR16_HA         6       /* adjusted high 16bit */
     2040#define R_PPC_ADDR14            7       /* 16bit address, 2 bits ignored */
     2041#define R_PPC_ADDR14_BRTAKEN    8
     2042#define R_PPC_ADDR14_BRNTAKEN   9
     2043#define R_PPC_REL24             10      /* PC relative 26 bit */
     2044#define R_PPC_REL14             11      /* PC relative 16 bit */
     2045#define R_PPC_REL14_BRTAKEN     12
     2046#define R_PPC_REL14_BRNTAKEN    13
     2047#define R_PPC_GOT16             14
     2048#define R_PPC_GOT16_LO          15
     2049#define R_PPC_GOT16_HI          16
     2050#define R_PPC_GOT16_HA          17
     2051#define R_PPC_PLTREL24          18
     2052#define R_PPC_COPY              19
     2053#define R_PPC_GLOB_DAT          20
     2054#define R_PPC_JMP_SLOT          21
     2055#define R_PPC_RELATIVE          22
     2056#define R_PPC_LOCAL24PC         23
     2057#define R_PPC_UADDR32           24
     2058#define R_PPC_UADDR16           25
     2059#define R_PPC_REL32             26
     2060#define R_PPC_PLT32             27
     2061#define R_PPC_PLTREL32          28
     2062#define R_PPC_PLT16_LO          29
     2063#define R_PPC_PLT16_HI          30
     2064#define R_PPC_PLT16_HA          31
     2065#define R_PPC_SDAREL16          32
     2066#define R_PPC_SECTOFF           33
     2067#define R_PPC_SECTOFF_LO        34
     2068#define R_PPC_SECTOFF_HI        35
     2069#define R_PPC_SECTOFF_HA        36
     2070
     2071/* PowerPC relocations defined for the TLS access ABI.  */
     2072#define R_PPC_TLS               67 /* none      (sym+add)@tls */
     2073#define R_PPC_DTPMOD32          68 /* word32    (sym+add)@dtpmod */
     2074#define R_PPC_TPREL16           69 /* half16*   (sym+add)@tprel */
     2075#define R_PPC_TPREL16_LO        70 /* half16    (sym+add)@tprel@l */
     2076#define R_PPC_TPREL16_HI        71 /* half16    (sym+add)@tprel@h */
     2077#define R_PPC_TPREL16_HA        72 /* half16    (sym+add)@tprel@ha */
     2078#define R_PPC_TPREL32           73 /* word32    (sym+add)@tprel */
     2079#define R_PPC_DTPREL16          74 /* half16*   (sym+add)@dtprel */
     2080#define R_PPC_DTPREL16_LO       75 /* half16    (sym+add)@dtprel@l */
     2081#define R_PPC_DTPREL16_HI       76 /* half16    (sym+add)@dtprel@h */
     2082#define R_PPC_DTPREL16_HA       77 /* half16    (sym+add)@dtprel@ha */
     2083#define R_PPC_DTPREL32          78 /* word32    (sym+add)@dtprel */
     2084#define R_PPC_GOT_TLSGD16       79 /* half16*   (sym+add)@got@tlsgd */
     2085#define R_PPC_GOT_TLSGD16_LO    80 /* half16    (sym+add)@got@tlsgd@l */
     2086#define R_PPC_GOT_TLSGD16_HI    81 /* half16    (sym+add)@got@tlsgd@h */
     2087#define R_PPC_GOT_TLSGD16_HA    82 /* half16    (sym+add)@got@tlsgd@ha */
     2088#define R_PPC_GOT_TLSLD16       83 /* half16*   (sym+add)@got@tlsld */
     2089#define R_PPC_GOT_TLSLD16_LO    84 /* half16    (sym+add)@got@tlsld@l */
     2090#define R_PPC_GOT_TLSLD16_HI    85 /* half16    (sym+add)@got@tlsld@h */
     2091#define R_PPC_GOT_TLSLD16_HA    86 /* half16    (sym+add)@got@tlsld@ha */
     2092#define R_PPC_GOT_TPREL16       87 /* half16*   (sym+add)@got@tprel */
     2093#define R_PPC_GOT_TPREL16_LO    88 /* half16    (sym+add)@got@tprel@l */
     2094#define R_PPC_GOT_TPREL16_HI    89 /* half16    (sym+add)@got@tprel@h */
     2095#define R_PPC_GOT_TPREL16_HA    90 /* half16    (sym+add)@got@tprel@ha */
     2096#define R_PPC_GOT_DTPREL16      91 /* half16*   (sym+add)@got@dtprel */
     2097#define R_PPC_GOT_DTPREL16_LO   92 /* half16*   (sym+add)@got@dtprel@l */
     2098#define R_PPC_GOT_DTPREL16_HI   93 /* half16*   (sym+add)@got@dtprel@h */
     2099#define R_PPC_GOT_DTPREL16_HA   94 /* half16*   (sym+add)@got@dtprel@ha */
     2100
     2101/* The remaining relocs are from the Embedded ELF ABI, and are not
     2102   in the SVR4 ELF ABI.  */
     2103#define R_PPC_EMB_NADDR32       101
     2104#define R_PPC_EMB_NADDR16       102
     2105#define R_PPC_EMB_NADDR16_LO    103
     2106#define R_PPC_EMB_NADDR16_HI    104
     2107#define R_PPC_EMB_NADDR16_HA    105
     2108#define R_PPC_EMB_SDAI16        106
     2109#define R_PPC_EMB_SDA2I16       107
     2110#define R_PPC_EMB_SDA2REL       108
     2111#define R_PPC_EMB_SDA21         109     /* 16 bit offset in SDA */
     2112#define R_PPC_EMB_MRKREF        110
     2113#define R_PPC_EMB_RELSEC16      111
     2114#define R_PPC_EMB_RELST_LO      112
     2115#define R_PPC_EMB_RELST_HI      113
     2116#define R_PPC_EMB_RELST_HA      114
     2117#define R_PPC_EMB_BIT_FLD       115
     2118#define R_PPC_EMB_RELSDA        116     /* 16 bit relative offset in SDA */
     2119
     2120/* Diab tool relocations.  */
     2121#define R_PPC_DIAB_SDA21_LO     180     /* like EMB_SDA21, but lower 16 bit */
     2122#define R_PPC_DIAB_SDA21_HI     181     /* like EMB_SDA21, but high 16 bit */
     2123#define R_PPC_DIAB_SDA21_HA     182     /* like EMB_SDA21, adjusted high 16 */
     2124#define R_PPC_DIAB_RELSDA_LO    183     /* like EMB_RELSDA, but lower 16 bit */
     2125#define R_PPC_DIAB_RELSDA_HI    184     /* like EMB_RELSDA, but high 16 bit */
     2126#define R_PPC_DIAB_RELSDA_HA    185     /* like EMB_RELSDA, adjusted high 16 */
     2127
     2128/* GNU extension to support local ifunc.  */
     2129#define R_PPC_IRELATIVE         248
     2130
     2131/* GNU relocs used in PIC code sequences.  */
     2132#define R_PPC_REL16             249     /* half16   (sym+add-.) */
     2133#define R_PPC_REL16_LO          250     /* half16   (sym+add-.)@l */
     2134#define R_PPC_REL16_HI          251     /* half16   (sym+add-.)@h */
     2135#define R_PPC_REL16_HA          252     /* half16   (sym+add-.)@ha */
     2136
     2137/* This is a phony reloc to handle any old fashioned TOC16 references
     2138   that may still be in object files.  */
     2139#define R_PPC_TOC16             255
     2140
     2141/* PowerPC specific values for the Dyn d_tag field.  */
     2142#define DT_PPC_GOT              (DT_LOPROC + 0)
     2143#define DT_PPC_NUM              1
     2144
     2145/* PowerPC64 relocations defined by the ABIs */
     2146#define R_PPC64_NONE            R_PPC_NONE
     2147#define R_PPC64_ADDR32          R_PPC_ADDR32 /* 32bit absolute address */
     2148#define R_PPC64_ADDR24          R_PPC_ADDR24 /* 26bit address, word aligned */
     2149#define R_PPC64_ADDR16          R_PPC_ADDR16 /* 16bit absolute address */
     2150#define R_PPC64_ADDR16_LO       R_PPC_ADDR16_LO /* lower 16bits of address */
     2151#define R_PPC64_ADDR16_HI       R_PPC_ADDR16_HI /* high 16bits of address. */
     2152#define R_PPC64_ADDR16_HA       R_PPC_ADDR16_HA /* adjusted high 16bits.  */
     2153#define R_PPC64_ADDR14          R_PPC_ADDR14 /* 16bit address, word aligned */
     2154#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
     2155#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
     2156#define R_PPC64_REL24           R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
     2157#define R_PPC64_REL14           R_PPC_REL14 /* PC relative 16 bit */
     2158#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
     2159#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
     2160#define R_PPC64_GOT16           R_PPC_GOT16
     2161#define R_PPC64_GOT16_LO        R_PPC_GOT16_LO
     2162#define R_PPC64_GOT16_HI        R_PPC_GOT16_HI
     2163#define R_PPC64_GOT16_HA        R_PPC_GOT16_HA
     2164
     2165#define R_PPC64_COPY            R_PPC_COPY
     2166#define R_PPC64_GLOB_DAT        R_PPC_GLOB_DAT
     2167#define R_PPC64_JMP_SLOT        R_PPC_JMP_SLOT
     2168#define R_PPC64_RELATIVE        R_PPC_RELATIVE
     2169
     2170#define R_PPC64_UADDR32         R_PPC_UADDR32
     2171#define R_PPC64_UADDR16         R_PPC_UADDR16
     2172#define R_PPC64_REL32           R_PPC_REL32
     2173#define R_PPC64_PLT32           R_PPC_PLT32
     2174#define R_PPC64_PLTREL32        R_PPC_PLTREL32
     2175#define R_PPC64_PLT16_LO        R_PPC_PLT16_LO
     2176#define R_PPC64_PLT16_HI        R_PPC_PLT16_HI
     2177#define R_PPC64_PLT16_HA        R_PPC_PLT16_HA
     2178
     2179#define R_PPC64_SECTOFF         R_PPC_SECTOFF
     2180#define R_PPC64_SECTOFF_LO      R_PPC_SECTOFF_LO
     2181#define R_PPC64_SECTOFF_HI      R_PPC_SECTOFF_HI
     2182#define R_PPC64_SECTOFF_HA      R_PPC_SECTOFF_HA
     2183#define R_PPC64_ADDR30          37 /* word30 (S + A - P) >> 2 */
     2184#define R_PPC64_ADDR64          38 /* doubleword64 S + A */
     2185#define R_PPC64_ADDR16_HIGHER   39 /* half16 #higher(S + A) */
     2186#define R_PPC64_ADDR16_HIGHERA  40 /* half16 #highera(S + A) */
     2187#define R_PPC64_ADDR16_HIGHEST  41 /* half16 #highest(S + A) */
     2188#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */
     2189#define R_PPC64_UADDR64         43 /* doubleword64 S + A */
     2190#define R_PPC64_REL64           44 /* doubleword64 S + A - P */
     2191#define R_PPC64_PLT64           45 /* doubleword64 L + A */
     2192#define R_PPC64_PLTREL64        46 /* doubleword64 L + A - P */
     2193#define R_PPC64_TOC16           47 /* half16* S + A - .TOC */
     2194#define R_PPC64_TOC16_LO        48 /* half16 #lo(S + A - .TOC.) */
     2195#define R_PPC64_TOC16_HI        49 /* half16 #hi(S + A - .TOC.) */
     2196#define R_PPC64_TOC16_HA        50 /* half16 #ha(S + A - .TOC.) */
     2197#define R_PPC64_TOC             51 /* doubleword64 .TOC */
     2198#define R_PPC64_PLTGOT16        52 /* half16* M + A */
     2199#define R_PPC64_PLTGOT16_LO     53 /* half16 #lo(M + A) */
     2200#define R_PPC64_PLTGOT16_HI     54 /* half16 #hi(M + A) */
     2201#define R_PPC64_PLTGOT16_HA     55 /* half16 #ha(M + A) */
     2202
     2203#define R_PPC64_ADDR16_DS       56 /* half16ds* (S + A) >> 2 */
     2204#define R_PPC64_ADDR16_LO_DS    57 /* half16ds  #lo(S + A) >> 2 */
     2205#define R_PPC64_GOT16_DS        58 /* half16ds* (G + A) >> 2 */
     2206#define R_PPC64_GOT16_LO_DS     59 /* half16ds  #lo(G + A) >> 2 */
     2207#define R_PPC64_PLT16_LO_DS     60 /* half16ds  #lo(L + A) >> 2 */
     2208#define R_PPC64_SECTOFF_DS      61 /* half16ds* (R + A) >> 2 */
     2209#define R_PPC64_SECTOFF_LO_DS   62 /* half16ds  #lo(R + A) >> 2 */
     2210#define R_PPC64_TOC16_DS        63 /* half16ds* (S + A - .TOC.) >> 2 */
     2211#define R_PPC64_TOC16_LO_DS     64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
     2212#define R_PPC64_PLTGOT16_DS     65 /* half16ds* (M + A) >> 2 */
     2213#define R_PPC64_PLTGOT16_LO_DS  66 /* half16ds  #lo(M + A) >> 2 */
     2214
     2215/* PowerPC64 relocations defined for the TLS access ABI.  */
     2216#define R_PPC64_TLS             67 /* none      (sym+add)@tls */
     2217#define R_PPC64_DTPMOD64        68 /* doubleword64 (sym+add)@dtpmod */
     2218#define R_PPC64_TPREL16         69 /* half16*   (sym+add)@tprel */
     2219#define R_PPC64_TPREL16_LO      70 /* half16    (sym+add)@tprel@l */
     2220#define R_PPC64_TPREL16_HI      71 /* half16    (sym+add)@tprel@h */
     2221#define R_PPC64_TPREL16_HA      72 /* half16    (sym+add)@tprel@ha */
     2222#define R_PPC64_TPREL64         73 /* doubleword64 (sym+add)@tprel */
     2223#define R_PPC64_DTPREL16        74 /* half16*   (sym+add)@dtprel */
     2224#define R_PPC64_DTPREL16_LO     75 /* half16    (sym+add)@dtprel@l */
     2225#define R_PPC64_DTPREL16_HI     76 /* half16    (sym+add)@dtprel@h */
     2226#define R_PPC64_DTPREL16_HA     77 /* half16    (sym+add)@dtprel@ha */
     2227#define R_PPC64_DTPREL64        78 /* doubleword64 (sym+add)@dtprel */
     2228#define R_PPC64_GOT_TLSGD16     79 /* half16*   (sym+add)@got@tlsgd */
     2229#define R_PPC64_GOT_TLSGD16_LO  80 /* half16    (sym+add)@got@tlsgd@l */
     2230#define R_PPC64_GOT_TLSGD16_HI  81 /* half16    (sym+add)@got@tlsgd@h */
     2231#define R_PPC64_GOT_TLSGD16_HA  82 /* half16    (sym+add)@got@tlsgd@ha */
     2232#define R_PPC64_GOT_TLSLD16     83 /* half16*   (sym+add)@got@tlsld */
     2233#define R_PPC64_GOT_TLSLD16_LO  84 /* half16    (sym+add)@got@tlsld@l */
     2234#define R_PPC64_GOT_TLSLD16_HI  85 /* half16    (sym+add)@got@tlsld@h */
     2235#define R_PPC64_GOT_TLSLD16_HA  86 /* half16    (sym+add)@got@tlsld@ha */
     2236#define R_PPC64_GOT_TPREL16_DS  87 /* half16ds* (sym+add)@got@tprel */
     2237#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
     2238#define R_PPC64_GOT_TPREL16_HI  89 /* half16    (sym+add)@got@tprel@h */
     2239#define R_PPC64_GOT_TPREL16_HA  90 /* half16    (sym+add)@got@tprel@ha */
     2240#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
     2241#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
     2242#define R_PPC64_GOT_DTPREL16_HI 93 /* half16    (sym+add)@got@dtprel@h */
     2243#define R_PPC64_GOT_DTPREL16_HA 94 /* half16    (sym+add)@got@dtprel@ha */
     2244#define R_PPC64_TPREL16_DS      95 /* half16ds* (sym+add)@tprel */
     2245#define R_PPC64_TPREL16_LO_DS   96 /* half16ds  (sym+add)@tprel@l */
     2246#define R_PPC64_TPREL16_HIGHER  97 /* half16    (sym+add)@tprel@higher */
     2247#define R_PPC64_TPREL16_HIGHERA 98 /* half16    (sym+add)@tprel@highera */
     2248#define R_PPC64_TPREL16_HIGHEST 99 /* half16    (sym+add)@tprel@highest */
     2249#define R_PPC64_TPREL16_HIGHESTA 100 /* half16  (sym+add)@tprel@highesta */
     2250#define R_PPC64_DTPREL16_DS     101 /* half16ds* (sym+add)@dtprel */
     2251#define R_PPC64_DTPREL16_LO_DS  102 /* half16ds (sym+add)@dtprel@l */
     2252#define R_PPC64_DTPREL16_HIGHER 103 /* half16   (sym+add)@dtprel@higher */
     2253#define R_PPC64_DTPREL16_HIGHERA 104 /* half16  (sym+add)@dtprel@highera */
     2254#define R_PPC64_DTPREL16_HIGHEST 105 /* half16  (sym+add)@dtprel@highest */
     2255#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
     2256
     2257/* GNU extension to support local ifunc.  */
     2258#define R_PPC64_JMP_IREL        247
     2259#define R_PPC64_IRELATIVE       248
     2260#define R_PPC64_REL16           249     /* half16   (sym+add-.) */
     2261#define R_PPC64_REL16_LO        250     /* half16   (sym+add-.)@l */
     2262#define R_PPC64_REL16_HI        251     /* half16   (sym+add-.)@h */
     2263#define R_PPC64_REL16_HA        252     /* half16   (sym+add-.)@ha */
     2264
     2265/* PowerPC64 specific values for the Dyn d_tag field.  */
     2266#define DT_PPC64_GLINK  (DT_LOPROC + 0)
     2267#define DT_PPC64_OPD    (DT_LOPROC + 1)
     2268#define DT_PPC64_OPDSZ  (DT_LOPROC + 2)
     2269#define DT_PPC64_NUM    3
     2270
     2271
     2272/* ARM specific declarations */
     2273
     2274/* Processor specific flags for the ELF header e_flags field.  */
     2275#define EF_ARM_RELEXEC          0x01
     2276#define EF_ARM_HASENTRY         0x02
     2277#define EF_ARM_INTERWORK        0x04
     2278#define EF_ARM_APCS_26          0x08
     2279#define EF_ARM_APCS_FLOAT       0x10
     2280#define EF_ARM_PIC              0x20
     2281#define EF_ARM_ALIGN8           0x40 /* 8-bit structure alignment is in use */
     2282#define EF_ARM_NEW_ABI          0x80
     2283#define EF_ARM_OLD_ABI          0x100
     2284#define EF_ARM_SOFT_FLOAT       0x200
     2285#define EF_ARM_VFP_FLOAT        0x400
     2286#define EF_ARM_MAVERICK_FLOAT   0x800
     2287
     2288#define EF_ARM_ABI_FLOAT_SOFT   0x200   /* NB conflicts with EF_ARM_SOFT_FLOAT */
     2289#define EF_ARM_ABI_FLOAT_HARD   0x400   /* NB conflicts with EF_ARM_VFP_FLOAT */
     2290
     2291
     2292/* Other constants defined in the ARM ELF spec. version B-01.  */
     2293/* NB. These conflict with values defined above.  */
     2294#define EF_ARM_SYMSARESORTED    0x04
     2295#define EF_ARM_DYNSYMSUSESEGIDX 0x08
     2296#define EF_ARM_MAPSYMSFIRST     0x10
     2297#define EF_ARM_EABIMASK         0XFF000000
     2298
     2299/* Constants defined in AAELF.  */
     2300#define EF_ARM_BE8          0x00800000
     2301#define EF_ARM_LE8          0x00400000
     2302
     2303#define EF_ARM_EABI_VERSION(flags)      ((flags) & EF_ARM_EABIMASK)
     2304#define EF_ARM_EABI_UNKNOWN     0x00000000
     2305#define EF_ARM_EABI_VER1        0x01000000
     2306#define EF_ARM_EABI_VER2        0x02000000
     2307#define EF_ARM_EABI_VER3        0x03000000
     2308#define EF_ARM_EABI_VER4        0x04000000
     2309#define EF_ARM_EABI_VER5        0x05000000
     2310
     2311/* Additional symbol types for Thumb.  */
     2312#define STT_ARM_TFUNC           STT_LOPROC /* A Thumb function.  */
     2313#define STT_ARM_16BIT           STT_HIPROC /* A Thumb label.  */
     2314
     2315/* ARM-specific values for sh_flags */
     2316#define SHF_ARM_ENTRYSECT       0x10000000 /* Section contains an entry point */
     2317#define SHF_ARM_COMDEF          0x80000000 /* Section may be multiply defined
     2318                                              in the input to a link step.  */
     2319
     2320/* ARM-specific program header flags */
     2321#define PF_ARM_SB               0x10000000 /* Segment contains the location
     2322                                              addressed by the static base. */
     2323#define PF_ARM_PI               0x20000000 /* Position-independent segment.  */
     2324#define PF_ARM_ABS              0x40000000 /* Absolute segment.  */
     2325
     2326/* Processor specific values for the Phdr p_type field.  */
     2327#define PT_ARM_EXIDX            (PT_LOPROC + 1) /* ARM unwind segment.  */
     2328
     2329/* Processor specific values for the Shdr sh_type field.  */
     2330#define SHT_ARM_EXIDX           (SHT_LOPROC + 1) /* ARM unwind section.  */
     2331#define SHT_ARM_PREEMPTMAP      (SHT_LOPROC + 2) /* Preemption details.  */
     2332#define SHT_ARM_ATTRIBUTES      (SHT_LOPROC + 3) /* ARM attributes section.  */
     2333
     2334
     2335/* AArch64 relocs.  */
     2336
     2337#define R_AARCH64_NONE            0     /* No relocation.  */
     2338#define R_AARCH64_ABS64         257     /* Direct 64 bit. */
     2339#define R_AARCH64_ABS32         258     /* Direct 32 bit.  */
     2340#define R_AARCH64_ABS16         259     /* Direct 16-bit.  */
     2341#define R_AARCH64_PREL64        260     /* PC-relative 64-bit.  */
     2342#define R_AARCH64_PREL32        261     /* PC-relative 32-bit.  */
     2343#define R_AARCH64_PREL16        262     /* PC-relative 16-bit.  */
     2344#define R_AARCH64_MOVW_UABS_G0  263     /* Dir. MOVZ imm. from bits 15:0.  */
     2345#define R_AARCH64_MOVW_UABS_G0_NC 264   /* Likewise for MOVK; no check.  */
     2346#define R_AARCH64_MOVW_UABS_G1  265     /* Dir. MOVZ imm. from bits 31:16.  */
     2347#define R_AARCH64_MOVW_UABS_G1_NC 266   /* Likewise for MOVK; no check.  */
     2348#define R_AARCH64_MOVW_UABS_G2  267     /* Dir. MOVZ imm. from bits 47:32.  */
     2349#define R_AARCH64_MOVW_UABS_G2_NC 268   /* Likewise for MOVK; no check.  */
     2350#define R_AARCH64_MOVW_UABS_G3  269     /* Dir. MOV{K,Z} imm. from 63:48.  */
     2351#define R_AARCH64_MOVW_SABS_G0  270     /* Dir. MOV{N,Z} imm. from 15:0.  */
     2352#define R_AARCH64_MOVW_SABS_G1  271     /* Dir. MOV{N,Z} imm. from 31:16.  */
     2353#define R_AARCH64_MOVW_SABS_G2  272     /* Dir. MOV{N,Z} imm. from 47:32.  */
     2354#define R_AARCH64_LD_PREL_LO19  273     /* PC-rel. LD imm. from bits 20:2.  */
     2355#define R_AARCH64_ADR_PREL_LO21 274     /* PC-rel. ADR imm. from bits 20:0.  */
     2356#define R_AARCH64_ADR_PREL_PG_HI21 275  /* Page-rel. ADRP imm. from 32:12.  */
     2357#define R_AARCH64_ADR_PREL_PG_HI21_NC 276       /* Likewise; no overflow check.  */
     2358#define R_AARCH64_ADD_ABS_LO12_NC 277   /* Dir. ADD imm. from bits 11:0.  */
     2359#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */
     2360#define R_AARCH64_TSTBR14       279     /* PC-rel. TBZ/TBNZ imm. from 15:2.  */
     2361#define R_AARCH64_CONDBR19      280     /* PC-rel. cond. br. imm. from 20:2. */
     2362#define R_AARCH64_JUMP26        282     /* PC-rel. B imm. from bits 27:2.  */
     2363#define R_AARCH64_CALL26        283     /* Likewise for CALL.  */
     2364#define R_AARCH64_LDST16_ABS_LO12_NC 284        /* Dir. ADD imm. from bits 11:1.  */
     2365#define R_AARCH64_LDST32_ABS_LO12_NC 285        /* Likewise for bits 11:2.  */
     2366#define R_AARCH64_LDST64_ABS_LO12_NC 286        /* Likewise for bits 11:3.  */
     2367#define R_AARCH64_MOVW_PREL_G0  287     /* PC-rel. MOV{N,Z} imm. from 15:0.  */
     2368#define R_AARCH64_MOVW_PREL_G0_NC 288   /* Likewise for MOVK; no check.  */
     2369#define R_AARCH64_MOVW_PREL_G1  289     /* PC-rel. MOV{N,Z} imm. from 31:16. */
     2370#define R_AARCH64_MOVW_PREL_G1_NC 290   /* Likewise for MOVK; no check.  */
     2371#define R_AARCH64_MOVW_PREL_G2  291     /* PC-rel. MOV{N,Z} imm. from 47:32. */
     2372#define R_AARCH64_MOVW_PREL_G2_NC 292   /* Likewise for MOVK; no check.  */
     2373#define R_AARCH64_MOVW_PREL_G3  293     /* PC-rel. MOV{N,Z} imm. from 63:48. */
     2374#define R_AARCH64_LDST128_ABS_LO12_NC 299       /* Dir. ADD imm. from bits 11:4.  */
     2375#define R_AARCH64_MOVW_GOTOFF_G0 300    /* GOT-rel. off. MOV{N,Z} imm. 15:0. */
     2376#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check.  */
     2377#define R_AARCH64_MOVW_GOTOFF_G1 302    /* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
     2378#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check.  */
     2379#define R_AARCH64_MOVW_GOTOFF_G2 304    /* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
     2380#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check.  */
     2381#define R_AARCH64_MOVW_GOTOFF_G3 306    /* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
     2382#define R_AARCH64_GOTREL64      307     /* GOT-relative 64-bit.  */
     2383#define R_AARCH64_GOTREL32      308     /* GOT-relative 32-bit.  */
     2384#define R_AARCH64_GOT_LD_PREL19 309     /* PC-rel. GOT off. load imm. 20:2.  */
     2385#define R_AARCH64_LD64_GOTOFF_LO15 310  /* GOT-rel. off. LD/ST imm. 14:3.  */
     2386#define R_AARCH64_ADR_GOT_PAGE  311     /* P-page-rel. GOT off. ADRP 32:12.  */
     2387#define R_AARCH64_LD64_GOT_LO12_NC 312  /* Dir. GOT off. LD/ST imm. 11:3.  */
     2388#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */
     2389#define R_AARCH64_TLSGD_ADR_PREL21 512  /* PC-relative ADR imm. 20:0.  */
     2390#define R_AARCH64_TLSGD_ADR_PAGE21 513  /* page-rel. ADRP imm. 32:12.  */
     2391#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0.  */
     2392#define R_AARCH64_TLSGD_MOVW_G1 515     /* GOT-rel. MOV{N,Z} 31:16.  */
     2393#define R_AARCH64_TLSGD_MOVW_G0_NC 516  /* GOT-rel. MOVK imm. 15:0.  */
     2394#define R_AARCH64_TLSLD_ADR_PREL21 517  /* Like 512; local dynamic model.  */
     2395#define R_AARCH64_TLSLD_ADR_PAGE21 518  /* Like 513; local dynamic model.  */
     2396#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model.  */
     2397#define R_AARCH64_TLSLD_MOVW_G1 520     /* Like 515; local dynamic model.  */
     2398#define R_AARCH64_TLSLD_MOVW_G0_NC 521  /* Like 516; local dynamic model.  */
     2399#define R_AARCH64_TLSLD_LD_PREL19 522   /* TLS PC-rel. load imm. 20:2.  */
     2400#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523      /* TLS DTP-rel. MOV{N,Z} 47:32.  */
     2401#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524      /* TLS DTP-rel. MOV{N,Z} 31:16.  */
     2402#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525   /* Likewise; MOVK; no check.  */
     2403#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526      /* TLS DTP-rel. MOV{N,Z} 15:0.  */
     2404#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527   /* Likewise; MOVK; no check.  */
     2405#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528     /* DTP-rel. ADD imm. from 23:12. */
     2406#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529     /* DTP-rel. ADD imm. from 11:0.  */
     2407#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530  /* Likewise; no ovfl. check.  */
     2408#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531   /* DTP-rel. LD/ST imm. 11:0.  */
     2409#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532        /* Likewise; no check.  */
     2410#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533  /* DTP-rel. LD/ST imm. 11:1.  */
     2411#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534       /* Likewise; no check.  */
     2412#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535  /* DTP-rel. LD/ST imm. 11:2.  */
     2413#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536       /* Likewise; no check.  */
     2414#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537  /* DTP-rel. LD/ST imm. 11:3.  */
     2415#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538       /* Likewise; no check.  */
     2416#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539    /* GOT-rel. MOV{N,Z} 31:16.  */
     2417#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
     2418#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
     2419#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542       /* Direct LD off. 11:3.  */
     2420#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543  /* PC-rel. load imm. 20:2.  */
     2421#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544       /* TLS TP-rel. MOV{N,Z} 47:32.  */
     2422#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545       /* TLS TP-rel. MOV{N,Z} 31:16.  */
     2423#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546    /* Likewise; MOVK; no check.  */
     2424#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547       /* TLS TP-rel. MOV{N,Z} 15:0.  */
     2425#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548    /* Likewise; MOVK; no check.  */
     2426#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549      /* TP-rel. ADD imm. 23:12.  */
     2427#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550      /* TP-rel. ADD imm. 11:0.  */
     2428#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551   /* Likewise; no ovfl. check.  */
     2429#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552    /* TP-rel. LD/ST off. 11:0.  */
     2430#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
     2431#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554   /* TP-rel. LD/ST off. 11:1.  */
     2432#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555        /* Likewise; no check.  */
     2433#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556   /* TP-rel. LD/ST off. 11:2.  */
     2434#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557        /* Likewise; no check.  */
     2435#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558   /* TP-rel. LD/ST off. 11:3.  */
     2436#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559        /* Likewise; no check.  */
     2437#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2.  */
     2438#define R_AARCH64_TLSDESC_ADR_PREL21 561        /* PC-rel. ADR immediate 20:0.  */
     2439#define R_AARCH64_TLSDESC_ADR_PAGE21 562        /* Page-rel. ADRP imm. 32:12.  */
     2440#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3.  */
     2441#define R_AARCH64_TLSDESC_ADD_LO12 564  /* Direct ADD imm. from 11:0.  */
     2442#define R_AARCH64_TLSDESC_OFF_G1 565    /* GOT-rel. MOV{N,Z} imm. 31:16.  */
     2443#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck.  */
     2444#define R_AARCH64_TLSDESC_LDR   567     /* Relax LDR.  */
     2445#define R_AARCH64_TLSDESC_ADD   568     /* Relax ADD.  */
     2446#define R_AARCH64_TLSDESC_CALL  569     /* Relax BLR.  */
     2447#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570  /* TP-rel. LD/ST off. 11:4.  */
     2448#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571       /* Likewise; no check.  */
     2449#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
     2450#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573      /* Likewise; no check.  */
     2451#define R_AARCH64_COPY         1024     /* Copy symbol at runtime.  */
     2452#define R_AARCH64_GLOB_DAT     1025     /* Create GOT entry.  */
     2453#define R_AARCH64_JUMP_SLOT    1026     /* Create PLT entry.  */
     2454#define R_AARCH64_RELATIVE     1027     /* Adjust by program base.  */
     2455#define R_AARCH64_TLS_DTPMOD64 1028     /* Module number, 64 bit.  */
     2456#define R_AARCH64_TLS_DTPREL64 1029     /* Module-relative offset, 64 bit.  */
     2457#define R_AARCH64_TLS_TPREL64  1030     /* TP-relative offset, 64 bit.  */
     2458#define R_AARCH64_TLSDESC      1031     /* TLS Descriptor.  */
     2459#define R_AARCH64_IRELATIVE    1032     /* STT_GNU_IFUNC relocation.  */
     2460/* Keep this the last entry.  */
     2461#define R_AARCH64_NUM          1033
     2462
     2463/* ARM relocs.  */
     2464
     2465#define R_ARM_NONE              0       /* No reloc */
     2466#define R_ARM_PC24              1       /* PC relative 26 bit branch */
     2467#define R_ARM_ABS32             2       /* Direct 32 bit  */
     2468#define R_ARM_REL32             3       /* PC relative 32 bit */
     2469#define R_ARM_PC13              4
     2470#define R_ARM_ABS16             5       /* Direct 16 bit */
     2471#define R_ARM_ABS12             6       /* Direct 12 bit */
     2472#define R_ARM_THM_ABS5          7
     2473#define R_ARM_ABS8              8       /* Direct 8 bit */
     2474#define R_ARM_SBREL32           9
     2475#define R_ARM_THM_PC22          10
     2476#define R_ARM_THM_PC8           11
     2477#define R_ARM_AMP_VCALL9        12
     2478#define R_ARM_SWI24             13      /* Obsolete static relocation.  */
     2479#define R_ARM_TLS_DESC          13      /* Dynamic relocation.  */
     2480#define R_ARM_THM_SWI8          14
     2481#define R_ARM_XPC25             15
     2482#define R_ARM_THM_XPC22         16
     2483#define R_ARM_TLS_DTPMOD32      17      /* ID of module containing symbol */
     2484#define R_ARM_TLS_DTPOFF32      18      /* Offset in TLS block */
     2485#define R_ARM_TLS_TPOFF32       19      /* Offset in static TLS block */
     2486#define R_ARM_COPY              20      /* Copy symbol at runtime */
     2487#define R_ARM_GLOB_DAT          21      /* Create GOT entry */
     2488#define R_ARM_JUMP_SLOT         22      /* Create PLT entry */
     2489#define R_ARM_RELATIVE          23      /* Adjust by program base */
     2490#define R_ARM_GOTOFF            24      /* 32 bit offset to GOT */
     2491#define R_ARM_GOTPC             25      /* 32 bit PC relative offset to GOT */
     2492#define R_ARM_GOT32             26      /* 32 bit GOT entry */
     2493#define R_ARM_PLT32             27      /* 32 bit PLT address */
     2494#define R_ARM_CALL              28
     2495#define R_ARM_JUMP24            29
     2496#define R_ARM_THM_JUMP24        30
     2497#define R_ARM_ALU_PCREL_7_0     32
     2498#define R_ARM_ALU_PCREL_15_8    33
     2499#define R_ARM_ALU_PCREL_23_15   34
     2500#define R_ARM_LDR_SBREL_11_0    35
     2501#define R_ARM_ALU_SBREL_19_12   36
     2502#define R_ARM_ALU_SBREL_27_20   37
     2503#define R_ARM_V4BX              40
     2504#define R_ARM_PREL31            42
     2505#define R_ARM_MOVW_ABS_NC       43
     2506#define R_ARM_MOVT_ABS           44
     2507#define R_ARM_THM_MOVW_ABS_NC   47
     2508#define R_ARM_THM_MOVT_ABS      48
     2509#define R_ARM_TLS_GOTDESC       90
     2510#define R_ARM_TLS_CALL          91
     2511#define R_ARM_TLS_DESCSEQ       92
     2512#define R_ARM_THM_TLS_CALL      93
     2513#define R_ARM_GNU_VTENTRY       100
     2514#define R_ARM_GNU_VTINHERIT     101
     2515#define R_ARM_THM_PC11          102     /* thumb unconditional branch */
     2516#define R_ARM_THM_PC9           103     /* thumb conditional branch */
     2517#define R_ARM_TLS_GD32          104     /* PC-rel 32 bit for global dynamic
     2518                                           thread local data */
     2519#define R_ARM_TLS_LDM32         105     /* PC-rel 32 bit for local dynamic
     2520                                           thread local data */
     2521#define R_ARM_TLS_LDO32         106     /* 32 bit offset relative to TLS
     2522                                           block */
     2523#define R_ARM_TLS_IE32          107     /* PC-rel 32 bit for GOT entry of
     2524                                           static TLS block offset */
     2525#define R_ARM_TLS_LE32          108     /* 32 bit offset relative to static
     2526                                           TLS block */
     2527#define R_ARM_THM_TLS_DESCSEQ   129
     2528#define R_ARM_IRELATIVE         160
     2529#define R_ARM_RXPC25            249
     2530#define R_ARM_RSBREL32          250
     2531#define R_ARM_THM_RPC22         251
     2532#define R_ARM_RREL32            252
     2533#define R_ARM_RABS22            253
     2534#define R_ARM_RPC24             254
     2535#define R_ARM_RBASE             255
     2536/* Keep this the last entry.  */
     2537#define R_ARM_NUM               256
     2538
     2539/* TMS320C67xx specific declarations */
     2540
     2541/* XXX: no ELF standard yet*/
     2542
     2543/* TMS320C67xx relocs. */
     2544#define R_C60_32       1
     2545#define R_C60_GOT32     3               /* 32 bit GOT entry */
     2546#define R_C60_PLT32     4               /* 32 bit PLT address */
     2547#define R_C60_COPY      5               /* Copy symbol at runtime */
     2548#define R_C60_GLOB_DAT  6               /* Create GOT entry */
     2549#define R_C60_JMP_SLOT  7               /* Create PLT entry */
     2550#define R_C60_RELATIVE  8               /* Adjust by program base */
     2551#define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
     2552#define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
     2553
     2554#define R_C60LO16      0x54       /* low 16 bit MVKL embedded */
     2555#define R_C60HI16      0x55       /* high 16 bit MVKH embedded */
     2556/* Keep this the last entry.  */
     2557#define R_C60_NUM      0x56
     2558
     2559/* IA-64 specific declarations.  */
     2560
     2561/* Processor specific flags for the Ehdr e_flags field.  */
     2562#define EF_IA_64_MASKOS         0x0000000f      /* os-specific flags */
     2563#define EF_IA_64_ABI64          0x00000010      /* 64-bit ABI */
     2564#define EF_IA_64_ARCH           0xff000000      /* arch. version mask */
     2565
     2566/* Processor specific values for the Phdr p_type field.  */
     2567#define PT_IA_64_ARCHEXT        (PT_LOPROC + 0) /* arch extension bits */
     2568#define PT_IA_64_UNWIND         (PT_LOPROC + 1) /* ia64 unwind bits */
     2569#define PT_IA_64_HP_OPT_ANOT    (PT_LOOS + 0x12)
     2570#define PT_IA_64_HP_HSL_ANOT    (PT_LOOS + 0x13)
     2571#define PT_IA_64_HP_STACK       (PT_LOOS + 0x14)
     2572
     2573/* Processor specific flags for the Phdr p_flags field.  */
     2574#define PF_IA_64_NORECOV        0x80000000      /* spec insns w/o recovery */
     2575
     2576/* Processor specific values for the Shdr sh_type field.  */
     2577#define SHT_IA_64_EXT           (SHT_LOPROC + 0) /* extension bits */
     2578#define SHT_IA_64_UNWIND        (SHT_LOPROC + 1) /* unwind bits */
     2579
     2580/* Processor specific flags for the Shdr sh_flags field.  */
     2581#define SHF_IA_64_SHORT         0x10000000      /* section near gp */
     2582#define SHF_IA_64_NORECOV       0x20000000      /* spec insns w/o recovery */
     2583
     2584/* Processor specific values for the Dyn d_tag field.  */
     2585#define DT_IA_64_PLT_RESERVE    (DT_LOPROC + 0)
     2586#define DT_IA_64_NUM            1
     2587
     2588/* IA-64 relocations.  */
     2589#define R_IA64_NONE             0x00    /* none */
     2590#define R_IA64_IMM14            0x21    /* symbol + addend, add imm14 */
     2591#define R_IA64_IMM22            0x22    /* symbol + addend, add imm22 */
     2592#define R_IA64_IMM64            0x23    /* symbol + addend, mov imm64 */
     2593#define R_IA64_DIR32MSB         0x24    /* symbol + addend, data4 MSB */
     2594#define R_IA64_DIR32LSB         0x25    /* symbol + addend, data4 LSB */
     2595#define R_IA64_DIR64MSB         0x26    /* symbol + addend, data8 MSB */
     2596#define R_IA64_DIR64LSB         0x27    /* symbol + addend, data8 LSB */
     2597#define R_IA64_GPREL22          0x2a    /* @gprel(sym + add), add imm22 */
     2598#define R_IA64_GPREL64I         0x2b    /* @gprel(sym + add), mov imm64 */
     2599#define R_IA64_GPREL32MSB       0x2c    /* @gprel(sym + add), data4 MSB */
     2600#define R_IA64_GPREL32LSB       0x2d    /* @gprel(sym + add), data4 LSB */
     2601#define R_IA64_GPREL64MSB       0x2e    /* @gprel(sym + add), data8 MSB */
     2602#define R_IA64_GPREL64LSB       0x2f    /* @gprel(sym + add), data8 LSB */
     2603#define R_IA64_LTOFF22          0x32    /* @ltoff(sym + add), add imm22 */
     2604#define R_IA64_LTOFF64I         0x33    /* @ltoff(sym + add), mov imm64 */
     2605#define R_IA64_PLTOFF22         0x3a    /* @pltoff(sym + add), add imm22 */
     2606#define R_IA64_PLTOFF64I        0x3b    /* @pltoff(sym + add), mov imm64 */
     2607#define R_IA64_PLTOFF64MSB      0x3e    /* @pltoff(sym + add), data8 MSB */
     2608#define R_IA64_PLTOFF64LSB      0x3f    /* @pltoff(sym + add), data8 LSB */
     2609#define R_IA64_FPTR64I          0x43    /* @fptr(sym + add), mov imm64 */
     2610#define R_IA64_FPTR32MSB        0x44    /* @fptr(sym + add), data4 MSB */
     2611#define R_IA64_FPTR32LSB        0x45    /* @fptr(sym + add), data4 LSB */
     2612#define R_IA64_FPTR64MSB        0x46    /* @fptr(sym + add), data8 MSB */
     2613#define R_IA64_FPTR64LSB        0x47    /* @fptr(sym + add), data8 LSB */
     2614#define R_IA64_PCREL60B         0x48    /* @pcrel(sym + add), brl */
     2615#define R_IA64_PCREL21B         0x49    /* @pcrel(sym + add), ptb, call */
     2616#define R_IA64_PCREL21M         0x4a    /* @pcrel(sym + add), chk.s */
     2617#define R_IA64_PCREL21F         0x4b    /* @pcrel(sym + add), fchkf */
     2618#define R_IA64_PCREL32MSB       0x4c    /* @pcrel(sym + add), data4 MSB */
     2619#define R_IA64_PCREL32LSB       0x4d    /* @pcrel(sym + add), data4 LSB */
     2620#define R_IA64_PCREL64MSB       0x4e    /* @pcrel(sym + add), data8 MSB */
     2621#define R_IA64_PCREL64LSB       0x4f    /* @pcrel(sym + add), data8 LSB */
     2622#define R_IA64_LTOFF_FPTR22     0x52    /* @ltoff(@fptr(s+a)), imm22 */
     2623#define R_IA64_LTOFF_FPTR64I    0x53    /* @ltoff(@fptr(s+a)), imm64 */
     2624#define R_IA64_LTOFF_FPTR32MSB  0x54    /* @ltoff(@fptr(s+a)), data4 MSB */
     2625#define R_IA64_LTOFF_FPTR32LSB  0x55    /* @ltoff(@fptr(s+a)), data4 LSB */
     2626#define R_IA64_LTOFF_FPTR64MSB  0x56    /* @ltoff(@fptr(s+a)), data8 MSB */
     2627#define R_IA64_LTOFF_FPTR64LSB  0x57    /* @ltoff(@fptr(s+a)), data8 LSB */
     2628#define R_IA64_SEGREL32MSB      0x5c    /* @segrel(sym + add), data4 MSB */
     2629#define R_IA64_SEGREL32LSB      0x5d    /* @segrel(sym + add), data4 LSB */
     2630#define R_IA64_SEGREL64MSB      0x5e    /* @segrel(sym + add), data8 MSB */
     2631#define R_IA64_SEGREL64LSB      0x5f    /* @segrel(sym + add), data8 LSB */
     2632#define R_IA64_SECREL32MSB      0x64    /* @secrel(sym + add), data4 MSB */
     2633#define R_IA64_SECREL32LSB      0x65    /* @secrel(sym + add), data4 LSB */
     2634#define R_IA64_SECREL64MSB      0x66    /* @secrel(sym + add), data8 MSB */
     2635#define R_IA64_SECREL64LSB      0x67    /* @secrel(sym + add), data8 LSB */
     2636#define R_IA64_REL32MSB         0x6c    /* data 4 + REL */
     2637#define R_IA64_REL32LSB         0x6d    /* data 4 + REL */
     2638#define R_IA64_REL64MSB         0x6e    /* data 8 + REL */
     2639#define R_IA64_REL64LSB         0x6f    /* data 8 + REL */
     2640#define R_IA64_LTV32MSB         0x74    /* symbol + addend, data4 MSB */
     2641#define R_IA64_LTV32LSB         0x75    /* symbol + addend, data4 LSB */
     2642#define R_IA64_LTV64MSB         0x76    /* symbol + addend, data8 MSB */
     2643#define R_IA64_LTV64LSB         0x77    /* symbol + addend, data8 LSB */
     2644#define R_IA64_PCREL21BI        0x79    /* @pcrel(sym + add), 21bit inst */
     2645#define R_IA64_PCREL22          0x7a    /* @pcrel(sym + add), 22bit inst */
     2646#define R_IA64_PCREL64I         0x7b    /* @pcrel(sym + add), 64bit inst */
     2647#define R_IA64_IPLTMSB          0x80    /* dynamic reloc, imported PLT, MSB */
     2648#define R_IA64_IPLTLSB          0x81    /* dynamic reloc, imported PLT, LSB */
     2649#define R_IA64_COPY             0x84    /* copy relocation */
     2650#define R_IA64_SUB              0x85    /* Addend and symbol difference */
     2651#define R_IA64_LTOFF22X         0x86    /* LTOFF22, relaxable.  */
     2652#define R_IA64_LDXMOV           0x87    /* Use of LTOFF22X.  */
     2653#define R_IA64_TPREL14          0x91    /* @tprel(sym + add), imm14 */
     2654#define R_IA64_TPREL22          0x92    /* @tprel(sym + add), imm22 */
     2655#define R_IA64_TPREL64I         0x93    /* @tprel(sym + add), imm64 */
     2656#define R_IA64_TPREL64MSB       0x96    /* @tprel(sym + add), data8 MSB */
     2657#define R_IA64_TPREL64LSB       0x97    /* @tprel(sym + add), data8 LSB */
     2658#define R_IA64_LTOFF_TPREL22    0x9a    /* @ltoff(@tprel(s+a)), imm2 */
     2659#define R_IA64_DTPMOD64MSB      0xa6    /* @dtpmod(sym + add), data8 MSB */
     2660#define R_IA64_DTPMOD64LSB      0xa7    /* @dtpmod(sym + add), data8 LSB */
     2661#define R_IA64_LTOFF_DTPMOD22   0xaa    /* @ltoff(@dtpmod(sym + add)), imm22 */
     2662#define R_IA64_DTPREL14         0xb1    /* @dtprel(sym + add), imm14 */
     2663#define R_IA64_DTPREL22         0xb2    /* @dtprel(sym + add), imm22 */
     2664#define R_IA64_DTPREL64I        0xb3    /* @dtprel(sym + add), imm64 */
     2665#define R_IA64_DTPREL32MSB      0xb4    /* @dtprel(sym + add), data4 MSB */
     2666#define R_IA64_DTPREL32LSB      0xb5    /* @dtprel(sym + add), data4 LSB */
     2667#define R_IA64_DTPREL64MSB      0xb6    /* @dtprel(sym + add), data8 MSB */
     2668#define R_IA64_DTPREL64LSB      0xb7    /* @dtprel(sym + add), data8 LSB */
     2669#define R_IA64_LTOFF_DTPREL22   0xba    /* @ltoff(@dtprel(s+a)), imm22 */
     2670
     2671/* SH specific declarations */
     2672
     2673/* Processor specific flags for the ELF header e_flags field.  */
     2674#define EF_SH_MACH_MASK         0x1f
     2675#define EF_SH_UNKNOWN           0x0
     2676#define EF_SH1                  0x1
     2677#define EF_SH2                  0x2
     2678#define EF_SH3                  0x3
     2679#define EF_SH_DSP               0x4
     2680#define EF_SH3_DSP              0x5
     2681#define EF_SH4AL_DSP            0x6
     2682#define EF_SH3E                 0x8
     2683#define EF_SH4                  0x9
     2684#define EF_SH2E                 0xb
     2685#define EF_SH4A                 0xc
     2686#define EF_SH2A                 0xd
     2687#define EF_SH4_NOFPU            0x10
     2688#define EF_SH4A_NOFPU           0x11
     2689#define EF_SH4_NOMMU_NOFPU      0x12
     2690#define EF_SH2A_NOFPU           0x13
     2691#define EF_SH3_NOMMU            0x14
     2692#define EF_SH2A_SH4_NOFPU       0x15
     2693#define EF_SH2A_SH3_NOFPU       0x16
     2694#define EF_SH2A_SH4             0x17
     2695#define EF_SH2A_SH3E            0x18
     2696
     2697/* SH relocs.  */
     2698#define R_SH_NONE               0
     2699#define R_SH_DIR32              1
     2700#define R_SH_REL32              2
     2701#define R_SH_DIR8WPN            3
     2702#define R_SH_IND12W             4
     2703#define R_SH_DIR8WPL            5
     2704#define R_SH_DIR8WPZ            6
     2705#define R_SH_DIR8BP             7
     2706#define R_SH_DIR8W              8
     2707#define R_SH_DIR8L              9
     2708#define R_SH_SWITCH16           25
     2709#define R_SH_SWITCH32           26
     2710#define R_SH_USES               27
     2711#define R_SH_COUNT              28
     2712#define R_SH_ALIGN              29
     2713#define R_SH_CODE               30
     2714#define R_SH_DATA               31
     2715#define R_SH_LABEL              32
     2716#define R_SH_SWITCH8            33
     2717#define R_SH_GNU_VTINHERIT      34
     2718#define R_SH_GNU_VTENTRY        35
     2719#define R_SH_TLS_GD_32          144
     2720#define R_SH_TLS_LD_32          145
     2721#define R_SH_TLS_LDO_32         146
     2722#define R_SH_TLS_IE_32          147
     2723#define R_SH_TLS_LE_32          148
     2724#define R_SH_TLS_DTPMOD32       149
     2725#define R_SH_TLS_DTPOFF32       150
     2726#define R_SH_TLS_TPOFF32        151
     2727#define R_SH_GOT32              160
     2728#define R_SH_PLT32              161
     2729#define R_SH_COPY               162
     2730#define R_SH_GLOB_DAT           163
     2731#define R_SH_JMP_SLOT           164
     2732#define R_SH_RELATIVE           165
     2733#define R_SH_GOTOFF             166
     2734#define R_SH_GOTPC              167
     2735/* Keep this the last entry.  */
     2736#define R_SH_NUM                256
     2737
     2738/* S/390 specific definitions.  */
     2739
     2740/* Valid values for the e_flags field.  */
     2741
     2742#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
     2743
     2744/* Additional s390 relocs */
     2745
     2746#define R_390_NONE              0       /* No reloc.  */
     2747#define R_390_8                 1       /* Direct 8 bit.  */
     2748#define R_390_12                2       /* Direct 12 bit.  */
     2749#define R_390_16                3       /* Direct 16 bit.  */
     2750#define R_390_32                4       /* Direct 32 bit.  */
     2751#define R_390_PC32              5       /* PC relative 32 bit.  */
     2752#define R_390_GOT12             6       /* 12 bit GOT offset.  */
     2753#define R_390_GOT32             7       /* 32 bit GOT offset.  */
     2754#define R_390_PLT32             8       /* 32 bit PC relative PLT address.  */
     2755#define R_390_COPY              9       /* Copy symbol at runtime.  */
     2756#define R_390_GLOB_DAT          10      /* Create GOT entry.  */
     2757#define R_390_JMP_SLOT          11      /* Create PLT entry.  */
     2758#define R_390_RELATIVE          12      /* Adjust by program base.  */
     2759#define R_390_GOTOFF32          13      /* 32 bit offset to GOT.         */
     2760#define R_390_GOTPC             14      /* 32 bit PC relative offset to GOT.  */
     2761#define R_390_GOT16             15      /* 16 bit GOT offset.  */
     2762#define R_390_PC16              16      /* PC relative 16 bit.  */
     2763#define R_390_PC16DBL           17      /* PC relative 16 bit shifted by 1.  */
     2764#define R_390_PLT16DBL          18      /* 16 bit PC rel. PLT shifted by 1.  */
     2765#define R_390_PC32DBL           19      /* PC relative 32 bit shifted by 1.  */
     2766#define R_390_PLT32DBL          20      /* 32 bit PC rel. PLT shifted by 1.  */
     2767#define R_390_GOTPCDBL          21      /* 32 bit PC rel. GOT shifted by 1.  */
     2768#define R_390_64                22      /* Direct 64 bit.  */
     2769#define R_390_PC64              23      /* PC relative 64 bit.  */
     2770#define R_390_GOT64             24      /* 64 bit GOT offset.  */
     2771#define R_390_PLT64             25      /* 64 bit PC relative PLT address.  */
     2772#define R_390_GOTENT            26      /* 32 bit PC rel. to GOT entry >> 1. */
     2773#define R_390_GOTOFF16          27      /* 16 bit offset to GOT. */
     2774#define R_390_GOTOFF64          28      /* 64 bit offset to GOT. */
     2775#define R_390_GOTPLT12          29      /* 12 bit offset to jump slot.  */
     2776#define R_390_GOTPLT16          30      /* 16 bit offset to jump slot.  */
     2777#define R_390_GOTPLT32          31      /* 32 bit offset to jump slot.  */
     2778#define R_390_GOTPLT64          32      /* 64 bit offset to jump slot.  */
     2779#define R_390_GOTPLTENT         33      /* 32 bit rel. offset to jump slot.  */
     2780#define R_390_PLTOFF16          34      /* 16 bit offset from GOT to PLT. */
     2781#define R_390_PLTOFF32          35      /* 32 bit offset from GOT to PLT. */
     2782#define R_390_PLTOFF64          36      /* 16 bit offset from GOT to PLT. */
     2783#define R_390_TLS_LOAD          37      /* Tag for load insn in TLS code.  */
     2784#define R_390_TLS_GDCALL        38      /* Tag for function call in general
     2785                                           dynamic TLS code. */
     2786#define R_390_TLS_LDCALL        39      /* Tag for function call in local
     2787                                           dynamic TLS code. */
     2788#define R_390_TLS_GD32          40      /* Direct 32 bit for general dynamic
     2789                                           thread local data.  */
     2790#define R_390_TLS_GD64          41      /* Direct 64 bit for general dynamic
     2791                                          thread local data.  */
     2792#define R_390_TLS_GOTIE12       42      /* 12 bit GOT offset for static TLS
     2793                                           block offset.  */
     2794#define R_390_TLS_GOTIE32       43      /* 32 bit GOT offset for static TLS
     2795                                           block offset.  */
     2796#define R_390_TLS_GOTIE64       44      /* 64 bit GOT offset for static TLS
     2797                                           block offset. */
     2798#define R_390_TLS_LDM32         45      /* Direct 32 bit for local dynamic
     2799                                           thread local data in LE code.  */
     2800#define R_390_TLS_LDM64         46      /* Direct 64 bit for local dynamic
     2801                                           thread local data in LE code.  */
     2802#define R_390_TLS_IE32          47      /* 32 bit address of GOT entry for
     2803                                           negated static TLS block offset.  */
     2804#define R_390_TLS_IE64          48      /* 64 bit address of GOT entry for
     2805                                           negated static TLS block offset.  */
     2806#define R_390_TLS_IEENT         49      /* 32 bit rel. offset to GOT entry for
     2807                                           negated static TLS block offset.  */
     2808#define R_390_TLS_LE32          50      /* 32 bit negated offset relative to
     2809                                           static TLS block.  */
     2810#define R_390_TLS_LE64          51      /* 64 bit negated offset relative to
     2811                                           static TLS block.  */
     2812#define R_390_TLS_LDO32         52      /* 32 bit offset relative to TLS
     2813                                           block.  */
     2814#define R_390_TLS_LDO64         53      /* 64 bit offset relative to TLS
     2815                                           block.  */
     2816#define R_390_TLS_DTPMOD        54      /* ID of module containing symbol.  */
     2817#define R_390_TLS_DTPOFF        55      /* Offset in TLS block.  */
     2818#define R_390_TLS_TPOFF         56      /* Negated offset in static TLS
     2819                                           block.  */
     2820#define R_390_20                57      /* Direct 20 bit.  */
     2821#define R_390_GOT20             58      /* 20 bit GOT offset.  */
     2822#define R_390_GOTPLT20          59      /* 20 bit offset to jump slot.  */
     2823#define R_390_TLS_GOTIE20       60      /* 20 bit GOT offset for static TLS
     2824                                           block offset.  */
     2825#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
     2826/* Keep this the last entry.  */
     2827#define R_390_NUM               62
     2828
     2829
     2830/* CRIS relocations.  */
     2831#define R_CRIS_NONE             0
     2832#define R_CRIS_8                1
     2833#define R_CRIS_16               2
     2834#define R_CRIS_32               3
     2835#define R_CRIS_8_PCREL          4
     2836#define R_CRIS_16_PCREL         5
     2837#define R_CRIS_32_PCREL         6
     2838#define R_CRIS_GNU_VTINHERIT    7
     2839#define R_CRIS_GNU_VTENTRY      8
     2840#define R_CRIS_COPY             9
     2841#define R_CRIS_GLOB_DAT         10
     2842#define R_CRIS_JUMP_SLOT        11
     2843#define R_CRIS_RELATIVE         12
     2844#define R_CRIS_16_GOT           13
     2845#define R_CRIS_32_GOT           14
     2846#define R_CRIS_16_GOTPLT        15
     2847#define R_CRIS_32_GOTPLT        16
     2848#define R_CRIS_32_GOTREL        17
     2849#define R_CRIS_32_PLT_GOTREL    18
     2850#define R_CRIS_32_PLT_PCREL     19
     2851
     2852#define R_CRIS_NUM              20
     2853
    10472854
    10482855/* AMD x86-64 relocations.  */
     
    10752882                                           to GOT entry for IE symbol */
    10762883#define R_X86_64_TPOFF32        23      /* Offset in initial TLS block */
    1077 
    1078 #define R_X86_64_NUM            24
    1079 
    1080 /* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
    1081 
    1082 #define DT_SPARC_REGISTER 0x70000001
    1083 #define DT_SPARC_NUM    2
    1084 
    1085 /* Bits present in AT_HWCAP, primarily for Sparc32.  */
    1086 
    1087 #define HWCAP_SPARC_FLUSH       1       /* The cpu supports flush insn.  */
    1088 #define HWCAP_SPARC_STBAR       2
    1089 #define HWCAP_SPARC_SWAP        4
    1090 #define HWCAP_SPARC_MULDIV      8
    1091 #define HWCAP_SPARC_V9          16      /* The cpu is v9, so v8plus is ok.  */
    1092 
    1093 /* MIPS R3000 specific definitions.  */
    1094 
    1095 /* Legal values for e_flags field of Elf32_Ehdr.  */
    1096 
    1097 #define EF_MIPS_NOREORDER   1           /* A .noreorder directive was used */
    1098 #define EF_MIPS_PIC         2           /* Contains PIC code */
    1099 #define EF_MIPS_CPIC        4           /* Uses PIC calling sequence */
    1100 #define EF_MIPS_XGOT        8
    1101 #define EF_MIPS_64BIT_WHIRL 16
    1102 #define EF_MIPS_ABI2        32
    1103 #define EF_MIPS_ABI_ON32    64
    1104 #define EF_MIPS_ARCH        0xf0000000  /* MIPS architecture level */
    1105 
    1106 /* Legal values for MIPS architecture level.  */
    1107 
    1108 #define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
    1109 #define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
    1110 #define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
    1111 #define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
    1112 #define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
    1113 
    1114 /* The following are non-official names and should not be used.  */
    1115 
    1116 #define E_MIPS_ARCH_1     0x00000000    /* -mips1 code.  */
    1117 #define E_MIPS_ARCH_2     0x10000000    /* -mips2 code.  */
    1118 #define E_MIPS_ARCH_3     0x20000000    /* -mips3 code.  */
    1119 #define E_MIPS_ARCH_4     0x30000000    /* -mips4 code.  */
    1120 #define E_MIPS_ARCH_5     0x40000000    /* -mips5 code.  */
    1121 
    1122 /* Special section indices.  */
    1123 
    1124 #define SHN_MIPS_ACOMMON 0xff00         /* Allocated common symbols */
    1125 #define SHN_MIPS_TEXT    0xff01         /* Allocated test symbols.  */
    1126 #define SHN_MIPS_DATA    0xff02         /* Allocated data symbols.  */
    1127 #define SHN_MIPS_SCOMMON 0xff03         /* Small common symbols */
    1128 #define SHN_MIPS_SUNDEFINED 0xff04      /* Small undefined symbols */
    1129 
    1130 /* Legal values for sh_type field of Elf32_Shdr.  */
    1131 
    1132 #define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
    1133 #define SHT_MIPS_MSYM          0x70000001
    1134 #define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
    1135 #define SHT_MIPS_GPTAB         0x70000003 /* Global data area sizes */
    1136 #define SHT_MIPS_UCODE         0x70000004 /* Reserved for SGI/MIPS compilers */
    1137 #define SHT_MIPS_DEBUG         0x70000005 /* MIPS ECOFF debugging information*/
    1138 #define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
    1139 #define SHT_MIPS_PACKAGE       0x70000007
    1140 #define SHT_MIPS_PACKSYM       0x70000008
    1141 #define SHT_MIPS_RELD          0x70000009
    1142 #define SHT_MIPS_IFACE         0x7000000b
    1143 #define SHT_MIPS_CONTENT       0x7000000c
    1144 #define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
    1145 #define SHT_MIPS_SHDR          0x70000010
    1146 #define SHT_MIPS_FDESC         0x70000011
    1147 #define SHT_MIPS_EXTSYM        0x70000012
    1148 #define SHT_MIPS_DENSE         0x70000013
    1149 #define SHT_MIPS_PDESC         0x70000014
    1150 #define SHT_MIPS_LOCSYM        0x70000015
    1151 #define SHT_MIPS_AUXSYM        0x70000016
    1152 #define SHT_MIPS_OPTSYM        0x70000017
    1153 #define SHT_MIPS_LOCSTR        0x70000018
    1154 #define SHT_MIPS_LINE          0x70000019
    1155 #define SHT_MIPS_RFDESC        0x7000001a
    1156 #define SHT_MIPS_DELTASYM      0x7000001b
    1157 #define SHT_MIPS_DELTAINST     0x7000001c
    1158 #define SHT_MIPS_DELTACLASS    0x7000001d
    1159 #define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
    1160 #define SHT_MIPS_DELTADECL     0x7000001f
    1161 #define SHT_MIPS_SYMBOL_LIB    0x70000020
    1162 #define SHT_MIPS_EVENTS        0x70000021 /* Event section.  */
    1163 #define SHT_MIPS_TRANSLATE     0x70000022
    1164 #define SHT_MIPS_PIXIE         0x70000023
    1165 #define SHT_MIPS_XLATE         0x70000024
    1166 #define SHT_MIPS_XLATE_DEBUG   0x70000025
    1167 #define SHT_MIPS_WHIRL         0x70000026
    1168 #define SHT_MIPS_EH_REGION     0x70000027
    1169 #define SHT_MIPS_XLATE_OLD     0x70000028
    1170 #define SHT_MIPS_PDR_EXCEPTION 0x70000029
    1171 
    1172 /* Legal values for sh_flags field of Elf32_Shdr.  */
    1173 
    1174 #define SHF_MIPS_GPREL   0x10000000     /* Must be part of global data area */
    1175 #define SHF_MIPS_MERGE   0x20000000
    1176 #define SHF_MIPS_ADDR    0x40000000
    1177 #define SHF_MIPS_STRINGS 0x80000000
    1178 #define SHF_MIPS_NOSTRIP 0x08000000
    1179 #define SHF_MIPS_LOCAL   0x04000000
    1180 #define SHF_MIPS_NAMES   0x02000000
    1181 #define SHF_MIPS_NODUPE  0x01000000
    1182 
    1183 
    1184 /* Symbol tables.  */
    1185 
    1186 /* MIPS specific values for `st_other'.  */
    1187 #define STO_MIPS_DEFAULT                0x0
    1188 #define STO_MIPS_INTERNAL               0x1
    1189 #define STO_MIPS_HIDDEN                 0x2
    1190 #define STO_MIPS_PROTECTED              0x3
    1191 #define STO_MIPS_SC_ALIGN_UNUSED        0xff
    1192 
    1193 /* MIPS specific values for `st_info'.  */
    1194 #define STB_MIPS_SPLIT_COMMON           13
    1195 
    1196 /* Entries found in sections of type SHT_MIPS_GPTAB.  */
    1197 
    1198 typedef union
    1199 {
    1200   struct
    1201     {
    1202       Elf32_Word gt_current_g_value;    /* -G value used for compilation */
    1203       Elf32_Word gt_unused;             /* Not used */
    1204     } gt_header;                        /* First entry in section */
    1205   struct
    1206     {
    1207       Elf32_Word gt_g_value;            /* If this value were used for -G */
    1208       Elf32_Word gt_bytes;              /* This many bytes would be used */
    1209     } gt_entry;                         /* Subsequent entries in section */
    1210 } Elf32_gptab;
    1211 
    1212 /* Entry found in sections of type SHT_MIPS_REGINFO.  */
    1213 
    1214 typedef struct
    1215 {
    1216   Elf32_Word    ri_gprmask;             /* General registers used */
    1217   Elf32_Word    ri_cprmask[4];          /* Coprocessor registers used */
    1218   Elf32_Sword   ri_gp_value;            /* $gp register value */
    1219 } Elf32_RegInfo;
    1220 
    1221 /* Entries found in sections of type SHT_MIPS_OPTIONS.  */
    1222 
    1223 typedef struct
    1224 {
    1225   unsigned char kind;           /* Determines interpretation of the
    1226                                    variable part of descriptor.  */
    1227   unsigned char size;           /* Size of descriptor, including header.  */
    1228   Elf32_Section section;        /* Section header index of section affected,
    1229                                    0 for global options.  */
    1230   Elf32_Word info;              /* Kind-specific information.  */
    1231 } Elf_Options;
    1232 
    1233 /* Values for `kind' field in Elf_Options.  */
    1234 
    1235 #define ODK_NULL        0       /* Undefined.  */
    1236 #define ODK_REGINFO     1       /* Register usage information.  */
    1237 #define ODK_EXCEPTIONS  2       /* Exception processing options.  */
    1238 #define ODK_PAD         3       /* Section padding options.  */
    1239 #define ODK_HWPATCH     4       /* Hardware workarounds performed */
    1240 #define ODK_FILL        5       /* record the fill value used by the linker. */
    1241 #define ODK_TAGS        6       /* reserve space for desktop tools to write. */
    1242 #define ODK_HWAND       7       /* HW workarounds.  'AND' bits when merging. */
    1243 #define ODK_HWOR        8       /* HW workarounds.  'OR' bits when merging.  */
    1244 
    1245 /* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
    1246 
    1247 #define OEX_FPU_MIN     0x1f    /* FPE's which MUST be enabled.  */
    1248 #define OEX_FPU_MAX     0x1f00  /* FPE's which MAY be enabled.  */
    1249 #define OEX_PAGE0       0x10000 /* page zero must be mapped.  */
    1250 #define OEX_SMM         0x20000 /* Force sequential memory mode?  */
    1251 #define OEX_FPDBUG      0x40000 /* Force floating point debug mode?  */
    1252 #define OEX_PRECISEFP   OEX_FPDBUG
    1253 #define OEX_DISMISS     0x80000 /* Dismiss invalid address faults?  */
    1254 
    1255 #define OEX_FPU_INVAL   0x10
    1256 #define OEX_FPU_DIV0    0x08
    1257 #define OEX_FPU_OFLO    0x04
    1258 #define OEX_FPU_UFLO    0x02
    1259 #define OEX_FPU_INEX    0x01
    1260 
    1261 /* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
    1262 
    1263 #define OHW_R4KEOP      0x1     /* R4000 end-of-page patch.  */
    1264 #define OHW_R8KPFETCH   0x2     /* may need R8000 prefetch patch.  */
    1265 #define OHW_R5KEOP      0x4     /* R5000 end-of-page patch.  */
    1266 #define OHW_R5KCVTL     0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
    1267 
    1268 #define OPAD_PREFIX     0x1
    1269 #define OPAD_POSTFIX    0x2
    1270 #define OPAD_SYMBOL     0x4
    1271 
    1272 /* Entry found in `.options' section.  */
    1273 
    1274 typedef struct
    1275 {
    1276   Elf32_Word hwp_flags1;        /* Extra flags.  */
    1277   Elf32_Word hwp_flags2;        /* Extra flags.  */
    1278 } Elf_Options_Hw;
    1279 
    1280 /* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
    1281 
    1282 #define OHWA0_R4KEOP_CHECKED    0x00000001
    1283 #define OHWA1_R4KEOP_CLEAN      0x00000002
    1284 
    1285 /* MIPS relocs.  */
    1286 
    1287 #define R_MIPS_NONE             0       /* No reloc */
    1288 #define R_MIPS_16               1       /* Direct 16 bit */
    1289 #define R_MIPS_32               2       /* Direct 32 bit */
    1290 #define R_MIPS_REL32            3       /* PC relative 32 bit */
    1291 #define R_MIPS_26               4       /* Direct 26 bit shifted */
    1292 #define R_MIPS_HI16             5       /* High 16 bit */
    1293 #define R_MIPS_LO16             6       /* Low 16 bit */
    1294 #define R_MIPS_GPREL16          7       /* GP relative 16 bit */
    1295 #define R_MIPS_LITERAL          8       /* 16 bit literal entry */
    1296 #define R_MIPS_GOT16            9       /* 16 bit GOT entry */
    1297 #define R_MIPS_PC16             10      /* PC relative 16 bit */
    1298 #define R_MIPS_CALL16           11      /* 16 bit GOT entry for function */
    1299 #define R_MIPS_GPREL32          12      /* GP relative 32 bit */
    1300 
    1301 #define R_MIPS_SHIFT5           16
    1302 #define R_MIPS_SHIFT6           17
    1303 #define R_MIPS_64               18
    1304 #define R_MIPS_GOT_DISP         19
    1305 #define R_MIPS_GOT_PAGE         20
    1306 #define R_MIPS_GOT_OFST         21
    1307 #define R_MIPS_GOT_HI16         22
    1308 #define R_MIPS_GOT_LO16         23
    1309 #define R_MIPS_SUB              24
    1310 #define R_MIPS_INSERT_A         25
    1311 #define R_MIPS_INSERT_B         26
    1312 #define R_MIPS_DELETE           27
    1313 #define R_MIPS_HIGHER           28
    1314 #define R_MIPS_HIGHEST          29
    1315 #define R_MIPS_CALL_HI16        30
    1316 #define R_MIPS_CALL_LO16        31
    1317 #define R_MIPS_SCN_DISP         32
    1318 #define R_MIPS_REL16            33
    1319 #define R_MIPS_ADD_IMMEDIATE    34
    1320 #define R_MIPS_PJUMP            35
    1321 #define R_MIPS_RELGOT           36
    1322 #define R_MIPS_JALR             37
    1323 /* Keep this the last entry.  */
    1324 #define R_MIPS_NUM              38
    1325 
    1326 /* Legal values for p_type field of Elf32_Phdr.  */
    1327 
    1328 #define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
    1329 #define PT_MIPS_RTPROC  0x70000001      /* Runtime procedure table. */
    1330 #define PT_MIPS_OPTIONS 0x70000002
    1331 
    1332 /* Special program header types.  */
    1333 
    1334 #define PF_MIPS_LOCAL   0x10000000
    1335 
    1336 /* Legal values for d_tag field of Elf32_Dyn.  */
    1337 
    1338 #define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime linker interface version */
    1339 #define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
    1340 #define DT_MIPS_ICHECKSUM    0x70000003 /* Checksum */
    1341 #define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
    1342 #define DT_MIPS_FLAGS        0x70000005 /* Flags */
    1343 #define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
    1344 #define DT_MIPS_MSYM         0x70000007
    1345 #define DT_MIPS_CONFLICT     0x70000008 /* Address of CONFLICT section */
    1346 #define DT_MIPS_LIBLIST      0x70000009 /* Address of LIBLIST section */
    1347 #define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local GOT entries */
    1348 #define DT_MIPS_CONFLICTNO   0x7000000b /* Number of CONFLICT entries */
    1349 #define DT_MIPS_LIBLISTNO    0x70000010 /* Number of LIBLIST entries */
    1350 #define DT_MIPS_SYMTABNO     0x70000011 /* Number of DYNSYM entries */
    1351 #define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
    1352 #define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in DYNSYM */
    1353 #define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
    1354 #define DT_MIPS_RLD_MAP      0x70000016 /* Address of run time loader map.  */
    1355 #define DT_MIPS_DELTA_CLASS  0x70000017 /* Delta C++ class definition.  */
    1356 #define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
    1357                                                 DT_MIPS_DELTA_CLASS.  */
    1358 #define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
    1359 #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
    1360                                                 DT_MIPS_DELTA_INSTANCE.  */
    1361 #define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
    1362 #define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
    1363                                              DT_MIPS_DELTA_RELOC.  */
    1364 #define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
    1365                                            relocations refer to.  */
    1366 #define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
    1367                                            DT_MIPS_DELTA_SYM.  */
    1368 #define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
    1369                                              class declaration.  */
    1370 #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
    1371                                                 DT_MIPS_DELTA_CLASSSYM.  */
    1372 #define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
    1373 #define DT_MIPS_PIXIE_INIT   0x70000023
    1374 #define DT_MIPS_SYMBOL_LIB   0x70000024
    1375 #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
    1376 #define DT_MIPS_LOCAL_GOTIDX 0x70000026
    1377 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027
    1378 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028
    1379 #define DT_MIPS_OPTIONS      0x70000029 /* Address of .options.  */
    1380 #define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
    1381 #define DT_MIPS_DYNSTR_ALIGN 0x7000002b
    1382 #define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
    1383 #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
    1384                                                     function stored in GOT.  */
    1385 #define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
    1386                                            by rld on dlopen() calls.  */
    1387 #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
    1388 #define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
    1389 #define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
    1390 #define DT_MIPS_NUM          0x32
    1391 
    1392 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
    1393 
    1394 #define RHF_NONE                   0            /* No flags */
    1395 #define RHF_QUICKSTART             (1 << 0)     /* Use quickstart */
    1396 #define RHF_NOTPOT                 (1 << 1)     /* Hash size not power of 2 */
    1397 #define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)     /* Ignore LD_LIBRARY_PATH */
    1398 #define RHF_NO_MOVE                (1 << 3)
    1399 #define RHF_SGI_ONLY               (1 << 4)
    1400 #define RHF_GUARANTEE_INIT         (1 << 5)
    1401 #define RHF_DELTA_C_PLUS_PLUS      (1 << 6)
    1402 #define RHF_GUARANTEE_START_INIT   (1 << 7)
    1403 #define RHF_PIXIE                  (1 << 8)
    1404 #define RHF_DEFAULT_DELAY_LOAD     (1 << 9)
    1405 #define RHF_REQUICKSTART           (1 << 10)
    1406 #define RHF_REQUICKSTARTED         (1 << 11)
    1407 #define RHF_CORD                   (1 << 12)
    1408 #define RHF_NO_UNRES_UNDEF         (1 << 13)
    1409 #define RHF_RLD_ORDER_SAFE         (1 << 14)
    1410 
    1411 /* Entries found in sections of type SHT_MIPS_LIBLIST.  */
    1412 
    1413 typedef struct
    1414 {
    1415   Elf32_Word l_name;            /* Name (string table index) */
    1416   Elf32_Word l_time_stamp;      /* Timestamp */
    1417   Elf32_Word l_checksum;        /* Checksum */
    1418   Elf32_Word l_version;         /* Interface version */
    1419   Elf32_Word l_flags;           /* Flags */
    1420 } Elf32_Lib;
    1421 
    1422 typedef struct
    1423 {
    1424   Elf64_Word l_name;            /* Name (string table index) */
    1425   Elf64_Word l_time_stamp;      /* Timestamp */
    1426   Elf64_Word l_checksum;        /* Checksum */
    1427   Elf64_Word l_version;         /* Interface version */
    1428   Elf64_Word l_flags;           /* Flags */
    1429 } Elf64_Lib;
    1430 
    1431 
    1432 /* Legal values for l_flags.  */
    1433 
    1434 #define LL_NONE           0
    1435 #define LL_EXACT_MATCH    (1 << 0)      /* Require exact match */
    1436 #define LL_IGNORE_INT_VER (1 << 1)      /* Ignore interface version */
    1437 #define LL_REQUIRE_MINOR  (1 << 2)
    1438 #define LL_EXPORTS        (1 << 3)
    1439 #define LL_DELAY_LOAD     (1 << 4)
    1440 #define LL_DELTA          (1 << 5)
    1441 
    1442 /* Entries found in sections of type SHT_MIPS_CONFLICT.  */
    1443 
    1444 typedef Elf32_Addr Elf32_Conflict;
    1445 
    1446 
    1447 /* HPPA specific definitions.  */
    1448 
    1449 /* Legal values for e_flags field of Elf32_Ehdr.  */
    1450 
    1451 #define EF_PARISC_TRAPNL        1       /* Trap nil pointer dereference.  */
    1452 #define EF_PARISC_EXT           2       /* Program uses arch. extensions.  */
    1453 #define EF_PARISC_ARCH          0xffff0000 /* Architecture version.  */
    1454 /* Defined values are:
    1455                                 0x020b  PA-RISC 1.0 big-endian
    1456                                 0x0210  PA-RISC 1.1 big-endian
    1457                                 0x028b  PA-RISC 1.0 little-endian
    1458                                 0x0290  PA-RISC 1.1 little-endian
    1459 */
    1460 
    1461 /* Legal values for sh_type field of Elf32_Shdr.  */
    1462 
    1463 #define SHT_PARISC_GOT          0x70000000 /* GOT for external data.  */
    1464 #define SHT_PARISC_ARCH         0x70000001 /* Architecture extensions.  */
    1465 #define SHT_PARISC_GLOBAL       0x70000002 /* Definition of $global$.  */
    1466 #define SHT_PARISC_MILLI        0x70000003 /* Millicode routines.  */
    1467 #define SHT_PARISC_UNWIND       0x70000004 /* Unwind information.  */
    1468 #define SHT_PARISC_PLT          0x70000005 /* Procedure linkage table.  */
    1469 #define SHT_PARISC_SDATA        0x70000006 /* Short initialized data.  */
    1470 #define SHT_PARISC_SBSS         0x70000007 /* Short uninitialized data.  */
    1471 #define SHT_PARISC_SYMEXTN      0x70000008 /* Argument/relocation info.  */
    1472 #define SHT_PARISC_STUBS        0x70000009 /* Linker stubs.  */
    1473 
    1474 /* Legal values for sh_flags field of Elf32_Shdr.  */
    1475 
    1476 #define SHF_PARISC_GLOBAL       0x10000000 /* Section defines dp.  */
    1477 #define SHF_PARISC_SHORT        0x20000000 /* Section with short addressing. */
    1478 
    1479 /* Legal values for ST_TYPE subfield of st_info (symbol type).  */
    1480 
    1481 #define STT_PARISC_MILLICODE    13      /* Millicode function entry point.  */
    1482 
    1483 /* HPPA relocs.  */
    1484 
    1485 #define R_PARISC_NONE           0       /* No reloc.  */
    1486 #define R_PARISC_DIR32          1       /* Direct 32-bit reference.  */
    1487 #define R_PARISC_DIR21L         2       /* Left 21 bits of eff. address.  */
    1488 #define R_PARISC_DIR17R         3       /* Right 17 bits of eff. address.  */
    1489 #define R_PARISC_DIR14R         4       /* Right 14 bits of eff. address.  */
    1490 #define R_PARISC_PCREL21L       5       /* PC-relative, left 21 bits.  */
    1491 #define R_PARISC_PCREL14R       6       /* PC-relative, right 14 bits.  */
    1492 #define R_PARISC_PCREL17C       7       /* Conditional PC-relative, ignore
    1493                                            if displacement > 17bits.  */
    1494 #define R_PARISC_PCREL17F       8       /* Conditional PC-relative, must
    1495                                            fit in 17bits.  */
    1496 #define R_PARISC_DPREL21L       9       /* DP-relative, left 21 bits.  */
    1497 #define R_PARISC_DPREL14R       10      /* DP-relative, right 14 bits.  */
    1498 #define R_PARISC_DPREL14F       11      /* DP-relative, must bit in 14 bits. */
    1499 #define R_PARISC_DLTREL21L      12      /* DLT-relative, left 21 bits.  */
    1500 #define R_PARISC_DLTREL14R      13      /* DLT-relative, right 14 bits.  */
    1501 #define R_PARISC_DLTREL14F      14      /* DLT-relative, must fit in 14 bits.*/
    1502 #define R_PARISC_DLTIND21L      15      /* DLT-relative indirect, left
    1503                                            21 bits.  */
    1504 #define R_PARISC_DLTIND14R      16      /* DLT-relative indirect, right
    1505                                            14 bits.  */
    1506 #define R_PARISC_DLTIND14F      17      /* DLT-relative indirect, must fit
    1507                                            int 14 bits.  */
    1508 #define R_PARISC_PLABEL32       18      /* Direct 32-bit reference to proc.  */
    1509 
    1510 /* Alpha specific definitions.  */
    1511 
    1512 /* Legal values for e_flags field of Elf64_Ehdr.  */
    1513 
    1514 #define EF_ALPHA_32BIT          1       /* All addresses must be < 2GB.  */
    1515 #define EF_ALPHA_CANRELAX       2       /* Relocations for relaxing exist.  */
    1516 
    1517 /* Legal values for sh_type field of Elf64_Shdr.  */
    1518 
    1519 /* These two are primerily concerned with ECOFF debugging info.  */
    1520 #define SHT_ALPHA_DEBUG         0x70000001
    1521 #define SHT_ALPHA_REGINFO       0x70000002
    1522 
    1523 /* Legal values for sh_flags field of Elf64_Shdr.  */
    1524 
    1525 #define SHF_ALPHA_GPREL         0x10000000
    1526 
    1527 /* Legal values for st_other field of Elf64_Sym.  */
    1528 #define STO_ALPHA_NOPV          0x80    /* No PV required.  */
    1529 #define STO_ALPHA_STD_GPLOAD    0x88    /* PV only used for initial ldgp.  */
    1530 
    1531 /* Alpha relocs.  */
    1532 
    1533 #define R_ALPHA_NONE            0       /* No reloc */
    1534 #define R_ALPHA_REFLONG         1       /* Direct 32 bit */
    1535 #define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
    1536 #define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
    1537 #define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
    1538 #define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
    1539 #define R_ALPHA_GPDISP          6       /* Add displacement to GP */
    1540 #define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
    1541 #define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
    1542 #define R_ALPHA_SREL16          9       /* PC relative 16 bit */
    1543 #define R_ALPHA_SREL32          10      /* PC relative 32 bit */
    1544 #define R_ALPHA_SREL64          11      /* PC relative 64 bit */
    1545 #define R_ALPHA_OP_PUSH         12      /* OP stack push */
    1546 #define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
    1547 #define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
    1548 #define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
    1549 #define R_ALPHA_GPVALUE         16
    1550 #define R_ALPHA_GPRELHIGH       17
    1551 #define R_ALPHA_GPRELLOW        18
    1552 #define R_ALPHA_IMMED_GP_16     19
    1553 #define R_ALPHA_IMMED_GP_HI32   20
    1554 #define R_ALPHA_IMMED_SCN_HI32  21
    1555 #define R_ALPHA_IMMED_BR_HI32   22
    1556 #define R_ALPHA_IMMED_LO32      23
    1557 #define R_ALPHA_COPY            24      /* Copy symbol at runtime */
    1558 #define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
    1559 #define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
    1560 #define R_ALPHA_RELATIVE        27      /* Adjust by program base */
    1561 /* Keep this the last entry.  */
    1562 #define R_ALPHA_NUM             28
    1563 
    1564 
    1565 /* PowerPC specific declarations */
    1566 
    1567 /* PowerPC relocations defined by the ABIs */
    1568 #define R_PPC_NONE              0
    1569 #define R_PPC_ADDR32            1       /* 32bit absolute address */
    1570 #define R_PPC_ADDR24            2       /* 26bit address, 2 bits ignored.  */
    1571 #define R_PPC_ADDR16            3       /* 16bit absolute address */
    1572 #define R_PPC_ADDR16_LO         4       /* lower 16bit of absolute address */
    1573 #define R_PPC_ADDR16_HI         5       /* high 16bit of absolute address */
    1574 #define R_PPC_ADDR16_HA         6       /* adjusted high 16bit */
    1575 #define R_PPC_ADDR14            7       /* 16bit address, 2 bits ignored */
    1576 #define R_PPC_ADDR14_BRTAKEN    8
    1577 #define R_PPC_ADDR14_BRNTAKEN   9
    1578 #define R_PPC_REL24             10      /* PC relative 26 bit */
    1579 #define R_PPC_REL14             11      /* PC relative 16 bit */
    1580 #define R_PPC_REL14_BRTAKEN     12
    1581 #define R_PPC_REL14_BRNTAKEN    13
    1582 #define R_PPC_GOT16             14
    1583 #define R_PPC_GOT16_LO          15
    1584 #define R_PPC_GOT16_HI          16
    1585 #define R_PPC_GOT16_HA          17
    1586 #define R_PPC_PLTREL24          18
    1587 #define R_PPC_COPY              19
    1588 #define R_PPC_GLOB_DAT          20
    1589 #define R_PPC_JMP_SLOT          21
    1590 #define R_PPC_RELATIVE          22
    1591 #define R_PPC_LOCAL24PC         23
    1592 #define R_PPC_UADDR32           24
    1593 #define R_PPC_UADDR16           25
    1594 #define R_PPC_REL32             26
    1595 #define R_PPC_PLT32             27
    1596 #define R_PPC_PLTREL32          28
    1597 #define R_PPC_PLT16_LO          29
    1598 #define R_PPC_PLT16_HI          30
    1599 #define R_PPC_PLT16_HA          31
    1600 #define R_PPC_SDAREL16          32
    1601 #define R_PPC_SECTOFF           33
    1602 #define R_PPC_SECTOFF_LO        34
    1603 #define R_PPC_SECTOFF_HI        35
    1604 #define R_PPC_SECTOFF_HA        36
    1605 /* Keep this the last entry.  */
    1606 #define R_PPC_NUM               37
    1607 
    1608 /* The remaining relocs are from the Embedded ELF ABI, and are not
    1609    in the SVR4 ELF ABI.  */
    1610 #define R_PPC_EMB_NADDR32       101
    1611 #define R_PPC_EMB_NADDR16       102
    1612 #define R_PPC_EMB_NADDR16_LO    103
    1613 #define R_PPC_EMB_NADDR16_HI    104
    1614 #define R_PPC_EMB_NADDR16_HA    105
    1615 #define R_PPC_EMB_SDAI16        106
    1616 #define R_PPC_EMB_SDA2I16       107
    1617 #define R_PPC_EMB_SDA2REL       108
    1618 #define R_PPC_EMB_SDA21         109     /* 16 bit offset in SDA */
    1619 #define R_PPC_EMB_MRKREF        110
    1620 #define R_PPC_EMB_RELSEC16      111
    1621 #define R_PPC_EMB_RELST_LO      112
    1622 #define R_PPC_EMB_RELST_HI      113
    1623 #define R_PPC_EMB_RELST_HA      114
    1624 #define R_PPC_EMB_BIT_FLD       115
    1625 #define R_PPC_EMB_RELSDA        116     /* 16 bit relative offset in SDA */
    1626 
    1627 /* Diab tool relocations.  */
    1628 #define R_PPC_DIAB_SDA21_LO     180     /* like EMB_SDA21, but lower 16 bit */
    1629 #define R_PPC_DIAB_SDA21_HI     181     /* like EMB_SDA21, but high 16 bit */
    1630 #define R_PPC_DIAB_SDA21_HA     182     /* like EMB_SDA21, adjusted high 16 */
    1631 #define R_PPC_DIAB_RELSDA_LO    183     /* like EMB_RELSDA, but lower 16 bit */
    1632 #define R_PPC_DIAB_RELSDA_HI    184     /* like EMB_RELSDA, but high 16 bit */
    1633 #define R_PPC_DIAB_RELSDA_HA    185     /* like EMB_RELSDA, adjusted high 16 */
    1634 
    1635 /* This is a phony reloc to handle any old fashioned TOC16 references
    1636    that may still be in object files.  */
    1637 #define R_PPC_TOC16             255
    1638 
    1639 
    1640 /* ARM specific declarations */
    1641 
    1642 /* Processor specific flags for the ELF header e_flags field.  */
    1643 #define EF_ARM_RELEXEC     0x01
    1644 #define EF_ARM_HASENTRY    0x02
    1645 #define EF_ARM_INTERWORK   0x04
    1646 #define EF_ARM_APCS_26     0x08
    1647 #define EF_ARM_APCS_FLOAT  0x10
    1648 #define EF_ARM_PIC         0x20
    1649 #define EF_ALIGN8          0x40         /* 8-bit structure alignment is in use */
    1650 #define EF_NEW_ABI         0x80
    1651 #define EF_OLD_ABI         0x100
    1652 
    1653 /* Additional symbol types for Thumb */
    1654 #define STT_ARM_TFUNC      0xd
    1655 
    1656 /* ARM-specific values for sh_flags */
    1657 #define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
    1658 #define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
    1659                                            in the input to a link step */
    1660 
    1661 /* ARM-specific program header flags */
    1662 #define PF_ARM_SB          0x10000000   /* Segment contains the location
    1663                                            addressed by the static base */
    1664 
    1665 /* ARM relocs.  */
    1666 #define R_ARM_NONE              0       /* No reloc */
    1667 #define R_ARM_PC24              1       /* PC relative 26 bit branch */
    1668 #define R_ARM_ABS32             2       /* Direct 32 bit  */
    1669 #define R_ARM_REL32             3       /* PC relative 32 bit */
    1670 #define R_ARM_PC13              4
    1671 #define R_ARM_ABS16             5       /* Direct 16 bit */
    1672 #define R_ARM_ABS12             6       /* Direct 12 bit */
    1673 #define R_ARM_THM_ABS5          7
    1674 #define R_ARM_ABS8              8       /* Direct 8 bit */
    1675 #define R_ARM_SBREL32           9
    1676 #define R_ARM_THM_CALL          10
    1677 #define R_ARM_THM_PC8           11
    1678 #define R_ARM_AMP_VCALL9        12
    1679 #define R_ARM_SWI24             13
    1680 #define R_ARM_THM_SWI8          14
    1681 #define R_ARM_XPC25             15
    1682 #define R_ARM_THM_XPC22         16
    1683 #define R_ARM_COPY              20      /* Copy symbol at runtime */
    1684 #define R_ARM_GLOB_DAT          21      /* Create GOT entry */
    1685 #define R_ARM_JUMP_SLOT         22      /* Create PLT entry */
    1686 #define R_ARM_RELATIVE          23      /* Adjust by program base */
    1687 #define R_ARM_GOTOFF32          24      /* 32 bit offset to GOT */
    1688 #define R_ARM_BASE_PREL         25      /* 32 bit PC relative offset to GOT */
    1689 #define R_ARM_GOT_BREL          26      /* 32 bit GOT entry */
    1690 #define R_ARM_PLT32             27      /* 32 bit PLT address */
    1691 #define R_ARM_CALL              28
    1692 #define R_ARM_JUMP24            29
    1693 #define R_ARM_THM_JUMP24        30
    1694 #define R_ARM_V4BX              40
    1695 #define R_ARM_PREL31            42
    1696 #define R_ARM_MOVW_ABS_NC       43
    1697 #define R_ARM_MOVT_ABS          44
    1698 #define R_ARM_THM_MOVW_ABS_NC   47
    1699 #define R_ARM_THM_MOVT_ABS      48
    1700 #define R_ARM_GNU_VTENTRY       100
    1701 #define R_ARM_GNU_VTINHERIT     101
    1702 #define R_ARM_THM_PC11          102     /* thumb unconditional branch */
    1703 #define R_ARM_THM_PC9           103     /* thumb conditional branch */
    1704 #define R_ARM_RXPC25            249
    1705 #define R_ARM_RSBREL32          250
    1706 #define R_ARM_THM_RPC22         251
    1707 #define R_ARM_RREL32            252
    1708 #define R_ARM_RABS22            253
    1709 #define R_ARM_RPC24             254
    1710 #define R_ARM_RBASE             255
    1711 /* Keep this the last entry.  */
    1712 #define R_ARM_NUM               256
    1713 
    1714 /* TMS320C67xx specific declarations */
    1715 /* XXX: no ELF standard yet */
    1716 
    1717 /* TMS320C67xx relocs. */
    1718 #define R_C60_32       1
    1719 #define R_C60_GOT32     3               /* 32 bit GOT entry */
    1720 #define R_C60_PLT32     4               /* 32 bit PLT address */
    1721 #define R_C60_COPY      5               /* Copy symbol at runtime */
    1722 #define R_C60_GLOB_DAT  6               /* Create GOT entry */
    1723 #define R_C60_JMP_SLOT  7               /* Create PLT entry */
    1724 #define R_C60_RELATIVE  8               /* Adjust by program base */
    1725 #define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
    1726 #define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
    1727 
    1728 #define R_C60HI16      0x55       // high 16 bit MVKH embedded
    1729 #define R_C60LO16      0x54       // low 16 bit MVKL embedded
    1730 
    1731 #endif  /* elf.h */
     2884#define R_X86_64_PC64           24      /* PC relative 64 bit */
     2885#define R_X86_64_GOTOFF64       25      /* 64 bit offset to GOT */
     2886#define R_X86_64_GOTPC32        26      /* 32 bit signed pc relative
     2887                                           offset to GOT */
     2888#define R_X86_64_GOT64          27      /* 64-bit GOT entry offset */
     2889#define R_X86_64_GOTPCREL64     28      /* 64-bit PC relative offset
     2890                                           to GOT entry */
     2891#define R_X86_64_GOTPC64        29      /* 64-bit PC relative offset to GOT */
     2892#define R_X86_64_GOTPLT64       30      /* like GOT64, says PLT entry needed */
     2893#define R_X86_64_PLTOFF64       31      /* 64-bit GOT relative offset
     2894                                           to PLT entry */
     2895#define R_X86_64_SIZE32         32      /* Size of symbol plus 32-bit addend */
     2896#define R_X86_64_SIZE64         33      /* Size of symbol plus 64-bit addend */
     2897#define R_X86_64_GOTPC32_TLSDESC 34     /* GOT offset for TLS descriptor.  */
     2898#define R_X86_64_TLSDESC_CALL   35      /* Marker for call through TLS
     2899                                           descriptor.  */
     2900#define R_X86_64_TLSDESC        36      /* TLS descriptor.  */
     2901#define R_X86_64_IRELATIVE      37      /* Adjust indirectly by program base */
     2902#define R_X86_64_RELATIVE64     38      /* 64-bit adjust by program base */
     2903#define R_X86_64_GOTPCRELX      41      /* like GOTPCREL, but optionally with
     2904                                           linker optimizations */
     2905#define R_X86_64_REX_GOTPCRELX  42      /* like GOTPCRELX, but a REX prefix
     2906                                           is present */
     2907
     2908#define R_X86_64_NUM            43
     2909
     2910
     2911/* AM33 relocations.  */
     2912#define R_MN10300_NONE          0       /* No reloc.  */
     2913#define R_MN10300_32            1       /* Direct 32 bit.  */
     2914#define R_MN10300_16            2       /* Direct 16 bit.  */
     2915#define R_MN10300_8             3       /* Direct 8 bit.  */
     2916#define R_MN10300_PCREL32       4       /* PC-relative 32-bit.  */
     2917#define R_MN10300_PCREL16       5       /* PC-relative 16-bit signed.  */
     2918#define R_MN10300_PCREL8        6       /* PC-relative 8-bit signed.  */
     2919#define R_MN10300_GNU_VTINHERIT 7       /* Ancient C++ vtable garbage... */
     2920#define R_MN10300_GNU_VTENTRY   8       /* ... collection annotation.  */
     2921#define R_MN10300_24            9       /* Direct 24 bit.  */
     2922#define R_MN10300_GOTPC32       10      /* 32-bit PCrel offset to GOT.  */
     2923#define R_MN10300_GOTPC16       11      /* 16-bit PCrel offset to GOT.  */
     2924#define R_MN10300_GOTOFF32      12      /* 32-bit offset from GOT.  */
     2925#define R_MN10300_GOTOFF24      13      /* 24-bit offset from GOT.  */
     2926#define R_MN10300_GOTOFF16      14      /* 16-bit offset from GOT.  */
     2927#define R_MN10300_PLT32         15      /* 32-bit PCrel to PLT entry.  */
     2928#define R_MN10300_PLT16         16      /* 16-bit PCrel to PLT entry.  */
     2929#define R_MN10300_GOT32         17      /* 32-bit offset to GOT entry.  */
     2930#define R_MN10300_GOT24         18      /* 24-bit offset to GOT entry.  */
     2931#define R_MN10300_GOT16         19      /* 16-bit offset to GOT entry.  */
     2932#define R_MN10300_COPY          20      /* Copy symbol at runtime.  */
     2933#define R_MN10300_GLOB_DAT      21      /* Create GOT entry.  */
     2934#define R_MN10300_JMP_SLOT      22      /* Create PLT entry.  */
     2935#define R_MN10300_RELATIVE      23      /* Adjust by program base.  */
     2936#define R_MN10300_TLS_GD        24      /* 32-bit offset for global dynamic.  */
     2937#define R_MN10300_TLS_LD        25      /* 32-bit offset for local dynamic.  */
     2938#define R_MN10300_TLS_LDO       26      /* Module-relative offset.  */
     2939#define R_MN10300_TLS_GOTIE     27      /* GOT offset for static TLS block
     2940                                           offset.  */
     2941#define R_MN10300_TLS_IE        28      /* GOT address for static TLS block
     2942                                           offset.  */
     2943#define R_MN10300_TLS_LE        29      /* Offset relative to static TLS
     2944                                           block.  */
     2945#define R_MN10300_TLS_DTPMOD    30      /* ID of module containing symbol.  */
     2946#define R_MN10300_TLS_DTPOFF    31      /* Offset in module TLS block.  */
     2947#define R_MN10300_TLS_TPOFF     32      /* Offset in static TLS block.  */
     2948#define R_MN10300_SYM_DIFF      33      /* Adjustment for next reloc as needed
     2949                                           by linker relaxation.  */
     2950#define R_MN10300_ALIGN         34      /* Alignment requirement for linker
     2951                                           relaxation.  */
     2952#define R_MN10300_NUM           35
     2953
     2954
     2955/* M32R relocs.  */
     2956#define R_M32R_NONE             0       /* No reloc. */
     2957#define R_M32R_16               1       /* Direct 16 bit. */
     2958#define R_M32R_32               2       /* Direct 32 bit. */
     2959#define R_M32R_24               3       /* Direct 24 bit. */
     2960#define R_M32R_10_PCREL         4       /* PC relative 10 bit shifted. */
     2961#define R_M32R_18_PCREL         5       /* PC relative 18 bit shifted. */
     2962#define R_M32R_26_PCREL         6       /* PC relative 26 bit shifted. */
     2963#define R_M32R_HI16_ULO         7       /* High 16 bit with unsigned low. */
     2964#define R_M32R_HI16_SLO         8       /* High 16 bit with signed low. */
     2965#define R_M32R_LO16             9       /* Low 16 bit. */
     2966#define R_M32R_SDA16            10      /* 16 bit offset in SDA. */
     2967#define R_M32R_GNU_VTINHERIT    11
     2968#define R_M32R_GNU_VTENTRY      12
     2969/* M32R relocs use SHT_RELA.  */
     2970#define R_M32R_16_RELA          33      /* Direct 16 bit. */
     2971#define R_M32R_32_RELA          34      /* Direct 32 bit. */
     2972#define R_M32R_24_RELA          35      /* Direct 24 bit. */
     2973#define R_M32R_10_PCREL_RELA    36      /* PC relative 10 bit shifted. */
     2974#define R_M32R_18_PCREL_RELA    37      /* PC relative 18 bit shifted. */
     2975#define R_M32R_26_PCREL_RELA    38      /* PC relative 26 bit shifted. */
     2976#define R_M32R_HI16_ULO_RELA    39      /* High 16 bit with unsigned low */
     2977#define R_M32R_HI16_SLO_RELA    40      /* High 16 bit with signed low */
     2978#define R_M32R_LO16_RELA        41      /* Low 16 bit */
     2979#define R_M32R_SDA16_RELA       42      /* 16 bit offset in SDA */
     2980#define R_M32R_RELA_GNU_VTINHERIT       43
     2981#define R_M32R_RELA_GNU_VTENTRY 44
     2982#define R_M32R_REL32            45      /* PC relative 32 bit.  */
     2983
     2984#define R_M32R_GOT24            48      /* 24 bit GOT entry */
     2985#define R_M32R_26_PLTREL        49      /* 26 bit PC relative to PLT shifted */
     2986#define R_M32R_COPY             50      /* Copy symbol at runtime */
     2987#define R_M32R_GLOB_DAT         51      /* Create GOT entry */
     2988#define R_M32R_JMP_SLOT         52      /* Create PLT entry */
     2989#define R_M32R_RELATIVE         53      /* Adjust by program base */
     2990#define R_M32R_GOTOFF           54      /* 24 bit offset to GOT */
     2991#define R_M32R_GOTPC24          55      /* 24 bit PC relative offset to GOT */
     2992#define R_M32R_GOT16_HI_ULO     56      /* High 16 bit GOT entry with unsigned
     2993                                           low */
     2994#define R_M32R_GOT16_HI_SLO     57      /* High 16 bit GOT entry with signed
     2995                                           low */
     2996#define R_M32R_GOT16_LO         58      /* Low 16 bit GOT entry */
     2997#define R_M32R_GOTPC_HI_ULO     59      /* High 16 bit PC relative offset to
     2998                                           GOT with unsigned low */
     2999#define R_M32R_GOTPC_HI_SLO     60      /* High 16 bit PC relative offset to
     3000                                           GOT with signed low */
     3001#define R_M32R_GOTPC_LO         61      /* Low 16 bit PC relative offset to
     3002                                           GOT */
     3003#define R_M32R_GOTOFF_HI_ULO    62      /* High 16 bit offset to GOT
     3004                                           with unsigned low */
     3005#define R_M32R_GOTOFF_HI_SLO    63      /* High 16 bit offset to GOT
     3006                                           with signed low */
     3007#define R_M32R_GOTOFF_LO        64      /* Low 16 bit offset to GOT */
     3008#define R_M32R_NUM              256     /* Keep this the last entry. */
     3009
     3010
     3011/* TILEPro relocations.  */
     3012#define R_TILEPRO_NONE          0       /* No reloc */
     3013#define R_TILEPRO_32            1       /* Direct 32 bit */
     3014#define R_TILEPRO_16            2       /* Direct 16 bit */
     3015#define R_TILEPRO_8             3       /* Direct 8 bit */
     3016#define R_TILEPRO_32_PCREL      4       /* PC relative 32 bit */
     3017#define R_TILEPRO_16_PCREL      5       /* PC relative 16 bit */
     3018#define R_TILEPRO_8_PCREL       6       /* PC relative 8 bit */
     3019#define R_TILEPRO_LO16          7       /* Low 16 bit */
     3020#define R_TILEPRO_HI16          8       /* High 16 bit */
     3021#define R_TILEPRO_HA16          9       /* High 16 bit, adjusted */
     3022#define R_TILEPRO_COPY          10      /* Copy relocation */
     3023#define R_TILEPRO_GLOB_DAT      11      /* Create GOT entry */
     3024#define R_TILEPRO_JMP_SLOT      12      /* Create PLT entry */
     3025#define R_TILEPRO_RELATIVE      13      /* Adjust by program base */
     3026#define R_TILEPRO_BROFF_X1      14      /* X1 pipe branch offset */
     3027#define R_TILEPRO_JOFFLONG_X1   15      /* X1 pipe jump offset */
     3028#define R_TILEPRO_JOFFLONG_X1_PLT 16    /* X1 pipe jump offset to PLT */
     3029#define R_TILEPRO_IMM8_X0       17      /* X0 pipe 8-bit */
     3030#define R_TILEPRO_IMM8_Y0       18      /* Y0 pipe 8-bit */
     3031#define R_TILEPRO_IMM8_X1       19      /* X1 pipe 8-bit */
     3032#define R_TILEPRO_IMM8_Y1       20      /* Y1 pipe 8-bit */
     3033#define R_TILEPRO_MT_IMM15_X1   21      /* X1 pipe mtspr */
     3034#define R_TILEPRO_MF_IMM15_X1   22      /* X1 pipe mfspr */
     3035#define R_TILEPRO_IMM16_X0      23      /* X0 pipe 16-bit */
     3036#define R_TILEPRO_IMM16_X1      24      /* X1 pipe 16-bit */
     3037#define R_TILEPRO_IMM16_X0_LO   25      /* X0 pipe low 16-bit */
     3038#define R_TILEPRO_IMM16_X1_LO   26      /* X1 pipe low 16-bit */
     3039#define R_TILEPRO_IMM16_X0_HI   27      /* X0 pipe high 16-bit */
     3040#define R_TILEPRO_IMM16_X1_HI   28      /* X1 pipe high 16-bit */
     3041#define R_TILEPRO_IMM16_X0_HA   29      /* X0 pipe high 16-bit, adjusted */
     3042#define R_TILEPRO_IMM16_X1_HA   30      /* X1 pipe high 16-bit, adjusted */
     3043#define R_TILEPRO_IMM16_X0_PCREL 31     /* X0 pipe PC relative 16 bit */
     3044#define R_TILEPRO_IMM16_X1_PCREL 32     /* X1 pipe PC relative 16 bit */
     3045#define R_TILEPRO_IMM16_X0_LO_PCREL 33  /* X0 pipe PC relative low 16 bit */
     3046#define R_TILEPRO_IMM16_X1_LO_PCREL 34  /* X1 pipe PC relative low 16 bit */
     3047#define R_TILEPRO_IMM16_X0_HI_PCREL 35  /* X0 pipe PC relative high 16 bit */
     3048#define R_TILEPRO_IMM16_X1_HI_PCREL 36  /* X1 pipe PC relative high 16 bit */
     3049#define R_TILEPRO_IMM16_X0_HA_PCREL 37  /* X0 pipe PC relative ha() 16 bit */
     3050#define R_TILEPRO_IMM16_X1_HA_PCREL 38  /* X1 pipe PC relative ha() 16 bit */
     3051#define R_TILEPRO_IMM16_X0_GOT  39      /* X0 pipe 16-bit GOT offset */
     3052#define R_TILEPRO_IMM16_X1_GOT  40      /* X1 pipe 16-bit GOT offset */
     3053#define R_TILEPRO_IMM16_X0_GOT_LO 41    /* X0 pipe low 16-bit GOT offset */
     3054#define R_TILEPRO_IMM16_X1_GOT_LO 42    /* X1 pipe low 16-bit GOT offset */
     3055#define R_TILEPRO_IMM16_X0_GOT_HI 43    /* X0 pipe high 16-bit GOT offset */
     3056#define R_TILEPRO_IMM16_X1_GOT_HI 44    /* X1 pipe high 16-bit GOT offset */
     3057#define R_TILEPRO_IMM16_X0_GOT_HA 45    /* X0 pipe ha() 16-bit GOT offset */
     3058#define R_TILEPRO_IMM16_X1_GOT_HA 46    /* X1 pipe ha() 16-bit GOT offset */
     3059#define R_TILEPRO_MMSTART_X0    47      /* X0 pipe mm "start" */
     3060#define R_TILEPRO_MMEND_X0      48      /* X0 pipe mm "end" */
     3061#define R_TILEPRO_MMSTART_X1    49      /* X1 pipe mm "start" */
     3062#define R_TILEPRO_MMEND_X1      50      /* X1 pipe mm "end" */
     3063#define R_TILEPRO_SHAMT_X0      51      /* X0 pipe shift amount */
     3064#define R_TILEPRO_SHAMT_X1      52      /* X1 pipe shift amount */
     3065#define R_TILEPRO_SHAMT_Y0      53      /* Y0 pipe shift amount */
     3066#define R_TILEPRO_SHAMT_Y1      54      /* Y1 pipe shift amount */
     3067#define R_TILEPRO_DEST_IMM8_X1  55      /* X1 pipe destination 8-bit */
     3068/* Relocs 56-59 are currently not defined.  */
     3069#define R_TILEPRO_TLS_GD_CALL   60      /* "jal" for TLS GD */
     3070#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
     3071#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
     3072#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
     3073#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
     3074#define R_TILEPRO_TLS_IE_LOAD   65      /* "lw_tls" for TLS IE */
     3075#define R_TILEPRO_IMM16_X0_TLS_GD 66    /* X0 pipe 16-bit TLS GD offset */
     3076#define R_TILEPRO_IMM16_X1_TLS_GD 67    /* X1 pipe 16-bit TLS GD offset */
     3077#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
     3078#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
     3079#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
     3080#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
     3081#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
     3082#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
     3083#define R_TILEPRO_IMM16_X0_TLS_IE 74    /* X0 pipe 16-bit TLS IE offset */
     3084#define R_TILEPRO_IMM16_X1_TLS_IE 75    /* X1 pipe 16-bit TLS IE offset */
     3085#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
     3086#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
     3087#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
     3088#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
     3089#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
     3090#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
     3091#define R_TILEPRO_TLS_DTPMOD32  82      /* ID of module containing symbol */
     3092#define R_TILEPRO_TLS_DTPOFF32  83      /* Offset in TLS block */
     3093#define R_TILEPRO_TLS_TPOFF32   84      /* Offset in static TLS block */
     3094#define R_TILEPRO_IMM16_X0_TLS_LE 85    /* X0 pipe 16-bit TLS LE offset */
     3095#define R_TILEPRO_IMM16_X1_TLS_LE 86    /* X1 pipe 16-bit TLS LE offset */
     3096#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
     3097#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
     3098#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
     3099#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
     3100#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
     3101#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
     3102
     3103#define R_TILEPRO_GNU_VTINHERIT 128     /* GNU C++ vtable hierarchy */
     3104#define R_TILEPRO_GNU_VTENTRY   129     /* GNU C++ vtable member usage */
     3105
     3106#define R_TILEPRO_NUM           130
     3107
     3108
     3109/* TILE-Gx relocations.  */
     3110#define R_TILEGX_NONE           0       /* No reloc */
     3111#define R_TILEGX_64             1       /* Direct 64 bit */
     3112#define R_TILEGX_32             2       /* Direct 32 bit */
     3113#define R_TILEGX_16             3       /* Direct 16 bit */
     3114#define R_TILEGX_8              4       /* Direct 8 bit */
     3115#define R_TILEGX_64_PCREL       5       /* PC relative 64 bit */
     3116#define R_TILEGX_32_PCREL       6       /* PC relative 32 bit */
     3117#define R_TILEGX_16_PCREL       7       /* PC relative 16 bit */
     3118#define R_TILEGX_8_PCREL        8       /* PC relative 8 bit */
     3119#define R_TILEGX_HW0            9       /* hword 0 16-bit */
     3120#define R_TILEGX_HW1            10      /* hword 1 16-bit */
     3121#define R_TILEGX_HW2            11      /* hword 2 16-bit */
     3122#define R_TILEGX_HW3            12      /* hword 3 16-bit */
     3123#define R_TILEGX_HW0_LAST       13      /* last hword 0 16-bit */
     3124#define R_TILEGX_HW1_LAST       14      /* last hword 1 16-bit */
     3125#define R_TILEGX_HW2_LAST       15      /* last hword 2 16-bit */
     3126#define R_TILEGX_COPY           16      /* Copy relocation */
     3127#define R_TILEGX_GLOB_DAT       17      /* Create GOT entry */
     3128#define R_TILEGX_JMP_SLOT       18      /* Create PLT entry */
     3129#define R_TILEGX_RELATIVE       19      /* Adjust by program base */
     3130#define R_TILEGX_BROFF_X1       20      /* X1 pipe branch offset */
     3131#define R_TILEGX_JUMPOFF_X1     21      /* X1 pipe jump offset */
     3132#define R_TILEGX_JUMPOFF_X1_PLT 22      /* X1 pipe jump offset to PLT */
     3133#define R_TILEGX_IMM8_X0        23      /* X0 pipe 8-bit */
     3134#define R_TILEGX_IMM8_Y0        24      /* Y0 pipe 8-bit */
     3135#define R_TILEGX_IMM8_X1        25      /* X1 pipe 8-bit */
     3136#define R_TILEGX_IMM8_Y1        26      /* Y1 pipe 8-bit */
     3137#define R_TILEGX_DEST_IMM8_X1   27      /* X1 pipe destination 8-bit */
     3138#define R_TILEGX_MT_IMM14_X1    28      /* X1 pipe mtspr */
     3139#define R_TILEGX_MF_IMM14_X1    29      /* X1 pipe mfspr */
     3140#define R_TILEGX_MMSTART_X0     30      /* X0 pipe mm "start" */
     3141#define R_TILEGX_MMEND_X0       31      /* X0 pipe mm "end" */
     3142#define R_TILEGX_SHAMT_X0       32      /* X0 pipe shift amount */
     3143#define R_TILEGX_SHAMT_X1       33      /* X1 pipe shift amount */
     3144#define R_TILEGX_SHAMT_Y0       34      /* Y0 pipe shift amount */
     3145#define R_TILEGX_SHAMT_Y1       35      /* Y1 pipe shift amount */
     3146#define R_TILEGX_IMM16_X0_HW0   36      /* X0 pipe hword 0 */
     3147#define R_TILEGX_IMM16_X1_HW0   37      /* X1 pipe hword 0 */
     3148#define R_TILEGX_IMM16_X0_HW1   38      /* X0 pipe hword 1 */
     3149#define R_TILEGX_IMM16_X1_HW1   39      /* X1 pipe hword 1 */
     3150#define R_TILEGX_IMM16_X0_HW2   40      /* X0 pipe hword 2 */
     3151#define R_TILEGX_IMM16_X1_HW2   41      /* X1 pipe hword 2 */
     3152#define R_TILEGX_IMM16_X0_HW3   42      /* X0 pipe hword 3 */
     3153#define R_TILEGX_IMM16_X1_HW3   43      /* X1 pipe hword 3 */
     3154#define R_TILEGX_IMM16_X0_HW0_LAST 44   /* X0 pipe last hword 0 */
     3155#define R_TILEGX_IMM16_X1_HW0_LAST 45   /* X1 pipe last hword 0 */
     3156#define R_TILEGX_IMM16_X0_HW1_LAST 46   /* X0 pipe last hword 1 */
     3157#define R_TILEGX_IMM16_X1_HW1_LAST 47   /* X1 pipe last hword 1 */
     3158#define R_TILEGX_IMM16_X0_HW2_LAST 48   /* X0 pipe last hword 2 */
     3159#define R_TILEGX_IMM16_X1_HW2_LAST 49   /* X1 pipe last hword 2 */
     3160#define R_TILEGX_IMM16_X0_HW0_PCREL 50  /* X0 pipe PC relative hword 0 */
     3161#define R_TILEGX_IMM16_X1_HW0_PCREL 51  /* X1 pipe PC relative hword 0 */
     3162#define R_TILEGX_IMM16_X0_HW1_PCREL 52  /* X0 pipe PC relative hword 1 */
     3163#define R_TILEGX_IMM16_X1_HW1_PCREL 53  /* X1 pipe PC relative hword 1 */
     3164#define R_TILEGX_IMM16_X0_HW2_PCREL 54  /* X0 pipe PC relative hword 2 */
     3165#define R_TILEGX_IMM16_X1_HW2_PCREL 55  /* X1 pipe PC relative hword 2 */
     3166#define R_TILEGX_IMM16_X0_HW3_PCREL 56  /* X0 pipe PC relative hword 3 */
     3167#define R_TILEGX_IMM16_X1_HW3_PCREL 57  /* X1 pipe PC relative hword 3 */
     3168#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
     3169#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
     3170#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
     3171#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
     3172#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
     3173#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
     3174#define R_TILEGX_IMM16_X0_HW0_GOT 64    /* X0 pipe hword 0 GOT offset */
     3175#define R_TILEGX_IMM16_X1_HW0_GOT 65    /* X1 pipe hword 0 GOT offset */
     3176#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
     3177#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
     3178#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
     3179#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
     3180#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
     3181#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
     3182#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
     3183#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
     3184#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
     3185#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
     3186#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
     3187#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
     3188#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
     3189#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
     3190#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
     3191#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
     3192#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
     3193#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
     3194#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
     3195#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
     3196#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
     3197#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
     3198#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
     3199#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
     3200/* Relocs 90-91 are currently not defined.  */
     3201#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
     3202#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
     3203#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
     3204#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
     3205#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
     3206#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
     3207#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
     3208#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
     3209#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
     3210#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
     3211#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
     3212#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
     3213/* Relocs 104-105 are currently not defined.  */
     3214#define R_TILEGX_TLS_DTPMOD64   106     /* 64-bit ID of symbol's module */
     3215#define R_TILEGX_TLS_DTPOFF64   107     /* 64-bit offset in TLS block */
     3216#define R_TILEGX_TLS_TPOFF64    108     /* 64-bit offset in static TLS block */
     3217#define R_TILEGX_TLS_DTPMOD32   109     /* 32-bit ID of symbol's module */
     3218#define R_TILEGX_TLS_DTPOFF32   110     /* 32-bit offset in TLS block */
     3219#define R_TILEGX_TLS_TPOFF32    111     /* 32-bit offset in static TLS block */
     3220#define R_TILEGX_TLS_GD_CALL    112     /* "jal" for TLS GD */
     3221#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
     3222#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
     3223#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
     3224#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
     3225#define R_TILEGX_TLS_IE_LOAD    117     /* "ld_tls" for TLS IE */
     3226#define R_TILEGX_IMM8_X0_TLS_ADD 118    /* X0 pipe "addi" for TLS GD/IE */
     3227#define R_TILEGX_IMM8_X1_TLS_ADD 119    /* X1 pipe "addi" for TLS GD/IE */
     3228#define R_TILEGX_IMM8_Y0_TLS_ADD 120    /* Y0 pipe "addi" for TLS GD/IE */
     3229#define R_TILEGX_IMM8_Y1_TLS_ADD 121    /* Y1 pipe "addi" for TLS GD/IE */
     3230
     3231#define R_TILEGX_GNU_VTINHERIT  128     /* GNU C++ vtable hierarchy */
     3232#define R_TILEGX_GNU_VTENTRY    129     /* GNU C++ vtable member usage */
     3233
     3234#define R_TILEGX_NUM            130
     3235
     3236
     3237#endif  /* elf.h */
  • EcnlProtoTool/trunk/tcc-0.9.27/examples/ex3.c

    r321 r331  
    1 #include <stdlib.h>
    2 #include <stdio.h>
     1#include <tcclib.h>
    32
    43int fib(n)
  • EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.c

    r321 r331  
    2222#include "tcc.h"
    2323
    24 // #define NB_ASM_REGS 8
    2524#define MAX_OPERANDS 3
    26 #define NB_SAVED_REGS 3
    2725
    2826#define TOK_ASM_first TOK_ASM_clc
    2927#define TOK_ASM_last TOK_ASM_emms
    30 
    31 #define OPC_JMP        0x01  /* jmp operand */
    32 #define OPC_B          0x02  /* only used with OPC_WL */
    33 #define OPC_WL         0x04  /* accepts w, l or no suffix */
     28#define TOK_ASM_alllast TOK_ASM_subps
     29
     30#define OPC_B          0x01  /* only used with OPC_WL */
     31#define OPC_WL         0x02  /* accepts w, l or no suffix */
    3432#define OPC_BWL        (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
    35 #define OPC_REG        0x08 /* register is added to opcode */
    36 #define OPC_MODRM      0x10 /* modrm encoding */
    37 #define OPC_FWAIT      0x20 /* add fwait opcode */
    38 #define OPC_TEST       0x40 /* test opcodes */
    39 #define OPC_SHIFT      0x80 /* shift opcodes */
    40 #define OPC_D16      0x0100 /* generate data16 prefix */
    41 #define OPC_ARITH    0x0200 /* arithmetic opcodes */
    42 #define OPC_SHORTJMP 0x0400 /* short jmp operand */
    43 #define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
     33#define OPC_REG        0x04 /* register is added to opcode */
     34#define OPC_MODRM      0x08 /* modrm encoding */
     35
     36#define OPCT_MASK      0x70
     37#define OPC_FWAIT      0x10 /* add fwait opcode */
     38#define OPC_SHIFT      0x20 /* shift opcodes */
     39#define OPC_ARITH      0x30 /* arithmetic opcodes */
     40#define OPC_FARITH     0x40 /* FPU arithmetic opcodes */
     41#define OPC_TEST       0x50 /* test opcodes */
     42#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))
     43
     44#define OPC_0F        0x100 /* Is secondary map (0x0f prefix) */
     45#define OPC_48        0x200 /* Always has REX prefix */
    4446#ifdef TCC_TARGET_X86_64
    4547# define OPC_WLQ     0x1000  /* accepts w, l, q or no suffix */
    4648# define OPC_BWLQ    (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */
    4749# define OPC_WLX     OPC_WLQ
     50# define OPC_BWLX    OPC_BWLQ
    4851#else
    4952# define OPC_WLX     OPC_WL
     53# define OPC_BWLX    OPC_BWL
    5054#endif
    5155
     
    6872    OPT_SEG,
    6973    OPT_ST,
     74#ifdef TCC_TARGET_X86_64
     75    OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but
     76                     with REX prefix, not used in insn templates */
     77#endif
    7078    OPT_IM8,
    7179    OPT_IM8S,
     
    8391    /* composite types */
    8492    OPT_COMPOSITE_FIRST,
    85     OPT_IM,     /* IM8 | IM16 | IM32 | IM64 */
     93    OPT_IM,     /* IM8 | IM16 | IM32 */
    8694    OPT_REG,    /* REG8 | REG16 | REG32 | REG64 */
    8795    OPT_REGW,   /* REG16 | REG32 | REG64 */
    88     OPT_IMW,    /* IM16 | IM32 | IM64 */
    89 #ifdef TCC_TARGET_X86_64
    90     OPT_IMNO64, /* IM16 | IM32 */
    91 #endif
     96    OPT_IMW,    /* IM16 | IM32 */
     97    OPT_MMXSSE, /* MMX | SSE */
     98    OPT_DISP,   /* Like OPT_ADDR, but emitted as displacement (for jumps) */
     99    OPT_DISP8,  /* Like OPT_ADDR, but only 8bit (short jumps) */
    92100    /* can be ored with any OPT_xxx */
    93101    OPT_EA = 0x80
     
    115123#define OP_INDIR  (1 << OPT_INDIR)
    116124#ifdef TCC_TARGET_X86_64
    117 # define OP_REG64  (1 << OPT_REG64)
    118 # define OP_IM64   (1 << OPT_IM64)
     125# define OP_REG64 (1 << OPT_REG64)
     126# define OP_REG8_LOW (1 << OPT_REG8_LOW)
     127# define OP_IM64  (1 << OPT_IM64)
     128# define OP_EA32  (OP_EA << 1)
    119129#else
    120130# define OP_REG64 0
     131# define OP_REG8_LOW 0
    121132# define OP_IM64  0
     133# define OP_EA32  0
    122134#endif
    123135
     
    126138
    127139#ifdef TCC_TARGET_X86_64
    128 # define OP_IM      OP_IM64
    129140# define TREG_XAX   TREG_RAX
    130141# define TREG_XCX   TREG_RCX
    131142# define TREG_XDX   TREG_RDX
    132143#else
    133 # define OP_IM      OP_IM32
    134144# define TREG_XAX   TREG_EAX
    135145# define TREG_XCX   TREG_ECX
     
    211221static const ASMInstr asm_instrs[] = {
    212222#define ALT(x) x
     223/* This removes a 0x0f in the second byte */
     224#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
     225/* This constructs instr_type from opcode, type and group.  */
     226#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
    213227#define DEF_ASM_OP0(name, opcode)
    214 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
    215 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
    216 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
    217 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
     228#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 0, { 0 } },
     229#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 1, { op0 }},
     230#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }},
     231#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }},
    218232#ifdef TCC_TARGET_X86_64
    219233# include "x86_64-asm.h"
     
    242256{
    243257    int shift, v;
    244 #ifdef I386_ASM_16
    245     if (s1->seg_size == 16)
    246         tcc_error("invalid effective address");
    247 #endif
    248258    v = asm_int_expr(s1);
    249259    switch(v) {
     
    268278}
    269279
    270 static int asm_parse_reg(void)
     280#ifdef TCC_TARGET_X86_64
     281static int asm_parse_numeric_reg(int t, unsigned int *type)
     282{
     283    int reg = -1;
     284    if (t >= TOK_IDENT && t < tok_ident) {
     285        const char *s = table_ident[t - TOK_IDENT]->str;
     286        char c;
     287        *type = OP_REG64;
     288        if (*s == 'c') {
     289            s++;
     290            *type = OP_CR;
     291        }
     292        if (*s++ != 'r')
     293          return -1;
     294        /* Don't allow leading '0'.  */
     295        if ((c = *s++) >= '1' && c <= '9')
     296          reg = c - '0';
     297        else
     298          return -1;
     299        if ((c = *s) >= '0' && c <= '5')
     300          s++, reg = reg * 10 + c - '0';
     301        if (reg > 15)
     302          return -1;
     303        if ((c = *s) == 0)
     304          ;
     305        else if (*type != OP_REG64)
     306          return -1;
     307        else if (c == 'b' && !s[1])
     308          *type = OP_REG8;
     309        else if (c == 'w' && !s[1])
     310          *type = OP_REG16;
     311        else if (c == 'd' && !s[1])
     312          *type = OP_REG32;
     313        else
     314          return -1;
     315    }
     316    return reg;
     317}
     318#endif
     319
     320static int asm_parse_reg(unsigned int *type)
    271321{
    272322    int reg = 0;
     323    *type = 0;
    273324    if (tok != '%')
    274325        goto error_32;
     
    276327    if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
    277328        reg = tok - TOK_ASM_eax;
     329        *type = OP_REG32;
    278330#ifdef TCC_TARGET_X86_64
    279331    } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
    280332        reg = tok - TOK_ASM_rax;
    281 #endif
    282 #ifdef I386_ASM_16
    283     } else if (tok >= TOK_ASM_ax && tok <= TOK_ASM_di) {
    284         reg = tok - TOK_ASM_ax;
     333        *type = OP_REG64;
     334    } else if (tok == TOK_ASM_rip) {
     335        reg = -2; /* Probably should use different escape code. */
     336        *type = OP_REG64;
     337    } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0
     338               && (*type == OP_REG32 || *type == OP_REG64)) {
     339        ;
    285340#endif
    286341    } else {
     
    330385                if (tok != TOK_PPNUM)
    331386                    goto reg_error;
    332                 p = tokc.cstr->data;
     387                p = tokc.str.data;
    333388                reg = p[0] - '0';
    334389                if ((unsigned)reg >= 8 || p[1] != '\0')
     
    341396                op->type |= OP_ST0;
    342397            goto no_skip;
     398#ifdef TCC_TARGET_X86_64
     399        } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
     400            op->type = OP_REG8 | OP_REG8_LOW;
     401            op->reg = 4 + tok - TOK_ASM_spl;
     402        } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
     403            ;
     404#endif
    343405        } else {
    344406        reg_error:
    345             tcc_error("unknown register");
     407            tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
    346408        }
    347409        next();
     
    351413        next();
    352414        asm_expr(s1, &e);
    353         op->type = OP_IM;
    354         op->e.v = e.v;
    355         op->e.sym = e.sym;
     415        op->type = OP_IM32;
     416        op->e = e;
    356417        if (!op->e.sym) {
    357418            if (op->e.v == (uint8_t)op->e.v)
     
    362423                op->type |= OP_IM16;
    363424#ifdef TCC_TARGET_X86_64
    364             if (op->e.v == (uint32_t)op->e.v)
    365                 op->type |= OP_IM32;
     425            if (op->e.v != (int32_t)op->e.v && op->e.v != (uint32_t)op->e.v)
     426                op->type = OP_IM64;
    366427#endif
    367428        }
     
    374435        if (tok != '(') {
    375436            asm_expr(s1, &e);
    376             op->e.v = e.v;
    377             op->e.sym = e.sym;
     437            op->e = e;
    378438        } else {
    379439            next();
     
    391451                op->e.sym = e.sym;
    392452            }
     453            op->e.pcrel = 0;
    393454        }
    394455        if (tok == '(') {
     456            unsigned int type = 0;
    395457            next();
    396458            if (tok != ',') {
    397                 op->reg = asm_parse_reg();
     459                op->reg = asm_parse_reg(&type);
    398460            }
    399461            if (tok == ',') {
    400462                next();
    401463                if (tok != ',') {
    402                     op->reg2 = asm_parse_reg();
     464                    op->reg2 = asm_parse_reg(&type);
    403465                }
    404466                if (tok == ',') {
     
    407469                }
    408470            }
     471            if (type & OP_REG32)
     472                op->type |= OP_EA32;
    409473            skip(')');
    410474        }
     
    418482ST_FUNC void gen_expr32(ExprValue *pe)
    419483{
    420     gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
     484    if (pe->pcrel)
     485        /* If PC-relative, always set VT_SYM, even without symbol,
     486           so as to force a relocation to be emitted.  */
     487        gen_addrpc32(VT_SYM, pe->sym, pe->v);
     488    else
     489        gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
    421490}
    422491
    423492#ifdef TCC_TARGET_X86_64
    424 static void gen_expr64(ExprValue *pe)
     493ST_FUNC void gen_expr64(ExprValue *pe)
    425494{
    426495    gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
     
    432501{
    433502    Sym *sym = pe->sym;
    434     if (sym && sym->r == cur_text_section->sh_num) {
     503    ElfSym *esym = elfsym(sym);
     504    if (esym && esym->st_shndx == cur_text_section->sh_num) {
    435505        /* same section: we can output an absolute value. Note
    436506           that the TCC compiler behaves differently here because
    437507           it always outputs a relocation to ease (future) code
    438508           elimination in the linker */
    439         gen_le32(pe->v + sym->jnext - ind - 4);
     509        gen_le32(pe->v + esym->st_value - ind - 4);
    440510    } else {
    441511        if (sym && sym->type.t == VT_VOID) {
     
    447517}
    448518
    449 #ifdef I386_ASM_16
    450 static void gen_expr16(ExprValue *pe)
    451 {
    452     if (pe->sym)
    453         greloc(cur_text_section, pe->sym, ind, R_386_16);
    454     gen_le16(pe->v);
    455 }
    456 static void gen_disp16(ExprValue *pe)
    457 {
    458     Sym *sym;
    459     sym = pe->sym;
    460     if (sym) {
    461         if (sym->r == cur_text_section->sh_num) {
    462             /* same section: we can output an absolute value. Note
    463                that the TCC compiler behaves differently here because
    464                it always outputs a relocation to ease (future) code
    465                elimination in the linker */
    466             gen_le16(pe->v + sym->jnext - ind - 2);
    467         } else {
    468             greloc(cur_text_section, sym, ind, R_386_PC16);
    469             gen_le16(pe->v - 2);
    470         }
    471     } else {
    472         /* put an empty PC32 relocation */
    473         put_elf_reloc(symtab_section, cur_text_section,
    474                       ind, R_386_PC16, 0);
    475         gen_le16(pe->v - 2);
    476     }
    477 }
    478 #endif
    479 
    480519/* generate the modrm operand */
    481 static inline void asm_modrm(int reg, Operand *op)
     520static inline int asm_modrm(int reg, Operand *op)
    482521{
    483522    int mod, reg1, reg2, sib_reg1;
     
    487526    } else if (op->reg == -1 && op->reg2 == -1) {
    488527        /* displacement only */
    489 #ifdef I386_ASM_16
    490         if (tcc_state->seg_size == 16) {
    491             g(0x06 + (reg << 3));
    492             gen_expr16(&op->e);
    493         } else if (tcc_state->seg_size == 32)
    494 #endif
    495         {
    496             g(0x05 + (reg << 3));
    497             gen_expr32(&op->e);
    498         }
     528#ifdef TCC_TARGET_X86_64
     529        g(0x04 + (reg << 3));
     530        g(0x25);
     531#else
     532        g(0x05 + (reg << 3));
     533#endif
     534        gen_expr32(&op->e);
     535#ifdef TCC_TARGET_X86_64
     536    } else if (op->reg == -2) {
     537        ExprValue *pe = &op->e;
     538        g(0x05 + (reg << 3));
     539        gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
     540        return ind;
     541#endif
    499542    } else {
    500543        sib_reg1 = op->reg;
     
    514557        if (op->reg2 != -1)
    515558            reg1 = 4;
    516 #ifdef I386_ASM_16
    517         if (tcc_state->seg_size == 32) {
    518 #endif
    519559        g(mod + (reg << 3) + reg1);
    520560        if (reg1 == 4) {
     
    525565            g((op->shift << 6) + (reg2 << 3) + sib_reg1);
    526566        }
    527 #ifdef I386_ASM_16
    528         } else if (tcc_state->seg_size == 16) {
    529             /* edi = 7, esi = 6 --> di = 5, si = 4 */
    530             if ((reg1 == 6) || (reg1 == 7)) {
    531                 reg1 -= 2;
    532             /* ebx = 3 --> bx = 7 */
    533             } else if (reg1 == 3) {
    534                 reg1 = 7;
    535             /* o32 = 5 --> o16 = 6 */
    536             } else if (reg1 == 5) {
    537                 reg1 = 6;
    538             /* sib not valid in 16-bit mode */
    539             } else if (reg1 == 4) {
    540                 reg2 = op->reg2;
    541                 /* bp + si + offset */
    542                 if ((sib_reg1 == 5) && (reg2 == 6)) {
    543                     reg1 = 2;
    544                 /* bp + di + offset */
    545                 } else if ((sib_reg1 == 5) && (reg2 == 7)) {
    546                     reg1 = 3;
    547                 /* bx + si + offset */
    548                 } else if ((sib_reg1 == 3) && (reg2 == 6)) {
    549                     reg1 = 0;
    550                 /* bx + di + offset */
    551                 } else if ((sib_reg1 == 3) && (reg2 == 7)) {
    552                     reg1 = 1;
    553                 } else {
    554                     tcc_error("invalid effective address");
    555                 }
    556                 if (op->e.v == 0)
    557                     mod = 0;
    558             } else {
    559                 tcc_error("invalid register");
    560             }
    561             g(mod + (reg << 3) + reg1);
    562         }
    563 #endif
    564567        /* add offset */
    565568        if (mod == 0x40) {
    566569            g(op->e.v);
    567570        } else if (mod == 0x80 || op->reg == -1) {
    568 #ifdef I386_ASM_16
    569             if (tcc_state->seg_size == 16)
    570                 gen_expr16(&op->e);
    571             else if (tcc_state->seg_size == 32)
    572 #endif
    573                 gen_expr32(&op->e);
    574         }
     571            gen_expr32(&op->e);
     572        }
     573    }
     574    return 0;
     575}
     576
     577#ifdef TCC_TARGET_X86_64
     578#define REX_W 0x48
     579#define REX_R 0x44
     580#define REX_X 0x42
     581#define REX_B 0x41
     582
     583static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,
     584                    int regi, int rmi)
     585{
     586  unsigned char rex = width64 ? 0x48 : 0;
     587  int saw_high_8bit = 0;
     588  int i;
     589  if (rmi == -1) {
     590      /* No mod/rm byte, but we might have a register op nevertheless
     591         (we will add it to the opcode later).  */
     592      for(i = 0; i < nb_ops; i++) {
     593          if (op_type[i] & (OP_REG | OP_ST)) {
     594              if (ops[i].reg >= 8) {
     595                  rex |= REX_B;
     596                  ops[i].reg -= 8;
     597              } else if (ops[i].type & OP_REG8_LOW)
     598                  rex |= 0x40;
     599              else if (ops[i].type & OP_REG8 && ops[i].reg >= 4)
     600                  /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
     601                  saw_high_8bit = ops[i].reg;
     602              break;
     603          }
     604      }
     605  } else {
     606      if (regi != -1) {
     607          if (ops[regi].reg >= 8) {
     608              rex |= REX_R;
     609              ops[regi].reg -= 8;
     610          } else if (ops[regi].type & OP_REG8_LOW)
     611              rex |= 0x40;
     612          else if (ops[regi].type & OP_REG8 && ops[regi].reg >= 4)
     613              /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
     614              saw_high_8bit = ops[regi].reg;
     615      }
     616      if (ops[rmi].type & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_EA)) {
     617          if (ops[rmi].reg >= 8) {
     618              rex |= REX_B;
     619              ops[rmi].reg -= 8;
     620          } else if (ops[rmi].type & OP_REG8_LOW)
     621              rex |= 0x40;
     622          else if (ops[rmi].type & OP_REG8 && ops[rmi].reg >= 4)
     623              /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
     624              saw_high_8bit = ops[rmi].reg;
     625      }
     626      if (ops[rmi].type & OP_EA && ops[rmi].reg2 >= 8) {
     627          rex |= REX_X;
     628          ops[rmi].reg2 -= 8;
     629      }
     630  }
     631  if (rex) {
     632      if (saw_high_8bit)
     633          tcc_error("can't encode register %%%ch when REX prefix is required",
     634                    "acdb"[saw_high_8bit-4]);
     635      g(rex);
     636  }
     637}
     638#endif
     639
     640static void maybe_print_stats (void)
     641{
     642  static int already = 1;
     643  if (!already)
     644    /* print stats about opcodes */
     645    {
     646        const struct ASMInstr *pa;
     647        int freq[4];
     648        int op_vals[500];
     649        int nb_op_vals, i, j;
     650
     651        already = 1;
     652        nb_op_vals = 0;
     653        memset(freq, 0, sizeof(freq));
     654        for(pa = asm_instrs; pa->sym != 0; pa++) {
     655            freq[pa->nb_ops]++;
     656            //for(i=0;i<pa->nb_ops;i++) {
     657                for(j=0;j<nb_op_vals;j++) {
     658                    //if (pa->op_type[i] == op_vals[j])
     659                    if (pa->instr_type == op_vals[j])
     660                        goto found;
     661                }
     662                //op_vals[nb_op_vals++] = pa->op_type[i];
     663                op_vals[nb_op_vals++] = pa->instr_type;
     664            found: ;
     665            //}
     666        }
     667        for(i=0;i<nb_op_vals;i++) {
     668            int v = op_vals[i];
     669            //if ((v & (v - 1)) != 0)
     670                printf("%3d: %08x\n", i, v);
     671        }
     672        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
     673               (int)sizeof(asm_instrs),
     674               (int)sizeof(asm_instrs) / (int)sizeof(ASMInstr),
     675               freq[0], freq[1], freq[2], freq[3]);
    575676    }
    576677}
     
    579680{
    580681    const ASMInstr *pa;
    581     int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
     682    int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
    582683    int nb_ops, s;
    583684    Operand ops[MAX_OPERANDS], *pop;
    584685    int op_type[3]; /* decoded op type */
    585 #ifdef I386_ASM_16
    586     static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0;
    587 #endif
    588 
     686    int alltypes;   /* OR of all operand types */
     687    int autosize;
     688    int p66;
     689#ifdef TCC_TARGET_X86_64
     690    int rex64;
     691#endif
     692
     693    maybe_print_stats();
    589694    /* force synthetic ';' after prefix instruction, so we can handle */
    590695    /* one-line things like "rep stosb" instead of only "rep\nstosb" */
     
    596701    nb_ops = 0;
    597702    seg_prefix = 0;
     703    alltypes = 0;
    598704    for(;;) {
    599705        if (tok == ';' || tok == TOK_LINEFEED)
     
    609715           next();
    610716           parse_operand(s1, pop);
    611 #ifndef I386_ASM_16
    612717           if (!(pop->type & OP_EA)) {
    613718               tcc_error("segment prefix must be followed by memory reference");
    614719           }
    615 #endif
    616720        }
    617721        pop++;
     
    622726    }
    623727
    624     is_short_jmp = 0;
    625728    s = 0; /* avoid warning */
    626729
     730again:
    627731    /* optimize matching by using a lookup table (no hashing is needed
    628732       !) */
    629733    for(pa = asm_instrs; pa->sym != 0; pa++) {
     734        int it = pa->instr_type & OPCT_MASK;
    630735        s = 0;
    631         if (pa->instr_type & OPC_FARITH) {
     736        if (it == OPC_FARITH) {
    632737            v = opcode - pa->sym;
    633738            if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
    634739                continue;
    635         } else if (pa->instr_type & OPC_ARITH) {
     740        } else if (it == OPC_ARITH) {
    636741            if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX))
    637742                continue;
    638743            s = (opcode - pa->sym) % NBWLX;
    639         } else if (pa->instr_type & OPC_SHIFT) {
     744            if ((pa->instr_type & OPC_BWLX) == OPC_WLX)
     745              {
     746                /* We need to reject the xxxb opcodes that we accepted above.
     747                   Note that pa->sym for WLX opcodes is the 'w' token,
     748                   to get the 'b' token subtract one.  */
     749                if (((opcode - pa->sym + 1) % NBWLX) == 0)
     750                    continue;
     751                s++;
     752              }
     753        } else if (it == OPC_SHIFT) {
    640754            if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX))
    641755                continue;
    642756            s = (opcode - pa->sym) % NBWLX;
    643         } else if (pa->instr_type & OPC_TEST) {
     757        } else if (it == OPC_TEST) {
    644758            if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
    645759                continue;
     760            /* cmovxx is a test opcode but accepts multiple sizes.
     761               The suffixes aren't encoded in the table, instead we
     762               simply force size autodetection always and deal with suffixed
     763               variants below when we don't find e.g. "cmovzl".  */
     764            if (pa->instr_type & OPC_WLX)
     765                s = NBWLX - 1;
    646766        } else if (pa->instr_type & OPC_B) {
     767#ifdef TCC_TARGET_X86_64
     768            /* Some instructions don't have the full size but only
     769               bwl form.  insb e.g. */
     770            if ((pa->instr_type & OPC_WLQ) != OPC_WLQ
     771                && !(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
     772                continue;
     773#endif
    647774            if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX))
    648775                continue;
     
    658785        if (pa->nb_ops != nb_ops)
    659786            continue;
     787#ifdef TCC_TARGET_X86_64
     788        /* Special case for moves.  Selecting the IM64->REG64 form
     789           should only be done if we really have an >32bit imm64, and that
     790           is hardcoded.  Ignore it here.  */
     791        if (pa->opcode == 0xb0 && ops[0].type != OP_IM64
     792            && (ops[1].type & OP_REG) == OP_REG64
     793            && !(pa->instr_type & OPC_0F))
     794            continue;
     795#endif
    660796        /* now decode and check each operand */
     797        alltypes = 0;
    661798        for(i = 0; i < nb_ops; i++) {
    662799            int op1, op2;
     
    665802            switch(op2) {
    666803            case OPT_IM:
    667                 v = OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64;
     804                v = OP_IM8 | OP_IM16 | OP_IM32;
    668805                break;
    669806            case OPT_REG:
     
    674811                break;
    675812            case OPT_IMW:
    676                 v = OP_IM16 | OP_IM32 | OP_IM64;
    677                 break;
    678 #ifdef TCC_TARGET_X86_64
    679             case OPT_IMNO64:
    680813                v = OP_IM16 | OP_IM32;
    681814                break;
    682 #endif
     815            case OPT_MMXSSE:
     816                v = OP_MMX | OP_SSE;
     817                break;
     818            case OPT_DISP:
     819            case OPT_DISP8:
     820                v = OP_ADDR;
     821                break;
    683822            default:
    684823                v = 1 << op2;
     
    687826            if (op1 & OPT_EA)
    688827                v |= OP_EA;
    689             op_type[i] = v;
     828            op_type[i] = v;
    690829            if ((ops[i].type & v) == 0)
    691830                goto next;
     831            alltypes |= ops[i].type;
    692832        }
    693833        /* all is matching ! */
     
    699839            int b;
    700840            b = op0_codes[opcode - TOK_ASM_first];
    701 #ifdef I386_ASM_16
    702             if (opcode == TOK_ASM_o32) {
    703                 if (s1->seg_size == 32)
    704                     tcc_error("incorrect prefix");
    705                 else
    706                     o32 = data32 = 1;
    707             } else if (opcode == TOK_ASM_a32) {
    708                 if (s1->seg_size == 32)
    709                     tcc_error("incorrect prefix");
    710                 else
    711                     a32 = addr32 = 1;
    712             }
    713 #endif
    714841            if (b & 0xff00)
    715842                g(b >> 8);
    716843            g(b);
    717844            return;
     845        } else if (opcode <= TOK_ASM_alllast) {
     846            tcc_error("bad operand with opcode '%s'",
     847                  get_tok_str(opcode, NULL));
    718848        } else {
    719             tcc_error("unknown opcode '%s'",
    720                   get_tok_str(opcode, NULL));
     849            /* Special case for cmovcc, we accept size suffixes but ignore
     850               them, but we don't want them to blow up our tables.  */
     851            TokenSym *ts = table_ident[opcode - TOK_IDENT];
     852            if (ts->len >= 6
     853                && strchr("wlq", ts->str[ts->len-1])
     854                && !memcmp(ts->str, "cmov", 4)) {
     855                opcode = tok_alloc(ts->str, ts->len-1)->tok;
     856                goto again;
     857            }
     858            tcc_error("unknown opcode '%s'", ts->str);
    721859        }
    722860    }
    723861    /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
    724     if (s == NBWLX-1) {
    725         for(i = 0; s == NBWLX-1 && i < nb_ops; i++) {
     862    autosize = NBWLX-1;
     863#ifdef TCC_TARGET_X86_64
     864    /* XXX the autosize should rather be zero, to not have to adjust this
     865       all the time.  */
     866    if ((pa->instr_type & OPC_BWLQ) == OPC_B)
     867        autosize = NBWLX-2;
     868#endif
     869    if (s == autosize) {
     870        /* Check for register operands providing hints about the size.
     871           Start from the end, i.e. destination operands.  This matters
     872           only for opcodes accepting different sized registers, lar and lsl
     873           are such opcodes.  */
     874        for(i = nb_ops - 1; s == autosize && i >= 0; i--) {
    726875            if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
    727876                s = reg_to_size[ops[i].type & OP_REG];
    728877        }
    729         if (s == NBWLX-1) {
     878        if (s == autosize) {
    730879            if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
    731                 (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32 | OP_IM64)))
     880                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
    732881                s = 2;
     882            else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
     883                     (ops[0].type & OP_EA))
     884                s = NBWLX - 2;
    733885            else
    734886                tcc_error("cannot infer opcode suffix");
     
    736888    }
    737889
    738 #ifdef I386_ASM_16
     890#ifdef TCC_TARGET_X86_64
     891    /* Generate addr32 prefix if needed */
    739892    for(i = 0; i < nb_ops; i++) {
    740         if (ops[i].type & OP_REG32) {
    741             if (s1->seg_size == 16)
    742                 o32 = 1;
    743         } else if (!(ops[i].type & OP_REG32)) {
    744             if (s1->seg_size == 32)
    745                 o32 = 1;
    746         }
    747     }
    748 
    749 
    750     if (s == 1 || (pa->instr_type & OPC_D16)) {
    751         if (s1->seg_size == 32)
    752             o32 = 1;
    753     } else if (s == 2) {
    754         if (s1->seg_size == 16) {
    755             if (!(pa->instr_type & OPC_D16))
    756             o32 = 1;
    757         }
    758     }
    759 
    760     /* generate a16/a32 prefix if needed */
    761     if ((a32 == 1) && (addr32 == 0))
    762         g(0x67);
    763     /* generate o16/o32 prefix if needed */
    764     if ((o32 == 1) && (data32 == 0))
     893        if (ops[i].type & OP_EA32) {
     894            g(0x67);
     895            break;
     896        }
     897    }
     898#endif
     899    /* generate data16 prefix if needed */
     900    p66 = 0;
     901    if (s == 1)
     902        p66 = 1;
     903    else {
     904        /* accepting mmx+sse in all operands --> needs 0x66 to
     905           switch to sse mode.  Accepting only sse in an operand --> is
     906           already SSE insn and needs 0x66/f2/f3 handling.  */
     907        for (i = 0; i < nb_ops; i++)
     908            if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE)
     909                && ops[i].type & OP_SSE)
     910                p66 = 1;
     911    }
     912    if (p66)
    765913        g(0x66);
    766 
    767     addr32 = data32 = 0;
    768 #else
    769     /* generate data16 prefix if needed */
    770     if (s == 1 || (pa->instr_type & OPC_D16))
    771         g(0x66);
    772 #ifdef TCC_TARGET_X86_64
    773     else if (s == 3) {
     914#ifdef TCC_TARGET_X86_64
     915    rex64 = 0;
     916    if (pa->instr_type & OPC_48)
     917        rex64 = 1;
     918    else if (s == 3 || (alltypes & OP_REG64)) {
    774919        /* generate REX prefix */
    775         if ((opcode != TOK_ASM_push && opcode != TOK_ASM_pop)
    776             || !(ops[0].type & OP_REG64))
    777             g(0x48);
    778     }
    779 #endif
     920        int default64 = 0;
     921        for(i = 0; i < nb_ops; i++) {
     922            if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) {
     923                /* If only 64bit regs are accepted in one operand
     924                   this is a default64 instruction without need for
     925                   REX prefixes, except for movabs(0xb8).  */
     926                default64 = 1;
     927                break;
     928            }
     929        }
     930        /* XXX find better encoding for the default64 instructions.  */
     931        if (((opcode != TOK_ASM_push && opcode != TOK_ASM_pop
     932              && opcode != TOK_ASM_pushw && opcode != TOK_ASM_pushl
     933              && opcode != TOK_ASM_pushq && opcode != TOK_ASM_popw
     934              && opcode != TOK_ASM_popl && opcode != TOK_ASM_popq
     935              && opcode != TOK_ASM_call && opcode != TOK_ASM_jmp))
     936            && !default64)
     937            rex64 = 1;
     938    }
    780939#endif
    781940
    782941    /* now generates the operation */
    783     if (pa->instr_type & OPC_FWAIT)
     942    if (OPCT_IS(pa->instr_type, OPC_FWAIT))
    784943        g(0x9b);
    785944    if (seg_prefix)
     
    787946
    788947    v = pa->opcode;
     948    if (pa->instr_type & OPC_0F)
     949        v = ((v & ~0xff) << 8) | 0x0f00 | (v & 0xff);
    789950    if ((v == 0x69 || v == 0x6b) && nb_ops == 2) {
    790951        /* kludge for imul $im, %reg */
     
    806967        /* arith case */
    807968        v += ((opcode - TOK_ASM_addb) / NBWLX) << 3;
    808     } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
     969    } else if ((pa->instr_type & (OPCT_MASK | OPC_MODRM)) == OPC_FARITH) {
    809970        /* fpu arith case */
    810971        v += ((opcode - pa->sym) / 6) << 3;
    811972    }
     973
     974    /* search which operand will be used for modrm */
     975    modrm_index = -1;
     976    modreg_index = -1;
     977    if (pa->instr_type & OPC_MODRM) {
     978        if (!nb_ops) {
     979            /* A modrm opcode without operands is a special case (e.g. mfence).
     980               It has a group and acts as if there's an register operand 0
     981               (ax).  */
     982            i = 0;
     983            ops[i].type = OP_REG;
     984            ops[i].reg = 0;
     985            goto modrm_found;
     986        }
     987        /* first look for an ea operand */
     988        for(i = 0;i < nb_ops; i++) {
     989            if (op_type[i] & OP_EA)
     990                goto modrm_found;
     991        }
     992        /* then if not found, a register or indirection (shift instructions) */
     993        for(i = 0;i < nb_ops; i++) {
     994            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
     995                goto modrm_found;
     996        }
     997#ifdef ASM_DEBUG
     998        tcc_error("bad op table");
     999#endif
     1000    modrm_found:
     1001        modrm_index = i;
     1002        /* if a register is used in another operand then it is
     1003           used instead of group */
     1004        for(i = 0;i < nb_ops; i++) {
     1005            int t = op_type[i];
     1006            if (i != modrm_index &&
     1007                (t & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
     1008                modreg_index = i;
     1009                break;
     1010            }
     1011        }
     1012    }
     1013#ifdef TCC_TARGET_X86_64
     1014    asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
     1015#endif
     1016
    8121017    if (pa->instr_type & OPC_REG) {
     1018        /* mov $im, %reg case */
     1019        if (v == 0xb0 && s >= 1)
     1020            v += 7;
    8131021        for(i = 0; i < nb_ops; i++) {
    8141022            if (op_type[i] & (OP_REG | OP_ST)) {
     
    8171025            }
    8181026        }
    819         /* mov $im, %reg case */
    820         if (pa->opcode == 0xb0 && s >= 1)
    821             v += 7;
    8221027    }
    8231028    if (pa->instr_type & OPC_B)
    8241029        v += s >= 1;
    825     if (pa->instr_type & OPC_TEST)
    826         v += test_bits[opcode - pa->sym];
    827     if (pa->instr_type & OPC_SHORTJMP) {
    828         Sym *sym;
     1030    if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
     1031        ElfSym *esym;
    8291032        int jmp_disp;
    8301033
    8311034        /* see if we can really generate the jump with a byte offset */
    832         sym = ops[0].e.sym;
    833         if (!sym)
     1035        esym = elfsym(ops[0].e.sym);
     1036        if (!esym || esym->st_shndx != cur_text_section->sh_num)
    8341037            goto no_short_jump;
    835         if (sym->r != cur_text_section->sh_num)
    836             goto no_short_jump;
    837         jmp_disp = ops[0].e.v + sym->jnext - ind - 2;
     1038        jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
    8381039        if (jmp_disp == (int8_t)jmp_disp) {
    8391040            /* OK to generate jump */
    840             is_short_jmp = 1;
     1041            ops[0].e.sym = 0;
    8411042            ops[0].e.v = jmp_disp;
     1043            op_type[0] = OP_IM8S;
    8421044        } else {
    8431045        no_short_jump:
    844             if (pa->instr_type & OPC_JMP) {
    845                 /* long jump will be allowed. need to modify the
    846                    opcode slightly */
    847                 if (v == 0xeb)
    848                     v = 0xe9;
    849                 else
    850                     v += 0x0f10;
    851             } else {
    852                 tcc_error("invalid displacement");
    853             }
    854         }
    855     }
    856     op1 = v >> 8;
     1046            /* long jump will be allowed. need to modify the
     1047               opcode slightly */
     1048            if (v == 0xeb) /* jmp */
     1049                v = 0xe9;
     1050            else if (v == 0x70) /* jcc */
     1051                v += 0x0f10;
     1052            else
     1053                tcc_error("invalid displacement");
     1054        }
     1055    }
     1056    if (OPCT_IS(pa->instr_type, OPC_TEST))
     1057        v += test_bits[opcode - pa->sym];
     1058    op1 = v >> 16;
     1059    if (op1)
     1060        g(op1);
     1061    op1 = (v >> 8) & 0xff;
    8571062    if (op1)
    8581063        g(op1);
    8591064    g(v);
    8601065
    861     /* search which operand will used for modrm */
    862     modrm_index = 0;
    863     if (pa->instr_type & OPC_SHIFT) {
     1066    if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
    8641067        reg = (opcode - pa->sym) / NBWLX;
    8651068        if (reg == 6)
    8661069            reg = 7;
    867     } else if (pa->instr_type & OPC_ARITH) {
     1070    } else if (OPCT_IS(pa->instr_type, OPC_ARITH)) {
    8681071        reg = (opcode - pa->sym) / NBWLX;
    869     } else if (pa->instr_type & OPC_FARITH) {
     1072    } else if (OPCT_IS(pa->instr_type, OPC_FARITH)) {
    8701073        reg = (opcode - pa->sym) / 6;
    8711074    } else {
    8721075        reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
    8731076    }
     1077
     1078    pc = 0;
    8741079    if (pa->instr_type & OPC_MODRM) {
    875         /* first look for an ea operand */
    876         for(i = 0;i < nb_ops; i++) {
    877             if (op_type[i] & OP_EA)
    878                 goto modrm_found;
    879         }
    880         /* then if not found, a register or indirection (shift instructions) */
    881         for(i = 0;i < nb_ops; i++) {
    882             if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
    883                 goto modrm_found;
    884         }
    885 #ifdef ASM_DEBUG
    886         tcc_error("bad op table");
    887 #endif
    888     modrm_found:
    889         modrm_index = i;
    8901080        /* if a register is used in another operand then it is
    8911081           used instead of group */
    892         for(i = 0;i < nb_ops; i++) {
    893             v = op_type[i];
    894             if (i != modrm_index &&
    895                 (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
    896                 reg = ops[i].reg;
    897                 break;
    898             }
    899         }
    900 
    901         asm_modrm(reg, &ops[modrm_index]);
     1082        if (modreg_index >= 0)
     1083            reg = ops[modreg_index].reg;
     1084        pc = asm_modrm(reg, &ops[modrm_index]);
    9021085    }
    9031086
    9041087    /* emit constants */
    9051088#ifndef TCC_TARGET_X86_64
    906     if (pa->opcode == 0x9a || pa->opcode == 0xea) {
     1089    if (!(pa->instr_type & OPC_0F)
     1090        && (pa->opcode == 0x9a || pa->opcode == 0xea)) {
    9071091        /* ljmp or lcall kludge */
    908 #ifdef I386_ASM_16
    909         if (s1->seg_size == 16 && o32 == 0)
    910             gen_expr16(&ops[1].e);
    911         else
    912 #endif
    913             gen_expr32(&ops[1].e);
     1092        gen_expr32(&ops[1].e);
    9141093        if (ops[0].e.sym)
    9151094            tcc_error("cannot relocate");
     
    9331112                    v = OP_IM64;
    9341113            }
     1114
     1115            if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
     1116                tcc_error("cannot relocate");
     1117
    9351118            if (v & (OP_IM8 | OP_IM8S)) {
    936                 if (ops[i].e.sym)
    937                     goto error_relocate;
    9381119                g(ops[i].e.v);
    9391120            } else if (v & OP_IM16) {
    940 #ifdef I386_ASM_16
    941                 if (s1->seg_size == 16)
    942                     gen_expr16(&ops[i].e);
    943                 else
    944 #endif
    945                 if (ops[i].e.sym)
    946                 error_relocate:
    947                     tcc_error("cannot relocate");
    948                 else
    949                     gen_le16(ops[i].e.v);
     1121                gen_le16(ops[i].e.v);
     1122#ifdef TCC_TARGET_X86_64
     1123            } else if (v & OP_IM64) {
     1124                gen_expr64(&ops[i].e);
     1125#endif
     1126            } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
     1127                gen_disp32(&ops[i].e);
    9501128            } else {
    951                 if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
    952                     if (is_short_jmp)
    953                         g(ops[i].e.v);
    954 #ifdef I386_ASM_16
    955                     else if (s1->seg_size == 16)
    956                         gen_disp16(&ops[i].e);
    957 #endif
    958                     else
    959                         gen_disp32(&ops[i].e);
    960                 } else {
    961 #ifdef I386_ASM_16
    962                     if (s1->seg_size == 16 && !((o32 == 1) && (v & OP_IM32)))
    963                         gen_expr16(&ops[i].e);
    964                     else
    965 #endif
    966 #ifdef TCC_TARGET_X86_64
    967                     if (v & OP_IM64)
    968                         gen_expr64(&ops[i].e);
    969                     else
    970 #endif
    971                         gen_expr32(&ops[i].e);
    972                 }
     1129                gen_expr32(&ops[i].e);
    9731130            }
    974 #ifdef I386_ASM_16
    975         } else if (v & (OP_REG16 | OP_REG32)) {
    976             if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
    977                 /* jmp $r */
    978                 g(0xE0 + ops[i].reg);
    979             }
    980 #endif
    981 #ifdef TCC_TARGET_X86_64
    982         } else if (v & (OP_REG32 | OP_REG64)) {
    983             if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
    984                 /* jmp $r */
    985                 g(0xE0 + ops[i].reg);
    986             }
    987 #endif
    988         }
    989     }
    990 #ifdef I386_ASM_16
    991     a32 = o32 = 0;
    992 #endif
     1131        }
     1132    }
     1133
     1134    /* after immediate operands, adjust pc-relative address */
     1135    if (pc)
     1136        add32le(cur_text_section->data + pc - 4, pc - ind);
    9931137}
    9941138
     
    10221166            break;
    10231167        case 'r':
     1168        case 'R':
     1169        case 'p':
    10241170            pr = 3;
    10251171            break;
     
    10271173        case 'M':
    10281174        case 'I':
     1175        case 'e':
    10291176        case 'i':
    10301177        case 'm':
     
    10471194        p++;
    10481195    return p;
     1196}
     1197
     1198/* If T (a token) is of the form "%reg" returns the register
     1199   number and type, otherwise return -1.  */
     1200ST_FUNC int asm_parse_regvar (int t)
     1201{
     1202    const char *s;
     1203    Operand op;
     1204    if (t < TOK_IDENT)
     1205        return -1;
     1206    s = table_ident[t - TOK_IDENT]->str;
     1207    if (s[0] != '%')
     1208        return -1;
     1209    t = tok_alloc(s+1, strlen(s)-1)->tok;
     1210    unget_tok(t);
     1211    unget_tok('%');
     1212    parse_operand(tcc_state, &op);
     1213    /* Accept only integer regs for now.  */
     1214    if (op.type & OP_REG)
     1215        return op.reg;
     1216    else
     1217        return -1;
    10491218}
    10501219
     
    10911260            operands[k].input_index = i;
    10921261            op->priority = 5;
     1262        } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
     1263                   && op->vt->sym
     1264                   && (reg = op->vt->sym->r & VT_VALMASK) < VT_CONST) {
     1265            op->priority = 1;
     1266            op->reg = reg;
    10931267        } else {
    10941268            op->priority = constraint_priority(str);
     
    11381312            reg_mask = REG_IN_MASK;
    11391313        }
     1314        if (op->reg >= 0) {
     1315            if (is_reg_allocated(op->reg))
     1316                tcc_error("asm regvar requests register that's taken already");
     1317            reg = op->reg;
     1318            goto reg_found;
     1319        }
    11401320    try_next:
    11411321        c = *str++;
     
    11901370            goto try_next;
    11911371        case 'r':
     1372        case 'R':
     1373        case 'p': /* A general address, for x86(64) any register is acceptable*/
    11921374            /* any general register */
    11931375            for(reg = 0; reg < 8; reg++) {
     
    12021384            regs_allocated[reg] |= reg_mask;
    12031385            break;
     1386        case 'e':
    12041387        case 'i':
    12051388            if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
     
    12941477    r = sv->r;
    12951478    if ((r & VT_VALMASK) == VT_CONST) {
    1296         if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
     1479        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
     1480            modifier != 'P')
    12971481            cstr_ccat(add_str, '$');
    12981482        if (r & VT_SYM) {
    1299             cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
    1300             if (sv->c.i != 0) {
    1301                 cstr_ccat(add_str, '+');
    1302             } else {
    1303                 return;
    1304             }
     1483            const char *name = get_tok_str(sv->sym->v, NULL);
     1484            if (sv->sym->v >= SYM_FIRST_ANOM) {
     1485                /* In case of anonymous symbols ("L.42", used
     1486                   for static data labels) we can't find them
     1487                   in the C symbol table when later looking up
     1488                   this name.  So enter them now into the asm label
     1489                   list when we still know the symbol.  */
     1490                get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
     1491            }
     1492            cstr_cat(add_str, name, -1);
     1493            if ((uint32_t)sv->c.i == 0)
     1494                goto no_offset;
     1495            cstr_ccat(add_str, '+');
    13051496        }
    13061497        val = sv->c.i;
    13071498        if (modifier == 'n')
    13081499            val = -val;
    1309         snprintf(buf, sizeof(buf), "%d", sv->c.i);
    1310         cstr_cat(add_str, buf);
     1500        snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
     1501        cstr_cat(add_str, buf, -1);
     1502    no_offset:;
     1503#ifdef TCC_TARGET_X86_64
     1504        if (r & VT_LVAL)
     1505            cstr_cat(add_str, "(%rip)", -1);
     1506#endif
    13111507    } else if ((r & VT_VALMASK) == VT_LOCAL) {
    1312         snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
    1313         cstr_cat(add_str, buf);
     1508#ifdef TCC_TARGET_X86_64
     1509        snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i);
     1510#else
     1511        snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
     1512#endif
     1513        cstr_cat(add_str, buf, -1);
    13141514    } else if (r & VT_LVAL) {
    13151515        reg = r & VT_VALMASK;
     
    13171517            tcc_error("internal compiler error");
    13181518        snprintf(buf, sizeof(buf), "(%%%s)",
    1319                  get_tok_str(TOK_ASM_eax + reg, NULL));
    1320         cstr_cat(add_str, buf);
     1519#ifdef TCC_TARGET_X86_64
     1520                 get_tok_str(TOK_ASM_rax + reg, NULL)
     1521#else
     1522                 get_tok_str(TOK_ASM_eax + reg, NULL)
     1523#endif
     1524                 );
     1525        cstr_cat(add_str, buf, -1);
    13211526    } else {
    13221527        /* register case */
     
    13261531
    13271532        /* choose register operand size */
    1328         if ((sv->type.t & VT_BTYPE) == VT_BYTE)
     1533        if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
     1534            (sv->type.t & VT_BTYPE) == VT_BOOL)
    13291535            size = 1;
    13301536        else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
    13311537            size = 2;
    13321538#ifdef TCC_TARGET_X86_64
    1333         else if ((sv->type.t & VT_BTYPE) == VT_LLONG)
     1539        else if ((sv->type.t & VT_BTYPE) == VT_LLONG ||
     1540                 (sv->type.t & VT_BTYPE) == VT_PTR)
    13341541            size = 8;
    13351542#endif
     
    13491556        } else if (modifier == 'w') {
    13501557            size = 2;
     1558        } else if (modifier == 'k') {
     1559            size = 4;
    13511560#ifdef TCC_TARGET_X86_64
    13521561        } else if (modifier == 'q') {
     
    13751584        }
    13761585        snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
    1377         cstr_cat(add_str, buf);
     1586        cstr_cat(add_str, buf, -1);
    13781587    }
    13791588}
    13801589
    1381 /* generate prolog and epilog code for asm statment */
     1590/* generate prolog and epilog code for asm statement */
    13821591ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
    13831592                         int nb_outputs, int is_output,
     
    13881597    ASMOperand *op;
    13891598    int i, reg;
    1390     static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
     1599
     1600    /* Strictly speaking %Xbp and %Xsp should be included in the
     1601       call-preserved registers, but currently it doesn't matter.  */
     1602#ifdef TCC_TARGET_X86_64
     1603#ifdef TCC_TARGET_PE
     1604    static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 };
     1605#else
     1606    static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
     1607#endif
     1608#else
     1609    static uint8_t reg_saved[] = { 3, 6, 7 };
     1610#endif
    13911611
    13921612    /* mark all used registers */
     
    13991619    if (!is_output) {
    14001620        /* generate reg save code */
    1401         for(i = 0; i < NB_SAVED_REGS; i++) {
     1621        for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
    14021622            reg = reg_saved[i];
    14031623            if (regs_allocated[reg]) {
    1404 #ifdef I386_ASM_16
    1405                 if (tcc_state->seg_size == 16)
    1406                     g(0x66);
    1407 #endif
     1624                if (reg >= 8)
     1625                  g(0x41), reg-=8;
    14081626                g(0x50 + reg);
    14091627            }
     
    14201638                    SValue sv;
    14211639                    sv = *op->vt;
    1422                     sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
     1640                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
     1641                    sv.type.t = VT_PTR;
    14231642                    load(op->reg, &sv);
    14241643                } else if (i >= nb_outputs || op->is_rw) {
     
    14281647                        SValue sv;
    14291648                        sv = *op->vt;
    1430                         sv.c.ul += 4;
     1649                        sv.c.i += 4;
    14311650                        load(TREG_XDX, &sv);
    14321651                    }
     
    14441663                        sv = *op->vt;
    14451664                        sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
     1665                        sv.type.t = VT_PTR;
    14461666                        load(out_reg, &sv);
    14471667
     1668                        sv = *op->vt;
    14481669                        sv.r = (sv.r & ~VT_VALMASK) | out_reg;
    14491670                        store(op->reg, &sv);
     
    14541675                        SValue sv;
    14551676                        sv = *op->vt;
    1456                         sv.c.ul += 4;
     1677                        sv.c.i += 4;
    14571678                        store(TREG_XDX, &sv);
    14581679                    }
     
    14611682        }
    14621683        /* generate reg restore code */
    1463         for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
     1684        for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) {
    14641685            reg = reg_saved[i];
    14651686            if (regs_allocated[reg]) {
    1466 #ifdef I386_ASM_16
    1467                 if (tcc_state->seg_size == 16)
    1468                     g(0x66);
    1469 #endif
     1687                if (reg >= 8)
     1688                  g(0x41), reg-=8;
    14701689                g(0x58 + reg);
    14711690            }
     
    14781697    int reg;
    14791698    TokenSym *ts;
     1699#ifdef TCC_TARGET_X86_64
     1700    unsigned int type;
     1701#endif
    14801702
    14811703    if (!strcmp(str, "memory") ||
    1482         !strcmp(str, "cc"))
     1704        !strcmp(str, "cc") ||
     1705        !strcmp(str, "flags"))
    14831706        return;
    14841707    ts = tok_alloc(str, strlen(str));
     
    14911714    } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {
    14921715        reg -= TOK_ASM_rax;
     1716    } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {
     1717        ;
    14931718#endif
    14941719    } else {
  • EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.h

    r321 r331  
    3939
    4040     /* strings */
    41 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
    42 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
     41ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
     42ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
    4343
    4444ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
    4545ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
    4646
    47 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
    48 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
    49 
    50 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
    51 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
    52 
    53 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
    54 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
    55 
    56 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
    57 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
     47ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
     48ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
     49
     50ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
     51ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
     52
     53ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
     54ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
     55
     56ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
     57ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
    5858
    5959     /* bits */
    6060     
    61 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
    62 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
    63 
    64 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
    65 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
    66 
    67 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
    68 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
    69 
    70 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
    71 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
    72 
    73 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
    74 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
     61ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
     62ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
     63
     64ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     65ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
     66
     67ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     68ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
     69
     70ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     71ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
     72
     73ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     74ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
    7575
    7676     /* prefixes */
    7777     DEF_ASM_OP0(wait, 0x9b)
    7878     DEF_ASM_OP0(fwait, 0x9b)
    79 #ifdef I386_ASM_16
    80      DEF_ASM_OP0(a32, 0x67)
    81      DEF_ASM_OP0(o32, 0x66)
    82 #else
    8379     DEF_ASM_OP0(aword, 0x67)
    8480     DEF_ASM_OP0(addr16, 0x67)
    8581     ALT(DEF_ASM_OP0(word, 0x66))
    8682     DEF_ASM_OP0(data16, 0x66)
    87 #endif
    8883     DEF_ASM_OP0(lock, 0xf0)
    8984     DEF_ASM_OP0(rep, 0xf3)
     
    10398
    10499     /* NOTE: we took the same order as gas opcode definition order */
    105 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
    106 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
    107 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
    108 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
    109 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
    110 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
    111 
    112 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
    113 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
    114 
    115 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
    116 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
    117 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
    118 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
    119 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
    120 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
     100ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
     101ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR))
     102ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
     103ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
     104ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
     105ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
     106
     107ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
     108ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
     109
     110ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG32))
     111ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG32))
     112ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLX, OPT_TR, OPT_REG32))
     113ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_CR))
     114ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_DB))
     115ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_TR))
    121116
    122117ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
    123 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
     118ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
    124119ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
    125 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
     120ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
    126121ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
    127122
    128 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
    129 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
    130 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
    131 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
    132 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
    133 
    134 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
    135 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
    136 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
    137 
    138 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
    139 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
    140 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
    141 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
     123ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REGW))
     124ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
     125ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WLX, OPT_IM8S))
     126ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
     127ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
     128
     129ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REGW))
     130ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
     131ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
     132
     133ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
     134ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
     135ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
     136ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
    142137
    143138ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
     
    151146ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
    152147
    153 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
     148ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
    154149
    155150ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
     
    160155
    161156     /* arith */
    162 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
    163 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
    164 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
    165 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
    166 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
    167 
    168 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
    169 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
    170 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
    171 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
    172 
    173 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
    174 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    175 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
    176 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    177 
    178 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    179 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    180 
    181 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    182 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    183 
    184 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
    185 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
    186 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
    187 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
    188 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
    189 
    190 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    191 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
    192 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
    193 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
     157ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
     158ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
     159ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
     160ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
     161ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
     162
     163ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
     164ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
     165ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
     166ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
     167
     168ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLX, OPT_REGW))
     169ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     170ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLX, OPT_REGW))
     171ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     172
     173ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     174ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     175
     176ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     177ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     178
     179ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
     180ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
     181ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
     182ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
     183ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
     184
     185ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     186ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
     187ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     188ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
    194189
    195190     /* shifts */
    196 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
    197 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
    198 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
    199 
    200 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
    201 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
    202 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
    203 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
    204 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
    205 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
     191ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
     192ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
     193ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
     194
     195ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
     196ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
     197ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
     198ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
     199ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
     200ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
    206201
    207202ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
    208 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
     203ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
    209204ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
    210 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
    211 #ifdef I386_ASM_16
    212 ALT(DEF_ASM_OP1(jmp, 0xff, 0, OPC_JMP | OPC_WL, OPT_REGW))
    213 #endif
     205ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
    214206
    215207ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
    216 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
     208ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
    217209ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
    218 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
     210ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
    219211
    220212ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
    221213ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
     214ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
    222215    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
    223216    DEF_ASM_OP0(leave, 0xc9)
     
    229222ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
    230223
    231 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
    232     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
    233     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
    234     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
    235     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
    236     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
    237     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
     224ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
     225    DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
     226    DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
     227    DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
     228    DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
     229    DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
     230    DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8)
    238231     
    239232     /* float */
     
    349342    /* segments */
    350343    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
    351     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
     344ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
    352345    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
    353346    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
    354347    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
    355348    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
    356 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
     349ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
    357350    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
    358351    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
     
    364357    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
    365358
    366 #ifdef I386_ASM_16
    367     /* 386 */
    368     DEF_ASM_OP0(loadall386, 0x0f07)
    369 #endif
    370 
    371359    /* 486 */
    372360    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
    373 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
    374 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
     361ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
     362ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
    375363    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
    376364
    377365    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
    378     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
     366    DEF_ASM_OP2(boundw, 0x6662, 0, OPC_MODRM, OPT_REG16, OPT_EA)
    379367
    380368    /* pentium */
     
    382370   
    383371    /* pentium pro */
    384     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    385 #ifdef I386_ASM_16
    386 ALT(DEF_ASM_OP2(cmovno, 0x0f41, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    387 ALT(DEF_ASM_OP2(cmovc, 0x0f42, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    388 ALT(DEF_ASM_OP2(cmovnc, 0x0f43, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    389 ALT(DEF_ASM_OP2(cmovz, 0x0f44, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    390 ALT(DEF_ASM_OP2(cmovnz, 0x0f45, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    391 ALT(DEF_ASM_OP2(cmovna, 0x0f46, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    392 ALT(DEF_ASM_OP2(cmova, 0x0f47, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    393 #endif
     372ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
    394373    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
    395374    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
     
    408387    /* mmx */
    409388    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
    410 
    411     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
    412 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
     389    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
    413390    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
     391ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
    414392ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
    415     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    416     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    417     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    418     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    419     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    420     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    421     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    422     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    423     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    424     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    425     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    426     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    427     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    428     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    429     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    430     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    431     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    432     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    433     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    434     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    435     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    436     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    437     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    438 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
    439     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    440 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
    441     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    442 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
    443     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    444 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
    445     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    446 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
    447     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    448 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
    449     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    450 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
    451     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    452 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
    453     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    454     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    455     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    456     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    457     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    458     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    459     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    460     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    461     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    462     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    463     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    464     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    465     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    466     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
     393ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
     394ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
     395
     396    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     397    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     398    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     399    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     400    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     401    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     402    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     403    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     404    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     405    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     406    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     407    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     408    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     409    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     410    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     411    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     412    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     413    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     414    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     415    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     416    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     417    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     418    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     419ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     420    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     421ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     422    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     423ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     424    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     425ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     426    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     427ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     428    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     429ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     430    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     431ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     432    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     433ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     434    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     435    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     436    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     437    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     438    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     439    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     440    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     441    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     442    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     443    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     444    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     445    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     446    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     447    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     448
     449    /* sse */
     450    DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
     451ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
     452    DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
     453ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
     454    DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
     455ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
     456    DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     457    DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
     458    DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
     459    DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
     460    DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     461    DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     462    DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     463    DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     464    DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     465    DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     466    DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     467    DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     468    DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     469    DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     470    DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     471    DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     472    DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     473    DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
    467474
    468475#undef ALT
  • EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c

    r321 r331  
    2222
    2323/* number of available registers */
    24 #define NB_REGS         4
     24#define NB_REGS         5
    2525#define NB_ASM_REGS     8
     26#define CONFIG_TCC_ASM
    2627
    2728/* a register can belong to several classes. The classes must be
     
    3435#define RC_ECX     0x0010
    3536#define RC_EDX     0x0020
     37#define RC_EBX     0x0040
     38
    3639#define RC_IRET    RC_EAX /* function return: integer register */
    3740#define RC_LRET    RC_EDX /* function return: second integer register */
     
    4346    TREG_ECX,
    4447    TREG_EDX,
     48    TREG_EBX,
    4549    TREG_ST0,
     50    TREG_ESP = 4
    4651};
    4752
     
    5661/* defined if structures are passed as pointers. Otherwise structures
    5762   are directly pushed on stack. */
    58 //#define FUNC_STRUCT_PARAM_AS_PTR
     63/* #define FUNC_STRUCT_PARAM_AS_PTR */
    5964
    6065/* pointer size, in bytes */
     
    6772#define MAX_ALIGN     8
    6873
    69 
    70 #define psym oad
    71 
    72 /******************************************************/
    73 /* ELF defines */
    74 
    75 #define EM_TCC_TARGET EM_386
    76 
    77 /* relocation type for 32 bit data relocation */
    78 #define R_DATA_32   R_386_32
    79 #define R_DATA_PTR  R_386_32
    80 #define R_JMP_SLOT  R_386_JMP_SLOT
    81 #define R_COPY      R_386_COPY
    82 
    83 #define ELF_START_ADDR 0x08048000
    84 #define ELF_PAGE_SIZE  0x1000
    85 
    8674/******************************************************/
    8775#else /* ! TARGET_DEFS_ONLY */
     
    8977#include "tcc.h"
    9078
     79/* define to 1/0 to [not] have EBX as 4th register */
     80#define USE_EBX 0
     81
    9182ST_DATA const int reg_classes[NB_REGS] = {
    9283    /* eax */ RC_INT | RC_EAX,
    9384    /* ecx */ RC_INT | RC_ECX,
    9485    /* edx */ RC_INT | RC_EDX,
     86    /* ebx */ (RC_INT | RC_EBX) * USE_EBX,
    9587    /* st0 */ RC_FLOAT | RC_ST0,
    9688};
     
    9991static int func_ret_sub;
    10092#ifdef CONFIG_TCC_BCHECK
    101 static unsigned long func_bound_offset;
     93static addr_t func_bound_offset;
     94static unsigned long func_bound_ind;
    10295#endif
    10396
     
    10699{
    107100    int ind1;
     101    if (nocode_wanted)
     102        return;
    108103    ind1 = ind + 1;
    109104    if (ind1 > cur_text_section->data_allocated)
     
    138133ST_FUNC void gsym_addr(int t, int a)
    139134{
    140     int n, *ptr;
    141135    while (t) {
    142         ptr = (int *)(cur_text_section->data + t);
    143         n = *ptr; /* next value */
    144         *ptr = a - t - 4;
     136        unsigned char *ptr = cur_text_section->data + t;
     137        uint32_t n = read32le(ptr); /* next value */
     138        write32le(ptr, a - t - 4);
    145139        t = n;
    146140    }
     
    152146}
    153147
    154 /* psym is used to put an instruction with a data field which is a
    155    reference to a symbol. It is in fact the same as oad ! */
    156 #define psym oad
    157 
    158148/* instruction + 4 bytes data. Return the address of the data */
    159 ST_FUNC int oad(int c, int s)
    160 {
    161     int ind1;
    162 
     149static int oad(int c, int s)
     150{
     151    int t;
     152    if (nocode_wanted)
     153        return s;
    163154    o(c);
    164     ind1 = ind + 4;
    165     if (ind1 > cur_text_section->data_allocated)
    166         section_realloc(cur_text_section, ind1);
    167     *(int *)(cur_text_section->data + ind) = s;
    168     s = ind;
    169     ind = ind1;
    170     return s;
    171 }
     155    t = ind;
     156    gen_le32(s);
     157    return t;
     158}
     159
     160/* generate jmp to a label */
     161#define gjmp2(instr,lbl) oad(instr,lbl)
    172162
    173163/* output constant with relocation if 'r & VT_SYM' is true */
     
    186176}
    187177
    188 /* generate a modrm reference. 'op_reg' contains the addtionnal 3
     178/* generate a modrm reference. 'op_reg' contains the additional 3
    189179   opcode bits */
    190180static void gen_modrm(int op_reg, int r, Sym *sym, int c)
     
    221211
    222212    fr = sv->r;
    223     ft = sv->type.t;
    224     fc = sv->c.ul;
     213    ft = sv->type.t & ~VT_DEFSIGN;
     214    fc = sv->c.i;
     215
     216    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    225217
    226218    v = fr & VT_VALMASK;
     
    229221            v1.type.t = VT_INT;
    230222            v1.r = VT_LOCAL | VT_LVAL;
    231             v1.c.ul = fc;
     223            v1.c.i = fc;
    232224            fr = r;
    233225            if (!(reg_classes[fr] & RC_INT))
     
    244236            o(0xdb); /* fldt */
    245237            r = 5;
    246         } else if ((ft & VT_TYPE) == VT_BYTE) {
     238        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
    247239            o(0xbe0f);   /* movsbl */
    248240        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
     
    297289
    298290    ft = v->type.t;
    299     fc = v->c.ul;
     291    fc = v->c.i;
    300292    fr = v->r & VT_VALMASK;
     293    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    301294    bt = ft & VT_BTYPE;
    302295    /* XXX: incorrect if float reg to reg */
     
    338331}
    339332
     333#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
     334static void gen_static_call(int v)
     335{
     336    Sym *sym;
     337
     338    sym = external_global_sym(v, &func_old_type, 0);
     339    oad(0xe8, -4);
     340    greloc(cur_text_section, sym, ind-4, R_386_PC32);
     341}
     342#endif
     343
    340344/* 'is_jmp' is '1' if it is a jump */
    341345static void gcall_or_jmp(int is_jmp)
    342346{
    343347    int r;
    344     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    345         /* constant case */
    346         if (vtop->r & VT_SYM) {
    347             /* relocation case */
    348             greloc(cur_text_section, vtop->sym,
    349                    ind + 1, R_386_PC32);
    350         } else {
    351             /* put an empty PC32 relocation */
    352             put_elf_reloc(symtab_section, cur_text_section,
    353                           ind + 1, R_386_PC32, 0);
    354         }
    355         oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
     348    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
     349        /* constant and relocation case */
     350        greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
     351        oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
    356352    } else {
    357353        /* otherwise, indirect call */
     
    360356        o(0xd0 + r + (is_jmp << 4));
    361357    }
     358    if (!is_jmp) {
     359        int rt;
     360        /* extend the return value to the whole register if necessary
     361           visual studio and gcc do not always set the whole eax register
     362           when assigning the return value of a function  */
     363        rt = vtop->type.ref->type.t;
     364        switch (rt & VT_BTYPE) {
     365            case VT_BYTE:
     366                if (rt & VT_UNSIGNED) {
     367                    o(0xc0b60f); /* movzx %al, %eax */
     368                }
     369                else {
     370                    o(0xc0be0f); /* movsx %al, %eax */
     371                }
     372                break;
     373            case VT_SHORT:
     374                if (rt & VT_UNSIGNED) {
     375                    o(0xc0b70f); /* movzx %ax, %eax */
     376                }
     377                else {
     378                    o(0xc0bf0f); /* movsx %ax, %eax */
     379                }
     380                break;
     381            default:
     382                break;
     383        }
     384    }
    362385}
    363386
    364387static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
    365388static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
     389
     390/* Return the number of registers needed to return the struct, or 0 if
     391   returning via struct pointer. */
     392ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
     393{
     394#ifdef TCC_TARGET_PE
     395    int size, align;
     396    *ret_align = 1; // Never have to re-align return values for x86
     397    *regsize = 4;
     398    size = type_size(vt, &align);
     399    if (size > 8 || (size & (size - 1)))
     400        return 0;
     401    if (size == 8)
     402        ret->t = VT_LLONG;
     403    else if (size == 4)
     404        ret->t = VT_INT;
     405    else if (size == 2)
     406        ret->t = VT_SHORT;
     407    else
     408        ret->t = VT_BYTE;
     409    ret->ref = NULL;
     410    return 1;
     411#else
     412    *ret_align = 1; // Never have to re-align return values for x86
     413    return 0;
     414#endif
     415}
    366416
    367417/* Generate function call. The function address is pushed first, then
     
    422472    save_regs(0); /* save used temporary registers */
    423473    func_sym = vtop->type.ref;
    424     func_call = FUNC_CALL(func_sym->r);
     474    func_call = func_sym->f.func_call;
    425475    /* fast call case */
    426476    if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
     
    443493        }
    444494    }
     495#ifndef TCC_TARGET_PE
     496    else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
     497        args_size -= 4;
     498#endif
    445499    gcall_or_jmp(0);
    446500
    447 #ifdef TCC_TARGET_PE
    448     if ((func_sym->type.t & VT_BTYPE) == VT_STRUCT)
    449         args_size -= 4;
    450 #endif
    451     if (args_size && func_call != FUNC_STDCALL)
     501    if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
    452502        gadd_sp(args_size);
    453503    vtop--;
     
    455505
    456506#ifdef TCC_TARGET_PE
    457 #define FUNC_PROLOG_SIZE 10
     507#define FUNC_PROLOG_SIZE (10 + USE_EBX)
    458508#else
    459 #define FUNC_PROLOG_SIZE 9
     509#define FUNC_PROLOG_SIZE (9 + USE_EBX)
    460510#endif
    461511
     
    470520
    471521    sym = func_type->ref;
    472     func_call = FUNC_CALL(sym->r);
     522    func_call = sym->f.func_call;
    473523    addr = 8;
    474524    loc = 0;
     
    492542       implicit pointer parameter */
    493543    func_vt = sym->type;
     544    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
     545#ifdef TCC_TARGET_PE
     546    size = type_size(&func_vt,&align);
     547    if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
     548        && (size > 8 || (size & (size - 1)))) {
     549#else
    494550    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
     551#endif
    495552        /* XXX: fastcall case ? */
    496553        func_vc = addr;
     
    524581    }
    525582    func_ret_sub = 0;
    526     /* pascal type call ? */
    527     if (func_call == FUNC_STDCALL)
     583    /* pascal type call or fastcall ? */
     584    if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
    528585        func_ret_sub = addr - 8;
    529 #ifdef TCC_TARGET_PE
     586#ifndef TCC_TARGET_PE
    530587    else if (func_vc)
    531588        func_ret_sub = 4;
     
    535592    /* leave some room for bound checking code */
    536593    if (tcc_state->do_bounds_check) {
     594        func_bound_offset = lbounds_section->data_offset;
     595        func_bound_ind = ind;
    537596        oad(0xb8, 0); /* lbound section pointer */
    538597        oad(0xb8, 0); /* call to function */
    539         func_bound_offset = lbounds_section->data_offset;
    540598    }
    541599#endif
     
    545603ST_FUNC void gfunc_epilog(void)
    546604{
    547     int v, saved_ind;
     605    addr_t v, saved_ind;
    548606
    549607#ifdef CONFIG_TCC_BCHECK
    550608    if (tcc_state->do_bounds_check
    551609     && func_bound_offset != lbounds_section->data_offset) {
    552         int saved_ind;
    553         int *bounds_ptr;
    554         Sym *sym, *sym_data;
     610        addr_t saved_ind;
     611        addr_t *bounds_ptr;
     612        Sym *sym_data;
     613
    555614        /* add end of table info */
    556         bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
     615        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
    557616        *bounds_ptr = 0;
     617
    558618        /* generate bound local allocation */
    559619        saved_ind = ind;
    560         ind = func_sub_sp_offset;
     620        ind = func_bound_ind;
    561621        sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
    562622                               func_bound_offset, lbounds_section->data_offset);
     
    564624               ind + 1, R_386_32);
    565625        oad(0xb8, 0); /* mov %eax, xxx */
    566         sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
    567         greloc(cur_text_section, sym,
    568                ind + 1, R_386_PC32);
    569         oad(0xe8, -4);
     626        gen_static_call(TOK___bound_local_new);
    570627        ind = saved_ind;
     628
    571629        /* generate bound check local freeing */
    572630        o(0x5250); /* save returned value, if any */
    573         greloc(cur_text_section, sym_data,
    574                ind + 1, R_386_32);
     631        greloc(cur_text_section, sym_data, ind + 1, R_386_32);
    575632        oad(0xb8, 0); /* mov %eax, xxx */
    576         sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
    577         greloc(cur_text_section, sym,
    578                ind + 1, R_386_PC32);
    579         oad(0xe8, -4);
     633        gen_static_call(TOK___bound_local_delete);
    580634        o(0x585a); /* restore returned value, if any */
    581635    }
    582636#endif
     637
     638    /* align local size to word & save local variables */
     639    v = (-loc + 3) & -4;
     640
     641#if USE_EBX
     642    o(0x8b);
     643    gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
     644#endif
     645
    583646    o(0xc9); /* leave */
    584647    if (func_ret_sub == 0) {
     
    589652        g(func_ret_sub >> 8);
    590653    }
    591     /* align local size to word & save local variables */
    592    
    593     v = (-loc + 3) & -4;
    594654    saved_ind = ind;
    595655    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
    596656#ifdef TCC_TARGET_PE
    597657    if (v >= 4096) {
    598         Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
    599658        oad(0xb8, v); /* mov stacksize, %eax */
    600         oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
    601         greloc(cur_text_section, sym, ind-4, R_386_PC32);
     659        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
    602660    } else
    603661#endif
     
    606664        o(0xec81);  /* sub esp, stacksize */
    607665        gen_le32(v);
    608 #if FUNC_PROLOG_SIZE == 10
     666#ifdef TCC_TARGET_PE
    609667        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
    610668#endif
    611669    }
     670    o(0x53 * USE_EBX); /* push ebx */
    612671    ind = saved_ind;
    613672}
     
    616675ST_FUNC int gjmp(int t)
    617676{
    618     return psym(0xe9, t);
     677    return gjmp2(0xe9, t);
    619678}
    620679
     
    632691}
    633692
     693ST_FUNC void gtst_addr(int inv, int a)
     694{
     695    int v = vtop->r & VT_VALMASK;
     696    if (v == VT_CMP) {
     697        inv ^= (vtop--)->c.i;
     698        a -= ind + 2;
     699        if (a == (char)a) {
     700            g(inv - 32);
     701            g(a);
     702        } else {
     703            g(0x0f);
     704            oad(inv - 16, a - 4);
     705        }
     706    } else if ((v & ~1) == VT_JMP) {
     707        if ((v & 1) != inv) {
     708            gjmp_addr(a);
     709            gsym(vtop->c.i);
     710        } else {
     711            gsym(vtop->c.i);
     712            o(0x05eb);
     713            gjmp_addr(a);
     714        }
     715        vtop--;
     716    }
     717}
     718
    634719/* generate a test. set 'inv' to invert test. Stack entry is popped */
    635720ST_FUNC int gtst(int inv, int t)
    636721{
    637     int v, *p;
    638 
    639     v = vtop->r & VT_VALMASK;
    640     if (v == VT_CMP) {
     722    int v = vtop->r & VT_VALMASK;
     723    if (nocode_wanted) {
     724        ;
     725    } else if (v == VT_CMP) {
    641726        /* fast case : can jump directly since flags are set */
    642727        g(0x0f);
    643         t = psym((vtop->c.i - 16) ^ inv, t);
     728        t = gjmp2((vtop->c.i - 16) ^ inv, t);
    644729    } else if (v == VT_JMP || v == VT_JMPI) {
    645730        /* && or || optimization */
    646731        if ((v & 1) == inv) {
    647732            /* insert vtop->c jump list in t */
    648             p = &vtop->c.i;
    649             while (*p != 0)
    650                 p = (int *)(cur_text_section->data + *p);
    651             *p = t;
    652             t = vtop->c.i;
     733            uint32_t n1, n = vtop->c.i;
     734            if (n) {
     735                while ((n1 = read32le(cur_text_section->data + n)))
     736                    n = n1;
     737                write32le(cur_text_section->data + n, t);
     738                t = vtop->c.i;
     739            }
    653740        } else {
    654741            t = gjmp(t);
    655742            gsym(vtop->c.i);
    656         }
    657     } else {
    658         if (is_float(vtop->type.t) ||
    659             (vtop->type.t & VT_BTYPE) == VT_LLONG) {
    660             vpushi(0);
    661             gen_op(TOK_NE);
    662         }
    663         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    664             /* constant jmp optimization */
    665             if ((vtop->c.i != 0) != inv)
    666                 t = gjmp(t);
    667         } else {
    668             v = gv(RC_INT);
    669             o(0x85);
    670             o(0xc0 + v * 9);
    671             g(0x0f);
    672             t = psym(0x85 ^ inv, t);
    673743        }
    674744    }
     
    695765            if (c == (char)c) {
    696766                /* generate inc and dec for smaller code */
    697                 if (c==1 && opc==0) {
     767                if (c==1 && opc==0 && op != TOK_ADDC1) {
    698768                    o (0x40 | r); // inc
    699                 } else if (c==1 && opc==5) {
     769                } else if (c==1 && opc==5 && op != TOK_SUBC1) {
    700770                    o (0x48 | r); // dec
    701771                } else {
     
    789859        vtop--;
    790860        save_reg(TREG_EDX);
     861        /* save EAX too if used otherwise */
     862        save_reg_upstack(TREG_EAX, 1);
    791863        if (op == TOK_UMULL) {
    792864            o(0xf7); /* mul fr */
     
    816888
    817889/* generate a floating point operation 'v = t1 op t2' instruction. The
    818    two operands are guaranted to have the same floating point type */
     890   two operands are guaranteed to have the same floating point type */
    819891/* XXX: need to use ST1 too */
    820892ST_FUNC void gen_opf(int op)
     
    855927        if (swapped)
    856928            o(0xc9d9); /* fxch %st(1) */
    857         o(0xe9da); /* fucompp */
     929        if (op == TOK_EQ || op == TOK_NE)
     930            o(0xe9da); /* fucompp */
     931        else
     932            o(0xd9de); /* fcompp */
    858933        o(0xe0df); /* fnstsw %ax */
    859934        if (op == TOK_EQ) {
     
    901976        }
    902977        ft = vtop->type.t;
    903         fc = vtop->c.ul;
     978        fc = vtop->c.i;
    904979        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
    905980            o(0xde); /* fxxxp %st, %st(1) */
     
    913988                v1.type.t = VT_INT;
    914989                v1.r = VT_LOCAL | VT_LVAL;
    915                 v1.c.ul = fc;
     990                v1.c.i = fc;
    916991                load(r, &v1);
    917992                fc = 0;
     
    9591034
    9601035/* convert fp to int 't' type */
    961 /* XXX: handle long long case */
    9621036ST_FUNC void gen_cvt_ftoi(int t)
    9631037{
    964     int r, r2, size;
    965     Sym *sym;
    966     CType ushort_type;
    967 
    968     ushort_type.t = VT_SHORT | VT_UNSIGNED;
    969     ushort_type.ref = 0;
    970 
    971     gv(RC_FLOAT);
    972     if (t != VT_INT)
    973         size = 8;
    974     else
    975         size = 4;
    976    
    977     o(0x2dd9); /* ldcw xxx */
    978     sym = external_global_sym(TOK___tcc_int_fpu_control,
    979                               &ushort_type, VT_LVAL);
    980     greloc(cur_text_section, sym,
    981            ind, R_386_32);
    982     gen_le32(0);
    983    
    984     oad(0xec81, size); /* sub $xxx, %esp */
    985     if (size == 4)
    986         o(0x1cdb); /* fistpl */
     1038    int bt = vtop->type.t & VT_BTYPE;
     1039    if (bt == VT_FLOAT)
     1040        vpush_global_sym(&func_old_type, TOK___fixsfdi);
     1041    else if (bt == VT_LDOUBLE)
     1042        vpush_global_sym(&func_old_type, TOK___fixxfdi);
    9871043    else
    988         o(0x3cdf); /* fistpll */
    989     o(0x24);
    990     o(0x2dd9); /* ldcw xxx */
    991     sym = external_global_sym(TOK___tcc_fpu_control,
    992                               &ushort_type, VT_LVAL);
    993     greloc(cur_text_section, sym,
    994            ind, R_386_32);
    995     gen_le32(0);
    996 
    997     r = get_reg(RC_INT);
    998     o(0x58 + r); /* pop r */
    999     if (size == 8) {
    1000         if (t == VT_LLONG) {
    1001             vtop->r = r; /* mark reg as used */
    1002             r2 = get_reg(RC_INT);
    1003             o(0x58 + r2); /* pop r2 */
    1004             vtop->r2 = r2;
    1005         } else {
    1006             o(0x04c483); /* add $4, %esp */
    1007         }
    1008     }
    1009     vtop->r = r;
     1044        vpush_global_sym(&func_old_type, TOK___fixdfdi);
     1045    vswap();
     1046    gfunc_call(1);
     1047    vpushi(0);
     1048    vtop->r = REG_IRET;
     1049    vtop->r2 = REG_LRET;
    10101050}
    10111051
     
    10301070ST_FUNC void gen_bounded_ptr_add(void)
    10311071{
    1032     Sym *sym;
    1033 
    10341072    /* prepare fast i386 function call (args in eax and edx) */
    10351073    gv2(RC_EAX, RC_EDX);
     
    10381076    save_regs(0);
    10391077    /* do a fast function call */
    1040     sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
    1041     greloc(cur_text_section, sym,
    1042            ind + 1, R_386_PC32);
    1043     oad(0xe8, -4);
     1078    gen_static_call(TOK___bound_ptr_add);
    10441079    /* returned pointer is in eax */
    10451080    vtop++;
    10461081    vtop->r = TREG_EAX | VT_BOUNDED;
    10471082    /* address of bounding function call point */
    1048     vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
     1083    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
    10491084}
    10501085
     
    10531088ST_FUNC void gen_bounded_ptr_deref(void)
    10541089{
    1055     int func;
    1056     int size, align;
     1090    addr_t func;
     1091    int  size, align;
    10571092    Elf32_Rel *rel;
    10581093    Sym *sym;
     
    10831118    /* patch relocation */
    10841119    /* XXX: find a better solution ? */
    1085     rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
     1120    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
    10861121    sym = external_global_sym(func, &func_old_type, 0);
    10871122    if (!sym->c)
     
    10911126#endif
    10921127
     1128/* Save the stack pointer onto the stack */
     1129ST_FUNC void gen_vla_sp_save(int addr) {
     1130    /* mov %esp,addr(%ebp)*/
     1131    o(0x89);
     1132    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
     1133}
     1134
     1135/* Restore the SP from a location on the stack */
     1136ST_FUNC void gen_vla_sp_restore(int addr) {
     1137    o(0x8b);
     1138    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
     1139}
     1140
     1141/* Subtract from the stack pointer, and push the resulting value onto the stack */
     1142ST_FUNC void gen_vla_alloc(CType *type, int align) {
     1143#ifdef TCC_TARGET_PE
     1144    /* alloca does more than just adjust %rsp on Windows */
     1145    vpush_global_sym(&func_old_type, TOK_alloca);
     1146    vswap(); /* Move alloca ref past allocation size */
     1147    gfunc_call(1);
     1148#else
     1149    int r;
     1150    r = gv(RC_INT); /* allocation size */
     1151    /* sub r,%rsp */
     1152    o(0x2b);
     1153    o(0xe0 | r);
     1154    /* We align to 16 bytes rather than align */
     1155    /* and ~15, %esp */
     1156    o(0xf0e483);
     1157    vpop();
     1158#endif
     1159}
     1160
    10931161/* end of X86 code generator */
    10941162/*************************************************************/
  • EcnlProtoTool/trunk/tcc-0.9.27/i386-tok.h

    r321 r331  
    9292 DEF_ASM(gs)
    9393 DEF_ASM(st)
    94 
     94 DEF_ASM(rip)
     95
     96#ifdef TCC_TARGET_X86_64
     97 /* The four low parts of sp/bp/si/di that exist only on
     98    x86-64 (encoding aliased to ah,ch,dh,dh when not using REX). */
     99 DEF_ASM(spl)
     100 DEF_ASM(bpl)
     101 DEF_ASM(sil)
     102 DEF_ASM(dil)
     103#endif
    95104 /* generic two operands */
    96105 DEF_BWLX(mov)
     
    127136 DEF_BWLX(sar)
    128137
    129  DEF_ASM(shldw)
    130  DEF_ASM(shldl)
    131  DEF_ASM(shld)
    132  DEF_ASM(shrdw)
    133  DEF_ASM(shrdl)
    134  DEF_ASM(shrd)
     138 DEF_WLX(shld)
     139 DEF_WLX(shrd)
    135140
    136141 DEF_ASM(pushw)
     
    151156 DEF_BWL(out)
    152157
    153  DEF_WL(movzb)
     158 DEF_WLX(movzb)
    154159 DEF_ASM(movzwl)
    155160 DEF_ASM(movsbw)
     
    157162 DEF_ASM(movswl)
    158163#ifdef TCC_TARGET_X86_64
     164 DEF_ASM(movsbq)
     165 DEF_ASM(movswq)
     166 DEF_ASM(movzwq)
    159167 DEF_ASM(movslq)
    160168#endif
     
    173181 DEF_ASM(ljmp)
    174182
    175  DEF_ASMTEST(j)
    176 
    177  DEF_ASMTEST(set)
    178  DEF_ASMTEST(cmov)
     183 DEF_ASMTEST(j,)
     184
     185 DEF_ASMTEST(set,)
     186 DEF_ASMTEST(set,b)
     187 DEF_ASMTEST(cmov,)
    179188
    180189 DEF_WLX(bsf)
     
    185194 DEF_WLX(btc)
    186195
     196 DEF_WLX(lar)
    187197 DEF_WLX(lsl)
    188198
     
    192202
    193203 DEF_ASM(fcom)
    194  DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
     204 DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
    195205 DEF_FP1(com)
    196206
  • EcnlProtoTool/trunk/tcc-0.9.27/il-gen.c

    r321 r331  
    1818 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1919 */
    20 #ifdef TARGET_DEFS_ONLY
     20
     21#error this code has bit-rotted since 2003
    2122
    2223/* number of available registers */
    2324#define NB_REGS             3
    24 #define NB_ASM_REGS         8 // TODO:
    25 #define ELF_PAGE_SIZE  0x1000 // TODO:
    26 #define MAX_ALIGN           8 // TODO:
    27 #define R_DATA_32   R_386_32 // TODO:
    28 #define R_DATA_PTR  R_386_32 // TODO:
    29 #define R_JMP_SLOT  R_386_JMP_SLOT // TODO:
    30 #define R_COPY      R_386_COPY // TODO:
    31 #define ELF_START_ADDR 0x08048000 // TODO:
    32 #define EM_TCC_TARGET 0xFF // TODO:
    3325
    3426/* a register can belong to several classes. The classes must be
     
    5244};
    5345
     46const int reg_classes[NB_REGS] = {
     47    /* ST0 */ RC_ST | RC_ST0,
     48    /* ST1 */ RC_ST | RC_ST1,
     49    /* ST2 */ RC_ST,
     50};
     51
    5452/* return registers for function */
    5553#define REG_IRET REG_ST0 /* single word int return register */
     
    5856
    5957/* defined if function parameters must be evaluated in reverse order */
    60 //#define INVERT_FUNC_PARAMS
     58/* #define INVERT_FUNC_PARAMS */
    6159
    6260/* defined if structures are passed as pointers. Otherwise structures
    6361   are directly pushed on stack. */
    64 //#define FUNC_STRUCT_PARAM_AS_PTR
     62/* #define FUNC_STRUCT_PARAM_AS_PTR */
    6563
    6664/* pointer size, in bytes */
     
    8280
    8381enum ILOPCodes {
    84 #define ENUM_ILOPCODES_DEF
    8582#define OP(name, str, n) IL_OP_ ## name = n,
    8683#include "il-opcodes.h"
    8784#undef OP
    88 #undef ENUM_ILOPCODES_DEF
    8985};
    9086
    91 /******************************************************/
    92 #else /* ! TARGET_DEFS_ONLY */
    93  /******************************************************/
    94 #include "tcc.h"
    95 
    96 const int reg_classes[NB_REGS] = {
    97         /* ST0 */ RC_ST | RC_ST0,
    98         /* ST1 */ RC_ST | RC_ST1,
    99         /* ST2 */ RC_ST,
    100 };
    101 
    10287char *il_opcodes_str[] = {
    103 #define OP(name, str, n) /*[n] = */str,
     88#define OP(name, str, n) [n] = str,
    10489#include "il-opcodes.h"
    10590#undef OP
     
    115100static void out_byte(int c)
    116101{
    117     int ind1 = ind + 1;
    118     if (ind1 > cur_text_section->data_allocated)
    119         section_realloc(cur_text_section, ind1);
    120     *(char *)(cur_text_section->data + ind) = c;
    121     ind++;
     102    *(char *)ind++ = c;
    122103}
    123104
     
    219200    case VT_FUNC:
    220201        s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
    221         if (s == NULL)
    222             break;
    223         il_type_to_str(buf, buf_size, s->type.t, varstr);
     202        il_type_to_str(buf, buf_size, s->t, varstr);
    224203        pstrcat(buf, buf_size, "(");
    225204        sa = s->next;
    226205        while (sa != NULL) {
    227             il_type_to_str(buf1, sizeof(buf1), sa->type.t, NULL);
     206            il_type_to_str(buf1, sizeof(buf1), sa->t, NULL);
    228207            pstrcat(buf, buf_size, buf1);
    229208            sa = sa->next;
     
    235214    case VT_PTR:
    236215        s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
    237         if (s == NULL)
    238             break;
    239216        pstrcpy(buf1, sizeof(buf1), "*");
    240217        if (varstr)
    241218            pstrcat(buf1, sizeof(buf1), varstr);
    242         il_type_to_str(buf, buf_size, s->type.t, buf1);
     219        il_type_to_str(buf, buf_size, s->t, buf1);
    243220        goto no_var;
    244221    }
     
    250227}
    251228
    252 #define Reloc void
     229
    253230/* patch relocation entry with value 'val' */
    254231void greloc_patch1(Reloc *p, int val)
     
    285262    v = sv->r & VT_VALMASK;
    286263    fc = sv->c.i;
    287     ft = sv->type.t;
     264    ft = sv->t;
    288265
    289266    if (sv->r & VT_LVAL) {
     
    364341    v = sv->r & VT_VALMASK;
    365342    fc = sv->c.i;
    366     ft = sv->type.t;
     343    ft = sv->t;
    367344    if (v == VT_LOCAL) {
    368345        if (fc >= ARG_BASE) {
     
    412389void gfunc_param(GFuncContext *c)
    413390{
    414     if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
     391    if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
    415392        tcc_error("structures passed as value not handled yet");
    416393    } else {
     
    429406    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    430407        /* XXX: more info needed from tcc */
    431         il_type_to_str(buf, sizeof(buf), vtop->type.t, "xxx");
     408        il_type_to_str(buf, sizeof(buf), vtop->t, "xxx");
    432409        fprintf(il_outfile, " call %s\n", buf);
    433410    } else {
    434411        /* indirect call */
    435412        gv(RC_INT);
    436         il_type_to_str(buf, sizeof(buf), vtop->type.t, NULL);
     413        il_type_to_str(buf, sizeof(buf), vtop->t, NULL);
    437414        fprintf(il_outfile, " calli %s\n", buf);
    438415    }
     
    461438       
    462439    sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
    463     if (sym == NULL)
    464         return;
     440    func_call = sym->r;
    465441
    466442    addr = ARG_BASE;
    467443    /* if the function returns a structure, then add an
    468444       implicit pointer parameter */
    469     func_vt = sym->type;
    470     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
     445    func_vt = sym->t;
     446    func_var = (sym->c == FUNC_ELLIPSIS);
     447    if ((func_vt & VT_BTYPE) == VT_STRUCT) {
    471448        func_vc = addr;
    472449        addr++;
     
    474451    /* define parameters */
    475452    while ((sym = sym->next) != NULL) {
    476         u = sym->type.t;
     453        u = sym->t;
    477454        sym_push(sym->v & ~SYM_FIELD, u,
    478455                 VT_LOCAL | lvalue_type(sym->type.t), addr);
     
    555532            gsym(vtop->c.i);
    556533        }
    557     } else {
    558         if (is_float(vtop->type.t)) {
    559             vpushi(0);
    560             gen_op(TOK_NE);
    561         }
    562 #define VT_FORWARD 0
    563         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) {
    564             /* constant jmp optimization */
    565             if ((vtop->c.i != 0) != inv)
    566                 t = gjmp(t);
    567         } else {
    568             v = gv(RC_INT);
    569             t = out_opj(IL_OP_BRTRUE - inv, t);
    570         }
    571534    }
    572535    vtop--;
     
    640603
    641604/* generate a floating point operation 'v = t1 op t2' instruction. The
    642    two operands are guaranted to have the same floating point type */
     605   two operands are guaranteed to have the same floating point type */
    643606void gen_opf(int op)
    644607{
     
    690653}
    691654
    692 void ggoto(void) { }
    693 void gen_bounded_ptr_add(void) {}
    694 void gen_bounded_ptr_deref(int t) {}
    695 void gen_expr32(void) {}
    696 void asm_opcode(TCCState *s1, int opcode) {}
    697 void asm_compute_constraints(ASMOperand *operands,
    698         int nb_operands, int nb_outputs,
    699         const uint8_t *clobber_regs,
    700         int *pout_reg) {}
    701 void subst_asm_operand(CString *add_str,
    702         SValue *sv, int modifier) {}
    703 void asm_gen_code(ASMOperand *operands, int nb_operands,
    704         int nb_outputs, int is_output,
    705         uint8_t *clobber_regs,
    706         int out_reg) {}
    707 void asm_clobber(uint8_t *clobber_regs, const char *str) {}
    708 void gen_le32(int c) {}
    709 void g(int c) {}
    710 void gen_le16(int v) {}
    711 
    712655/* end of CIL code generator */
    713656/*************************************************************/
    714 #endif
    715 /*************************************************************/
     657
  • EcnlProtoTool/trunk/tcc-0.9.27/il-opcodes.h

    r321 r331  
    138138OP(CONV_R_UN, "conv.r.un", 0x76)
    139139OP(ANN_DATA_S, "ann.data.s", 0x77)
    140 #ifndef ENUM_ILOPCODES_DEF
    141 OP(0, NULL, 0x78)
    142 #endif
    143140OP(UNBOX, "unbox", 0x79)
    144141OP(THROW, "throw", 0x7a)
     
    183180OP(STELEM_R8, "stelem.r8", 0xa1)
    184181OP(STELEM_REF, "stelem.ref", 0xa2)
    185 #ifndef ENUM_ILOPCODES_DEF
    186 OP(0, NULL, 0xa3)
    187 OP(0, NULL, 0xa4)
    188 OP(0, NULL, 0xa5)
    189 OP(0, NULL, 0xa6)
    190 OP(0, NULL, 0xa7)
    191 OP(0, NULL, 0xa8)
    192 OP(0, NULL, 0xa9)
    193 OP(0, NULL, 0xaa)
    194 OP(0, NULL, 0xab)
    195 OP(0, NULL, 0xac)
    196 OP(0, NULL, 0xad)
    197 OP(0, NULL, 0xae)
    198 OP(0, NULL, 0xaf)
    199 OP(0, NULL, 0xb0)
    200 OP(0, NULL, 0xb1)
    201 OP(0, NULL, 0xb2)
    202 #endif
    203182OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3)
    204183OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4)
     
    209188OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9)
    210189OP(CONV_OVF_U8, "conv.ovf.u8", 0xba)
    211 #ifndef ENUM_ILOPCODES_DEF
    212 OP(0, NULL, 0xbb)
    213 OP(0, NULL, 0xbc)
    214 OP(0, NULL, 0xbd)
    215 OP(0, NULL, 0xbe)
    216 OP(0, NULL, 0xbf)
    217 OP(0, NULL, 0xc0)
    218 OP(0, NULL, 0xc1)
    219 #endif
    220190OP(REFANYVAL, "refanyval", 0xc2)
    221191OP(CKFINITE, "ckfinite", 0xc3)
    222 #ifndef ENUM_ILOPCODES_DEF
    223 OP(0, NULL, 0xc4)
    224 OP(0, NULL, 0xc5)
    225 #endif
    226192OP(MKREFANY, "mkrefany", 0xc6)
    227193OP(ANN_CALL, "ann.call", 0xc7)
     
    251217OP(STIND_I, "stind.i", 0xdf)
    252218OP(CONV_U, "conv.u", 0xe0)
    253 #ifndef ENUM_ILOPCODES_DEF
    254 OP(0, NULL, 0xe1)
    255 OP(0, NULL, 0xe2)
    256 OP(0, NULL, 0xe3)
    257 OP(0, NULL, 0xe4)
    258 OP(0, NULL, 0xe5)
    259 OP(0, NULL, 0xe6)
    260 OP(0, NULL, 0xe7)
    261 OP(0, NULL, 0xe8)
    262 OP(0, NULL, 0xe9)
    263 OP(0, NULL, 0xea)
    264 OP(0, NULL, 0xeb)
    265 OP(0, NULL, 0xec)
    266 OP(0, NULL, 0xed)
    267 OP(0, NULL, 0xee)
    268 OP(0, NULL, 0xef)
    269 OP(0, NULL, 0xf0)
    270 OP(0, NULL, 0xf1)
    271 OP(0, NULL, 0xf2)
    272 OP(0, NULL, 0xf3)
    273 OP(0, NULL, 0xf4)
    274 OP(0, NULL, 0xf5)
    275 OP(0, NULL, 0xf6)
    276 OP(0, NULL, 0xf7)
    277 OP(0, NULL, 0xf8)
    278 OP(0, NULL, 0xf9)
    279 OP(0, NULL, 0xfa)
    280 OP(0, NULL, 0xfb)
    281 OP(0, NULL, 0xfc)
    282 OP(0, NULL, 0xfd)
    283 OP(0, NULL, 0xfe)
    284 OP(0, NULL, 0xff)
    285 #endif
    286219
    287220/* prefix instructions. we use an opcode >= 256 to ease coding */
     
    303236OP(STLOC, "stloc", 0x10e)
    304237OP(LOCALLOC, "localloc", 0x10f)
    305 #ifndef ENUM_ILOPCODES_DEF
    306 OP(0, NULL, 0x110)
    307 #endif
    308238OP(ENDFILTER, "endfilter", 0x111)
    309239OP(UNALIGNED, "unaligned", 0x112)
     
    316246OP(ANN_REF, "ann.ref", 0x119)
    317247OP(RETHROW, "rethrow", 0x11a)
    318 #ifndef ENUM_ILOPCODES_DEF
    319 OP(0, NULL, 0x11b)
    320 #endif
    321248OP(SIZEOF, "sizeof", 0x11c)
    322249OP(REFANYTYPE, "refanytype", 0x11d)
    323 #ifndef ENUM_ILOPCODES_DEF
    324 OP(0, NULL, 0x11e)
    325 OP(0, NULL, 0x11f)
    326 OP(0, NULL, 0x120)
    327 OP(0, NULL, 0x121)
    328 #endif
    329250OP(ANN_DATA, "ann.data", 0x122)
    330251OP(ANN_ARG, "ann.arg", 0x123)
  • EcnlProtoTool/trunk/tcc-0.9.27/include/float.h

    r321 r331  
    2828
    2929/* horrible intel long double */
    30 #ifdef __i386__
     30#if defined __i386__ || defined __x86_64__
    3131
    3232#define LDBL_MANT_DIG 64
  • EcnlProtoTool/trunk/tcc-0.9.27/include/stdarg.h

    r321 r331  
    55#ifndef _WIN64
    66
    7 typedef void *va_list;
     7//This should be in sync with the declaration on our lib/libtcc1.c
     8/* GCC compatible definition of va_list. */
     9typedef struct {
     10    unsigned int gp_offset;
     11    unsigned int fp_offset;
     12    union {
     13        unsigned int overflow_offset;
     14        char *overflow_arg_area;
     15    };
     16    char *reg_save_area;
     17} __va_list_struct;
    818
    9 va_list __va_start(void *fp);
    10 void *__va_arg(va_list ap, int arg_type, int size);
    11 va_list __va_copy(va_list src);
    12 void __va_end(va_list ap);
     19typedef __va_list_struct va_list[1];
    1320
    14 #define va_start(ap, last) ((ap) = __va_start(__builtin_frame_address(0)))
     21void __va_start(__va_list_struct *ap, void *fp);
     22void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);
     23
     24#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0))
    1525#define va_arg(ap, type)                                                \
    16     (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type))))
    17 #define va_copy(dest, src) ((dest) = __va_copy(src))
    18 #define va_end(ap) __va_end(ap)
     26    (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type))))
     27#define va_copy(dest, src) (*(dest) = *(src))
     28#define va_end(ap)
     29
     30/* avoid conflicting definition for va_list on Macs. */
     31#define _VA_LIST_T
    1932
    2033#else /* _WIN64 */
    2134typedef char *va_list;
    22 #define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+7)&~7)
    23 #define va_arg(ap,type) (ap += (sizeof(type)+7)&~7, *(type *)(ap - ((sizeof(type)+7)&~7)))
     35#define va_start(ap,last) __builtin_va_start(ap,last)
     36#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
     37        ? **(t **)((ap += 8) - 8) : *(t  *)((ap += 8) - 8))
     38#define va_copy(dest, src) ((dest) = (src))
     39#define va_end(ap)
     40#endif
     41
     42#elif __arm__
     43typedef char *va_list;
     44#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x)
     45#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \
     46                               & ~(_tcc_alignof(type) - 1))
     47#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
     48#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
     49                        &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
    2450#define va_copy(dest, src) (dest) = (src)
    2551#define va_end(ap)
    26 #endif
     52
     53#elif defined(__aarch64__)
     54typedef struct {
     55    void *__stack;
     56    void *__gr_top;
     57    void *__vr_top;
     58    int   __gr_offs;
     59    int   __vr_offs;
     60} va_list;
     61#define va_start(ap, last) __va_start(ap, last)
     62#define va_arg(ap, type) __va_arg(ap, type)
     63#define va_end(ap)
     64#define va_copy(dest, src) ((dest) = (src))
    2765
    2866#else /* __i386__ */
  • EcnlProtoTool/trunk/tcc-0.9.27/include/stdbool.h

    r321 r331  
    77#define true    1
    88#define false   0
     9#define __bool_true_false_are_defined 1
    910
    1011#endif /* _STDBOOL_H */
  • EcnlProtoTool/trunk/tcc-0.9.27/include/stddef.h

    r321 r331  
    1414typedef signed short int int16_t;
    1515typedef signed int int32_t;
     16#ifdef __LP64__
     17typedef signed long int int64_t;
     18#else
    1619typedef signed long long int int64_t;
     20#endif
    1721typedef unsigned char uint8_t;
    1822typedef unsigned short int uint16_t;
    1923typedef unsigned int uint32_t;
     24#ifdef __LP64__
     25typedef unsigned long int uint64_t;
     26#else
    2027typedef unsigned long long int uint64_t;
    2128#endif
     29#endif
    2230
     31#ifndef NULL
    2332#define NULL ((void*)0)
     33#endif
     34
    2435#define offsetof(type, field) ((size_t)&((type *)0)->field)
    2536
     
    2738
    2839#endif
     40
     41/* Older glibc require a wint_t from <stddef.h> (when requested
     42   by __need_wint_t, as otherwise stddef.h isn't allowed to
     43   define this type).   Note that this must be outside the normal
     44   _STDDEF_H guard, so that it works even when we've included the file
     45   already (without requiring wint_t).  Some other libs define _WINT_T
     46   if they've already provided that type, so we can use that as guard.
     47   TCC defines __WINT_TYPE__ for us.  */
     48#if defined (__need_wint_t)
     49#ifndef _WINT_T
     50#define _WINT_T
     51typedef __WINT_TYPE__ wint_t;
     52#endif
     53#undef __need_wint_t
     54#endif
  • EcnlProtoTool/trunk/tcc-0.9.27/lib/Makefile

    r279 r331  
    55TOP = ..
    66include $(TOP)/Makefile
    7 VPATH = $(top_srcdir)/lib $(top_srcdir)/win32/lib
     7VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
     8T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
     9X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
     10BIN = $(TOP)/$(X)libtcc1.a
    811
    9 ifndef TARGET
    10  ifdef CONFIG_WIN64
    11   TARGET = x86_64-win32
    12  else
    13  ifdef CONFIG_WIN32
    14   TARGET = i386-win32
    15  else
    16  ifeq ($(ARCH),i386)
    17   TARGET = i386
    18   ifneq ($(TARGETOS),Darwin)
    19    XCC = $(CC)
    20   endif
    21  else
    22  ifeq ($(ARCH),x86-64)
    23   TARGET = x86_64
    24   ifneq ($(TARGETOS),Darwin)
    25    XCC = $(CC)
    26   endif
    27  endif
    28  endif
    29  endif
    30  endif
    31  BCHECK_O = bcheck.o
     12XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
     13XCC = $(XTCC)
     14XAR = $(XTCC) -ar
     15XFLAGS-unx = -B$(TOPSRC)
     16XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
     17XFLAGS = $(XFLAGS$(XCFG))
     18XCFG = $(or $(findstring -win,$T),-unx)
     19
     20# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
     21arm-libtcc1-usegcc ?= no
     22
     23ifeq "$($(T)-libtcc1-usegcc)" "yes"
     24 XCC = $(CC)
     25 XAR = $(AR)
     26 XFLAGS = $(CFLAGS) -fPIC
    3227endif
    3328
    34 DIR = $(TARGET)
     29# only for native compiler
     30$(X)BCHECK_O = bcheck.o
    3531
    36 native : ../libtcc1.a
    37 cross : $(DIR)/libtcc1.a
    38 
    39 native : TCC = $(TOP)/tcc$(EXESUF)
    40 cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
    41 
    42 I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
    43 X86_64_O = libtcc1.o alloca86_64.o
    44 WIN32_O = $(I386_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
    45 WIN64_O = $(X86_64_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
    46 
    47 ifeq "$(TARGET)" "i386-win32"
    48  OBJ = $(addprefix $(DIR)/,$(WIN32_O))
    49  TGT = -DTCC_TARGET_I386 -DTCC_TARGET_PE
    50  XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
    51  XAR = $(DIR)/tiny_libmaker$(EXESUF)
    52 else
    53 ifeq "$(TARGET)" "x86_64-win32"
    54  OBJ = $(addprefix $(DIR)/,$(WIN64_O))
    55  TGT = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
    56  XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
    57  XAR = $(DIR)/tiny_libmaker$(EXESUF)
    58 else
    59 ifeq "$(TARGET)" "i386"
    60  OBJ = $(addprefix $(DIR)/,$(I386_O))
    61  TGT = -DTCC_TARGET_I386
    62  XCC ?= $(TCC) -B$(TOP)
    63 else
    64 ifeq "$(TARGET)" "x86_64"
    65  OBJ = $(addprefix $(DIR)/,$(X86_64_O))
    66  TGT = -DTCC_TARGET_X86_64
    67  XCC ?= $(TCC) -B$(TOP)
    68 else
    69  $(error libtcc1.a not supported on target '$(TARGET)')
    70 endif
    71 endif
    72 endif
    73 endif
    74 
    75 XFLAGS = $(CPPFLAGS) $(CFLAGS) $(TGT)
    76 
    77 ifeq ($(TARGETOS),Darwin)
    78  XAR = $(DIR)/tiny_libmaker$(EXESUF)
    79  XFLAGS += -D_ANSI_SOURCE
     32ifeq ($(CONFIG_musl)$(CONFIG_uClibc),yes)
    8033 BCHECK_O =
    8134endif
    8235
    83 ifdef XAR
    84 AR = $(XAR)
     36ifdef CONFIG_OSX
     37 XFLAGS += -D_ANSI_SOURCE
    8538endif
    8639
    87 $(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
    88         $(AR) rcs $@ $(OBJ)
    89 $(DIR)/%.o : %.c
     40I386_O = libtcc1.o alloca86.o alloca86-bt.o
     41X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
     42ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
     43ARM64_O = lib-arm64.o
     44WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
     45
     46OBJ-i386 = $(I386_O) $(BCHECK_O)
     47OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O)
     48OBJ-x86_64-osx = $(X86_64_O) va_list.o
     49OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
     50OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
     51OBJ-arm64 = $(ARM64_O)
     52OBJ-arm = $(ARM_O)
     53OBJ-arm-fpa = $(ARM_O)
     54OBJ-arm-fpa-ld = $(ARM_O)
     55OBJ-arm-vfp = $(ARM_O)
     56OBJ-arm-eabi = $(ARM_O)
     57OBJ-arm-eabihf = $(ARM_O)
     58OBJ-arm-wince = $(ARM_O) $(WIN_O)
     59
     60$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
     61        $(XAR) rcs $@ $^
     62
     63$(X)%.o : %.c
    9064        $(XCC) -c $< -o $@ $(XFLAGS)
    91 $(DIR)/%.o : %.S
     65
     66$(X)%.o : %.S
    9267        $(XCC) -c $< -o $@ $(XFLAGS)
    93 $(DIR)/%$(EXESUF) : $(TOP)/win32/tools/%.c
    94         $(CC) -o $@ $< $(XFLAGS) $(LDFLAGS)
    9568
    96 $(OBJ) $(XAR) : $(DIR)/exists
    97 $(DIR)/exists :
    98         mkdir -p $(DIR)
    99         @echo $@ > $@
     69$(X)crt1w.o : crt1.c
     70$(X)wincrt1w.o : wincrt1.c
    10071
    10172clean :
    102         rm -rfv i386-win32 x86_64-win32 i386 x86_64
     73        rm -f *.a *.o $(BIN)
  • EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86-bt.S

    • Property svn:keywords deleted
    r279 r331  
    1212    jz      p6
    1313
    14 #ifdef TCC_TARGET_PE
     14#ifdef _WIN32
    1515p4:
    1616    cmp     $4096,%eax
    17     jle     p5
     17    jbe     p5
     18    test    %eax,-4096(%esp)
    1819    sub     $4096,%esp
    1920    sub     $4096,%eax
    20     test    %eax,(%esp)
    2121    jmp p4
    2222
  • EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86.S

    • Property svn:keywords deleted
    r279 r331  
    1111    jz      p3
    1212
    13 #ifdef TCC_TARGET_PE
     13#ifdef _WIN32
    1414p1:
    1515    cmp     $4096,%eax
    16     jle     p2
     16    jbe     p2
     17    test    %eax,-4096(%esp)
    1718    sub     $4096,%esp
    1819    sub     $4096,%eax
    19     test    %eax,(%esp)
    2020    jmp p1
    2121p2:
     
    2929    ret
    3030
    31 /* mark stack as nonexecutable */
    32 #if defined __ELF__ && defined __linux__
    33     .section    .note.GNU-stack,"",@progbits
    34 #endif
    3531/* ---------------------------------------------- */
  • EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64.S

    • Property svn:keywords deleted
    r279 r331  
    66alloca:
    77    pop     %rdx
    8 #ifdef TCC_TARGET_PE
     8#ifdef _WIN32
    99    mov     %rcx,%rax
    1010#else
     
    1515    jz      p3
    1616
    17 #ifdef TCC_TARGET_PE
     17#ifdef _WIN32
    1818p1:
    1919    cmp     $4096,%rax
    20     jle     p2
     20    jbe     p2
     21    test    %rax,-4096(%rsp)
    2122    sub     $4096,%rsp
    2223    sub     $4096,%rax
    23     test    %rax,(%rsp)
    2424    jmp p1
    2525p2:
     
    2828    sub     %rax,%rsp
    2929    mov     %rsp,%rax
    30 #ifdef TCC_TARGET_PE
    31     add     $32,%rax
    32 #endif
    33 
    3430p3:
    3531    push    %rdx
    3632    ret
    3733
    38 /* mark stack as nonexecutable */
    39 #if defined __ELF__ && defined __linux__
    40     .section    .note.GNU-stack,"",@progbits
    41 #endif
    4234/* ---------------------------------------------- */
  • EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c

    r321 r331  
    2222#include <stdarg.h>
    2323#include <string.h>
    24 #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) \
    25     && !defined(__DragonFly__) && !defined(__OpenBSD__)
     24
     25#if !defined(__FreeBSD__) \
     26 && !defined(__FreeBSD_kernel__) \
     27 && !defined(__DragonFly__) \
     28 && !defined(__OpenBSD__) \
     29 && !defined(__NetBSD__)
    2630#include <malloc.h>
    2731#endif
     32
    2833#if !defined(_WIN32)
    2934#include <unistd.h>
    3035#endif
    3136
    32 //#define BOUND_DEBUG
     37/* #define BOUND_DEBUG */
     38
     39#ifdef BOUND_DEBUG
     40 #define dprintf(a...) fprintf(a)
     41#else
     42 #define dprintf(a...)
     43#endif
    3344
    3445/* define so that bound array is static (faster, but use memory if
    3546   bound checking not used) */
    36 //#define BOUND_STATIC
     47/* #define BOUND_STATIC */
    3748
    3849/* use malloc hooks. Currently the code cannot be reliable if no hooks */
     
    4051#define HAVE_MEMALIGN
    4152
    42 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
    43     || defined(__DragonFly__) || defined(__dietlibc__) \
    44     || defined(__UCLIBC__) || defined(__OpenBSD__) \
    45     || defined(_WIN32) || defined(TCC_UCLIBC)
    46 #warning Bound checking does not support malloc (etc.) in this environment.
     53#if defined(__FreeBSD__) \
     54 || defined(__FreeBSD_kernel__) \
     55 || defined(__DragonFly__) \
     56 || defined(__OpenBSD__) \
     57 || defined(__NetBSD__) \
     58 || defined(__dietlibc__) \
     59 || defined(_WIN32)
     60//#warning Bound checking does not support malloc (etc.) in this environment.
    4761#undef CONFIG_TCC_MALLOC_HOOKS
    4862#undef HAVE_MEMALIGN
     
    5165#define BOUND_T1_BITS 13
    5266#define BOUND_T2_BITS 11
    53 #define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
    54 
    55 #define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
    56 #define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
    57 #define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
    58 #define BOUND_E_BITS  4
     67#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS)
     68#define BOUND_E_BITS  (sizeof(size_t))
     69
     70#define BOUND_T1_SIZE ((size_t)1 << BOUND_T1_BITS)
     71#define BOUND_T2_SIZE ((size_t)1 << BOUND_T2_BITS)
     72#define BOUND_T3_SIZE ((size_t)1 << BOUND_T3_BITS)
    5973
    6074#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
    61 #define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
     75#define BOUND_T23_SIZE ((size_t)1 << BOUND_T23_BITS)
    6276
    6377
     
    6579#define INVALID_POINTER ((void *)(-2))
    6680/* size of an empty region */
    67 #define EMPTY_SIZE        0xffffffff
     81#define EMPTY_SIZE  ((size_t)(-1))
    6882/* size of an invalid region */
    6983#define INVALID_SIZE      0
    7084
    7185typedef struct BoundEntry {
    72     unsigned long start;
    73     unsigned long size;
     86    size_t start;
     87    size_t size;
    7488    struct BoundEntry *next;
    75     unsigned long is_invalid; /* true if pointers outside region are invalid */
     89    size_t is_invalid; /* true if pointers outside region are invalid */
    7690} BoundEntry;
    7791
    7892/* external interface */
    7993void __bound_init(void);
    80 void __bound_new_region(void *p, unsigned long size);
     94void __bound_new_region(void *p, size_t size);
    8195int __bound_delete_region(void *p);
    8296
     97#ifdef __attribute__
     98  /* an __attribute__ macro is defined in the system headers */
     99  #undef __attribute__
     100#endif
    83101#define FASTCALL __attribute__((regparm(3)))
    84102
     
    105123
    106124/* runtime error output */
    107 extern void rt_error(unsigned long pc, const char *fmt, ...);
     125extern void rt_error(size_t pc, const char *fmt, ...);
    108126
    109127#ifdef BOUND_STATIC
     
    117135static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
    118136{
    119     unsigned long addr, tmp;
     137    size_t addr, tmp;
    120138    BoundEntry *e;
    121139
    122140    e = e1;
    123141    while (e != NULL) {
    124         addr = (unsigned long)p;
     142        addr = (size_t)p;
    125143        addr -= e->start;
    126144        if (addr <= e->size) {
     
    147165{
    148166    __bound_error_msg = fmt;
    149     *(int *)0 = 0; /* force a runtime error */
     167    fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt);
     168    *(void **)0 = 0; /* force a runtime error */
    150169}
    151170
     
    157176/* return '(p + offset)' for pointer arithmetic (a pointer can reach
    158177   the end of a region in this case */
    159 void * FASTCALL __bound_ptr_add(void *p, int offset)
    160 {
    161     unsigned long addr = (unsigned long)p;
     178void * FASTCALL __bound_ptr_add(void *p, size_t offset)
     179{
     180    size_t addr = (size_t)p;
    162181    BoundEntry *e;
    163 #if defined(BOUND_DEBUG)
    164     printf("add: 0x%x %d\n", (int)p, offset);
    165 #endif
     182
     183    dprintf(stderr, "%s %s: %p %x\n",
     184        __FILE__, __FUNCTION__, p, (unsigned)offset);
     185
     186    __bound_init();
    166187
    167188    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
     
    172193    if (addr > e->size) {
    173194        e = __bound_find_region(e, p);
    174         addr = (unsigned long)p - e->start;
     195        addr = (size_t)p - e->start;
    175196    }
    176197    addr += offset;
    177     if (addr > e->size)
     198    if (addr >= e->size) {
     199        fprintf(stderr,"%s %s: %p is outside of the region\n",
     200            __FILE__, __FUNCTION__, p + offset);
    178201        return INVALID_POINTER; /* return an invalid pointer */
     202    }
    179203    return p + offset;
    180204}
     
    183207   be strictly inside the region */
    184208#define BOUND_PTR_INDIR(dsize)                                          \
    185 void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset)        \
     209void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset)     \
    186210{                                                                       \
    187     unsigned long addr = (unsigned long)p;                              \
     211    size_t addr = (size_t)p;                                            \
    188212    BoundEntry *e;                                                      \
    189213                                                                        \
     214    dprintf(stderr, "%s %s: %p %x start\n",                             \
     215        __FILE__, __FUNCTION__, p, (unsigned)offset);                   \
     216                                                                        \
     217    __bound_init();                                                     \
    190218    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];            \
    191219    e = (BoundEntry *)((char *)e +                                      \
     
    195223    if (addr > e->size) {                                               \
    196224        e = __bound_find_region(e, p);                                  \
    197         addr = (unsigned long)p - e->start;                             \
     225        addr = (size_t)p - e->start;                                    \
    198226    }                                                                   \
    199227    addr += offset + dsize;                                             \
    200     if (addr > e->size)                                                 \
     228    if (addr > e->size) {                                               \
     229        fprintf(stderr,"%s %s: %p is outside of the region\n",          \
     230            __FILE__, __FUNCTION__, p + offset);                        \
    201231        return INVALID_POINTER; /* return an invalid pointer */         \
     232    }                                                                   \
     233    dprintf(stderr, "%s %s: return p+offset = %p\n",                    \
     234        __FILE__, __FUNCTION__, p + offset);                            \
    202235    return p + offset;                                                  \
    203236}
     
    210243BOUND_PTR_INDIR(16)
    211244
     245#if defined(__GNUC__) && (__GNUC__ >= 6)
     246/*
     247 * At least gcc 6.2 complains when __builtin_frame_address is used with
     248 * nonzero argument.
     249 */
     250#pragma GCC diagnostic push
     251#pragma GCC diagnostic ignored "-Wframe-address"
     252#endif
     253
    212254/* return the frame pointer of the caller */
    213255#define GET_CALLER_FP(fp)\
    214256{\
    215     fp = (unsigned long)__builtin_frame_address(1);\
     257    fp = (size_t)__builtin_frame_address(1);\
    216258}
    217259
     
    219261void FASTCALL __bound_local_new(void *p1)
    220262{
    221     unsigned long addr, size, fp, *p = p1;
     263    size_t addr, size, fp, *p = p1;
     264
     265    dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p);
    222266    GET_CALLER_FP(fp);
    223267    for(;;) {
     
    230274        __bound_new_region((void *)addr, size);
    231275    }
     276    dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
    232277}
    233278
     
    235280void FASTCALL __bound_local_delete(void *p1)
    236281{
    237     unsigned long addr, fp, *p = p1;
     282    size_t addr, fp, *p = p1;
    238283    GET_CALLER_FP(fp);
    239284    for(;;) {
     
    247292}
    248293
     294#if defined(__GNUC__) && (__GNUC__ >= 6)
     295#pragma GCC diagnostic pop
     296#endif
     297
    249298static BoundEntry *__bound_new_page(void)
    250299{
    251300    BoundEntry *page;
    252     int i;
     301    size_t i;
    253302
    254303    page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
     
    278327}
    279328
    280 static inline BoundEntry *get_page(int index)
     329static BoundEntry *get_page(size_t index)
    281330{
    282331    BoundEntry *page;
    283332    page = __bound_t1[index];
    284     if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
     333    if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) {
    285334        /* create a new page if necessary */
    286335        page = __bound_new_page();
     
    291340
    292341/* mark a region as being invalid (can only be used during init) */
    293 static void mark_invalid(unsigned long addr, unsigned long size)
    294 {
    295     unsigned long start, end;
     342static void mark_invalid(size_t addr, size_t size)
     343{
     344    size_t start, end;
    296345    BoundEntry *page;
    297     int t1_start, t1_end, i, j, t2_start, t2_end;
     346    size_t t1_start, t1_end, i, j, t2_start, t2_end;
    298347
    299348    start = addr;
     
    307356
    308357#if 0
    309     printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
     358    dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
    310359#endif
    311360   
     
    346395void __bound_init(void)
    347396{
    348     int i;
     397    size_t i;
    349398    BoundEntry *page;
    350     unsigned long start, size;
    351     int *p;
     399    size_t start, size;
     400    size_t *p;
     401
     402    static int inited;
     403    if (inited)
     404        return;
     405
     406    inited = 1;
     407
     408    dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
    352409
    353410    /* save malloc hooks and install bound check hooks */
     
    375432
    376433    /* invalid pointer zone */
    377     start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
     434    start = (size_t)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
    378435    size = BOUND_T23_SIZE;
    379436    mark_invalid(start, size);
     
    406463     *     start_brk from /proc/self/stat
    407464     */
    408     start = (unsigned long)sbrk(0);
     465    start = (size_t)sbrk(0);
    409466    size = 128 * 0x100000;
    410467    mark_invalid(start, size);
     
    412469
    413470    /* add all static bound check values */
    414     p = (int *)&__bounds_start;
     471    p = (size_t *)&__bounds_start;
    415472    while (p[0] != 0) {
    416473        __bound_new_region((void *)p[0], p[1]);
    417474        p += 2;
    418475    }
     476
     477    dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
     478}
     479
     480void __bound_main_arg(void **p)
     481{
     482    void *start = p;
     483    while (*p++);
     484
     485    dprintf(stderr, "%s, %s calling __bound_new_region(%p %x)\n",
     486            __FILE__, __FUNCTION__, start, (unsigned)((void *)p - start));
     487
     488    __bound_new_region(start, (void *) p - start);
    419489}
    420490
    421491void __bound_exit(void)
    422492{
     493    dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
    423494    restore_malloc_hooks();
    424495}
    425496
    426497static inline void add_region(BoundEntry *e,
    427                               unsigned long start, unsigned long size)
     498                              size_t start, size_t size)
    428499{
    429500    BoundEntry *e1;
     
    445516
    446517/* create a new region. It should not already exist in the region list */
    447 void __bound_new_region(void *p, unsigned long size)
    448 {
    449     unsigned long start, end;
     518void __bound_new_region(void *p, size_t size)
     519{
     520    size_t start, end;
    450521    BoundEntry *page, *e, *e2;
    451     int t1_start, t1_end, i, t2_start, t2_end;
    452 
    453     start = (unsigned long)p;
     522    size_t t1_start, t1_end, i, t2_start, t2_end;
     523
     524    dprintf(stderr, "%s, %s(%p, %x) start\n",
     525        __FILE__, __FUNCTION__, p, (unsigned)size);
     526
     527    __bound_init();
     528
     529    start = (size_t)p;
    454530    end = start + size;
    455531    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
     
    462538    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
    463539        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
    464 #ifdef BOUND_DEBUG
    465     printf("new %lx %lx %x %x %x %x\n",
    466            start, end, t1_start, t1_end, t2_start, t2_end);
    467 #endif
     540
    468541
    469542    e = (BoundEntry *)((char *)page + t2_start);
     
    507580        add_region(e, start, size);
    508581    }
     582
     583    dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
    509584}
    510585
    511586/* delete a region */
    512 static inline void delete_region(BoundEntry *e,
    513                                  void *p, unsigned long empty_size)
    514 {
    515     unsigned long addr;
     587static inline void delete_region(BoundEntry *e, void *p, size_t empty_size)
     588{
     589    size_t addr;
    516590    BoundEntry *e1;
    517591
    518     addr = (unsigned long)p;
     592    addr = (size_t)p;
    519593    addr -= e->start;
    520594    if (addr <= e->size) {
     
    540614            if (e == NULL)
    541615                break;
    542             addr = (unsigned long)p - e->start;
     616            addr = (size_t)p - e->start;
    543617            if (addr <= e->size) {
    544618                /* found: remove entry */
     
    555629int __bound_delete_region(void *p)
    556630{
    557     unsigned long start, end, addr, size, empty_size;
     631    size_t start, end, addr, size, empty_size;
    558632    BoundEntry *page, *e, *e2;
    559     int t1_start, t1_end, t2_start, t2_end, i;
    560 
    561     start = (unsigned long)p;
     633    size_t t1_start, t1_end, t2_start, t2_end, i;
     634
     635    dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
     636
     637    __bound_init();
     638
     639    start = (size_t)p;
    562640    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
    563641    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
     
    571649        e = __bound_find_region(e, p);
    572650    /* test if invalid region */
    573     if (e->size == EMPTY_SIZE || (unsigned long)p != e->start)
     651    if (e->size == EMPTY_SIZE || (size_t)p != e->start)
    574652        return -1;
    575653    /* compute the size we put in invalid regions */
     
    625703        delete_region(e, p, empty_size);
    626704    }
     705
     706    dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
     707
    627708    return 0;
    628709}
    629710
    630711/* return the size of the region starting at p, or EMPTY_SIZE if non
    631    existant region. */
    632 static unsigned long get_region_size(void *p)
    633 {
    634     unsigned long addr = (unsigned long)p;
     712   existent region. */
     713static size_t get_region_size(void *p)
     714{
     715    size_t addr = (size_t)p;
    635716    BoundEntry *e;
    636717
     
    642723    if (addr > e->size)
    643724        e = __bound_find_region(e, p);
    644     if (e->start != (unsigned long)p)
     725    if (e->start != (size_t)p)
    645726        return EMPTY_SIZE;
    646727    return e->size;
     
    710791    if (!ptr)
    711792        return NULL;
     793
     794    dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
     795           __FILE__, __FUNCTION__, ptr, (unsigned)size);
     796
    712797    __bound_new_region(ptr, size);
    713798    return ptr;
     
    739824    if (!ptr)
    740825        return NULL;
     826
     827    dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
     828           __FILE__, __FUNCTION__, ptr, (unsigned)size);
     829
    741830    __bound_new_region(ptr, size);
    742831    return ptr;
     
    756845{
    757846    void *ptr1;
    758     int old_size;
     847    size_t old_size;
    759848
    760849    if (size == 0) {
     
    791880{
    792881    BoundEntry *page, *e;
    793     int i, j;
    794 
    795     printf("region dump:\n");
     882    size_t i, j;
     883
     884    fprintf(stderr, "region dump:\n");
    796885    for(i=0;i<BOUND_T1_SIZE;i++) {
    797886        page = __bound_t1[i];
     
    800889            /* do not print invalid or empty entries */
    801890            if (e->size != EMPTY_SIZE && e->start != 0) {
    802                 printf("%08x:",
     891                fprintf(stderr, "%08x:",
    803892                       (i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
    804893                       (j << BOUND_T3_BITS));
    805894                do {
    806                     printf(" %08lx:%08lx", e->start, e->start + e->size);
     895                    fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
    807896                    e = e->next;
    808897                } while (e != NULL);
    809                 printf("\n");
     898                fprintf(stderr, "\n");
    810899            }
    811900        }
     
    821910    if (size == 0)
    822911        return;
    823     p = __bound_ptr_add((void *)p, size);
     912    p = __bound_ptr_add((void *)p, size - 1);
    824913    if (p == INVALID_POINTER)
    825914        bound_error("invalid pointer");
     
    828917void *__bound_memcpy(void *dst, const void *src, size_t size)
    829918{
     919    void* p;
     920
     921    dprintf(stderr, "%s %s: start, dst=%p src=%p size=%x\n",
     922            __FILE__, __FUNCTION__, dst, src, (unsigned)size);
     923
    830924    __bound_check(dst, size);
    831925    __bound_check(src, size);
     
    833927    if (src >= dst && src < dst + size)
    834928        bound_error("overlapping regions in memcpy()");
    835     return memcpy(dst, src, size);
     929
     930    p = memcpy(dst, src, size);
     931
     932    dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p);
     933    return p;
    836934}
    837935
     
    853951{
    854952    const char *p;
    855     int len;
     953    size_t len;
    856954
    857955    len = 0;
     
    869967char *__bound_strcpy(char *dst, const char *src)
    870968{
    871     int len;
     969    size_t len;
     970    void *p;
     971
     972    dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n",
     973            __FILE__, __FUNCTION__, dst, src);
    872974    len = __bound_strlen(src);
    873     return __bound_memcpy(dst, src, len + 1);
    874 }
    875 
     975    p = __bound_memcpy(dst, src, len + 1);
     976    dprintf(stderr, "%s %s: strcpy end, p = %p\n",
     977            __FILE__, __FUNCTION__, p);
     978    return p;
     979}
  • EcnlProtoTool/trunk/tcc-0.9.27/lib/libtcc1.c

    r321 r331  
    104104union float_long {
    105105    float f;
    106     long l;
     106    unsigned int l;
    107107};
    108108
    109109/* XXX: we don't support several builtin supports for now */
    110 #ifndef __x86_64__
     110#if !defined __x86_64__ && !defined __arm__
    111111
    112112/* XXX: use gcc/tcc intrinsic ? */
    113 #if defined(__i386__)
     113#if defined __i386__
    114114#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
    115115  __asm__ ("subl %5,%1\n\tsbbl %3,%0"                                   \
     
    479479}
    480480
    481 #if defined(__i386__)
    482 /* FPU control word for rounding to nearest mode */
    483 unsigned short __tcc_fpu_control = 0x137f;
    484 /* FPU control word for round to zero mode for int conversion */
    485 unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
    486 #endif
    487 
    488481#endif /* !__x86_64__ */
    489482
     
    558551}
    559552
     553long long __fixsfdi (float a1)
     554{
     555    long long ret; int s;
     556    ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
     557    return s ? ret : -ret;
     558}
     559
    560560unsigned long long __fixunsdfdi (double a1)
    561561{
     
    583583}
    584584
     585long long __fixdfdi (double a1)
     586{
     587    long long ret; int s;
     588    ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
     589    return s ? ret : -ret;
     590}
     591
     592#ifndef __arm__
    585593unsigned long long __fixunsxfdi (long double a1)
    586594{
     
    606614}
    607615
    608 #if defined(__x86_64__) && !defined(_WIN64)
    609 
    610 /* helper functions for stdarg.h */
    611 
    612 #include <stdlib.h>
    613 #ifndef __TINYC__
    614 /* gives "incompatible types for redefinition of __va_arg" below */
    615 #include <stdio.h>
    616 #endif
    617 
    618 enum __va_arg_type {
    619     __va_gen_reg, __va_float_reg, __va_stack
    620 };
    621 
    622 /* GCC compatible definition of va_list. */
    623 struct __va_list_struct {
    624     unsigned int gp_offset;
    625     unsigned int fp_offset;
    626     union {
    627         unsigned int overflow_offset;
    628         char *overflow_arg_area;
    629     };
    630     char *reg_save_area;
    631 };
    632 
    633 void *__va_start(void *fp)
    634 {
    635     struct __va_list_struct *ap =
    636         (struct __va_list_struct *)malloc(sizeof(struct __va_list_struct));
    637     *ap = *(struct __va_list_struct *)((char *)fp - 16);
    638     ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
    639     ap->reg_save_area = (char *)fp - 176 - 16;
    640     return ap;
    641 }
    642 
    643 void *__va_arg(struct __va_list_struct *ap,
    644                enum __va_arg_type arg_type,
    645                int size)
    646 {
    647     size = (size + 7) & ~7;
    648     switch (arg_type) {
    649     case __va_gen_reg:
    650         if (ap->gp_offset < 48) {
    651             ap->gp_offset += 8;
    652             return ap->reg_save_area + ap->gp_offset - 8;
    653         }
    654         size = 8;
    655         goto use_overflow_area;
    656 
    657     case __va_float_reg:
    658         if (ap->fp_offset < 128 + 48) {
    659             ap->fp_offset += 16;
    660             return ap->reg_save_area + ap->fp_offset - 16;
    661         }
    662         size = 8;
    663         goto use_overflow_area;
    664 
    665     case __va_stack:
    666     use_overflow_area:
    667         ap->overflow_arg_area += size;
    668         return ap->overflow_arg_area - size;
    669 
    670     default:
    671 #ifndef __TINYC__
    672         fprintf(stderr, "unknown ABI type for __va_arg\n");
    673 #endif
    674         abort();
    675     }
    676 }
    677 
    678 void *__va_copy(struct __va_list_struct *src)
    679 {
    680     struct __va_list_struct *dest =
    681         (struct __va_list_struct *)malloc(sizeof(struct __va_list_struct));
    682     *dest = *src;
    683     return dest;
    684 }
    685 
    686 void __va_end(struct __va_list_struct *ap)
    687 {
    688     free(ap);
    689 }
    690 
    691 #endif /* __x86_64__ */
     616long long __fixxfdi (long double a1)
     617{
     618    long long ret; int s;
     619    ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
     620    return s ? ret : -ret;
     621}
     622#endif /* !ARM */
  • EcnlProtoTool/trunk/tcc-0.9.27/libtcc.c

    r321 r331  
    11/*
    22 *  TCC - Tiny C Compiler
    3  * 
     3 *
    44 *  Copyright (c) 2001-2004 Fabrice Bellard
    55 *
     
    3333ST_DATA struct TCCState *tcc_state;
    3434
     35static int nb_states;
     36
    3537/********************************************************/
    3638
    37 #ifdef ONE_SOURCE
     39#if ONE_SOURCE
    3840#include "tccpp.c"
    3941#include "tccgen.c"
     
    4244#ifdef TCC_TARGET_I386
    4345#include "i386-gen.c"
     46#include "i386-link.c"
     47#include "i386-asm.c"
    4448#endif
    4549#ifdef TCC_TARGET_ARM
    4650#include "arm-gen.c"
     51#include "arm-link.c"
     52#include "arm-asm.c"
     53#endif
     54#ifdef TCC_TARGET_ARM64
     55#include "arm64-gen.c"
     56#include "arm64-link.c"
    4757#endif
    4858#ifdef TCC_TARGET_C67
    4959#include "c67-gen.c"
     60#include "c67-link.c"
     61#include "tcccoff.c"
    5062#endif
    5163#ifdef TCC_TARGET_X86_64
    5264#include "x86_64-gen.c"
    53 #endif
    54 #ifdef TCC_TARGET_IL
    55 #include "il-gen.c"
     65#include "x86_64-link.c"
     66#include "i386-asm.c"
    5667#endif
    5768#ifdef CONFIG_TCC_ASM
    5869#include "tccasm.c"
    59 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    60 #include "i386-asm.c"
    61 #endif
    62 #endif
    63 #ifdef TCC_TARGET_COFF
    64 #include "tcccoff.c"
    6570#endif
    6671#ifdef TCC_TARGET_PE
     
    8287
    8388/********************************************************/
    84 
    8589#ifdef _WIN32
    86 char *normalize_slashes(char *path)
     90ST_FUNC char *normalize_slashes(char *path)
    8791{
    8892    char *p;
     
    9397}
    9498
    95 #if 0
    9699static HMODULE tcc_module;
    97100
     
    102105    GetModuleFileNameA(tcc_module, path, sizeof path);
    103106    p = tcc_basename(normalize_slashes(strlwr(path)));
    104     if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
    105         p -= 5;
    106     else if (p > path)
    107         p--;
     107    if (p > path)
     108        --p;
    108109    *p = 0;
    109110    tcc_set_lib_path(s, path);
     
    119120#endif
    120121
    121 #ifndef CONFIG_TCC_STATIC
    122 void dlclose(void *p)
    123 {
    124     FreeLibrary((HMODULE)p);
    125 }
    126 #endif
    127 #else
    128 extern void tcc_set_lib_path_w32(TCCState *s);
    129 extern void dlclose(void *p);
    130 #endif
    131 
    132122#ifdef LIBTCC_AS_DLL
    133 BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
     123BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
    134124{
    135125    if (DLL_PROCESS_ATTACH == dwReason)
     
    142132/********************************************************/
    143133/* copy a string and truncate it. */
    144 PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
     134ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
    145135{
    146136    char *q, *q_end;
     
    162152
    163153/* strcat and truncate. */
    164 PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
     154ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
    165155{
    166156    int len;
    167157    len = strlen(buf);
    168     if (len < buf_size) 
     158    if (len < buf_size)
    169159        pstrcpy(buf + len, buf_size - len, s);
    170160    return buf;
    171161}
    172162
    173 PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num)
     163ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
    174164{
    175165    memcpy(out, in, num);
     
    205195#undef realloc
    206196
    207 #ifdef MEM_DEBUG
    208 ST_DATA int mem_cur_size;
    209 ST_DATA int mem_max_size;
    210 unsigned malloc_usable_size(void*);
    211 #endif
     197#ifndef MEM_DEBUG
    212198
    213199PUB_FUNC void tcc_free(void *ptr)
    214200{
    215 #ifdef MEM_DEBUG
    216     mem_cur_size -= malloc_usable_size(ptr);
    217 #endif
    218         free(ptr);
     201    free(ptr);
    219202}
    220203
     
    224207    ptr = malloc(size);
    225208    if (!ptr && size)
    226         tcc_error("memory full");
    227 #ifdef MEM_DEBUG
    228     mem_cur_size += malloc_usable_size(ptr);
    229     if (mem_cur_size > mem_max_size)
    230         mem_max_size = mem_cur_size;
    231 #endif
     209        tcc_error("memory full (malloc)");
    232210    return ptr;
    233211}
     
    244222{
    245223    void *ptr1;
    246 #ifdef MEM_DEBUG
    247     mem_cur_size -= malloc_usable_size(ptr);
    248 #endif
    249224    ptr1 = realloc(ptr, size);
    250225    if (!ptr1 && size)
    251         tcc_error("memory full");
    252 #ifdef MEM_DEBUG
    253     /* NOTE: count not correct if alloc error, but not critical */
    254     mem_cur_size += malloc_usable_size(ptr1);
    255     if (mem_cur_size > mem_max_size)
    256         mem_max_size = mem_cur_size;
    257 #endif
     226        tcc_error("memory full (realloc)");
    258227    return ptr1;
    259228}
     
    267236}
    268237
    269 PUB_FUNC void tcc_memstats(void)
    270 {
    271 #ifdef MEM_DEBUG
    272     printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
    273 #endif
    274 }
     238PUB_FUNC void tcc_memcheck(void)
     239{
     240}
     241
     242#else
     243
     244#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
     245#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
     246#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
     247#define MEM_DEBUG_FILE_LEN 40
     248#define MEM_DEBUG_CHECK3(header) \
     249    ((mem_debug_header_t*)((char*)header + header->size))->magic3
     250#define MEM_USER_PTR(header) \
     251    ((char *)header + offsetof(mem_debug_header_t, magic3))
     252#define MEM_HEADER_PTR(ptr) \
     253    (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))
     254
     255struct mem_debug_header {
     256    unsigned magic1;
     257    unsigned size;
     258    struct mem_debug_header *prev;
     259    struct mem_debug_header *next;
     260    int line_num;
     261    char file_name[MEM_DEBUG_FILE_LEN + 1];
     262    unsigned magic2;
     263    ALIGNED(16) unsigned magic3;
     264};
     265
     266typedef struct mem_debug_header mem_debug_header_t;
     267
     268static mem_debug_header_t *mem_debug_chain;
     269static unsigned mem_cur_size;
     270static unsigned mem_max_size;
     271
     272static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
     273{
     274    mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
     275    if (header->magic1 != MEM_DEBUG_MAGIC1 ||
     276        header->magic2 != MEM_DEBUG_MAGIC2 ||
     277        MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 ||
     278        header->size == (unsigned)-1) {
     279        fprintf(stderr, "%s check failed\n", msg);
     280        if (header->magic1 == MEM_DEBUG_MAGIC1)
     281            fprintf(stderr, "%s:%u: block allocated here.\n",
     282                header->file_name, header->line_num);
     283        exit(1);
     284    }
     285    return header;
     286}
     287
     288PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
     289{
     290    int ofs;
     291    mem_debug_header_t *header;
     292
     293    header = malloc(sizeof(mem_debug_header_t) + size);
     294    if (!header)
     295        tcc_error("memory full (malloc)");
     296
     297    header->magic1 = MEM_DEBUG_MAGIC1;
     298    header->magic2 = MEM_DEBUG_MAGIC2;
     299    header->size = size;
     300    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
     301    header->line_num = line;
     302    ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
     303    strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
     304    header->file_name[MEM_DEBUG_FILE_LEN] = 0;
     305
     306    header->next = mem_debug_chain;
     307    header->prev = NULL;
     308    if (header->next)
     309        header->next->prev = header;
     310    mem_debug_chain = header;
     311
     312    mem_cur_size += size;
     313    if (mem_cur_size > mem_max_size)
     314        mem_max_size = mem_cur_size;
     315
     316    return MEM_USER_PTR(header);
     317}
     318
     319PUB_FUNC void tcc_free_debug(void *ptr)
     320{
     321    mem_debug_header_t *header;
     322    if (!ptr)
     323        return;
     324    header = malloc_check(ptr, "tcc_free");
     325    mem_cur_size -= header->size;
     326    header->size = (unsigned)-1;
     327    if (header->next)
     328        header->next->prev = header->prev;
     329    if (header->prev)
     330        header->prev->next = header->next;
     331    if (header == mem_debug_chain)
     332        mem_debug_chain = header->next;
     333    free(header);
     334}
     335
     336PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
     337{
     338    void *ptr;
     339    ptr = tcc_malloc_debug(size,file,line);
     340    memset(ptr, 0, size);
     341    return ptr;
     342}
     343
     344PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
     345{
     346    mem_debug_header_t *header;
     347    int mem_debug_chain_update = 0;
     348    if (!ptr)
     349        return tcc_malloc_debug(size, file, line);
     350    header = malloc_check(ptr, "tcc_realloc");
     351    mem_cur_size -= header->size;
     352    mem_debug_chain_update = (header == mem_debug_chain);
     353    header = realloc(header, sizeof(mem_debug_header_t) + size);
     354    if (!header)
     355        tcc_error("memory full (realloc)");
     356    header->size = size;
     357    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
     358    if (header->next)
     359        header->next->prev = header;
     360    if (header->prev)
     361        header->prev->next = header;
     362    if (mem_debug_chain_update)
     363        mem_debug_chain = header;
     364    mem_cur_size += size;
     365    if (mem_cur_size > mem_max_size)
     366        mem_max_size = mem_cur_size;
     367    return MEM_USER_PTR(header);
     368}
     369
     370PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
     371{
     372    char *ptr;
     373    ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
     374    strcpy(ptr, str);
     375    return ptr;
     376}
     377
     378PUB_FUNC void tcc_memcheck(void)
     379{
     380    if (mem_cur_size) {
     381        mem_debug_header_t *header = mem_debug_chain;
     382        fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
     383            mem_cur_size, mem_max_size);
     384        while (header) {
     385            fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
     386                header->file_name, header->line_num, header->size);
     387            header = header->next;
     388        }
     389#if MEM_DEBUG-0 == 2
     390        exit(2);
     391#endif
     392    }
     393}
     394#endif /* MEM_DEBUG */
    275395
    276396#define free(p) use_tcc_free(p)
     
    281401/* dynarrays */
    282402
    283 ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
     403ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
    284404{
    285405    int nb, nb_alloc;
    286406    void **pp;
    287    
     407
    288408    nb = *nb_ptr;
    289     pp = *ptab;
     409    pp = *(void ***)ptab;
    290410    /* every power of two we double array size */
    291411    if ((nb & (nb - 1)) == 0) {
     
    295415            nb_alloc = nb * 2;
    296416        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
    297         *ptab = pp;
     417        *(void***)ptab = pp;
    298418    }
    299419    pp[nb++] = data;
     
    311431}
    312432
    313 static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in)
     433static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
    314434{
    315435    const char *p;
     
    319439
    320440        cstr_new(&str);
    321         for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
     441        for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
    322442            if (c == '{' && p[1] && p[2] == '}') {
    323443                c = p[1], p += 2;
    324444                if (c == 'B')
    325                     cstr_cat(&str, s->tcc_lib_path);
     445                    cstr_cat(&str, s->tcc_lib_path, -1);
    326446            } else {
    327447                cstr_ccat(&str, c);
    328448            }
    329449        }
    330         cstr_ccat(&str, '\0');
    331         dynarray_add(p_ary, p_nb_ary, str.data);
     450        if (str.size) {
     451            cstr_ccat(&str, '\0');
     452            dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
     453        }
     454        cstr_free(&str);
    332455        in = p+1;
    333456    } while (*p);
    334 }
    335 
    336 /********************************************************/
    337 
    338 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
    339 {
    340     Section *sec;
    341 
    342     sec = tcc_mallocz(sizeof(Section) + strlen(name));
    343     strcpy(sec->name, name);
    344     sec->sh_type = sh_type;
    345     sec->sh_flags = sh_flags;
    346     switch(sh_type) {
    347     case SHT_HASH:
    348     case SHT_REL:
    349     case SHT_RELA:
    350     case SHT_DYNSYM:
    351     case SHT_SYMTAB:
    352     case SHT_DYNAMIC:
    353         sec->sh_addralign = 4;
    354         break;
    355     case SHT_STRTAB:
    356         sec->sh_addralign = 1;
    357         break;
    358     default:
    359         sec->sh_addralign = 32; /* default conservative alignment */
    360         break;
    361     }
    362 
    363     if (sh_flags & SHF_PRIVATE) {
    364         dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
    365     } else {
    366         sec->sh_num = s1->nb_sections;
    367         dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
    368     }
    369 
    370     return sec;
    371 }
    372 
    373 static void free_section(Section *s)
    374 {
    375     tcc_free(s->data);
    376 }
    377 
    378 /* realloc section and set its content to zero */
    379 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
    380 {
    381     unsigned long size;
    382     unsigned char *data;
    383    
    384     size = sec->data_allocated;
    385     if (size == 0)
    386         size = 1;
    387     while (size < new_size)
    388         size = size * 2;
    389     data = tcc_realloc(sec->data, size);
    390     memset(data + sec->data_allocated, 0, size - sec->data_allocated);
    391     sec->data = data;
    392     sec->data_allocated = size;
    393 }
    394 
    395 /* reserve at least 'size' bytes in section 'sec' from
    396    sec->data_offset. */
    397 ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
    398 {
    399     unsigned long offset, offset1;
    400 
    401     offset = sec->data_offset;
    402     offset1 = offset + size;
    403     if (offset1 > sec->data_allocated)
    404         section_realloc(sec, offset1);
    405     sec->data_offset = offset1;
    406     return sec->data + offset;
    407 }
    408 
    409 /* reserve at least 'size' bytes from section start */
    410 ST_FUNC void section_reserve(Section *sec, unsigned long size)
    411 {
    412     if (size > sec->data_allocated)
    413         section_realloc(sec, size);
    414     if (size > sec->data_offset)
    415         sec->data_offset = size;
    416 }
    417 
    418 /* return a reference to a section, and create it if it does not
    419    exists */
    420 ST_FUNC Section *find_section(TCCState *s1, const char *name)
    421 {
    422     Section *sec;
    423     int i;
    424     for(i = 1; i < s1->nb_sections; i++) {
    425         sec = s1->sections[i];
    426         if (!strcmp(name, sec->name))
    427             return sec;
    428     }
    429     /* sections are created as PROGBITS */
    430     return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
    431 }
    432 
    433 /* update sym->c so that it points to an external symbol in section
    434    'section' with value 'value' */
    435 ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
    436                             addr_t value, unsigned long size,
    437                             int can_add_underscore)
    438 {
    439     int sym_type, sym_bind, sh_num, info, other;
    440     ElfW(Sym) *esym;
    441     const char *name;
    442     char buf1[256];
    443 
    444     if (section == NULL)
    445         sh_num = SHN_UNDEF;
    446     else if (section == SECTION_ABS)
    447         sh_num = SHN_ABS;
    448     else
    449         sh_num = section->sh_num;
    450 
    451     if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
    452         sym_type = STT_FUNC;
    453     } else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
    454         sym_type = STT_NOTYPE;
    455     } else {
    456         sym_type = STT_OBJECT;
    457     }
    458 
    459     if (sym->type.t & VT_STATIC)
    460         sym_bind = STB_LOCAL;
    461     else {
    462         if (sym->type.t & VT_WEAK)
    463             sym_bind = STB_WEAK;
    464         else
    465             sym_bind = STB_GLOBAL;
    466     }
    467 
    468     if (!sym->c) {
    469         name = get_tok_str(sym->v, NULL);
    470 #ifdef CONFIG_TCC_BCHECK
    471         if (tcc_state->do_bounds_check) {
    472             char buf[32];
    473 
    474             /* XXX: avoid doing that for statics ? */
    475             /* if bound checking is activated, we change some function
    476                names by adding the "__bound" prefix */
    477             switch(sym->v) {
    478 #ifdef TCC_TARGET_PE
    479             /* XXX: we rely only on malloc hooks */
    480             case TOK_malloc:
    481             case TOK_free:
    482             case TOK_realloc:
    483             case TOK_memalign:
    484             case TOK_calloc:
    485 #endif
    486             case TOK_memcpy:
    487             case TOK_memmove:
    488             case TOK_memset:
    489             case TOK_strlen:
    490             case TOK_strcpy:
    491 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    492             case TOK_alloca:
    493 #endif
    494                 strcpy(buf, "__bound_");
    495                 strcat(buf, name);
    496                 name = buf;
    497                 break;
    498             }
    499         }
    500 #endif
    501         other = 0;
    502 
    503 #ifdef TCC_TARGET_PE
    504         if (sym->type.t & VT_EXPORT)
    505             other |= 1;
    506         if (sym_type == STT_FUNC && sym->type.ref) {
    507             int attr = sym->type.ref->r;
    508             if (FUNC_EXPORT(attr))
    509                 other |= 1;
    510             if (FUNC_CALL(attr) == FUNC_STDCALL && can_add_underscore) {
    511                 sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr) * PTR_SIZE);
    512                 name = buf1;
    513                 other |= 2;
    514                 can_add_underscore = 0;
    515             }
    516         } else {
    517             if (find_elf_sym(tcc_state->dynsymtab_section, name))
    518                 other |= 4;
    519             if (sym->type.t & VT_IMPORT)
    520                 other |= 4;
    521         }
    522 #endif
    523         if (tcc_state->leading_underscore && can_add_underscore) {
    524             buf1[0] = '_';
    525             pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
    526             name = buf1;
    527         }
    528         if (sym->asm_label) {
    529             name = sym->asm_label;
    530         }
    531         info = ELFW(ST_INFO)(sym_bind, sym_type);
    532         sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
    533     } else {
    534         esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    535         esym->st_value = value;
    536         esym->st_size = size;
    537         esym->st_shndx = sh_num;
    538     }
    539 }
    540 
    541 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
    542                            addr_t value, unsigned long size)
    543 {
    544     put_extern_sym2(sym, section, value, size, 1);
    545 }
    546 
    547 /* add a new relocation entry to symbol 'sym' in section 's' */
    548 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
    549 {
    550     int c = 0;
    551     if (sym) {
    552         if (0 == sym->c)
    553             put_extern_sym(sym, NULL, 0, 0);
    554         c = sym->c;
    555     }
    556     /* now we can add ELF relocation info */
    557     put_elf_reloc(symtab_section, s, offset, type, c);
    558457}
    559458
     
    579478    char buf[2048];
    580479    BufferedFile **pf, *f;
    581    
     480
    582481    buf[0] = '\0';
    583482    /* use upper file if inline ":asm:" or token ":paste:" */
    584     for (f = file; f && f->filename[0] == ':'; f = f->prev);
     483    for (f = file; f && f->filename[0] == ':'; f = f->prev)
     484     ;
    585485    if (f) {
    586486        for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
    587487            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
    588488                (*pf)->filename, (*pf)->line_num);
    589         if (f->line_num > 0) {
     489        if (s1->error_set_jmp_enabled) {
    590490            strcat_printf(buf, sizeof(buf), "%s:%d: ",
    591                 f->filename, f->line_num);
     491                f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
    592492        } else {
    593493            strcat_printf(buf, sizeof(buf), "%s: ",
     
    605505    if (!s1->error_func) {
    606506        /* default case: stderr */
     507        if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
     508            /* print a newline during tcc -E */
     509            printf("\n"), fflush(stdout);
     510        fflush(stdout); /* flush -v output */
    607511        fprintf(stderr, "%s\n", buf);
     512        fflush(stderr); /* print error/warning now (win32) */
    608513    } else {
    609514        s1->error_func(s1->error_opaque, buf);
     
    669574    int buflen = initlen ? initlen : IO_BUF_SIZE;
    670575
    671     bf = tcc_malloc(sizeof(BufferedFile) + buflen);
     576    bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
    672577    bf->buf_ptr = bf->buffer;
    673578    bf->buf_end = bf->buffer + initlen;
    674579    bf->buf_end[0] = CH_EOB; /* put eob symbol */
    675580    pstrcpy(bf->filename, sizeof(bf->filename), filename);
    676 #ifdef _WIN32
    677     normalize_slashes(bf->filename);
    678 #endif
     581    bf->true_filename = bf->filename;
    679582    bf->line_num = 1;
    680     bf->ifndef_macro = 0;
    681583    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
    682584    bf->fd = -1;
    683585    bf->prev = file;
    684586    file = bf;
     587    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
    685588}
    686589
     
    692595        total_lines += bf->line_num;
    693596    }
     597    if (bf->true_filename != bf->filename)
     598        tcc_free(bf->true_filename);
    694599    file = bf->prev;
    695600    tcc_free(bf);
     
    700605    int fd;
    701606    if (strcmp(filename, "-") == 0)
    702         fd = 0, filename = "stdin";
     607        fd = 0, filename = "<stdin>";
    703608    else
    704609        fd = open(filename, O_RDONLY | O_BINARY);
     
    708613    if (fd < 0)
    709614        return -1;
    710 
    711615    tcc_open_bf(s1, filename, 0);
     616#ifdef _WIN32
     617    normalize_slashes(file->filename);
     618#endif
    712619    file->fd = fd;
    713620    return fd;
    714621}
    715622
    716 /* compile the C file opened in 'file'. Return non zero if errors. */
     623/* compile the file opened in 'file'. Return non zero if errors. */
    717624static int tcc_compile(TCCState *s1)
    718625{
    719626    Sym *define_start;
    720     SValue *pvtop;
    721     char buf[512];
    722     volatile int section_sym;
    723 
    724 #ifdef INC_DEBUG
    725     printf("%s: **** new file\n", file->filename);
    726 #endif
    727     preprocess_init(s1);
    728 
    729     cur_text_section = NULL;
    730     funcname = "";
    731     anon_sym = SYM_FIRST_ANOM;
    732 
    733     /* file info: full path + filename */
    734     section_sym = 0; /* avoid warning */
    735     if (s1->do_debug) {
    736         section_sym = put_elf_sym(symtab_section, 0, 0,
    737                                   ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
    738                                   text_section->sh_num, NULL);
    739         getcwd(buf, sizeof(buf));
    740 #ifdef _WIN32
    741         normalize_slashes(buf);
    742 #endif
    743         pstrcat(buf, sizeof(buf), "/");
    744         put_stabs_r(buf, N_SO, 0, 0,
    745                     text_section->data_offset, text_section, section_sym);
    746         put_stabs_r(file->filename, N_SO, 0, 0,
    747                     text_section->data_offset, text_section, section_sym);
    748     }
    749     /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
    750        symbols can be safely used */
    751     put_elf_sym(symtab_section, 0, 0,
    752                 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
    753                 SHN_ABS, file->filename);
    754 
    755     /* define some often used types */
    756     int_type.t = VT_INT;
    757 
    758     char_pointer_type.t = VT_BYTE;
    759     mk_pointer(&char_pointer_type);
    760 
    761 #if PTR_SIZE == 4
    762     size_type.t = VT_INT;
    763 #else
    764     size_type.t = VT_LLONG;
    765 #endif
    766 
    767     func_old_type.t = VT_FUNC;
    768     func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
    769 #ifdef TCC_TARGET_ARM
    770     arm_init_types();
    771 #endif
    772 
    773 #if 0
    774     /* define 'void *alloca(unsigned int)' builtin function */
    775     {
    776         Sym *s1;
    777 
    778         p = anon_sym++;
    779         sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
    780         s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
    781         s1->next = NULL;
    782         sym->next = s1;
    783         sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
    784     }
    785 #endif
     627    int filetype, is_asm;
    786628
    787629    define_start = define_stack;
    788     nocode_wanted = 1;
     630    filetype = s1->filetype;
     631    is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
     632    tccelf_begin_file(s1);
    789633
    790634    if (setjmp(s1->error_jmp_buf) == 0) {
     
    792636        s1->error_set_jmp_enabled = 1;
    793637
    794         ch = file->buf_ptr[0];
    795         tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
    796         parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
    797         pvtop = vtop;
    798         next();
    799         decl(VT_CONST);
    800         if (tok != TOK_EOF)
    801             expect("declaration");
    802         if (pvtop != vtop)
    803             tcc_warning("internal compiler error: vstack leak? (%d)", vtop - pvtop);
    804 
    805         /* end of translation unit info */
    806         if (s1->do_debug) {
    807             put_stabs_r(NULL, N_SO, 0, 0,
    808                         text_section->data_offset, text_section, section_sym);
     638        preprocess_start(s1, is_asm);
     639        if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
     640            tcc_preprocess(s1);
     641        } else if (is_asm) {
     642#ifdef CONFIG_TCC_ASM
     643            tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
     644#else
     645            tcc_error_noabort("asm not supported");
     646#endif
     647        } else {
     648            tccgen_compile(s1);
    809649        }
    810650    }
    811 
    812651    s1->error_set_jmp_enabled = 0;
    813652
    814     /* reset define stack, but leave -Dsymbols (may be incorrect if
    815        they are undefined) */
    816     free_defines(define_start);
    817 
    818     gen_inline_functions();
    819 
    820     sym_pop(&global_stack, NULL);
    821     sym_pop(&local_stack, NULL);
    822 
     653    preprocess_end(s1);
     654    free_inline_functions(s1);
     655    /* reset define stack, but keep -D and built-ins */
     656    free_defines(define_start);
     657    sym_pop(&global_stack, NULL, 0);
     658    sym_pop(&local_stack, NULL, 0);
     659    tccelf_end_file(s1);
    823660    return s1->nb_errors != 0 ? -1 : 0;
    824661}
     
    827664{
    828665    int len, ret;
     666
    829667    len = strlen(str);
    830 
    831668    tcc_open_bf(s, "<string>", len);
    832669    memcpy(file->buffer, str, len);
     
    853690
    854691    /* parse with define parser */
    855     ch = file->buf_ptr[0];
    856692    next_nomacro();
    857693    parse_define();
    858 
    859694    tcc_close();
    860695}
     
    875710static void tcc_cleanup(void)
    876711{
    877     int i, n;
    878712    if (NULL == tcc_state)
    879713        return;
     714    while (file)
     715        tcc_close();
     716    tccpp_delete(tcc_state);
    880717    tcc_state = NULL;
    881 
    882     /* free -D defines */
    883     free_defines(NULL);
    884 
    885     /* free tokens */
    886     n = tok_ident - TOK_IDENT;
    887     for(i = 0; i < n; i++)
    888         tcc_free(table_ident[i]);
    889     tcc_free(table_ident);
    890 
    891718    /* free sym_pools */
    892719    dynarray_reset(&sym_pools, &nb_sym_pools);
    893     /* string buffer */
    894     cstr_free(&tokcstr);
    895720    /* reset symbol stack */
    896721    sym_free_first = NULL;
    897     /* cleanup from error/setjmp */
    898     macro_ptr = NULL;
    899722}
    900723
     
    902725{
    903726    TCCState *s;
    904     char buffer[100];
    905     int a,b,c;
    906727
    907728    tcc_cleanup();
     
    911732        return NULL;
    912733    tcc_state = s;
     734    ++nb_states;
     735
     736    s->alacarte_link = 1;
     737    s->nocommon = 1;
     738    s->warn_implicit_function_declaration = 1;
     739    s->ms_extensions = 1;
     740
     741#ifdef CHAR_IS_UNSIGNED
     742    s->char_is_unsigned = 1;
     743#endif
     744#ifdef TCC_TARGET_I386
     745    s->seg_size = 32;
     746#endif
     747    /* enable this if you want symbols with leading underscore on windows: */
     748#if 0 /* def TCC_TARGET_PE */
     749    s->leading_underscore = 1;
     750#endif
    913751#ifdef _WIN32
    914752    tcc_set_lib_path_w32(s);
     
    916754    tcc_set_lib_path(s, CONFIG_TCCDIR);
    917755#endif
    918     s->output_type = TCC_OUTPUT_MEMORY;
    919     preprocess_new();
    920     s->include_stack_ptr = s->include_stack;
     756    tccelf_new(s);
     757    tccpp_new(s);
    921758
    922759    /* we add dummy defines for some special macros to speed up tests
     
    926763    define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
    927764    define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
    928 
    929     /* define __TINYC__ 92X  */
    930     sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
    931     sprintf(buffer, "%d", a*10000 + b*100 + c);
    932     tcc_define_symbol(s, "__TINYC__", buffer);
     765    define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
     766    {
     767        /* define __TINYC__ 92X  */
     768        char buffer[32]; int a,b,c;
     769        sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
     770        sprintf(buffer, "%d", a*10000 + b*100 + c);
     771        tcc_define_symbol(s, "__TINYC__", buffer);
     772    }
    933773
    934774    /* standard defines */
    935775    tcc_define_symbol(s, "__STDC__", NULL);
    936776    tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
     777    tcc_define_symbol(s, "__STDC_HOSTED__", NULL);
    937778
    938779    /* target defines */
     
    952793    tcc_define_symbol(s, "arm", NULL);
    953794    tcc_define_symbol(s, "__APCS_32__", NULL);
     795    tcc_define_symbol(s, "__ARMEL__", NULL);
     796#if defined(TCC_ARM_EABI)
     797    tcc_define_symbol(s, "__ARM_EABI__", NULL);
     798#endif
     799#if defined(TCC_ARM_HARDFLOAT)
     800    s->float_abi = ARM_HARD_FLOAT;
     801    tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
     802#else
     803    s->float_abi = ARM_SOFTFP_FLOAT;
     804#endif
     805#elif defined(TCC_TARGET_ARM64)
     806    tcc_define_symbol(s, "__aarch64__", NULL);
     807#elif defined TCC_TARGET_C67
     808    tcc_define_symbol(s, "__C67__", NULL);
    954809#endif
    955810
     
    963818    tcc_define_symbol(s, "__unix", NULL);
    964819    tcc_define_symbol(s, "unix", NULL);
    965 # if defined(__linux)
     820# if defined(__linux__)
    966821    tcc_define_symbol(s, "__linux__", NULL);
    967822    tcc_define_symbol(s, "__linux", NULL);
    968823# endif
    969824# if defined(__FreeBSD__)
    970 #  define str(s) #s
    971     tcc_define_symbol(s, "__FreeBSD__", str( __FreeBSD__));
    972 #  undef str
     825    tcc_define_symbol(s, "__FreeBSD__", "__FreeBSD__");
     826    /* No 'Thread Storage Local' on FreeBSD with tcc */
     827    tcc_define_symbol(s, "__NO_TLS", NULL);
    973828# endif
    974829# if defined(__FreeBSD_kernel__)
    975830    tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
    976831# endif
     832# if defined(__NetBSD__)
     833    tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
     834# endif
     835# if defined(__OpenBSD__)
     836    tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
     837# endif
    977838#endif
    978839
    979840    /* TinyCC & gcc defines */
    980 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
     841#if PTR_SIZE == 4
     842    /* 32bit systems. */
     843    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
     844    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
     845    tcc_define_symbol(s, "__ILP32__", NULL);
     846#elif LONG_SIZE == 4
     847    /* 64bit Windows. */
    981848    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
    982849    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
     850    tcc_define_symbol(s, "__LLP64__", NULL);
    983851#else
     852    /* Other 64bit systems. */
    984853    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
    985854    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
     855    tcc_define_symbol(s, "__LP64__", NULL);
    986856#endif
    987857
    988858#ifdef TCC_TARGET_PE
    989859    tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
     860    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
    990861#else
    991862    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
    992 #endif
    993 
    994 #ifndef TCC_TARGET_PE
     863    /* wint_t is unsigned int by default, but (signed) int on BSDs
     864       and unsigned short on windows.  Other OSes might have still
     865       other conventions, sigh.  */
     866# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \
     867  || defined(__NetBSD__) || defined(__OpenBSD__)
     868    tcc_define_symbol(s, "__WINT_TYPE__", "int");
     869#  ifdef __FreeBSD__
     870    /* define __GNUC__ to have some useful stuff from sys/cdefs.h
     871       that are unconditionally used in FreeBSDs other system headers :/ */
     872    tcc_define_symbol(s, "__GNUC__", "2");
     873    tcc_define_symbol(s, "__GNUC_MINOR__", "7");
     874    tcc_define_symbol(s, "__builtin_alloca", "alloca");
     875#  endif
     876# else
     877    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
    995878    /* glibc defines */
    996     tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)");
    997     tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW");
    998     /* default library paths */
    999     tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
    1000     /* paths for crt objects */
    1001     tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
    1002 #endif
    1003 
    1004     /* no section zero */
    1005     dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
    1006 
    1007     /* create standard sections */
    1008     text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
    1009     data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
    1010     bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
    1011 
    1012     /* symbols are always generated for linking stage */
    1013     symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
    1014                                 ".strtab",
    1015                                 ".hashtab", SHF_PRIVATE);
    1016     strtab_section = symtab_section->link;
    1017     s->symtab = symtab_section;
    1018    
    1019     /* private symbol table for dynamic symbols */
    1020     s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
    1021                                       ".dynstrtab",
    1022                                       ".dynhashtab", SHF_PRIVATE);
    1023     s->alacarte_link = 1;
    1024     s->nocommon = 1;
    1025     s->section_align = ELF_PAGE_SIZE;
    1026 
    1027 #ifdef CHAR_IS_UNSIGNED
    1028     s->char_is_unsigned = 1;
    1029 #endif
    1030     /* enable this if you want symbols with leading underscore on windows: */
    1031 #if 0 //def TCC_TARGET_PE
    1032     s->leading_underscore = 1;
    1033 #endif
    1034 #ifdef TCC_TARGET_I386
    1035     s->seg_size = 32;
    1036 #endif
     879    tcc_define_symbol(s, "__REDIRECT(name, proto, alias)",
     880        "name proto __asm__ (#alias)");
     881    tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
     882        "name proto __asm__ (#alias) __THROW");
     883# endif
     884# if defined(TCC_MUSL)
     885    tcc_define_symbol(s, "__DEFINED_va_list", "");
     886    tcc_define_symbol(s, "__DEFINED___isoc_va_list", "");
     887    tcc_define_symbol(s, "__isoc_va_list", "void *");
     888# endif /* TCC_MUSL */
     889    /* Some GCC builtins that are simple to express as macros.  */
     890    tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
     891#endif /* ndef TCC_TARGET_PE */
    1037892    return s;
    1038893}
     
    1040895LIBTCCAPI void tcc_delete(TCCState *s1)
    1041896{
    1042     int i;
    1043 
    1044897    tcc_cleanup();
    1045898
    1046     /* free all sections */
    1047     for(i = 1; i < s1->nb_sections; i++)
    1048         free_section(s1->sections[i]);
    1049     dynarray_reset(&s1->sections, &s1->nb_sections);
    1050 
    1051     for(i = 0; i < s1->nb_priv_sections; i++)
    1052         free_section(s1->priv_sections[i]);
    1053     dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
    1054        
    1055     /* free any loaded DLLs */
    1056     for ( i = 0; i < s1->nb_loaded_dlls; i++) {
    1057         DLLReference *ref = s1->loaded_dlls[i];
    1058         if ( ref->handle )
    1059             dlclose(ref->handle);
    1060     }
    1061    
    1062     /* free loaded dlls array */
    1063     dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
     899    /* free sections */
     900    tccelf_delete(s1);
    1064901
    1065902    /* free library paths */
     
    1071908    dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
    1072909    dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
     910    dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files);
    1073911
    1074912    tcc_free(s1->tcc_lib_path);
     
    1081919    dynarray_reset(&s1->files, &s1->nb_files);
    1082920    dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
     921    dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
     922    dynarray_reset(&s1->argv, &s1->argc);
    1083923
    1084924#ifdef TCC_IS_NATIVE
    1085 # ifdef HAVE_SELINUX
    1086     munmap (s1->write_mem, s1->mem_size);
    1087     munmap (s1->runtime_mem, s1->mem_size);   
    1088 # else
    1089     tcc_free(s1->runtime_mem);
     925    /* free runtime memory */
     926    tcc_run_free(s1);
     927#endif
     928
     929    tcc_free(s1);
     930    if (0 == --nb_states)
     931        tcc_memcheck();
     932}
     933
     934LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
     935{
     936    s->output_type = output_type;
     937
     938    /* always elf for objects */
     939    if (output_type == TCC_OUTPUT_OBJ)
     940        s->output_format = TCC_OUTPUT_FORMAT_ELF;
     941
     942    if (s->char_is_unsigned)
     943        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
     944
     945    if (!s->nostdinc) {
     946        /* default include paths */
     947        /* -isystem paths have already been handled */
     948        tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
     949    }
     950
     951#ifdef CONFIG_TCC_BCHECK
     952    if (s->do_bounds_check) {
     953        /* if bound checking, then add corresponding sections */
     954        tccelf_bounds_new(s);
     955        /* define symbol */
     956        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
     957    }
     958#endif
     959    if (s->do_debug) {
     960        /* add debug sections */
     961        tccelf_stab_new(s);
     962    }
     963
     964    tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
     965
     966#ifdef TCC_TARGET_PE
     967# ifdef _WIN32
     968    if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
     969        tcc_add_systemdir(s);
    1090970# endif
    1091 #endif
    1092 
    1093     tcc_free(s1);
     971#else
     972    /* paths for crt objects */
     973    tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
     974    /* add libc crt1/crti objects */
     975    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
     976        !s->nostdlib) {
     977        if (output_type != TCC_OUTPUT_DLL)
     978            tcc_add_crt(s, "crt1.o");
     979        tcc_add_crt(s, "crti.o");
     980    }
     981#endif
     982    return 0;
    1094983}
    1095984
    1096985LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
    1097986{
    1098     tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname);
     987    tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
    1099988    return 0;
    1100989}
     
    1102991LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
    1103992{
    1104     tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
     993    tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
    1105994    return 0;
    1106995}
     
    1108997ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
    1109998{
    1110     const char *ext;
    1111     ElfW(Ehdr) ehdr;
    1112     int fd, ret, size;
    1113 
    1114     /* find source file type with extension */
    1115     ext = tcc_fileextension(filename);
    1116     if (ext[0])
    1117         ext++;
    1118 
    1119 #ifdef CONFIG_TCC_ASM
    1120     /* if .S file, define __ASSEMBLER__ like gcc does */
    1121     if (!strcmp(ext, "S"))
    1122         tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
    1123 #endif
     999    int ret;
    11241000
    11251001    /* open the file */
     
    11321008
    11331009    /* update target deps */
    1134     dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
     1010    dynarray_add(&s1->target_deps, &s1->nb_target_deps,
    11351011            tcc_strdup(filename));
    11361012
    1137     if (flags & AFF_PREPROCESS) {
    1138         ret = tcc_preprocess(s1);
    1139         goto the_end;
    1140     }
    1141 
    1142     if (!ext[0] || !PATHCMP(ext, "c")) {
    1143         /* C file assumed */
    1144         ret = tcc_compile(s1);
    1145         goto the_end;
    1146     }
    1147 
    1148 #ifdef CONFIG_TCC_ASM
    1149     if (!strcmp(ext, "S")) {
    1150         /* preprocessed assembler */
    1151         ret = tcc_assemble(s1, 1);
    1152         goto the_end;
    1153     }
    1154 
    1155     if (!strcmp(ext, "s")) {
    1156         /* non preprocessed assembler */
    1157         ret = tcc_assemble(s1, 0);
    1158         goto the_end;
    1159     }
    1160 #endif
    1161 
    1162     fd = file->fd;
    1163     /* assume executable format: auto guess file type */
    1164     size = read(fd, &ehdr, sizeof(ehdr));
    1165     lseek(fd, 0, SEEK_SET);
    1166     if (size <= 0) {
    1167         tcc_error_noabort("could not read header");
    1168         goto the_end;
    1169     }
    1170 
    1171     if (size == sizeof(ehdr) &&
    1172         ehdr.e_ident[0] == ELFMAG0 &&
    1173         ehdr.e_ident[1] == ELFMAG1 &&
    1174         ehdr.e_ident[2] == ELFMAG2 &&
    1175         ehdr.e_ident[3] == ELFMAG3) {
    1176 
    1177         /* do not display line number if error */
    1178         file->line_num = 0;
    1179         if (ehdr.e_type == ET_REL) {
     1013    if (flags & AFF_TYPE_BIN) {
     1014        ElfW(Ehdr) ehdr;
     1015        int fd, obj_type;
     1016
     1017        fd = file->fd;
     1018        obj_type = tcc_object_type(fd, &ehdr);
     1019        lseek(fd, 0, SEEK_SET);
     1020
     1021#ifdef TCC_TARGET_MACHO
     1022        if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), ".dylib"))
     1023            obj_type = AFF_BINTYPE_DYN;
     1024#endif
     1025
     1026        switch (obj_type) {
     1027        case AFF_BINTYPE_REL:
    11801028            ret = tcc_load_object_file(s1, fd, 0);
    1181             goto the_end;
    1182 
    1183         }
     1029            break;
    11841030#ifndef TCC_TARGET_PE
    1185         if (ehdr.e_type == ET_DYN) {
     1031        case AFF_BINTYPE_DYN:
    11861032            if (s1->output_type == TCC_OUTPUT_MEMORY) {
     1033                ret = 0;
    11871034#ifdef TCC_IS_NATIVE
    1188                 void *h;
    1189                 h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
    1190                 if (h)
    1191 #endif
    1192                     ret = 0;
     1035                if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
     1036                    ret = -1;
     1037#endif
    11931038            } else {
    1194                 ret = tcc_load_dll(s1, fd, filename, 
     1039                ret = tcc_load_dll(s1, fd, filename,
    11951040                                   (flags & AFF_REFERENCED_DLL) != 0);
    11961041            }
    1197             goto the_end;
     1042            break;
     1043#endif
     1044        case AFF_BINTYPE_AR:
     1045            ret = tcc_load_archive(s1, fd);
     1046            break;
     1047#ifdef TCC_TARGET_COFF
     1048        case AFF_BINTYPE_C67:
     1049            ret = tcc_load_coff(s1, fd);
     1050            break;
     1051#endif
     1052        default:
     1053#ifdef TCC_TARGET_PE
     1054            ret = pe_load_file(s1, filename, fd);
     1055#else
     1056            /* as GNU ld, consider it is an ld script if not recognized */
     1057            ret = tcc_load_ldscript(s1);
     1058#endif
     1059            if (ret < 0)
     1060                tcc_error_noabort("unrecognized file type");
     1061            break;
    11981062        }
    1199 #endif
    1200         tcc_error_noabort("unrecognized ELF file");
    1201         goto the_end;
    1202     }
    1203 
    1204     if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
    1205         file->line_num = 0; /* do not display line number if error */
    1206         ret = tcc_load_archive(s1, fd);
    1207         goto the_end;
    1208     }
    1209 
    1210 #ifdef TCC_TARGET_COFF
    1211     if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
    1212         ret = tcc_load_coff(s1, fd);
    1213         goto the_end;
    1214     }
    1215 #endif
    1216 
    1217 #ifdef TCC_TARGET_PE
    1218     ret = pe_load_file(s1, filename, fd);
    1219 #else
    1220     /* as GNU ld, consider it is an ld script if not recognized */
    1221     ret = tcc_load_ldscript(s1);
    1222 #endif
    1223     if (ret < 0)
    1224         tcc_error_noabort("unrecognized file type");
    1225 
    1226 the_end:
     1063    } else {
     1064        ret = tcc_compile(s1);
     1065    }
    12271066    tcc_close();
    12281067    return ret;
     
    12311070LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
    12321071{
    1233     if (s->output_type == TCC_OUTPUT_PREPROCESS)
    1234         return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
    1235     else
    1236         return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
     1072    int filetype = s->filetype;
     1073    int flags = AFF_PRINT_ERROR;
     1074    if (filetype == 0) {
     1075        /* use a file extension to detect a filetype */
     1076        const char *ext = tcc_fileextension(filename);
     1077        if (ext[0]) {
     1078            ext++;
     1079            if (!strcmp(ext, "S"))
     1080                filetype = AFF_TYPE_ASMPP;
     1081            else if (!strcmp(ext, "s"))
     1082                filetype = AFF_TYPE_ASM;
     1083            else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
     1084                filetype = AFF_TYPE_C;
     1085            else
     1086                flags |= AFF_TYPE_BIN;
     1087        } else {
     1088            filetype = AFF_TYPE_C;
     1089        }
     1090        s->filetype = filetype;
     1091    }
     1092    return tcc_add_file_internal(s, filename, flags);
    12371093}
    12381094
    12391095LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
    12401096{
    1241     tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname);
     1097    tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
    12421098    return 0;
    12431099}
     
    12511107    for(i = 0; i < nb_paths; i++) {
    12521108        snprintf(buf, sizeof(buf), fmt, paths[i], filename);
    1253         if (tcc_add_file_internal(s, buf, flags) == 0)
     1109        if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
    12541110            return 0;
    12551111    }
     
    12761132LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
    12771133{
    1278 #ifdef TCC_TARGET_PE
     1134#if defined TCC_TARGET_PE
    12791135    const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
    12801136    const char **pp = s->static_link ? libs + 4 : libs;
     1137#elif defined TCC_TARGET_MACHO
     1138    const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
     1139    const char **pp = s->static_link ? libs + 1 : libs;
    12811140#else
    12821141    const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
     
    12921151}
    12931152
     1153PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
     1154{
     1155    int ret = tcc_add_library(s, libname);
     1156    if (ret < 0)
     1157        tcc_error_noabort("library '%s' not found", libname);
     1158    return ret;
     1159}
     1160
     1161/* handle #pragma comment(lib,) */
     1162ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
     1163{
     1164    int i;
     1165    for (i = 0; i < s1->nb_pragma_libs; i++)
     1166        tcc_add_library_err(s1, s1->pragma_libs[i]);
     1167}
     1168
    12941169LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
    12951170{
     
    12991174    pe_putimport(s, 0, name, (uintptr_t)val);
    13001175#else
    1301     /* XXX: Same problem on linux but currently "solved" elsewhere
    1302        via the rather dirty 'runtime_plt_and_got' hack. */
    1303     add_elf_sym(symtab_section, (uintptr_t)val, 0,
     1176    set_elf_sym(symtab_section, (uintptr_t)val, 0,
    13041177        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13051178        SHN_ABS, name);
    1306 #endif
    1307     return 0;
    1308 }
    1309 
    1310 LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
    1311 {
    1312     s->output_type = output_type;
    1313 
    1314     if (!s->nostdinc) {
    1315         /* default include paths */
    1316         /* -isystem paths have already been handled */
    1317         tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
    1318     }
    1319 
    1320     /* if bound checking, then add corresponding sections */
    1321 #ifdef CONFIG_TCC_BCHECK
    1322     if (s->do_bounds_check) {
    1323         /* define symbol */
    1324         tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
    1325         /* create bounds sections */
    1326         bounds_section = new_section(s, ".bounds",
    1327                                      SHT_PROGBITS, SHF_ALLOC);
    1328         lbounds_section = new_section(s, ".lbounds",
    1329                                       SHT_PROGBITS, SHF_ALLOC);
    1330     }
    1331 #endif
    1332 
    1333     if (s->char_is_unsigned) {
    1334         tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
    1335     }
    1336 
    1337     /* add debug sections */
    1338     if (s->do_debug) {
    1339         /* stab symbols */
    1340         stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
    1341         stab_section->sh_entsize = sizeof(Stab_Sym);
    1342         stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
    1343         put_elf_str(stabstr_section, "");
    1344         stab_section->link = stabstr_section;
    1345         /* put first entry */
    1346         put_stabs("", 0, 0, 0, 0);
    1347     }
    1348 
    1349 #ifdef TCC_TARGET_PE
    1350     tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
    1351 # ifdef _WIN32
    1352     tcc_add_systemdir(s);
    1353 # endif
    1354 #else
    1355     /* add libc crt1/crti objects */
    1356     if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
    1357         !s->nostdlib) {
    1358         if (output_type != TCC_OUTPUT_DLL)
    1359             tcc_add_crt(s, "crt1.o");
    1360         tcc_add_crt(s, "crti.o");
    1361     }
    13621179#endif
    13631180    return 0;
     
    13791196} FlagDef;
    13801197
    1381 static const FlagDef warning_defs[] = {
    1382     { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
    1383     { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
    1384     { offsetof(TCCState, warn_error), 0, "error" },
    1385     { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
    1386       "implicit-function-declaration" },
    1387 };
    1388 
    1389 ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
    1390                     const char *name, int value)
    1391 {
    1392     int i;
     1198static int no_flag(const char **pp)
     1199{
     1200    const char *p = *pp;
     1201    if (*p != 'n' || *++p != 'o' || *++p != '-')
     1202        return 0;
     1203    *pp = p + 1;
     1204    return 1;
     1205}
     1206
     1207ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
     1208{
     1209    int value, ret;
    13931210    const FlagDef *p;
    13941211    const char *r;
    13951212
     1213    value = 1;
    13961214    r = name;
    1397     if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
    1398         r += 3;
    1399         value = !value;
    1400     }
    1401     for(i = 0, p = flags; i < nb_flags; i++, p++) {
    1402         if (!strcmp(r, p->name))
    1403             goto found;
    1404     }
    1405     return -1;
    1406  found:
    1407     if (p->flags & FD_INVERT)
    1408         value = !value;
    1409     *(int *)((uint8_t *)s + p->offset) = value;
    1410     return 0;
    1411 }
    1412 
    1413 /* set/reset a warning */
    1414 static int tcc_set_warning(TCCState *s, const char *warning_name, int value)
    1415 {
    1416     int i;
    1417     const FlagDef *p;
    1418 
    1419     if (!strcmp(warning_name, "all")) {
    1420         for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
    1421             if (p->flags & WD_ALL)
    1422                 *(int *)((uint8_t *)s + p->offset) = 1;
     1215    if (no_flag(&r))
     1216        value = 0;
     1217
     1218    for (ret = -1, p = flags; p->name; ++p) {
     1219        if (ret) {
     1220            if (strcmp(r, p->name))
     1221                continue;
     1222        } else {
     1223            if (0 == (p->flags & WD_ALL))
     1224                continue;
    14231225        }
    1424         return 0;
    1425     } else {
    1426         return set_flag(s, warning_defs, countof(warning_defs),
    1427                         warning_name, value);
    1428     }
    1429 }
    1430 
    1431 static const FlagDef flag_defs[] = {
    1432     { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
    1433     { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
    1434     { offsetof(TCCState, nocommon), FD_INVERT, "common" },
    1435     { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
    1436 };
    1437 
    1438 /* set/reset a flag */
    1439 static int tcc_set_flag(TCCState *s, const char *flag_name, int value)
    1440 {
    1441     return set_flag(s, flag_defs, countof(flag_defs),
    1442                     flag_name, value);
    1443 }
    1444 
     1226        if (p->offset) {
     1227            *(int*)((char *)s + p->offset) =
     1228                p->flags & FD_INVERT ? !value : value;
     1229            if (ret)
     1230                return 0;
     1231        } else {
     1232            ret = 0;
     1233        }
     1234    }
     1235    return ret;
     1236}
    14451237
    14461238static int strstart(const char *val, const char **str)
     
    14701262{
    14711263    const char *p, *q;
     1264    int ret;
    14721265
    14731266    /* there should be 1 or 2 dashes */
     
    14771270        str++;
    14781271
    1479     /* then str & val should match (potentialy up to '=') */
     1272    /* then str & val should match (potentially up to '=') */
    14801273    p = str;
    14811274    q = val;
     1275
     1276    ret = 1;
     1277    if (q[0] == '?') {
     1278        ++q;
     1279        if (no_flag(&p))
     1280            ret = -1;
     1281    }
    14821282
    14831283    while (*q != '\0' && *q != '=') {
     
    14901290    /* '=' near eos means ',' or '=' is ok */
    14911291    if (*q == '=') {
     1292        if (*p == 0)
     1293            *ptr = p;
    14921294        if (*p != ',' && *p != '=')
    14931295            return 0;
    14941296        p++;
    1495         q++;
    1496     }
    1497 
    1498     if (ptr)
    1499         *ptr = p;
    1500     return 1;
     1297    } else if (*p) {
     1298        return 0;
     1299    }
     1300    *ptr = p;
     1301    return ret;
    15011302}
    15021303
     
    15091310}
    15101311
    1511 static char *copy_linker_arg(const char *p)
    1512 {
    1513     const char *q = p;
     1312static void copy_linker_arg(char **pp, const char *s, int sep)
     1313{
     1314    const char *q = s;
     1315    char *p = *pp;
     1316    int l = 0;
     1317    if (p && sep)
     1318        p[l = strlen(p)] = sep, ++l;
    15141319    skip_linker_arg(&q);
    1515     return pstrncpy(tcc_malloc(q - p + 1), p, q - p);
     1320    pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
    15161321}
    15171322
     
    15191324static int tcc_set_linker(TCCState *s, const char *option)
    15201325{
    1521     while (option && *option) {
    1522 
    1523         const char *p = option;
     1326    while (*option) {
     1327
     1328        const char *p = NULL;
    15241329        char *end = NULL;
    15251330        int ignoring = 0;
     1331        int ret;
    15261332
    15271333        if (link_option(option, "Bsymbolic", &p)) {
     
    15301336            s->nostdlib = 1;
    15311337        } else if (link_option(option, "fini=", &p)) {
    1532             s->fini_symbol = copy_linker_arg(p);
     1338            copy_linker_arg(&s->fini_symbol, p, 0);
    15331339            ignoring = 1;
    15341340        } else if (link_option(option, "image-base=", &p)
     
    15371343            s->has_text_addr = 1;
    15381344        } else if (link_option(option, "init=", &p)) {
    1539             s->init_symbol = copy_linker_arg(p);
     1345            copy_linker_arg(&s->init_symbol, p, 0);
    15401346            ignoring = 1;
    15411347        } else if (link_option(option, "oformat=", &p)) {
    15421348#if defined(TCC_TARGET_PE)
    15431349            if (strstart("pe-", &p)) {
    1544 #elif defined(TCC_TARGET_X86_64)
     1350#elif PTR_SIZE == 8
    15451351            if (strstart("elf64-", &p)) {
    15461352#else
     
    15571363                goto err;
    15581364
     1365        } else if (link_option(option, "as-needed", &p)) {
     1366            ignoring = 1;
     1367        } else if (link_option(option, "O", &p)) {
     1368            ignoring = 1;
     1369        } else if (link_option(option, "export-all-symbols", &p)) {
     1370            s->rdynamic = 1;
    15591371        } else if (link_option(option, "rpath=", &p)) {
    1560             s->rpath = copy_linker_arg(p);
     1372            copy_linker_arg(&s->rpath, p, ':');
     1373        } else if (link_option(option, "enable-new-dtags", &p)) {
     1374            s->enable_new_dtags = 1;
    15611375        } else if (link_option(option, "section-alignment=", &p)) {
    15621376            s->section_align = strtoul(p, &end, 16);
    15631377        } else if (link_option(option, "soname=", &p)) {
    1564             s->soname = copy_linker_arg(p);
     1378            copy_linker_arg(&s->soname, p, 0);
    15651379#ifdef TCC_TARGET_PE
     1380        } else if (link_option(option, "large-address-aware", &p)) {
     1381            s->pe_characteristics |= 0x20;
    15661382        } else if (link_option(option, "file-alignment=", &p)) {
    15671383            s->pe_file_align = strtoul(p, &end, 16);
     
    15741390            } else if (!strcmp(p, "console")) {
    15751391                s->pe_subsystem = 3;
    1576             } else if (!strcmp(p, "gui")) {
     1392            } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
    15771393                s->pe_subsystem = 2;
    15781394            } else if (!strcmp(p, "posix")) {
     
    15931409                goto err;
    15941410#endif
    1595         } else
    1596             goto err;
    1597 
    1598         if (ignoring && s->warn_unsupported) err: {
    1599             char buf[100], *e;
    1600             pstrcpy(buf, sizeof buf, e = copy_linker_arg(option)), tcc_free(e);
    1601             if (ignoring)
    1602                 tcc_warning("unsupported linker option '%s'", buf);
    1603             else
    1604                 tcc_error("unsupported linker option '%s'", buf);
     1411        } else if (ret = link_option(option, "?whole-archive", &p), ret) {
     1412            s->alacarte_link = ret < 0;
     1413        } else if (p) {
     1414            return 0;
     1415        } else {
     1416    err:
     1417            tcc_error("unsupported linker option '%s'", option);
    16051418        }
     1419
     1420        if (ignoring && s->warn_unsupported)
     1421            tcc_warning("unsupported linker option '%s'", option);
     1422
    16061423        option = skip_linker_arg(&p);
    16071424    }
    1608     return 0;
     1425    return 1;
    16091426}
    16101427
     
    16171434enum {
    16181435    TCC_OPTION_HELP,
     1436    TCC_OPTION_HELP2,
     1437    TCC_OPTION_v,
    16191438    TCC_OPTION_I,
    16201439    TCC_OPTION_D,
    16211440    TCC_OPTION_U,
     1441    TCC_OPTION_P,
    16221442    TCC_OPTION_L,
    16231443    TCC_OPTION_B,
     
    16281448    TCC_OPTION_g,
    16291449    TCC_OPTION_c,
     1450    TCC_OPTION_dumpversion,
     1451    TCC_OPTION_d,
    16301452    TCC_OPTION_static,
     1453    TCC_OPTION_std,
    16311454    TCC_OPTION_shared,
    16321455    TCC_OPTION_soname,
     
    16341457    TCC_OPTION_r,
    16351458    TCC_OPTION_s,
     1459    TCC_OPTION_traditional,
    16361460    TCC_OPTION_Wl,
     1461    TCC_OPTION_Wp,
    16371462    TCC_OPTION_W,
    16381463    TCC_OPTION_O,
     1464    TCC_OPTION_mfloat_abi,
    16391465    TCC_OPTION_m,
    16401466    TCC_OPTION_f,
    16411467    TCC_OPTION_isystem,
     1468    TCC_OPTION_iwithprefix,
     1469    TCC_OPTION_include,
    16421470    TCC_OPTION_nostdinc,
    16431471    TCC_OPTION_nostdlib,
    16441472    TCC_OPTION_print_search_dirs,
    16451473    TCC_OPTION_rdynamic,
     1474    TCC_OPTION_param,
    16461475    TCC_OPTION_pedantic,
    16471476    TCC_OPTION_pthread,
    16481477    TCC_OPTION_run,
    1649     TCC_OPTION_v,
    16501478    TCC_OPTION_w,
    16511479    TCC_OPTION_pipe,
     
    16541482    TCC_OPTION_MF,
    16551483    TCC_OPTION_x,
    1656     TCC_OPTION_dumpversion,
     1484    TCC_OPTION_ar,
     1485    TCC_OPTION_impdef
    16571486};
    16581487
     
    16641493    { "-help", TCC_OPTION_HELP, 0 },
    16651494    { "?", TCC_OPTION_HELP, 0 },
     1495    { "hh", TCC_OPTION_HELP2, 0 },
     1496    { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16661497    { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
    16671498    { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
    16681499    { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
     1500    { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16691501    { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
    16701502    { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
     
    16791511    { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16801512    { "c", TCC_OPTION_c, 0 },
     1513    { "dumpversion", TCC_OPTION_dumpversion, 0},
     1514    { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16811515    { "static", TCC_OPTION_static, 0 },
     1516    { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16821517    { "shared", TCC_OPTION_shared, 0 },
    16831518    { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
    16841519    { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
     1520    { "-param", TCC_OPTION_param, TCC_OPTION_HAS_ARG },
    16851521    { "pedantic", TCC_OPTION_pedantic, 0},
    16861522    { "pthread", TCC_OPTION_pthread, 0},
     
    16891525    { "r", TCC_OPTION_r, 0 },
    16901526    { "s", TCC_OPTION_s, 0 },
     1527    { "traditional", TCC_OPTION_traditional, 0 },
    16911528    { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     1529    { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16921530    { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16931531    { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    1694     { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
     1532#ifdef TCC_TARGET_ARM
     1533    { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
     1534#endif
     1535    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16951536    { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    16961537    { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
     1538    { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
    16971539    { "nostdinc", TCC_OPTION_nostdinc, 0 },
    16981540    { "nostdlib", TCC_OPTION_nostdlib, 0 },
    1699     { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
    1700     { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     1541    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
    17011542    { "w", TCC_OPTION_w, 0 },
    17021543    { "pipe", TCC_OPTION_pipe, 0},
     
    17051546    { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
    17061547    { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
    1707     { "dumpversion", TCC_OPTION_dumpversion, 0},
     1548    { "ar", TCC_OPTION_ar, 0},
     1549#ifdef TCC_TARGET_PE
     1550    { "impdef", TCC_OPTION_impdef, 0},
     1551#endif
    17081552    { NULL, 0, 0 },
     1553};
     1554
     1555static const FlagDef options_W[] = {
     1556    { 0, 0, "all" },
     1557    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
     1558    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
     1559    { offsetof(TCCState, warn_error), 0, "error" },
     1560    { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
     1561    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
     1562      "implicit-function-declaration" },
     1563    { 0, 0, NULL }
     1564};
     1565
     1566static const FlagDef options_f[] = {
     1567    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
     1568    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
     1569    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
     1570    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
     1571    { offsetof(TCCState, ms_extensions), 0, "ms-extensions" },
     1572    { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
     1573    { 0, 0, NULL }
     1574};
     1575
     1576static const FlagDef options_m[] = {
     1577    { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" },
     1578#ifdef TCC_TARGET_X86_64
     1579    { offsetof(TCCState, nosse), FD_INVERT, "sse" },
     1580#endif
     1581    { 0, 0, NULL }
    17091582};
    17101583
     
    17191592}
    17201593
    1721 PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
     1594static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
     1595{
     1596    struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
     1597    f->type = filetype;
     1598    f->alacarte = s->alacarte_link;
     1599    strcpy(f->name, filename);
     1600    dynarray_add(&s->files, &s->nb_files, f);
     1601}
     1602
     1603static int args_parser_make_argv(const char *r, int *argc, char ***argv)
     1604{
     1605    int ret = 0, q, c;
     1606    CString str;
     1607    for(;;) {
     1608        while (c = (unsigned char)*r, c && c <= ' ')
     1609            ++r;
     1610        if (c == 0)
     1611            break;
     1612        q = 0;
     1613        cstr_new(&str);
     1614        while (c = (unsigned char)*r, c) {
     1615            ++r;
     1616            if (c == '\\' && (*r == '"' || *r == '\\')) {
     1617                c = *r++;
     1618            } else if (c == '"') {
     1619                q = !q;
     1620                continue;
     1621            } else if (q == 0 && c <= ' ') {
     1622                break;
     1623            }
     1624            cstr_ccat(&str, c);
     1625        }
     1626        cstr_ccat(&str, 0);
     1627        //printf("<%s>\n", str.data), fflush(stdout);
     1628        dynarray_add(argv, argc, tcc_strdup(str.data));
     1629        cstr_free(&str);
     1630        ++ret;
     1631    }
     1632    return ret;
     1633}
     1634
     1635/* read list file */
     1636static void args_parser_listfile(TCCState *s,
     1637    const char *filename, int optind, int *pargc, char ***pargv)
     1638{
     1639    int fd, i;
     1640    size_t len;
     1641    char *p;
     1642    int argc = 0;
     1643    char **argv = NULL;
     1644
     1645    fd = open(filename, O_RDONLY | O_BINARY);
     1646    if (fd < 0)
     1647        tcc_error("listfile '%s' not found", filename);
     1648
     1649    len = lseek(fd, 0, SEEK_END);
     1650    p = tcc_malloc(len + 1), p[len] = 0;
     1651    lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd);
     1652
     1653    for (i = 0; i < *pargc; ++i)
     1654        if (i == optind)
     1655            args_parser_make_argv(p, &argc, &argv);
     1656        else
     1657            dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
     1658
     1659    tcc_free(p);
     1660    dynarray_reset(&s->argv, &s->argc);
     1661    *pargc = s->argc = argc, *pargv = s->argv = argv;
     1662}
     1663
     1664PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
    17221665{
    17231666    const TCCOption *popt;
    17241667    const char *optarg, *r;
    1725     int run = 0;
    1726     int pthread = 0;
    1727     int optind = 0;
    1728 
    1729     /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
    1730     CString linker_arg;
     1668    const char *run = NULL;
     1669    int last_o = -1;
     1670    int x;
     1671    CString linker_arg; /* collect -Wl options */
     1672    int tool = 0, arg_start = 0, noaction = optind;
     1673    char **argv = *pargv;
     1674    int argc = *pargc;
     1675
    17311676    cstr_new(&linker_arg);
    17321677
    17331678    while (optind < argc) {
    1734 
    1735         r = argv[optind++];
     1679        r = argv[optind];
     1680        if (r[0] == '@' && r[1] != '\0') {
     1681            args_parser_listfile(s, r + 1, optind, &argc, &argv);
     1682            continue;
     1683        }
     1684        optind++;
     1685        if (tool) {
     1686            if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
     1687                ++s->verbose;
     1688            continue;
     1689        }
     1690reparse:
    17361691        if (r[0] != '-' || r[1] == '\0') {
    1737             /* add a new file */
    1738             dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r));
     1692            if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
     1693                args_parser_add_file(s, r, s->filetype);
    17391694            if (run) {
    1740                 optind--;
    1741                 /* argv[0] will be this file */
     1695                tcc_set_options(s, run);
     1696                arg_start = optind - 1;
    17421697                break;
    17431698            }
     
    17571712                if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
    17581713                    if (optind >= argc)
     1714                arg_err:
    17591715                        tcc_error("argument to '%s' is missing", r);
    17601716                    optarg = argv[optind++];
     
    17671723        switch(popt->index) {
    17681724        case TCC_OPTION_HELP:
    1769             return 0;
     1725            return OPT_HELP;
     1726        case TCC_OPTION_HELP2:
     1727            return OPT_HELP2;
    17701728        case TCC_OPTION_I:
    1771             if (tcc_add_include_path(s, optarg) < 0)
    1772                 tcc_error("too many include paths");
     1729            tcc_add_include_path(s, optarg);
    17731730            break;
    17741731        case TCC_OPTION_D:
     
    17861743            break;
    17871744        case TCC_OPTION_l:
    1788             dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r));
     1745            args_parser_add_file(s, optarg, AFF_TYPE_LIB);
    17891746            s->nb_libraries++;
    17901747            break;
    17911748        case TCC_OPTION_pthread:
    17921749            parse_option_D(s, "_REENTRANT");
    1793             pthread = 1;
     1750            s->option_pthread = 1;
    17941751            break;
    17951752        case TCC_OPTION_bench:
     
    18111768            break;
    18121769        case TCC_OPTION_c:
    1813             s->output_type = TCC_OUTPUT_OBJ;
     1770            x = TCC_OUTPUT_OBJ;
     1771        set_output_type:
     1772            if (s->output_type)
     1773                tcc_warning("-%s: overriding compiler action already specified", popt->name);
     1774            s->output_type = x;
     1775            break;
     1776        case TCC_OPTION_d:
     1777            if (*optarg == 'D')
     1778                s->dflag = 3;
     1779            else if (*optarg == 'M')
     1780                s->dflag = 7;
     1781            else if (*optarg == 't')
     1782                s->dflag = 16;
     1783            else if (isnum(*optarg))
     1784                g_debug = atoi(optarg);
     1785            else
     1786                goto unsupported_option;
    18141787            break;
    18151788        case TCC_OPTION_static:
    18161789            s->static_link = 1;
    18171790            break;
     1791        case TCC_OPTION_std:
     1792            /* silently ignore, a current purpose:
     1793               allow to use a tcc as a reference compiler for "make test" */
     1794            break;
    18181795        case TCC_OPTION_shared:
    1819             s->output_type = TCC_OUTPUT_DLL;
    1820             break;
     1796            x = TCC_OUTPUT_DLL;
     1797            goto set_output_type;
    18211798        case TCC_OPTION_soname:
    18221799            s->soname = tcc_strdup(optarg);
    18231800            break;
    1824         case TCC_OPTION_m:
    1825             s->option_m = tcc_strdup(optarg);
    1826             break;
    18271801        case TCC_OPTION_o:
     1802            if (s->outfile) {
     1803                tcc_warning("multiple -o option");
     1804                tcc_free(s->outfile);
     1805            }
    18281806            s->outfile = tcc_strdup(optarg);
    18291807            break;
     
    18311809            /* generate a .o merging several output files */
    18321810            s->option_r = 1;
    1833             s->output_type = TCC_OUTPUT_OBJ;
    1834             break;
     1811            x = TCC_OUTPUT_OBJ;
     1812            goto set_output_type;
    18351813        case TCC_OPTION_isystem:
    18361814            tcc_add_sysinclude_path(s, optarg);
    18371815            break;
     1816        case TCC_OPTION_include:
     1817            dynarray_add(&s->cmd_include_files,
     1818                         &s->nb_cmd_include_files, tcc_strdup(optarg));
     1819            break;
    18381820        case TCC_OPTION_nostdinc:
    18391821            s->nostdinc = 1;
     
    18421824            s->nostdlib = 1;
    18431825            break;
    1844         case TCC_OPTION_print_search_dirs:
    1845             s->print_search_dirs = 1;
    1846             break;
    18471826        case TCC_OPTION_run:
    1848             s->output_type = TCC_OUTPUT_MEMORY;
    1849             tcc_set_options(s, optarg);
    1850             run = 1;
    1851             break;
     1827#ifndef TCC_IS_NATIVE
     1828            tcc_error("-run is not available in a cross compiler");
     1829#endif
     1830            run = optarg;
     1831            x = TCC_OUTPUT_MEMORY;
     1832            goto set_output_type;
    18521833        case TCC_OPTION_v:
    18531834            do ++s->verbose; while (*optarg++ == 'v');
     1835            ++noaction;
    18541836            break;
    18551837        case TCC_OPTION_f:
    1856             if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
     1838            if (set_flag(s, options_f, optarg) < 0)
    18571839                goto unsupported_option;
    18581840            break;
     1841#ifdef TCC_TARGET_ARM
     1842        case TCC_OPTION_mfloat_abi:
     1843            /* tcc doesn't support soft float yet */
     1844            if (!strcmp(optarg, "softfp")) {
     1845                s->float_abi = ARM_SOFTFP_FLOAT;
     1846                tcc_undefine_symbol(s, "__ARM_PCS_VFP");
     1847            } else if (!strcmp(optarg, "hard"))
     1848                s->float_abi = ARM_HARD_FLOAT;
     1849            else
     1850                tcc_error("unsupported float abi '%s'", optarg);
     1851            break;
     1852#endif
     1853        case TCC_OPTION_m:
     1854            if (set_flag(s, options_m, optarg) < 0) {
     1855                if (x = atoi(optarg), x != 32 && x != 64)
     1856                    goto unsupported_option;
     1857                if (PTR_SIZE != x/8)
     1858                    return x;
     1859                ++noaction;
     1860            }
     1861            break;
    18591862        case TCC_OPTION_W:
    1860             if (tcc_set_warning(s, optarg, 1) < 0 &&
    1861                 s->warn_unsupported)
     1863            if (set_flag(s, options_W, optarg) < 0)
    18621864                goto unsupported_option;
    18631865            break;
     
    18711873            if (linker_arg.size)
    18721874                --linker_arg.size, cstr_ccat(&linker_arg, ',');
    1873             cstr_cat(&linker_arg, optarg);
    1874             cstr_ccat(&linker_arg, '\0');
    1875             break;
     1875            cstr_cat(&linker_arg, optarg, 0);
     1876            if (tcc_set_linker(s, linker_arg.data))
     1877                cstr_free(&linker_arg);
     1878            break;
     1879        case TCC_OPTION_Wp:
     1880            r = optarg;
     1881            goto reparse;
    18761882        case TCC_OPTION_E:
    1877             s->output_type = TCC_OUTPUT_PREPROCESS;
     1883            x = TCC_OUTPUT_PREPROCESS;
     1884            goto set_output_type;
     1885        case TCC_OPTION_P:
     1886            s->Pflag = atoi(optarg) + 1;
    18781887            break;
    18791888        case TCC_OPTION_MD:
     
    18861895            printf ("%s\n", TCC_VERSION);
    18871896            exit(0);
     1897            break;
     1898        case TCC_OPTION_x:
     1899            if (*optarg == 'c')
     1900                s->filetype = AFF_TYPE_C;
     1901            else if (*optarg == 'a')
     1902                s->filetype = AFF_TYPE_ASMPP;
     1903            else if (*optarg == 'n')
     1904                s->filetype = AFF_TYPE_NONE;
     1905            else
     1906                tcc_warning("unsupported language '%s'", optarg);
     1907            break;
    18881908        case TCC_OPTION_O:
     1909            last_o = atoi(optarg);
     1910            break;
     1911        case TCC_OPTION_print_search_dirs:
     1912            x = OPT_PRINT_DIRS;
     1913            goto extra_action;
     1914        case TCC_OPTION_impdef:
     1915            x = OPT_IMPDEF;
     1916            goto extra_action;
     1917        case TCC_OPTION_ar:
     1918            x = OPT_AR;
     1919        extra_action:
     1920            arg_start = optind - 1;
     1921            if (arg_start != noaction)
     1922                tcc_error("cannot parse %s here", r);
     1923            tool = x;
     1924            break;
     1925        case TCC_OPTION_traditional:
    18891926        case TCC_OPTION_pedantic:
    18901927        case TCC_OPTION_pipe:
    18911928        case TCC_OPTION_s:
    1892         case TCC_OPTION_x:
    18931929            /* ignored */
    18941930            break;
    18951931        default:
    1896             if (s->warn_unsupported) {
    1897             unsupported_option:
     1932unsupported_option:
     1933            if (s->warn_unsupported)
    18981934                tcc_warning("unsupported option '%s'", r);
    1899             }
    19001935            break;
    19011936        }
    19021937    }
    1903 
    1904     if (pthread && s->output_type != TCC_OUTPUT_OBJ)
    1905         tcc_set_options(s, "-lpthread");
    1906 
    1907     tcc_set_linker(s, (const char *)linker_arg.data);
    1908     cstr_free(&linker_arg);
    1909 
    1910     return optind;
    1911 }
    1912 
    1913 LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)
    1914 {
    1915     const char *s1;
    1916     char **argv, *arg;
    1917     int argc, len;
    1918     int ret;
    1919 
    1920     argc = 0, argv = NULL;
    1921     for(;;) {
    1922         while (is_space(*str))
    1923             str++;
    1924         if (*str == '\0')
    1925             break;
    1926         s1 = str;
    1927         while (*str != '\0' && !is_space(*str))
    1928             str++;
    1929         len = str - s1;
    1930         arg = tcc_malloc(len + 1);
    1931         pstrncpy(arg, s1, len);
    1932         dynarray_add((void ***)&argv, &argc, arg);
    1933     }
    1934     ret = tcc_parse_args(s, argc, argv);
     1938    if (last_o > 0)
     1939        tcc_define_symbol(s, "__OPTIMIZE__", NULL);
     1940    if (linker_arg.size) {
     1941        r = linker_arg.data;
     1942        goto arg_err;
     1943    }
     1944    *pargc = argc - arg_start;
     1945    *pargv = argv + arg_start;
     1946    if (tool)
     1947        return tool;
     1948    if (optind != noaction)
     1949        return 0;
     1950    if (s->verbose == 2)
     1951        return OPT_PRINT_DIRS;
     1952    if (s->verbose)
     1953        return OPT_V;
     1954    return OPT_HELP;
     1955}
     1956
     1957LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
     1958{
     1959    char **argv = NULL;
     1960    int argc = 0;
     1961    args_parser_make_argv(r, &argc, &argv);
     1962    tcc_parse_args(s, &argc, &argv, 0);
    19351963    dynarray_reset(&argv, &argc);
    1936     return ret;
    1937 }
    1938 
    1939 PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
    1940 {
    1941     double tt;
    1942     tt = (double)total_time / 1000000.0;
    1943     if (tt < 0.001)
    1944         tt = 0.001;
     1964}
     1965
     1966PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
     1967{
     1968    if (total_time < 1)
     1969        total_time = 1;
    19451970    if (total_bytes < 1)
    19461971        total_bytes = 1;
    1947     printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
     1972    fprintf(stderr, "* %d idents, %d lines, %d bytes\n"
     1973                    "* %0.3f s, %u lines/s, %0.1f MB/s\n",
    19481974           tok_ident - TOK_IDENT, total_lines, total_bytes,
    1949            tt, (int)(total_lines / tt),
    1950            total_bytes / tt / 1000000.0);
    1951 }
     1975           (double)total_time/1000,
     1976           (unsigned)total_lines*1000/total_time,
     1977           (double)total_bytes/1000/total_time);
     1978#ifdef MEM_DEBUG
     1979    fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
     1980#endif
     1981}
  • EcnlProtoTool/trunk/tcc-0.9.27/libtcc.h

    r321 r331  
    2828
    2929/* set options as from command line (multiple supported) */
    30 LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
     30LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
    3131
    3232/*****************************/
     
    5959/* set output type. MUST BE CALLED before any compilation */
    6060LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
    61 #define TCC_OUTPUT_MEMORY   0 /* output will be run in memory (default) */
    62 #define TCC_OUTPUT_EXE      1 /* executable file */
    63 #define TCC_OUTPUT_DLL      2 /* dynamic library */
    64 #define TCC_OUTPUT_OBJ      3 /* object file */
    65 #define TCC_OUTPUT_PREPROCESS 4 /* only preprocess (used internally) */
     61#define TCC_OUTPUT_MEMORY   1 /* output will be run in memory (default) */
     62#define TCC_OUTPUT_EXE      2 /* executable file */
     63#define TCC_OUTPUT_DLL      3 /* dynamic library */
     64#define TCC_OUTPUT_OBJ      4 /* object file */
     65#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
    6666
    6767/* equivalent to -Lpath option */
  • EcnlProtoTool/trunk/tcc-0.9.27/stab.def

    • Property svn:keywords deleted
  • EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.html

    • Property svn:keywords deleted
    r279 r331  
    1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
    2 <html>
    3 <!-- Created on February 15, 2013 by texi2html 1.82
    4 texi2html was written by:
    5             Lionel Cons <Lionel.Cons@cern.ch> (original author)
    6             Karl Berry  <karl@freefriends.org>
    7             Olaf Bachmann <obachman@mathematik.uni-kl.de>
    8             and many others.
    9 Maintained by: Many creative people.
    10 Send bugs and suggestions to <texi2html-bug@nongnu.org>
     1<HTML>
     2<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     3<!-- Created on December, 17  2017 by texi2html 1.64 -->
     4<!--
     5Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
     6                        Karl Berry  <karl@freefriends.org>
     7                        Olaf Bachmann <obachman@mathematik.uni-kl.de>
     8                        and many others.
     9Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
     10Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
     11 
    1112-->
    12 <head>
    13 <title>Tiny C Compiler Reference Documentation</title>
    14 
    15 <meta name="description" content="Tiny C Compiler Reference Documentation">
    16 <meta name="keywords" content="Tiny C Compiler Reference Documentation">
    17 <meta name="resource-type" content="document">
    18 <meta name="distribution" content="global">
    19 <meta name="Generator" content="texi2html 1.82">
    20 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    21 <style type="text/css">
    22 <!--
    23 a.summary-letter {text-decoration: none}
    24 blockquote.smallquotation {font-size: smaller}
    25 pre.display {font-family: serif}
    26 pre.format {font-family: serif}
    27 pre.menu-comment {font-family: serif}
    28 pre.menu-preformatted {font-family: serif}
    29 pre.smalldisplay {font-family: serif; font-size: smaller}
    30 pre.smallexample {font-size: smaller}
    31 pre.smallformat {font-family: serif; font-size: smaller}
    32 pre.smalllisp {font-size: smaller}
    33 span.roman {font-family:serif; font-weight:normal;}
    34 span.sansserif {font-family:sans-serif; font-weight:normal;}
    35 ul.toc {list-style: none}
    36 -->
    37 </style>
    38 
    39 
    40 </head>
    41 
    42 <body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
    43 
    44 <a name="Top"></a>
    45 <table cellpadding="1" cellspacing="1" border="0">
    46 <tr><td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    47 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    48 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    49 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    50 </tr></table>
    51 <a name="Tiny-C-Compiler-Reference-Documentation"></a>
    52 <h1 class="settitle">Tiny C Compiler Reference Documentation</h1>
    53 
    54 <p>This manual documents version 0.9.26 of the Tiny C Compiler.
    55 </p>
    56 <table class="menu" border="0" cellspacing="0">
    57 <tr><td align="left" valign="top"><a href="#Introduction">1. Introduction</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                Introduction to tcc.
    58 </td></tr>
    59 <tr><td align="left" valign="top"><a href="#Invoke">2. Command line invocation</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Invocation of tcc (command line, options).
    60 </td></tr>
    61 <tr><td align="left" valign="top"><a href="#Clang">3. C language support</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                       ANSI C and extensions.
    62 </td></tr>
    63 <tr><td align="left" valign="top"><a href="#asm">4. TinyCC Assembler</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                         Assembler syntax.
    64 </td></tr>
    65 <tr><td align="left" valign="top"><a href="#linker">5. TinyCC Linker</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Output file generation and supported targets.
    66 </td></tr>
    67 <tr><td align="left" valign="top"><a href="#Bounds">6. TinyCC Memory and Bound checks</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Automatic bounds-checking of C code.
    68 </td></tr>
    69 <tr><td align="left" valign="top"><a href="#Libtcc">7. The <code>libtcc</code> library</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      The libtcc library.
    70 </td></tr>
    71 <tr><td align="left" valign="top"><a href="#devel">8. Developer&rsquo;s guide</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                       Guide for Developers.
    72 </td></tr>
    73 </table>
    74 
    75 
    76 <hr size="1">
    77 <a name="Introduction"></a>
    78 <table cellpadding="1" cellspacing="1" border="0">
    79 <tr><td valign="middle" align="left">[<a href="#Top" title="Previous section in reading order"> &lt; </a>]</td>
    80 <td valign="middle" align="left">[<a href="#Invoke" title="Next section in reading order"> &gt; </a>]</td>
    81 <td valign="middle" align="left"> &nbsp; </td>
    82 <td valign="middle" align="left">[<a href="#Top" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    83 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    84 <td valign="middle" align="left">[<a href="#Invoke" title="Next chapter"> &gt;&gt; </a>]</td>
    85 <td valign="middle" align="left"> &nbsp; </td>
    86 <td valign="middle" align="left"> &nbsp; </td>
    87 <td valign="middle" align="left"> &nbsp; </td>
    88 <td valign="middle" align="left"> &nbsp; </td>
    89 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    90 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    91 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    92 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    93 </tr></table>
    94 <a name="Introduction-1"></a>
    95 <h1 class="chapter">1. Introduction</h1>
    96 
    97 <p>TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
     13<HEAD>
     14<TITLE>Tiny C Compiler Reference Documentation: </TITLE>
     15
     16<META NAME="description" CONTENT="Tiny C Compiler Reference Documentation: ">
     17<META NAME="keywords" CONTENT="Tiny C Compiler Reference Documentation: ">
     18<META NAME="resource-type" CONTENT="document">
     19<META NAME="distribution" CONTENT="global">
     20<META NAME="Generator" CONTENT="texi2html 1.64">
     21
     22</HEAD>
     23
     24<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
     25
     26<A NAME="SEC_Top"></A>
     27<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     28<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     29<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     30<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     31<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     32</TR></TABLE>
     33<H1>Tiny C Compiler Reference Documentation</H1></P><P>
     34
     35This manual documents version 0.9.27
     36 of the Tiny C Compiler.
     37</P><P>
     38
     39<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0>
     40<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC1">1. Introduction</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Introduction to tcc.</TD></TR>
     41<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC2">2. Command line invocation</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Invocation of tcc (command line, options).</TD></TR>
     42<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC5">3. C language support</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">ANSI C and extensions.</TD></TR>
     43<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Assembler syntax.</TD></TR>
     44<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Output file generation and supported targets.</TD></TR>
     45<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Automatic bounds-checking of C code.</TD></TR>
     46<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">The libtcc library.</TD></TR>
     47<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC23">8. Developer's guide</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Guide for Developers.</TD></TR>
     48</TABLE></BLOCKQUOTE>
     49<P>
     50
     51<HR SIZE=1>
     52<A NAME="SEC1"></A>
     53<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     54<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> &lt; </A>]</TD>
     55<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt; </A>]</TD>
     56<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
     57<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     58<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt;&gt; </A>]</TD>
     59<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     60<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     61<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     62<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     63</TR></TABLE>
     64<A NAME="Introduction"></A>
     65<H1> 1. Introduction </H1>
     66<!--docid::SEC1::-->
     67<P>
     68
     69TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
    9870compilers, it is meant to be self-relying: you do not need an
    9971external assembler or linker because TCC does that for you.
    100 </p>
    101 <p>TCC compiles so <em>fast</em> that even for big projects <code>Makefile</code>s may
     72</P><P>
     73
     74TCC compiles so <EM>fast</EM> that even for big projects <CODE>Makefile</CODE>s may
    10275not be necessary.
    103 </p>
    104 <p>TCC not only supports ANSI C, but also most of the new ISO C99
     76</P><P>
     77
     78TCC not only supports ANSI C, but also most of the new ISO C99
    10579standard and many GNUC extensions including inline assembly.
    106 </p>
    107 <p>TCC can also be used to make <em>C scripts</em>, i.e. pieces of C source
     80</P><P>
     81
     82TCC can also be used to make <EM>C scripts</EM>, i.e. pieces of C source
    10883that you run as a Perl or Python script. Compilation is so fast that
    10984your script will be as fast as if it was an executable.
    110 </p>
    111 <p>TCC can also automatically generate memory and bound checks
    112 (see section <a href="#Bounds">TinyCC Memory and Bound checks</a>) while allowing all C pointers operations. TCC can do
     85</P><P>
     86
     87TCC can also automatically generate memory and bound checks
     88(see section <A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>) while allowing all C pointers operations. TCC can do
    11389these checks even if non patched libraries are used.
    114 </p>
    115 <p>With <code>libtcc</code>, you can use TCC as a backend for dynamic code
    116 generation (see section <a href="#Libtcc">The <code>libtcc</code> library</a>).
    117 </p>
    118 <p>TCC mainly supports the i386 target on Linux and Windows. There are alpha
    119 ports for the ARM (<code>arm-tcc</code>) and the TMS320C67xx targets
    120 (<code>c67-tcc</code>). More information about the ARM port is available at
    121 <a href="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</a>.
    122 </p>
    123 <p>For usage on Windows, see also <a href="tcc-win32.txt">tcc-win32.txt</a>.
    124 </p>
    125 <hr size="6">
    126 <a name="Invoke"></a>
    127 <table cellpadding="1" cellspacing="1" border="0">
    128 <tr><td valign="middle" align="left">[<a href="#Introduction" title="Previous section in reading order"> &lt; </a>]</td>
    129 <td valign="middle" align="left">[<a href="#Quick-start" title="Next section in reading order"> &gt; </a>]</td>
    130 <td valign="middle" align="left"> &nbsp; </td>
    131 <td valign="middle" align="left">[<a href="#Introduction" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    132 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    133 <td valign="middle" align="left">[<a href="#Clang" title="Next chapter"> &gt;&gt; </a>]</td>
    134 <td valign="middle" align="left"> &nbsp; </td>
    135 <td valign="middle" align="left"> &nbsp; </td>
    136 <td valign="middle" align="left"> &nbsp; </td>
    137 <td valign="middle" align="left"> &nbsp; </td>
    138 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    139 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    140 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    141 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    142 </tr></table>
    143 <a name="Command-line-invocation"></a>
    144 <h1 class="chapter">2. Command line invocation</h1>
    145 
    146 <hr size="6">
    147 <a name="Quick-start"></a>
    148 <table cellpadding="1" cellspacing="1" border="0">
    149 <tr><td valign="middle" align="left">[<a href="#Invoke" title="Previous section in reading order"> &lt; </a>]</td>
    150 <td valign="middle" align="left">[<a href="#Option-summary" title="Next section in reading order"> &gt; </a>]</td>
    151 <td valign="middle" align="left"> &nbsp; </td>
    152 <td valign="middle" align="left">[<a href="#Invoke" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    153 <td valign="middle" align="left">[<a href="#Invoke" title="Up section"> Up </a>]</td>
    154 <td valign="middle" align="left">[<a href="#Clang" title="Next chapter"> &gt;&gt; </a>]</td>
    155 <td valign="middle" align="left"> &nbsp; </td>
    156 <td valign="middle" align="left"> &nbsp; </td>
    157 <td valign="middle" align="left"> &nbsp; </td>
    158 <td valign="middle" align="left"> &nbsp; </td>
    159 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    160 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    161 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    162 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    163 </tr></table>
    164 <h2 class="section">2.1 Quick start</h2>
    165 
    166 <table><tr><td>&nbsp;</td><td><pre class="example">usage: tcc [options] [<var>infile1</var> <var>infile2</var>&hellip;] [&lsquo;<samp>-run</samp>&rsquo; <var>infile</var> <var>args</var>&hellip;]
    167 </pre></td></tr></table>
    168 
    169 <p>TCC options are a very much like gcc options. The main difference is that TCC
     90</P><P>
     91
     92With <CODE>libtcc</CODE>, you can use TCC as a backend for dynamic code
     93generation (see section <A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>).
     94</P><P>
     95
     96TCC mainly supports the i386 target on Linux and Windows. There are alpha
     97ports for the ARM (<CODE>arm-tcc</CODE>) and the TMS320C67xx targets
     98(<CODE>c67-tcc</CODE>). More information about the ARM port is available at
     99<A HREF="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</A>.
     100</P><P>
     101
     102For usage on Windows, see also <A HREF="tcc-win32.txt">tcc-win32.txt</A>.
     103</P><P>
     104
     105<A NAME="Invoke"></A>
     106<HR SIZE="6">
     107<A NAME="SEC2"></A>
     108<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     109<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC1"> &lt; </A>]</TD>
     110<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &gt; </A>]</TD>
     111<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
     112<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     113<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
     114<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     115<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     116<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     117<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     118</TR></TABLE>
     119<H1> 2. Command line invocation </H1>
     120<!--docid::SEC2::-->
     121<P>
     122
     123<HR SIZE="6">
     124<A NAME="SEC3"></A>
     125<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     126<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt; </A>]</TD>
     127<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &gt; </A>]</TD>
     128<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
     129<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
     130<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
     131<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     132<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     133<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     134<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     135</TR></TABLE>
     136<H2> 2.1 Quick start </H2>
     137<!--docid::SEC3::-->
     138<P>
     139
     140<TABLE><tr><td>&nbsp;</td><td class=example><pre>usage: tcc [options] [<VAR>infile1</VAR> <VAR>infile2</VAR><small>...</small>] [<SAMP>`-run'</SAMP> <VAR>infile</VAR> <VAR>args</VAR><small>...</small>]
     141</pre></td></tr></table></P><P>
     142
     143TCC options are a very much like gcc options. The main difference is that TCC
    170144can also execute directly the resulting program and give it runtime
    171145arguments.
    172 </p>
    173 <p>Here are some examples to understand the logic:
    174 </p>
    175 <dl compact="compact">
    176 <dt> <code>&lsquo;<samp>tcc -run a.c</samp>&rsquo;</code></dt>
    177 <dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and execute it directly
    178 </p>
    179 </dd>
    180 <dt> <code>&lsquo;<samp>tcc -run a.c arg1</samp>&rsquo;</code></dt>
    181 <dd><p>Compile a.c and execute it directly. arg1 is given as first argument to
    182 the <code>main()</code> of a.c.
    183 </p>
    184 </dd>
    185 <dt> <code>&lsquo;<samp>tcc a.c -run b.c arg1</samp>&rsquo;</code></dt>
    186 <dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them together and execute them. arg1 is given
    187 as first argument to the <code>main()</code> of the resulting program.
    188 </p>
    189 </dd>
    190 <dt> <code>&lsquo;<samp>tcc -o myprog a.c b.c</samp>&rsquo;</code></dt>
    191 <dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them and generate the executable &lsquo;<tt>myprog</tt>&rsquo;.
    192 </p>
    193 </dd>
    194 <dt> <code>&lsquo;<samp>tcc -o myprog a.o b.o</samp>&rsquo;</code></dt>
    195 <dd><p>link &lsquo;<tt>a.o</tt>&rsquo; and &lsquo;<tt>b.o</tt>&rsquo; together and generate the executable &lsquo;<tt>myprog</tt>&rsquo;.
    196 </p>
    197 </dd>
    198 <dt> <code>&lsquo;<samp>tcc -c a.c</samp>&rsquo;</code></dt>
    199 <dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and generate object file &lsquo;<tt>a.o</tt>&rsquo;.
    200 </p>
    201 </dd>
    202 <dt> <code>&lsquo;<samp>tcc -c asmfile.S</samp>&rsquo;</code></dt>
    203 <dd><p>Preprocess with C preprocess and assemble &lsquo;<tt>asmfile.S</tt>&rsquo; and generate
    204 object file &lsquo;<tt>asmfile.o</tt>&rsquo;.
    205 </p>
    206 </dd>
    207 <dt> <code>&lsquo;<samp>tcc -c asmfile.s</samp>&rsquo;</code></dt>
    208 <dd><p>Assemble (but not preprocess) &lsquo;<tt>asmfile.s</tt>&rsquo; and generate object file
    209 &lsquo;<tt>asmfile.o</tt>&rsquo;.
    210 </p>
    211 </dd>
    212 <dt> <code>&lsquo;<samp>tcc -r -o ab.o a.c b.c</samp>&rsquo;</code></dt>
    213 <dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them together and generate the object file &lsquo;<tt>ab.o</tt>&rsquo;.
    214 </p>
    215 </dd>
    216 </dl>
    217 
    218 <p>Scripting:
    219 </p>
    220 <p>TCC can be invoked from <em>scripts</em>, just as shell scripts. You just
    221 need to add <code>#!/usr/local/bin/tcc -run</code> at the start of your C source:
    222 </p>
    223 <table><tr><td>&nbsp;</td><td><pre class="example">#!/usr/local/bin/tcc -run
    224 #include &lt;stdio.h&gt;
     146</P><P>
     147
     148Here are some examples to understand the logic:
     149</P><P>
     150
     151<DL COMPACT>
     152<DT><CODE><SAMP>`tcc -run a.c'</SAMP></CODE>
     153<DD>Compile <TT>`a.c'</TT> and execute it directly
     154<P>
     155
     156<DT><CODE><SAMP>`tcc -run a.c arg1'</SAMP></CODE>
     157<DD>Compile a.c and execute it directly. arg1 is given as first argument to
     158the <CODE>main()</CODE> of a.c.
     159<P>
     160
     161<DT><CODE><SAMP>`tcc a.c -run b.c arg1'</SAMP></CODE>
     162<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and execute them. arg1 is given
     163as first argument to the <CODE>main()</CODE> of the resulting program.
     164<P>
     165
     166<DT><CODE><SAMP>`tcc -o myprog a.c b.c'</SAMP></CODE>
     167<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them and generate the executable <TT>`myprog'</TT>.
     168<P>
     169
     170<DT><CODE><SAMP>`tcc -o myprog a.o b.o'</SAMP></CODE>
     171<DD>link <TT>`a.o'</TT> and <TT>`b.o'</TT> together and generate the executable <TT>`myprog'</TT>.
     172<P>
     173
     174<DT><CODE><SAMP>`tcc -c a.c'</SAMP></CODE>
     175<DD>Compile <TT>`a.c'</TT> and generate object file <TT>`a.o'</TT>.
     176<P>
     177
     178<DT><CODE><SAMP>`tcc -c asmfile.S'</SAMP></CODE>
     179<DD>Preprocess with C preprocess and assemble <TT>`asmfile.S'</TT> and generate
     180object file <TT>`asmfile.o'</TT>.
     181<P>
     182
     183<DT><CODE><SAMP>`tcc -c asmfile.s'</SAMP></CODE>
     184<DD>Assemble (but not preprocess) <TT>`asmfile.s'</TT> and generate object file
     185<TT>`asmfile.o'</TT>.
     186<P>
     187
     188<DT><CODE><SAMP>`tcc -r -o ab.o a.c b.c'</SAMP></CODE>
     189<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and generate the object file <TT>`ab.o'</TT>.
     190<P>
     191
     192</DL>
     193<P>
     194
     195Scripting:
     196</P><P>
     197
     198TCC can be invoked from <EM>scripts</EM>, just as shell scripts. You just
     199need to add <CODE>#!/usr/local/bin/tcc -run</CODE> at the start of your C source:
     200</P><P>
     201
     202<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run
     203#include &#60;stdio.h&#62;
    225204
    226205int main()
    227206{
    228     printf(&quot;Hello World\n&quot;);
     207    printf("Hello World\n");
    229208    return 0;
    230209}
    231 </pre></td></tr></table>
    232 
    233 <p>TCC can read C source code from <em>standard input</em> when &lsquo;<samp>-</samp>&rsquo; is used in
    234 place of &lsquo;<samp>infile</samp>&rsquo;. Example:
    235 </p>
    236 <table><tr><td>&nbsp;</td><td><pre class="example">echo 'main(){puts(&quot;hello&quot;);}' | tcc -run -
    237 </pre></td></tr></table>
    238 
    239 <hr size="6">
    240 <a name="Option-summary"></a>
    241 <table cellpadding="1" cellspacing="1" border="0">
    242 <tr><td valign="middle" align="left">[<a href="#Quick-start" title="Previous section in reading order"> &lt; </a>]</td>
    243 <td valign="middle" align="left">[<a href="#Clang" title="Next section in reading order"> &gt; </a>]</td>
    244 <td valign="middle" align="left"> &nbsp; </td>
    245 <td valign="middle" align="left">[<a href="#Invoke" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    246 <td valign="middle" align="left">[<a href="#Invoke" title="Up section"> Up </a>]</td>
    247 <td valign="middle" align="left">[<a href="#Clang" title="Next chapter"> &gt;&gt; </a>]</td>
    248 <td valign="middle" align="left"> &nbsp; </td>
    249 <td valign="middle" align="left"> &nbsp; </td>
    250 <td valign="middle" align="left"> &nbsp; </td>
    251 <td valign="middle" align="left"> &nbsp; </td>
    252 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    253 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    254 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    255 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    256 </tr></table>
    257 <h2 class="section">2.2 Option summary</h2>
    258 
    259 <p>General Options:
    260 </p>
    261 <dl compact="compact">
    262 <dt> &lsquo;<samp>-c</samp>&rsquo;</dt>
    263 <dd><p>Generate an object file.
    264 </p>
    265 </dd>
    266 <dt> &lsquo;<samp>-o outfile</samp>&rsquo;</dt>
    267 <dd><p>Put object file, executable, or dll into output file &lsquo;<tt>outfile</tt>&rsquo;.
    268 </p>
    269 </dd>
    270 <dt> &lsquo;<samp>-run source [args...]</samp>&rsquo;</dt>
    271 <dd><p>Compile file <var>source</var> and run it with the command line arguments
    272 <var>args</var>. In order to be able to give more than one argument to a
    273 script, several TCC options can be given <em>after</em> the
    274 &lsquo;<samp>-run</samp>&rsquo; option, separated by spaces:
    275 </p><table><tr><td>&nbsp;</td><td><pre class="example">tcc &quot;-run -L/usr/X11R6/lib -lX11&quot; ex4.c
    276 </pre></td></tr></table>
    277 <p>In a script, it gives the following header:
    278 </p><table><tr><td>&nbsp;</td><td><pre class="example">#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
    279 </pre></td></tr></table>
    280 
    281 </dd>
    282 <dt> &lsquo;<samp>-dumpversion</samp>&rsquo;</dt>
    283 <dd><p>Print only the compiler version and nothing else.
    284 </p>
    285 </dd>
    286 <dt> &lsquo;<samp>-v</samp>&rsquo;</dt>
    287 <dd><p>Display TCC version.
    288 </p>
    289 </dd>
    290 <dt> &lsquo;<samp>-vv</samp>&rsquo;</dt>
    291 <dd><p>Show included files.  As sole argument, print search dirs (as below).
    292 </p>
    293 </dd>
    294 <dt> &lsquo;<samp>-bench</samp>&rsquo;</dt>
    295 <dd><p>Display compilation statistics.
    296 </p>
    297 </dd>
    298 <dt> &lsquo;<samp>-print-search-dirs</samp>&rsquo;</dt>
    299 <dd><p>Print the configured installation directory and a list of library
     210</pre></td></tr></table></P><P>
     211
     212TCC can read C source code from <EM>standard input</EM> when <SAMP>`-'</SAMP> is used in
     213place of <SAMP>`infile'</SAMP>. Example:
     214</P><P>
     215
     216<TABLE><tr><td>&nbsp;</td><td class=example><pre>echo 'main(){puts("hello");}' | tcc -run -
     217</pre></td></tr></table></P><P>
     218
     219<HR SIZE="6">
     220<A NAME="SEC4"></A>
     221<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     222<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &lt; </A>]</TD>
     223<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt; </A>]</TD>
     224<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
     225<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
     226<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
     227<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     228<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     229<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     230<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     231</TR></TABLE>
     232<H2> 2.2 Option summary </H2>
     233<!--docid::SEC4::-->
     234<P>
     235
     236General Options:
     237</P><P>
     238
     239<DL COMPACT>
     240<DT><SAMP>`-c'</SAMP>
     241<DD>Generate an object file.
     242<P>
     243
     244<DT><SAMP>`-o outfile'</SAMP>
     245<DD>Put object file, executable, or dll into output file <TT>`outfile'</TT>.
     246<P>
     247
     248<DT><SAMP>`-run source [args...]'</SAMP>
     249<DD>Compile file <VAR>source</VAR> and run it with the command line arguments
     250<VAR>args</VAR>. In order to be able to give more than one argument to a
     251script, several TCC options can be given <EM>after</EM> the
     252<SAMP>`-run'</SAMP> option, separated by spaces:
     253<TABLE><tr><td>&nbsp;</td><td class=example><pre>tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
     254</pre></td></tr></table>In a script, it gives the following header:
     255<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
     256</pre></td></tr></table><P>
     257
     258<DT><SAMP>`-v'</SAMP>
     259<DD>Display TCC version.
     260<P>
     261
     262<DT><SAMP>`-vv'</SAMP>
     263<DD>Show included files.  As sole argument, print search dirs.  -vvv shows tries too.
     264<P>
     265
     266<DT><SAMP>`-bench'</SAMP>
     267<DD>Display compilation statistics.
     268<P>
     269
     270</DL>
     271<P>
     272
     273Preprocessor options:
     274</P><P>
     275
     276<DL COMPACT>
     277<DT><SAMP>`-Idir'</SAMP>
     278<DD>Specify an additional include path. Include paths are searched in the
     279order they are specified.
     280<P>
     281
     282System include paths are always searched after. The default system
     283include paths are: <TT>`/usr/local/include'</TT>, <TT>`/usr/include'</TT>
     284and <TT>`PREFIX/lib/tcc/include'</TT>. (<TT>`PREFIX'</TT> is usually
     285<TT>`/usr'</TT> or <TT>`/usr/local'</TT>).
     286</P><P>
     287
     288<DT><SAMP>`-Dsym[=val]'</SAMP>
     289<DD>Define preprocessor symbol <SAMP>`sym'</SAMP> to
     290val. If val is not present, its value is <SAMP>`1'</SAMP>. Function-like macros can
     291also be defined: <SAMP>`-DF(a)=a+1'</SAMP>
     292<P>
     293
     294<DT><SAMP>`-Usym'</SAMP>
     295<DD>Undefine preprocessor symbol <SAMP>`sym'</SAMP>.
     296<P>
     297
     298<DT><SAMP>`-E'</SAMP>
     299<DD>Preprocess only, to stdout or file (with -o).
     300<P>
     301
     302</DL>
     303<P>
     304
     305Compilation flags:
     306</P><P>
     307
     308Note: each of the following options has a negative form beginning with
     309<SAMP>`-fno-'</SAMP>.
     310</P><P>
     311
     312<DL COMPACT>
     313<DT><SAMP>`-funsigned-char'</SAMP>
     314<DD>Let the <CODE>char</CODE> type be unsigned.
     315<P>
     316
     317<DT><SAMP>`-fsigned-char'</SAMP>
     318<DD>Let the <CODE>char</CODE> type be signed.
     319<P>
     320
     321<DT><SAMP>`-fno-common'</SAMP>
     322<DD>Do not generate common symbols for uninitialized data.
     323<P>
     324
     325<DT><SAMP>`-fleading-underscore'</SAMP>
     326<DD>Add a leading underscore at the beginning of each C symbol.
     327<P>
     328
     329<DT><SAMP>`-fms-extensions'</SAMP>
     330<DD>Allow a MS C compiler extensions to the language. Currently this
     331assumes a nested named structure declaration without an identifier
     332behaves like an unnamed one.
     333<P>
     334
     335<DT><SAMP>`-fdollars-in-identifiers'</SAMP>
     336<DD>Allow dollar signs in identifiers
     337<P>
     338
     339</DL>
     340<P>
     341
     342Warning options:
     343</P><P>
     344
     345<DL COMPACT>
     346<DT><SAMP>`-w'</SAMP>
     347<DD>Disable all warnings.
     348<P>
     349
     350</DL>
     351<P>
     352
     353Note: each of the following warning options has a negative form beginning with
     354<SAMP>`-Wno-'</SAMP>.
     355</P><P>
     356
     357<DL COMPACT>
     358<DT><SAMP>`-Wimplicit-function-declaration'</SAMP>
     359<DD>Warn about implicit function declaration.
     360<P>
     361
     362<DT><SAMP>`-Wunsupported'</SAMP>
     363<DD>Warn about unsupported GCC features that are ignored by TCC.
     364<P>
     365
     366<DT><SAMP>`-Wwrite-strings'</SAMP>
     367<DD>Make string constants be of type <CODE>const char *</CODE> instead of <CODE>char
     368*</CODE>.
     369<P>
     370
     371<DT><SAMP>`-Werror'</SAMP>
     372<DD>Abort compilation if warnings are issued.
     373<P>
     374
     375<DT><SAMP>`-Wall'</SAMP>
     376<DD>Activate all warnings, except <SAMP>`-Werror'</SAMP>, <SAMP>`-Wunusupported'</SAMP> and
     377<SAMP>`-Wwrite-strings'</SAMP>.
     378<P>
     379
     380</DL>
     381<P>
     382
     383Linker options:
     384</P><P>
     385
     386<DL COMPACT>
     387<DT><SAMP>`-Ldir'</SAMP>
     388<DD>Specify an additional static library path for the <SAMP>`-l'</SAMP> option. The
     389default library paths are <TT>`/usr/local/lib'</TT>, <TT>`/usr/lib'</TT> and <TT>`/lib'</TT>.
     390<P>
     391
     392<DT><SAMP>`-lxxx'</SAMP>
     393<DD>Link your program with dynamic library libxxx.so or static library
     394libxxx.a. The library is searched in the paths specified by the
     395<SAMP>`-L'</SAMP> option and <CODE>LIBRARY_PATH</CODE> variable.
     396<P>
     397
     398<DT><SAMP>`-Bdir'</SAMP>
     399<DD>Set the path where the tcc internal libraries (and include files) can be
     400found (default is <TT>`PREFIX/lib/tcc'</TT>).
     401<P>
     402
     403<DT><SAMP>`-shared'</SAMP>
     404<DD>Generate a shared library instead of an executable.
     405<P>
     406
     407<DT><SAMP>`-soname name'</SAMP>
     408<DD>set name for shared library to be used at runtime
     409<P>
     410
     411<DT><SAMP>`-static'</SAMP>
     412<DD>Generate a statically linked executable (default is a shared linked
     413executable).
     414<P>
     415
     416<DT><SAMP>`-rdynamic'</SAMP>
     417<DD>Export global symbols to the dynamic linker. It is useful when a library
     418opened with <CODE>dlopen()</CODE> needs to access executable symbols.
     419<P>
     420
     421<DT><SAMP>`-r'</SAMP>
     422<DD>Generate an object file combining all input files.
     423<P>
     424
     425<DT><SAMP>`-Wl,-rpath=path'</SAMP>
     426<DD>Put custom search path for dynamic libraries into executable.
     427<P>
     428
     429<DT><SAMP>`-Wl,--enable-new-dtags'</SAMP>
     430<DD>When putting a custom search path for dynamic libraries into the executable,
     431create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
     432<P>
     433
     434<DT><SAMP>`-Wl,--oformat=fmt'</SAMP>
     435<DD>Use <VAR>fmt</VAR> as output format. The supported output formats are:
     436<DL COMPACT>
     437<DT><CODE>elf32-i386</CODE>
     438<DD>ELF output format (default)
     439<DT><CODE>binary</CODE>
     440<DD>Binary image (only for executable output)
     441<DT><CODE>coff</CODE>
     442<DD>COFF output format (only for executable output for TMS320C67xx target)
     443</DL>
     444<P>
     445
     446<DT><SAMP>`-Wl,-subsystem=console/gui/wince/...'</SAMP>
     447<DD>Set type for PE (Windows) executables.
     448<P>
     449
     450<DT><SAMP>`-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]'</SAMP>
     451<DD>Modify executable layout.
     452<P>
     453
     454<DT><SAMP>`-Wl,-Bsymbolic'</SAMP>
     455<DD>Set DT_SYMBOLIC tag.
     456<P>
     457
     458<DT><SAMP>`-Wl,-(no-)whole-archive'</SAMP>
     459<DD>Turn on/off linking of all objects in archives.
     460<P>
     461
     462</DL>
     463<P>
     464
     465Debugger options:
     466</P><P>
     467
     468<DL COMPACT>
     469<DT><SAMP>`-g'</SAMP>
     470<DD>Generate run time debug information so that you get clear run time
     471error messages: <CODE> test.c:68: in function 'test5()': dereferencing
     472invalid pointer</CODE> instead of the laconic <CODE>Segmentation
     473fault</CODE>.
     474<P>
     475
     476<DT><SAMP>`-b'</SAMP>
     477<DD>Generate additional support code to check
     478memory allocations and array/pointer bounds. <SAMP>`-g'</SAMP> is implied. Note
     479that the generated code is slower and bigger in this case.
     480<P>
     481
     482Note: <SAMP>`-b'</SAMP> is only available on i386 when using libtcc for the moment.
     483</P><P>
     484
     485<DT><SAMP>`-bt N'</SAMP>
     486<DD>Display N callers in stack traces. This is useful with <SAMP>`-g'</SAMP> or
     487<SAMP>`-b'</SAMP>.
     488<P>
     489
     490</DL>
     491<P>
     492
     493Misc options:
     494</P><P>
     495
     496<DL COMPACT>
     497<DT><SAMP>`-MD'</SAMP>
     498<DD>Generate makefile fragment with dependencies.
     499<P>
     500
     501<DT><SAMP>`-MF depfile'</SAMP>
     502<DD>Use <TT>`depfile'</TT> as output for -MD.
     503<P>
     504
     505<DT><SAMP>`-print-search-dirs'</SAMP>
     506<DD>Print the configured installation directory and a list of library
    300507and include directories tcc will search.
    301 </p>
    302 </dd>
    303 </dl>
    304 
    305 <p>Preprocessor options:
    306 </p>
    307 <dl compact="compact">
    308 <dt> &lsquo;<samp>-Idir</samp>&rsquo;</dt>
    309 <dd><p>Specify an additional include path. Include paths are searched in the
    310 order they are specified.
    311 </p>
    312 <p>System include paths are always searched after. The default system
    313 include paths are: &lsquo;<tt>/usr/local/include</tt>&rsquo;, &lsquo;<tt>/usr/include</tt>&rsquo;
    314 and &lsquo;<tt>PREFIX/lib/tcc/include</tt>&rsquo;. (&lsquo;<tt>PREFIX</tt>&rsquo; is usually
    315 &lsquo;<tt>/usr</tt>&rsquo; or &lsquo;<tt>/usr/local</tt>&rsquo;).
    316 </p>
    317 </dd>
    318 <dt> &lsquo;<samp>-Dsym[=val]</samp>&rsquo;</dt>
    319 <dd><p>Define preprocessor symbol &lsquo;<samp>sym</samp>&rsquo; to
    320 val. If val is not present, its value is &lsquo;<samp>1</samp>&rsquo;. Function-like macros can
    321 also be defined: &lsquo;<samp>-DF(a)=a+1</samp>&rsquo;
    322 </p>
    323 </dd>
    324 <dt> &lsquo;<samp>-Usym</samp>&rsquo;</dt>
    325 <dd><p>Undefine preprocessor symbol &lsquo;<samp>sym</samp>&rsquo;.
    326 </p></dd>
    327 </dl>
    328 
    329 <p>Compilation flags:
    330 </p>
    331 <p>Note: each of the following warning options has a negative form beginning with
    332 &lsquo;<samp>-fno-</samp>&rsquo;.
    333 </p>
    334 <dl compact="compact">
    335 <dt> &lsquo;<samp>-funsigned-char</samp>&rsquo;</dt>
    336 <dd><p>Let the <code>char</code> type be unsigned.
    337 </p>
    338 </dd>
    339 <dt> &lsquo;<samp>-fsigned-char</samp>&rsquo;</dt>
    340 <dd><p>Let the <code>char</code> type be signed.
    341 </p>
    342 </dd>
    343 <dt> &lsquo;<samp>-fno-common</samp>&rsquo;</dt>
    344 <dd><p>Do not generate common symbols for uninitialized data.
    345 </p>
    346 </dd>
    347 <dt> &lsquo;<samp>-fleading-underscore</samp>&rsquo;</dt>
    348 <dd><p>Add a leading underscore at the beginning of each C symbol.
    349 </p>
    350 </dd>
    351 </dl>
    352 
    353 <p>Warning options:
    354 </p>
    355 <dl compact="compact">
    356 <dt> &lsquo;<samp>-w</samp>&rsquo;</dt>
    357 <dd><p>Disable all warnings.
    358 </p>
    359 </dd>
    360 </dl>
    361 
    362 <p>Note: each of the following warning options has a negative form beginning with
    363 &lsquo;<samp>-Wno-</samp>&rsquo;.
    364 </p>
    365 <dl compact="compact">
    366 <dt> &lsquo;<samp>-Wimplicit-function-declaration</samp>&rsquo;</dt>
    367 <dd><p>Warn about implicit function declaration.
    368 </p>
    369 </dd>
    370 <dt> &lsquo;<samp>-Wunsupported</samp>&rsquo;</dt>
    371 <dd><p>Warn about unsupported GCC features that are ignored by TCC.
    372 </p>
    373 </dd>
    374 <dt> &lsquo;<samp>-Wwrite-strings</samp>&rsquo;</dt>
    375 <dd><p>Make string constants be of type <code>const char *</code> instead of <code>char
    376 *</code>.
    377 </p>
    378 </dd>
    379 <dt> &lsquo;<samp>-Werror</samp>&rsquo;</dt>
    380 <dd><p>Abort compilation if warnings are issued.
    381 </p>
    382 </dd>
    383 <dt> &lsquo;<samp>-Wall</samp>&rsquo; </dt>
    384 <dd><p>Activate all warnings, except &lsquo;<samp>-Werror</samp>&rsquo;, &lsquo;<samp>-Wunusupported</samp>&rsquo; and
    385 &lsquo;<samp>-Wwrite-strings</samp>&rsquo;.
    386 </p>
    387 </dd>
    388 </dl>
    389 
    390 <p>Linker options:
    391 </p>
    392 <dl compact="compact">
    393 <dt> &lsquo;<samp>-Ldir</samp>&rsquo;</dt>
    394 <dd><p>Specify an additional static library path for the &lsquo;<samp>-l</samp>&rsquo; option. The
    395 default library paths are &lsquo;<tt>/usr/local/lib</tt>&rsquo;, &lsquo;<tt>/usr/lib</tt>&rsquo; and &lsquo;<tt>/lib</tt>&rsquo;.
    396 </p>
    397 </dd>
    398 <dt> &lsquo;<samp>-lxxx</samp>&rsquo;</dt>
    399 <dd><p>Link your program with dynamic library libxxx.so or static library
    400 libxxx.a. The library is searched in the paths specified by the
    401 &lsquo;<samp>-L</samp>&rsquo; option.
    402 </p>
    403 </dd>
    404 <dt> &lsquo;<samp>-Bdir</samp>&rsquo;</dt>
    405 <dd><p>Set the path where the tcc internal libraries (and include files) can be
    406 found (default is &lsquo;<tt>PREFIX/lib/tcc</tt>&rsquo;).
    407 </p>
    408 </dd>
    409 <dt> &lsquo;<samp>-shared</samp>&rsquo;</dt>
    410 <dd><p>Generate a shared library instead of an executable.
    411 </p>
    412 </dd>
    413 <dt> &lsquo;<samp>-soname name</samp>&rsquo;</dt>
    414 <dd><p>set name for shared library to be used at runtime
    415 </p>
    416 </dd>
    417 <dt> &lsquo;<samp>-static</samp>&rsquo;</dt>
    418 <dd><p>Generate a statically linked executable (default is a shared linked
    419 executable).
    420 </p>
    421 </dd>
    422 <dt> &lsquo;<samp>-rdynamic</samp>&rsquo;</dt>
    423 <dd><p>Export global symbols to the dynamic linker. It is useful when a library
    424 opened with <code>dlopen()</code> needs to access executable symbols.
    425 </p>
    426 </dd>
    427 <dt> &lsquo;<samp>-r</samp>&rsquo;</dt>
    428 <dd><p>Generate an object file combining all input files.
    429 </p>
    430 </dd>
    431 <dt> &lsquo;<samp>-Wl,-rpath=path</samp>&rsquo;</dt>
    432 <dd><p>Put custom seatch path for dynamic libraries into executable.
    433 </p>
    434 </dd>
    435 <dt> &lsquo;<samp>-Wl,--oformat=fmt</samp>&rsquo;</dt>
    436 <dd><p>Use <var>fmt</var> as output format. The supported output formats are:
    437 </p><dl compact="compact">
    438 <dt> <code>elf32-i386</code></dt>
    439 <dd><p>ELF output format (default)
    440 </p></dd>
    441 <dt> <code>binary</code></dt>
    442 <dd><p>Binary image (only for executable output)
    443 </p></dd>
    444 <dt> <code>coff</code></dt>
    445 <dd><p>COFF output format (only for executable output for TMS320C67xx target)
    446 </p></dd>
    447 </dl>
    448 
    449 </dd>
    450 <dt> &lsquo;<samp>-Wl,-subsystem=console/gui/wince/...</samp>&rsquo;</dt>
    451 <dd><p>Set type for PE (Windows) executables.
    452 </p>
    453 </dd>
    454 <dt> &lsquo;<samp>-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]</samp>&rsquo;</dt>
    455 <dd><p>Modify executable layout.
    456 </p>
    457 </dd>
    458 <dt> &lsquo;<samp>-Wl,-Bsymbolic</samp>&rsquo;</dt>
    459 <dd><p>Set DT_SYMBOLIC tag.
    460 </p>
    461 </dd>
    462 </dl>
    463 
    464 <p>Debugger options:
    465 </p>
    466 <dl compact="compact">
    467 <dt> &lsquo;<samp>-g</samp>&rsquo;</dt>
    468 <dd><p>Generate run time debug information so that you get clear run time
    469 error messages: <code> test.c:68: in function 'test5()': dereferencing
    470 invalid pointer</code> instead of the laconic <code>Segmentation
    471 fault</code>.
    472 </p>
    473 </dd>
    474 <dt> &lsquo;<samp>-b</samp>&rsquo;</dt>
    475 <dd><p>Generate additional support code to check
    476 memory allocations and array/pointer bounds. &lsquo;<samp>-g</samp>&rsquo; is implied. Note
    477 that the generated code is slower and bigger in this case.
    478 </p>
    479 <p>Note: &lsquo;<samp>-b</samp>&rsquo; is only available on i386 for the moment.
    480 </p>
    481 </dd>
    482 <dt> &lsquo;<samp>-bt N</samp>&rsquo;</dt>
    483 <dd><p>Display N callers in stack traces. This is useful with &lsquo;<samp>-g</samp>&rsquo; or
    484 &lsquo;<samp>-b</samp>&rsquo;.
    485 </p>
    486 </dd>
    487 </dl>
    488 
    489 <p>Misc options:
    490 </p>
    491 <dl compact="compact">
    492 <dt> &lsquo;<samp>-MD</samp>&rsquo;</dt>
    493 <dd><p>Generate makefile fragment with dependencies.
    494 </p>
    495 </dd>
    496 <dt> &lsquo;<samp>-MF depfile</samp>&rsquo;</dt>
    497 <dd><p>Use &lsquo;<tt>depfile</tt>&rsquo; as output for -MD.
    498 </p>
    499 </dd>
    500 </dl>
    501 
    502 <p>Note: GCC options &lsquo;<samp>-Ox</samp>&rsquo;, &lsquo;<samp>-fx</samp>&rsquo; and &lsquo;<samp>-mx</samp>&rsquo; are
     508<P>
     509
     510<DT><SAMP>`-dumpversion'</SAMP>
     511<DD>Print version.
     512<P>
     513
     514</DL>
     515<P>
     516
     517Target specific options:
     518</P><P>
     519
     520<DL COMPACT>
     521<DT><SAMP>`-mms-bitfields'</SAMP>
     522<DD>Use an algorithm for bitfield alignment consistent with MSVC. Default is
     523gcc's algorithm.
     524<P>
     525
     526<DT><SAMP>`-mfloat-abi (ARM only)'</SAMP>
     527<DD>Select the float ABI. Possible values: <CODE>softfp</CODE> and <CODE>hard</CODE>
     528<P>
     529
     530<DT><SAMP>`-mno-sse'</SAMP>
     531<DD>Do not use sse registers on x86_64
     532<P>
     533
     534<DT><SAMP>`-m32, -m64'</SAMP>
     535<DD>Pass command line to the i386/x86_64 cross compiler.
     536<P>
     537
     538</DL>
     539<P>
     540
     541Note: GCC options <SAMP>`-Ox'</SAMP>, <SAMP>`-fx'</SAMP> and <SAMP>`-mx'</SAMP> are
    503542ignored.
    504 </p>
    505 
    506 <hr size="6">
    507 <a name="Clang"></a>
    508 <table cellpadding="1" cellspacing="1" border="0">
    509 <tr><td valign="middle" align="left">[<a href="#Option-summary" title="Previous section in reading order"> &lt; </a>]</td>
    510 <td valign="middle" align="left">[<a href="#ANSI-C" title="Next section in reading order"> &gt; </a>]</td>
    511 <td valign="middle" align="left"> &nbsp; </td>
    512 <td valign="middle" align="left">[<a href="#Invoke" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    513 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    514 <td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
    515 <td valign="middle" align="left"> &nbsp; </td>
    516 <td valign="middle" align="left"> &nbsp; </td>
    517 <td valign="middle" align="left"> &nbsp; </td>
    518 <td valign="middle" align="left"> &nbsp; </td>
    519 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    520 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    521 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    522 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    523 </tr></table>
    524 <a name="C-language-support"></a>
    525 <h1 class="chapter">3. C language support</h1>
    526 
    527 <hr size="6">
    528 <a name="ANSI-C"></a>
    529 <table cellpadding="1" cellspacing="1" border="0">
    530 <tr><td valign="middle" align="left">[<a href="#Clang" title="Previous section in reading order"> &lt; </a>]</td>
    531 <td valign="middle" align="left">[<a href="#ISOC99-extensions" title="Next section in reading order"> &gt; </a>]</td>
    532 <td valign="middle" align="left"> &nbsp; </td>
    533 <td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    534 <td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
    535 <td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
    536 <td valign="middle" align="left"> &nbsp; </td>
    537 <td valign="middle" align="left"> &nbsp; </td>
    538 <td valign="middle" align="left"> &nbsp; </td>
    539 <td valign="middle" align="left"> &nbsp; </td>
    540 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    541 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    542 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    543 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    544 </tr></table>
    545 <h2 class="section">3.1 ANSI C</h2>
    546 
    547 <p>TCC implements all the ANSI C standard, including structure bit fields
    548 and floating point numbers (<code>long double</code>, <code>double</code>, and
    549 <code>float</code> fully supported).
    550 </p>
    551 <hr size="6">
    552 <a name="ISOC99-extensions"></a>
    553 <table cellpadding="1" cellspacing="1" border="0">
    554 <tr><td valign="middle" align="left">[<a href="#ANSI-C" title="Previous section in reading order"> &lt; </a>]</td>
    555 <td valign="middle" align="left">[<a href="#GNU-C-extensions" title="Next section in reading order"> &gt; </a>]</td>
    556 <td valign="middle" align="left"> &nbsp; </td>
    557 <td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    558 <td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
    559 <td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
    560 <td valign="middle" align="left"> &nbsp; </td>
    561 <td valign="middle" align="left"> &nbsp; </td>
    562 <td valign="middle" align="left"> &nbsp; </td>
    563 <td valign="middle" align="left"> &nbsp; </td>
    564 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    565 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    566 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    567 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    568 </tr></table>
    569 <h2 class="section">3.2 ISOC99 extensions</h2>
    570 
    571 <p>TCC implements many features of the new C standard: ISO C99. Currently
    572 missing items are: complex and imaginary numbers and variable length
    573 arrays.
    574 </p>
    575 <p>Currently implemented ISOC99 features:
    576 </p>
    577 <ul>
    578 <li> 64 bit <code>long long</code> types are fully supported.
    579 
    580 </li><li> The boolean type <code>_Bool</code> is supported.
    581 
    582 </li><li> <code>__func__</code> is a string variable containing the current
     543</P><P>
     544
     545Environment variables that affect how tcc operates.
     546</P><P>
     547
     548<DL COMPACT>
     549
     550<DT><SAMP>`CPATH'</SAMP>
     551<DD><DT><SAMP>`C_INCLUDE_PATH'</SAMP>
     552<DD>A colon-separated list of directories searched for include files,
     553directories given with <SAMP>`-I'</SAMP> are searched first.
     554<P>
     555
     556<DT><SAMP>`LIBRARY_PATH'</SAMP>
     557<DD>A colon-separated list of directories searched for libraries for the
     558<SAMP>`-l'</SAMP> option, directories given with <SAMP>`-L'</SAMP> are searched first.
     559<P>
     560
     561</DL>
     562<P>
     563
     564<A NAME="Clang"></A>
     565<HR SIZE="6">
     566<A NAME="SEC5"></A>
     567<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     568<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &lt; </A>]</TD>
     569<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &gt; </A>]</TD>
     570<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
     571<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     572<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
     573<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     574<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     575<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     576<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     577</TR></TABLE>
     578<H1> 3. C language support </H1>
     579<!--docid::SEC5::-->
     580<P>
     581
     582<HR SIZE="6">
     583<A NAME="SEC6"></A>
     584<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     585<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt; </A>]</TD>
     586<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &gt; </A>]</TD>
     587<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
     588<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
     589<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
     590<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     591<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     592<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     593<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     594</TR></TABLE>
     595<H2> 3.1 ANSI C </H2>
     596<!--docid::SEC6::-->
     597<P>
     598
     599TCC implements all the ANSI C standard, including structure bit fields
     600and floating point numbers (<CODE>long double</CODE>, <CODE>double</CODE>, and
     601<CODE>float</CODE> fully supported).
     602</P><P>
     603
     604<HR SIZE="6">
     605<A NAME="SEC7"></A>
     606<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     607<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &lt; </A>]</TD>
     608<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &gt; </A>]</TD>
     609<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt;&lt; </A>]</TD>
     610<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
     611<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
     612<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     613<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     614<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     615<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     616</TR></TABLE>
     617<H2> 3.2 ISOC99 extensions </H2>
     618<!--docid::SEC7::-->
     619<P>
     620
     621TCC implements many features of the new C standard: ISO C99. Currently
     622missing items are: complex and imaginary numbers.
     623</P><P>
     624
     625Currently implemented ISOC99 features:
     626</P><P>
     627
     628<UL>
     629
     630<LI>variable length arrays.
     631<P>
     632
     633<LI>64 bit <CODE>long long</CODE> types are fully supported.
     634<P>
     635
     636<LI>The boolean type <CODE>_Bool</CODE> is supported.
     637<P>
     638
     639<LI><CODE>__func__</CODE> is a string variable containing the current
    583640function name.
    584 
    585 </li><li> Variadic macros: <code>__VA_ARGS__</code> can be used for
     641<P>
     642
     643<LI>Variadic macros: <CODE>__VA_ARGS__</CODE> can be used for
    586644   function-like macros:
    587 <table><tr><td>&nbsp;</td><td><pre class="example">    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
    588 </pre></td></tr></table>
    589 
    590 <p><code>dprintf</code> can then be used with a variable number of parameters.
    591 </p>
    592 </li><li> Declarations can appear anywhere in a block (as in C++).
    593 
    594 </li><li> Array and struct/union elements can be initialized in any order by
     645<TABLE><tr><td>&nbsp;</td><td class=example><pre>    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
     646</pre></td></tr></table><P>
     647
     648<CODE>dprintf</CODE> can then be used with a variable number of parameters.
     649</P><P>
     650
     651<LI>Declarations can appear anywhere in a block (as in C++).
     652<P>
     653
     654<LI>Array and struct/union elements can be initialized in any order by
    595655  using designators:
    596 <table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
     656<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
    597657
    598658    int tab[10] = { 1, 2, [5] = 5, [9] = 9};
    599 </pre></td></tr></table>
    600    
    601 </li><li> Compound initializers are supported:
    602 <table><tr><td>&nbsp;</td><td><pre class="example">    int *p = (int []){ 1, 2, 3 };
    603 </pre></td></tr></table>
    604 <p>to initialize a pointer pointing to an initialized array. The same
     659</pre></td></tr></table>   
     660<LI>Compound initializers are supported:
     661<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int *p = (int []){ 1, 2, 3 };
     662</pre></td></tr></table>to initialize a pointer pointing to an initialized array. The same
    605663works for structures and strings.
    606 </p>
    607 </li><li> Hexadecimal floating point constants are supported:
    608 <table><tr><td>&nbsp;</td><td><pre class="example">          double d = 0x1234p10;
    609 </pre></td></tr></table>
    610 
    611 <p>is the same as writing
    612 </p><table><tr><td>&nbsp;</td><td><pre class="example">          double d = 4771840.0;
    613 </pre></td></tr></table>
    614 
    615 </li><li> <code>inline</code> keyword is ignored.
    616 
    617 </li><li> <code>restrict</code> keyword is ignored.
    618 </li></ul>
    619 
    620 <hr size="6">
    621 <a name="GNU-C-extensions"></a>
    622 <table cellpadding="1" cellspacing="1" border="0">
    623 <tr><td valign="middle" align="left">[<a href="#ISOC99-extensions" title="Previous section in reading order"> &lt; </a>]</td>
    624 <td valign="middle" align="left">[<a href="#TinyCC-extensions" title="Next section in reading order"> &gt; </a>]</td>
    625 <td valign="middle" align="left"> &nbsp; </td>
    626 <td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    627 <td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
    628 <td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
    629 <td valign="middle" align="left"> &nbsp; </td>
    630 <td valign="middle" align="left"> &nbsp; </td>
    631 <td valign="middle" align="left"> &nbsp; </td>
    632 <td valign="middle" align="left"> &nbsp; </td>
    633 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    634 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    635 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    636 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    637 </tr></table>
    638 <h2 class="section">3.3 GNU C extensions</h2>
    639 
    640 <p>TCC implements some GNU C extensions:
    641 </p>
    642 <ul>
    643 <li> array designators can be used without &rsquo;=&rsquo;:
    644 <table><tr><td>&nbsp;</td><td><pre class="example">    int a[10] = { [0] 1, [5] 2, 3, 4 };
    645 </pre></td></tr></table>
    646 
    647 </li><li> Structure field designators can be a label:
    648 <table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st = { x: 1, y: 1};
    649 </pre></td></tr></table>
    650 <p>instead of
    651 </p><table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st = { .x = 1, .y = 1};
    652 </pre></td></tr></table>
    653 
    654 </li><li> <code>\e</code> is ASCII character 27.
    655 
    656 </li><li> case ranges : ranges can be used in <code>case</code>s:
    657 <table><tr><td>&nbsp;</td><td><pre class="example">    switch(a) {
    658     case 1 &hellip; 9:
    659           printf(&quot;range 1 to 9\n&quot;);
     664<P>
     665
     666<LI>Hexadecimal floating point constants are supported:
     667<TABLE><tr><td>&nbsp;</td><td class=example><pre>          double d = 0x1234p10;
     668</pre></td></tr></table><P>
     669
     670is the same as writing
     671<TABLE><tr><td>&nbsp;</td><td class=example><pre>          double d = 4771840.0;
     672</pre></td></tr></table></P><P>
     673
     674<LI><CODE>inline</CODE> keyword is ignored.
     675<P>
     676
     677<LI><CODE>restrict</CODE> keyword is ignored.
     678</UL>
     679<P>
     680
     681<HR SIZE="6">
     682<A NAME="SEC8"></A>
     683<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     684<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &lt; </A>]</TD>
     685<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &gt; </A>]</TD>
     686<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt;&lt; </A>]</TD>
     687<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
     688<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
     689<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     690<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     691<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     692<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     693</TR></TABLE>
     694<H2> 3.3 GNU C extensions </H2>
     695<!--docid::SEC8::-->
     696<P>
     697
     698TCC implements some GNU C extensions:
     699</P><P>
     700
     701<UL>
     702
     703<LI>array designators can be used without '=':
     704<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int a[10] = { [0] 1, [5] 2, 3, 4 };
     705</pre></td></tr></table><P>
     706
     707<LI>Structure field designators can be a label:
     708<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st = { x: 1, y: 1};
     709</pre></td></tr></table>instead of
     710<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st = { .x = 1, .y = 1};
     711</pre></td></tr></table><P>
     712
     713<LI><CODE>\e</CODE> is ASCII character 27.
     714<P>
     715
     716<LI>case ranges : ranges can be used in <CODE>case</CODE>s:
     717<TABLE><tr><td>&nbsp;</td><td class=example><pre>    switch(a) {
     718    case 1 <small>...</small> 9:
     719          printf("range 1 to 9\n");
    660720          break;
    661721    default:
    662           printf(&quot;unexpected\n&quot;);
     722          printf("unexpected\n");
    663723          break;
    664724    }
    665 </pre></td></tr></table>
    666 
    667 <a name="index-aligned-attribute"></a>
    668 <a name="index-packed-attribute"></a>
    669 <a name="index-section-attribute"></a>
    670 <a name="index-unused-attribute"></a>
    671 <a name="index-cdecl-attribute"></a>
    672 <a name="index-stdcall-attribute"></a>
    673 <a name="index-regparm-attribute"></a>
    674 <a name="index-dllexport-attribute"></a>
    675 
    676 </li><li> The keyword <code>__attribute__</code> is handled to specify variable or
     725</pre></td></tr></table><P>
     726
     727<A NAME="IDX1"></A>
     728<A NAME="IDX2"></A>
     729<A NAME="IDX3"></A>
     730<A NAME="IDX4"></A>
     731<A NAME="IDX5"></A>
     732<A NAME="IDX6"></A>
     733<A NAME="IDX7"></A>
     734<A NAME="IDX8"></A>
     735</P><P>
     736
     737<LI>The keyword <CODE>__attribute__</CODE> is handled to specify variable or
    677738function attributes. The following attributes are supported:
    678   <ul>
    679 <li> <code>aligned(n)</code>: align a variable or a structure field to n bytes
     739<UL>
     740
     741<LI><CODE>aligned(n)</CODE>: align a variable or a structure field to n bytes
    680742(must be a power of two).
    681 
    682   </li><li> <code>packed</code>: force alignment of a variable or a structure field to
     743<P>
     744
     745<LI><CODE>packed</CODE>: force alignment of a variable or a structure field to
    683746  1.
    684 
    685   </li><li> <code>section(name)</code>: generate function or data in assembly section
     747<P>
     748
     749<LI><CODE>section(name)</CODE>: generate function or data in assembly section
    686750name (name is a string containing the section name) instead of the default
    687751section.
    688 
    689   </li><li> <code>unused</code>: specify that the variable or the function is unused.
    690 
    691   </li><li> <code>cdecl</code>: use standard C calling convention (default).
    692 
    693   </li><li> <code>stdcall</code>: use Pascal-like calling convention.
    694 
    695   </li><li> <code>regparm(n)</code>: use fast i386 calling convention. <var>n</var> must be
    696 between 1 and 3. The first <var>n</var> function parameters are respectively put in
    697 registers <code>%eax</code>, <code>%edx</code> and <code>%ecx</code>.
    698 
    699   </li><li> <code>dllexport</code>: export function from dll/executable (win32 only)
    700 
    701 </li></ul>
    702 
    703 <p>Here are some examples:
    704 </p><table><tr><td>&nbsp;</td><td><pre class="example">    int a __attribute__ ((aligned(8), section(&quot;.mysection&quot;)));
    705 </pre></td></tr></table>
    706 
    707 <p>align variable <code>a</code> to 8 bytes and put it in section <code>.mysection</code>.
    708 </p>
    709 <table><tr><td>&nbsp;</td><td><pre class="example">    int my_add(int a, int b) __attribute__ ((section(&quot;.mycodesection&quot;)))
     752<P>
     753
     754<LI><CODE>unused</CODE>: specify that the variable or the function is unused.
     755<P>
     756
     757<LI><CODE>cdecl</CODE>: use standard C calling convention (default).
     758<P>
     759
     760<LI><CODE>stdcall</CODE>: use Pascal-like calling convention.
     761<P>
     762
     763<LI><CODE>regparm(n)</CODE>: use fast i386 calling convention. <VAR>n</VAR> must be
     764between 1 and 3. The first <VAR>n</VAR> function parameters are respectively put in
     765registers <CODE>%eax</CODE>, <CODE>%edx</CODE> and <CODE>%ecx</CODE>.
     766<P>
     767
     768<LI><CODE>dllexport</CODE>: export function from dll/executable (win32 only)
     769<P>
     770
     771</UL>
     772<P>
     773
     774Here are some examples:
     775<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int a __attribute__ ((aligned(8), section(".mysection")));
     776</pre></td></tr></table></P><P>
     777
     778align variable <CODE>a</CODE> to 8 bytes and put it in section <CODE>.mysection</CODE>.
     779</P><P>
     780
     781<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
    710782    {
    711783        return a + b;
    712784    }
    713 </pre></td></tr></table>
    714 
    715 <p>generate function <code>my_add</code> in section <code>.mycodesection</code>.
    716 </p>
    717 </li><li> GNU style variadic macros:
    718 <table><tr><td>&nbsp;</td><td><pre class="example">    #define dprintf(fmt, args&hellip;) printf(fmt, ## args)
    719 
    720     dprintf(&quot;no arg\n&quot;);
    721     dprintf(&quot;one arg %d\n&quot;, 1);
    722 </pre></td></tr></table>
    723 
    724 </li><li> <code>__FUNCTION__</code> is interpreted as C99 <code>__func__</code>
     785</pre></td></tr></table></P><P>
     786
     787generate function <CODE>my_add</CODE> in section <CODE>.mycodesection</CODE>.
     788</P><P>
     789
     790<LI>GNU style variadic macros:
     791<TABLE><tr><td>&nbsp;</td><td class=example><pre>    #define dprintf(fmt, args<small>...</small>) printf(fmt, ## args)
     792
     793    dprintf("no arg\n");
     794    dprintf("one arg %d\n", 1);
     795</pre></td></tr></table><P>
     796
     797<LI><CODE>__FUNCTION__</CODE> is interpreted as C99 <CODE>__func__</CODE>
    725798(so it has not exactly the same semantics as string literal GNUC
    726799where it is a string literal).
    727 
    728 </li><li> The <code>__alignof__</code> keyword can be used as <code>sizeof</code>
     800<P>
     801
     802<LI>The <CODE>__alignof__</CODE> keyword can be used as <CODE>sizeof</CODE>
    729803to get the alignment of a type or an expression.
    730 
    731 </li><li> The <code>typeof(x)</code> returns the type of <code>x</code>.
    732 <code>x</code> is an expression or a type.
    733 
    734 </li><li> Computed gotos: <code>&amp;&amp;label</code> returns a pointer of type
    735 <code>void *</code> on the goto label <code>label</code>. <code>goto *expr</code> can be
    736 used to jump on the pointer resulting from <code>expr</code>.
    737 
    738 </li><li> Inline assembly with asm instruction:
    739 <a name="index-inline-assembly"></a>
    740 <a name="index-assembly_002c-inline"></a>
    741 <a name="index-_005f_005fasm_005f_005f"></a>
    742 <table><tr><td>&nbsp;</td><td><pre class="example">static inline void * my_memcpy(void * to, const void * from, size_t n)
     804<P>
     805
     806<LI>The <CODE>typeof(x)</CODE> returns the type of <CODE>x</CODE>.
     807<CODE>x</CODE> is an expression or a type.
     808<P>
     809
     810<LI>Computed gotos: <CODE>&#38;&#38;label</CODE> returns a pointer of type
     811<CODE>void *</CODE> on the goto label <CODE>label</CODE>. <CODE>goto *expr</CODE> can be
     812used to jump on the pointer resulting from <CODE>expr</CODE>.
     813<P>
     814
     815<LI>Inline assembly with asm instruction:
     816<A NAME="IDX9"></A>
     817<A NAME="IDX10"></A>
     818<A NAME="IDX11"></A>
     819<TABLE><tr><td>&nbsp;</td><td class=example><pre>static inline void * my_memcpy(void * to, const void * from, size_t n)
    743820{
    744821int d0, d1, d2;
    745822__asm__ __volatile__(
    746         &quot;rep ; movsl\n\t&quot;
    747         &quot;testb $2,%b4\n\t&quot;
    748         &quot;je 1f\n\t&quot;
    749         &quot;movsw\n&quot;
    750         &quot;1:\ttestb $1,%b4\n\t&quot;
    751         &quot;je 2f\n\t&quot;
    752         &quot;movsb\n&quot;
    753         &quot;2:&quot;
    754         : &quot;=&amp;c&quot; (d0), &quot;=&amp;D&quot; (d1), &quot;=&amp;S&quot; (d2)
    755         :&quot;0&quot; (n/4), &quot;q&quot; (n),&quot;1&quot; ((long) to),&quot;2&quot; ((long) from)
    756         : &quot;memory&quot;);
     823        "rep ; movsl\n\t"
     824        "testb $2,%b4\n\t"
     825        "je 1f\n\t"
     826        "movsw\n"
     827        "1:\ttestb $1,%b4\n\t"
     828        "je 2f\n\t"
     829        "movsb\n"
     830        "2:"
     831        : "=&c" (d0), "=&#38;D" (d1), "=&#38;S" (d2)
     832        :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
     833        : "memory");
    757834return (to);
    758835}
    759 </pre></td></tr></table>
    760 
    761 <a name="index-gas"></a>
    762 <p>TCC includes its own x86 inline assembler with a <code>gas</code>-like (GNU
     836</pre></td></tr></table><P>
     837
     838<A NAME="IDX12"></A>
     839TCC includes its own x86 inline assembler with a <CODE>gas</CODE>-like (GNU
    763840assembler) syntax. No intermediate files are generated. GCC 3.x named
    764841operands are supported.
    765 </p>
    766 </li><li> <code>__builtin_types_compatible_p()</code> and <code>__builtin_constant_p()</code>
     842</P><P>
     843
     844<LI><CODE>__builtin_types_compatible_p()</CODE> and <CODE>__builtin_constant_p()</CODE>
    767845are supported.
    768 
    769 </li><li> <code>#pragma pack</code> is supported for win32 compatibility.
    770 
    771 </li></ul>
    772 
    773 <hr size="6">
    774 <a name="TinyCC-extensions"></a>
    775 <table cellpadding="1" cellspacing="1" border="0">
    776 <tr><td valign="middle" align="left">[<a href="#GNU-C-extensions" title="Previous section in reading order"> &lt; </a>]</td>
    777 <td valign="middle" align="left">[<a href="#asm" title="Next section in reading order"> &gt; </a>]</td>
    778 <td valign="middle" align="left"> &nbsp; </td>
    779 <td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    780 <td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
    781 <td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
    782 <td valign="middle" align="left"> &nbsp; </td>
    783 <td valign="middle" align="left"> &nbsp; </td>
    784 <td valign="middle" align="left"> &nbsp; </td>
    785 <td valign="middle" align="left"> &nbsp; </td>
    786 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    787 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    788 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    789 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    790 </tr></table>
    791 <h2 class="section">3.4 TinyCC extensions</h2>
    792 
    793 <ul>
    794 <li> <code>__TINYC__</code> is a predefined macro to <code>1</code> to
    795 indicate that you use TCC.
    796 
    797 </li><li> <code>#!</code> at the start of a line is ignored to allow scripting.
    798 
    799 </li><li> Binary digits can be entered (<code>0b101</code> instead of
    800 <code>5</code>).
    801 
    802 </li><li> <code>__BOUNDS_CHECKING_ON</code> is defined if bound checking is activated.
    803 
    804 </li></ul>
    805 
    806 <hr size="6">
    807 <a name="asm"></a>
    808 <table cellpadding="1" cellspacing="1" border="0">
    809 <tr><td valign="middle" align="left">[<a href="#TinyCC-extensions" title="Previous section in reading order"> &lt; </a>]</td>
    810 <td valign="middle" align="left">[<a href="#Syntax" title="Next section in reading order"> &gt; </a>]</td>
    811 <td valign="middle" align="left"> &nbsp; </td>
    812 <td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    813 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    814 <td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
    815 <td valign="middle" align="left"> &nbsp; </td>
    816 <td valign="middle" align="left"> &nbsp; </td>
    817 <td valign="middle" align="left"> &nbsp; </td>
    818 <td valign="middle" align="left"> &nbsp; </td>
    819 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    820 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    821 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    822 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    823 </tr></table>
    824 <a name="TinyCC-Assembler"></a>
    825 <h1 class="chapter">4. TinyCC Assembler</h1>
    826 
    827 <p>Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
     846<P>
     847
     848<LI><CODE>#pragma pack</CODE> is supported for win32 compatibility.
     849<P>
     850
     851</UL>
     852<P>
     853
     854<HR SIZE="6">
     855<A NAME="SEC9"></A>
     856<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     857<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt; </A>]</TD>
     858<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt; </A>]</TD>
     859<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
     860<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
     861<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
     862<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     863<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     864<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     865<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     866</TR></TABLE>
     867<H2> 3.4 TinyCC extensions </H2>
     868<!--docid::SEC9::-->
     869<P>
     870
     871<UL>
     872
     873<LI><CODE>__TINYC__</CODE> is a predefined macro to indicate that you use TCC.
     874<P>
     875
     876<LI><CODE>#!</CODE> at the start of a line is ignored to allow scripting.
     877<P>
     878
     879<LI>Binary digits can be entered (<CODE>0b101</CODE> instead of
     880<CODE>5</CODE>).
     881<P>
     882
     883<LI><CODE>__BOUNDS_CHECKING_ON</CODE> is defined if bound checking is activated.
     884<P>
     885
     886</UL>
     887<P>
     888
     889<A NAME="asm"></A>
     890<HR SIZE="6">
     891<A NAME="SEC10"></A>
     892<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     893<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt; </A>]</TD>
     894<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &gt; </A>]</TD>
     895<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
     896<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     897<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
     898<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     899<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     900<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     901<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     902</TR></TABLE>
     903<H1> 4. TinyCC Assembler </H1>
     904<!--docid::SEC10::-->
     905<P>
     906
     907Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
    828908assembler supports a gas-like syntax (GNU assembler). You can
    829 desactivate assembler support if you want a smaller TinyCC executable
     909deactivate assembler support if you want a smaller TinyCC executable
    830910(the C compiler does not rely on the assembler).
    831 </p>
    832 <p>TinyCC Assembler is used to handle files with &lsquo;<tt>.S</tt>&rsquo; (C
    833 preprocessed assembler) and &lsquo;<tt>.s</tt>&rsquo; extensions. It is also used to
    834 handle the GNU inline assembler with the <code>asm</code> keyword.
    835 </p>
    836 <hr size="6">
    837 <a name="Syntax"></a>
    838 <table cellpadding="1" cellspacing="1" border="0">
    839 <tr><td valign="middle" align="left">[<a href="#asm" title="Previous section in reading order"> &lt; </a>]</td>
    840 <td valign="middle" align="left">[<a href="#Expressions" title="Next section in reading order"> &gt; </a>]</td>
    841 <td valign="middle" align="left"> &nbsp; </td>
    842 <td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    843 <td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
    844 <td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
    845 <td valign="middle" align="left"> &nbsp; </td>
    846 <td valign="middle" align="left"> &nbsp; </td>
    847 <td valign="middle" align="left"> &nbsp; </td>
    848 <td valign="middle" align="left"> &nbsp; </td>
    849 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    850 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    851 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    852 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    853 </tr></table>
    854 <h2 class="section">4.1 Syntax</h2>
    855 
    856 <p>TinyCC Assembler supports most of the gas syntax. The tokens are the
     911</P><P>
     912
     913TinyCC Assembler is used to handle files with <TT>`.S'</TT> (C
     914preprocessed assembler) and <TT>`.s'</TT> extensions. It is also used to
     915handle the GNU inline assembler with the <CODE>asm</CODE> keyword.
     916</P><P>
     917
     918<HR SIZE="6">
     919<A NAME="SEC11"></A>
     920<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     921<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt; </A>]</TD>
     922<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &gt; </A>]</TD>
     923<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
     924<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
     925<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
     926<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     927<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     928<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     929<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     930</TR></TABLE>
     931<H2> 4.1 Syntax </H2>
     932<!--docid::SEC11::-->
     933<P>
     934
     935TinyCC Assembler supports most of the gas syntax. The tokens are the
    857936same as C.
    858 </p>
    859 <ul>
    860 <li> C and C++ comments are supported.
    861 
    862 </li><li> Identifiers are the same as C, so you cannot use &rsquo;.&rsquo; or &rsquo;$&rsquo;.
    863 
    864 </li><li> Only 32 bit integer numbers are supported.
    865 
    866 </li></ul>
    867 
    868 <hr size="6">
    869 <a name="Expressions"></a>
    870 <table cellpadding="1" cellspacing="1" border="0">
    871 <tr><td valign="middle" align="left">[<a href="#Syntax" title="Previous section in reading order"> &lt; </a>]</td>
    872 <td valign="middle" align="left">[<a href="#Labels" title="Next section in reading order"> &gt; </a>]</td>
    873 <td valign="middle" align="left"> &nbsp; </td>
    874 <td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    875 <td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
    876 <td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
    877 <td valign="middle" align="left"> &nbsp; </td>
    878 <td valign="middle" align="left"> &nbsp; </td>
    879 <td valign="middle" align="left"> &nbsp; </td>
    880 <td valign="middle" align="left"> &nbsp; </td>
    881 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    882 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    883 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    884 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    885 </tr></table>
    886 <h2 class="section">4.2 Expressions</h2>
    887 
    888 <ul>
    889 <li> Integers in decimal, octal and hexa are supported.
    890 
    891 </li><li> Unary operators: +, -, ~.
    892 
    893 </li><li> Binary operators in decreasing priority order:
    894 
    895 <ol>
    896 <li> *, /, %
    897 </li><li> &amp;, |, ^
    898 </li><li> +, -
    899 </li></ol>
    900 
    901 </li><li> A value is either an absolute number or a label plus an offset.
    902 All operators accept absolute values except &rsquo;+&rsquo; and &rsquo;-&rsquo;. &rsquo;+&rsquo; or &rsquo;-&rsquo; can be
    903 used to add an offset to a label. &rsquo;-&rsquo; supports two labels only if they
     937</P><P>
     938
     939<UL>
     940
     941<LI>C and C++ comments are supported.
     942<P>
     943
     944<LI>Identifiers are the same as C, so you cannot use '.' or '$'.
     945<P>
     946
     947<LI>Only 32 bit integer numbers are supported.
     948<P>
     949
     950</UL>
     951<P>
     952
     953<HR SIZE="6">
     954<A NAME="SEC12"></A>
     955<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     956<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &lt; </A>]</TD>
     957<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &gt; </A>]</TD>
     958<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt;&lt; </A>]</TD>
     959<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
     960<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
     961<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     962<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     963<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     964<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     965</TR></TABLE>
     966<H2> 4.2 Expressions </H2>
     967<!--docid::SEC12::-->
     968<P>
     969
     970<UL>
     971
     972<LI>Integers in decimal, octal and hexa are supported.
     973<P>
     974
     975<LI>Unary operators: +, -, ~.
     976<P>
     977
     978<LI>Binary operators in decreasing priority order:
     979<P>
     980
     981<OL>
     982<LI>*, /, %
     983<LI>&#38;, |, ^
     984<LI>+, -
     985</OL>
     986<P>
     987
     988<LI>A value is either an absolute number or a label plus an offset.
     989All operators accept absolute values except '+' and '-'. '+' or '-' can be
     990used to add an offset to a label. '-' supports two labels only if they
    904991are the same or if they are both defined and in the same section.
    905 
    906 </li></ul>
    907 
    908 <hr size="6">
    909 <a name="Labels"></a>
    910 <table cellpadding="1" cellspacing="1" border="0">
    911 <tr><td valign="middle" align="left">[<a href="#Expressions" title="Previous section in reading order"> &lt; </a>]</td>
    912 <td valign="middle" align="left">[<a href="#Directives" title="Next section in reading order"> &gt; </a>]</td>
    913 <td valign="middle" align="left"> &nbsp; </td>
    914 <td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    915 <td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
    916 <td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
    917 <td valign="middle" align="left"> &nbsp; </td>
    918 <td valign="middle" align="left"> &nbsp; </td>
    919 <td valign="middle" align="left"> &nbsp; </td>
    920 <td valign="middle" align="left"> &nbsp; </td>
    921 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    922 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    923 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    924 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    925 </tr></table>
    926 <h2 class="section">4.3 Labels</h2>
    927 
    928 <ul>
    929 <li> All labels are considered as local, except undefined ones.
    930 
    931 </li><li> Numeric labels can be used as local <code>gas</code>-like labels.
    932 They can be defined several times in the same source. Use &rsquo;b&rsquo;
    933 (backward) or &rsquo;f&rsquo; (forward) as suffix to reference them:
    934 
    935 <table><tr><td>&nbsp;</td><td><pre class="example"> 1:
     992<P>
     993
     994</UL>
     995<P>
     996
     997<HR SIZE="6">
     998<A NAME="SEC13"></A>
     999<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1000<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &lt; </A>]</TD>
     1001<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &gt; </A>]</TD>
     1002<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt;&lt; </A>]</TD>
     1003<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
     1004<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
     1005<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1006<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1007<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1008<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1009</TR></TABLE>
     1010<H2> 4.3 Labels </H2>
     1011<!--docid::SEC13::-->
     1012<P>
     1013
     1014<UL>
     1015
     1016<LI>All labels are considered as local, except undefined ones.
     1017<P>
     1018
     1019<LI>Numeric labels can be used as local <CODE>gas</CODE>-like labels.
     1020They can be defined several times in the same source. Use 'b'
     1021(backward) or 'f' (forward) as suffix to reference them:
     1022<P>
     1023
     1024<TABLE><tr><td>&nbsp;</td><td class=example><pre> 1:
    9361025      jmp 1b /* jump to '1' label before */
    9371026      jmp 1f /* jump to '1' label after */
    9381027 1:
    939 </pre></td></tr></table>
    940 
    941 </li></ul>
    942 
    943 <hr size="6">
    944 <a name="Directives"></a>
    945 <table cellpadding="1" cellspacing="1" border="0">
    946 <tr><td valign="middle" align="left">[<a href="#Labels" title="Previous section in reading order"> &lt; </a>]</td>
    947 <td valign="middle" align="left">[<a href="#X86-Assembler" title="Next section in reading order"> &gt; </a>]</td>
    948 <td valign="middle" align="left"> &nbsp; </td>
    949 <td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    950 <td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
    951 <td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
    952 <td valign="middle" align="left"> &nbsp; </td>
    953 <td valign="middle" align="left"> &nbsp; </td>
    954 <td valign="middle" align="left"> &nbsp; </td>
    955 <td valign="middle" align="left"> &nbsp; </td>
    956 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    957 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    958 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    959 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    960 </tr></table>
    961 <h2 class="section">4.4 Directives</h2>
    962 <a name="index-assembler-directives"></a>
    963 <a name="index-directives_002c-assembler"></a>
    964 <a name="index-align-directive"></a>
    965 <a name="index-skip-directive"></a>
    966 <a name="index-space-directive"></a>
    967 <a name="index-byte-directive"></a>
    968 <a name="index-word-directive"></a>
    969 <a name="index-short-directive"></a>
    970 <a name="index-int-directive"></a>
    971 <a name="index-long-directive"></a>
    972 <a name="index-quad-directive"></a>
    973 <a name="index-globl-directive"></a>
    974 <a name="index-global-directive"></a>
    975 <a name="index-section-directive"></a>
    976 <a name="index-text-directive"></a>
    977 <a name="index-data-directive"></a>
    978 <a name="index-bss-directive"></a>
    979 <a name="index-fill-directive"></a>
    980 <a name="index-org-directive"></a>
    981 <a name="index-previous-directive"></a>
    982 <a name="index-string-directive"></a>
    983 <a name="index-asciz-directive"></a>
    984 <a name="index-ascii-directive"></a>
    985 
    986 <p>All directives are preceeded by a &rsquo;.&rsquo;. The following directives are
     1028</pre></td></tr></table></P><P>
     1029
     1030</UL>
     1031<P>
     1032
     1033<HR SIZE="6">
     1034<A NAME="SEC14"></A>
     1035<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1036<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt; </A>]</TD>
     1037<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &gt; </A>]</TD>
     1038<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt;&lt; </A>]</TD>
     1039<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
     1040<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
     1041<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1042<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1043<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1044<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1045</TR></TABLE>
     1046<H2> 4.4 Directives </H2>
     1047<!--docid::SEC14::-->
     1048<P>
     1049
     1050All directives are preceded by a '.'. The following directives are
    9871051supported:
    988 </p>
    989 <ul>
    990 <li> .align n[,value]
    991 </li><li> .skip n[,value]
    992 </li><li> .space n[,value]
    993 </li><li> .byte value1[,...]
    994 </li><li> .word value1[,...]
    995 </li><li> .short value1[,...]
    996 </li><li> .int value1[,...]
    997 </li><li> .long value1[,...]
    998 </li><li> .quad immediate_value1[,...]
    999 </li><li> .globl symbol
    1000 </li><li> .global symbol
    1001 </li><li> .section section
    1002 </li><li> .text
    1003 </li><li> .data
    1004 </li><li> .bss
    1005 </li><li> .fill repeat[,size[,value]]
    1006 </li><li> .org n
    1007 </li><li> .previous
    1008 </li><li> .string string[,...]
    1009 </li><li> .asciz string[,...]
    1010 </li><li> .ascii string[,...]
    1011 </li></ul>
    1012 
    1013 <hr size="6">
    1014 <a name="X86-Assembler"></a>
    1015 <table cellpadding="1" cellspacing="1" border="0">
    1016 <tr><td valign="middle" align="left">[<a href="#Directives" title="Previous section in reading order"> &lt; </a>]</td>
    1017 <td valign="middle" align="left">[<a href="#linker" title="Next section in reading order"> &gt; </a>]</td>
    1018 <td valign="middle" align="left"> &nbsp; </td>
    1019 <td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1020 <td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
    1021 <td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
    1022 <td valign="middle" align="left"> &nbsp; </td>
    1023 <td valign="middle" align="left"> &nbsp; </td>
    1024 <td valign="middle" align="left"> &nbsp; </td>
    1025 <td valign="middle" align="left"> &nbsp; </td>
    1026 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1027 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1028 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1029 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1030 </tr></table>
    1031 <h2 class="section">4.5 X86 Assembler</h2>
    1032 <a name="index-assembler"></a>
    1033 
    1034 <p>All X86 opcodes are supported. Only ATT syntax is supported (source
     1052</P><P>
     1053
     1054<UL>
     1055<LI>.align n[,value]
     1056<LI>.skip n[,value]
     1057<LI>.space n[,value]
     1058<LI>.byte value1[,...]
     1059<LI>.word value1[,...]
     1060<LI>.short value1[,...]
     1061<LI>.int value1[,...]
     1062<LI>.long value1[,...]
     1063<LI>.quad immediate_value1[,...]
     1064<LI>.globl symbol
     1065<LI>.global symbol
     1066<LI>.section section
     1067<LI>.text
     1068<LI>.data
     1069<LI>.bss
     1070<LI>.fill repeat[,size[,value]]
     1071<LI>.org n
     1072<LI>.previous
     1073<LI>.string string[,...]
     1074<LI>.asciz string[,...]
     1075<LI>.ascii string[,...]
     1076</UL>
     1077<P>
     1078
     1079<HR SIZE="6">
     1080<A NAME="SEC15"></A>
     1081<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1082<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt; </A>]</TD>
     1083<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt; </A>]</TD>
     1084<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
     1085<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
     1086<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
     1087<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1088<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1089<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1090<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1091</TR></TABLE>
     1092<H2> 4.5 X86 Assembler </H2>
     1093<!--docid::SEC15::-->
     1094<P>
     1095
     1096All X86 opcodes are supported. Only ATT syntax is supported (source
    10351097then destination operand order). If no size suffix is given, TinyCC
    10361098tries to guess it from the operand sizes.
    1037 </p>
    1038 <p>Currently, MMX opcodes are supported but not SSE ones.
    1039 </p>
    1040 <hr size="6">
    1041 <a name="linker"></a>
    1042 <table cellpadding="1" cellspacing="1" border="0">
    1043 <tr><td valign="middle" align="left">[<a href="#X86-Assembler" title="Previous section in reading order"> &lt; </a>]</td>
    1044 <td valign="middle" align="left">[<a href="#ELF-file-generation" title="Next section in reading order"> &gt; </a>]</td>
    1045 <td valign="middle" align="left"> &nbsp; </td>
    1046 <td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1047 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    1048 <td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
    1049 <td valign="middle" align="left"> &nbsp; </td>
    1050 <td valign="middle" align="left"> &nbsp; </td>
    1051 <td valign="middle" align="left"> &nbsp; </td>
    1052 <td valign="middle" align="left"> &nbsp; </td>
    1053 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1054 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1055 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1056 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1057 </tr></table>
    1058 <a name="TinyCC-Linker"></a>
    1059 <h1 class="chapter">5. TinyCC Linker</h1>
    1060 <a name="index-linker"></a>
    1061 
    1062 <hr size="6">
    1063 <a name="ELF-file-generation"></a>
    1064 <table cellpadding="1" cellspacing="1" border="0">
    1065 <tr><td valign="middle" align="left">[<a href="#linker" title="Previous section in reading order"> &lt; </a>]</td>
    1066 <td valign="middle" align="left">[<a href="#ELF-file-loader" title="Next section in reading order"> &gt; </a>]</td>
    1067 <td valign="middle" align="left"> &nbsp; </td>
    1068 <td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1069 <td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
    1070 <td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
    1071 <td valign="middle" align="left"> &nbsp; </td>
    1072 <td valign="middle" align="left"> &nbsp; </td>
    1073 <td valign="middle" align="left"> &nbsp; </td>
    1074 <td valign="middle" align="left"> &nbsp; </td>
    1075 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1076 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1077 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1078 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1079 </tr></table>
    1080 <h2 class="section">5.1 ELF file generation</h2>
    1081 <a name="index-ELF"></a>
    1082 
    1083 <p>TCC can directly output relocatable ELF files (object files),
     1099</P><P>
     1100
     1101Currently, MMX opcodes are supported but not SSE ones.
     1102</P><P>
     1103
     1104<A NAME="linker"></A>
     1105<HR SIZE="6">
     1106<A NAME="SEC16"></A>
     1107<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1108<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt; </A>]</TD>
     1109<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &gt; </A>]</TD>
     1110<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt;&lt; </A>]</TD>
     1111<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     1112<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
     1113<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1114<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1115<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1116<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1117</TR></TABLE>
     1118<H1> 5. TinyCC Linker </H1>
     1119<!--docid::SEC16::-->
     1120<P>
     1121
     1122<HR SIZE="6">
     1123<A NAME="SEC17"></A>
     1124<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1125<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt; </A>]</TD>
     1126<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &gt; </A>]</TD>
     1127<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
     1128<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
     1129<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
     1130<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1131<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1132<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1133<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1134</TR></TABLE>
     1135<H2> 5.1 ELF file generation </H2>
     1136<!--docid::SEC17::-->
     1137<P>
     1138
     1139TCC can directly output relocatable ELF files (object files),
    10841140executable ELF files and dynamic ELF libraries without relying on an
    10851141external linker.
    1086 </p>
    1087 <p>Dynamic ELF libraries can be output but the C compiler does not generate
     1142</P><P>
     1143
     1144Dynamic ELF libraries can be output but the C compiler does not generate
    10881145position independent code (PIC). It means that the dynamic library
    10891146code generated by TCC cannot be factorized among processes yet.
    1090 </p>
    1091 <p>TCC linker eliminates unreferenced object code in libraries. A single pass is
     1147</P><P>
     1148
     1149TCC linker eliminates unreferenced object code in libraries. A single pass is
    10921150done on the object and library list, so the order in which object files and
    10931151libraries are specified is important (same constraint as GNU ld). No grouping
    1094 options (&lsquo;<samp>--start-group</samp>&rsquo; and &lsquo;<samp>--end-group</samp>&rsquo;) are supported.
    1095 </p>
    1096 <hr size="6">
    1097 <a name="ELF-file-loader"></a>
    1098 <table cellpadding="1" cellspacing="1" border="0">
    1099 <tr><td valign="middle" align="left">[<a href="#ELF-file-generation" title="Previous section in reading order"> &lt; </a>]</td>
    1100 <td valign="middle" align="left">[<a href="#PE_002di386-file-generation" title="Next section in reading order"> &gt; </a>]</td>
    1101 <td valign="middle" align="left"> &nbsp; </td>
    1102 <td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1103 <td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
    1104 <td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
    1105 <td valign="middle" align="left"> &nbsp; </td>
    1106 <td valign="middle" align="left"> &nbsp; </td>
    1107 <td valign="middle" align="left"> &nbsp; </td>
    1108 <td valign="middle" align="left"> &nbsp; </td>
    1109 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1110 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1111 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1112 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1113 </tr></table>
    1114 <h2 class="section">5.2 ELF file loader</h2>
    1115 
    1116 <p>TCC can load ELF object files, archives (.a files) and dynamic
     1152options (<SAMP>`--start-group'</SAMP> and <SAMP>`--end-group'</SAMP>) are supported.
     1153</P><P>
     1154
     1155<HR SIZE="6">
     1156<A NAME="SEC18"></A>
     1157<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1158<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &lt; </A>]</TD>
     1159<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &gt; </A>]</TD>
     1160<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt;&lt; </A>]</TD>
     1161<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
     1162<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
     1163<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1164<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1165<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1166<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1167</TR></TABLE>
     1168<H2> 5.2 ELF file loader </H2>
     1169<!--docid::SEC18::-->
     1170<P>
     1171
     1172TCC can load ELF object files, archives (.a files) and dynamic
    11171173libraries (.so).
    1118 </p>
    1119 <hr size="6">
    1120 <a name="PE_002di386-file-generation"></a>
    1121 <table cellpadding="1" cellspacing="1" border="0">
    1122 <tr><td valign="middle" align="left">[<a href="#ELF-file-loader" title="Previous section in reading order"> &lt; </a>]</td>
    1123 <td valign="middle" align="left">[<a href="#GNU-Linker-Scripts" title="Next section in reading order"> &gt; </a>]</td>
    1124 <td valign="middle" align="left"> &nbsp; </td>
    1125 <td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1126 <td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
    1127 <td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
    1128 <td valign="middle" align="left"> &nbsp; </td>
    1129 <td valign="middle" align="left"> &nbsp; </td>
    1130 <td valign="middle" align="left"> &nbsp; </td>
    1131 <td valign="middle" align="left"> &nbsp; </td>
    1132 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1133 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1134 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1135 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1136 </tr></table>
    1137 <h2 class="section">5.3 PE-i386 file generation</h2>
    1138 <a name="index-PE_002di386"></a>
    1139 
    1140 <p>TCC for Windows supports the native Win32 executable file format (PE-i386).  It
     1174</P><P>
     1175
     1176<HR SIZE="6">
     1177<A NAME="SEC19"></A>
     1178<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1179<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &lt; </A>]</TD>
     1180<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &gt; </A>]</TD>
     1181<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt;&lt; </A>]</TD>
     1182<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
     1183<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
     1184<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1185<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1186<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1187<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1188</TR></TABLE>
     1189<H2> 5.3 PE-i386 file generation </H2>
     1190<!--docid::SEC19::-->
     1191<P>
     1192
     1193TCC for Windows supports the native Win32 executable file format (PE-i386).  It
    11411194generates EXE files (console and gui) and DLL files.
    1142 </p>
    1143 <p>For usage on Windows, see also tcc-win32.txt.
    1144 </p>
    1145 <hr size="6">
    1146 <a name="GNU-Linker-Scripts"></a>
    1147 <table cellpadding="1" cellspacing="1" border="0">
    1148 <tr><td valign="middle" align="left">[<a href="#PE_002di386-file-generation" title="Previous section in reading order"> &lt; </a>]</td>
    1149 <td valign="middle" align="left">[<a href="#Bounds" title="Next section in reading order"> &gt; </a>]</td>
    1150 <td valign="middle" align="left"> &nbsp; </td>
    1151 <td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1152 <td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
    1153 <td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
    1154 <td valign="middle" align="left"> &nbsp; </td>
    1155 <td valign="middle" align="left"> &nbsp; </td>
    1156 <td valign="middle" align="left"> &nbsp; </td>
    1157 <td valign="middle" align="left"> &nbsp; </td>
    1158 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1159 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1160 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1161 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1162 </tr></table>
    1163 <h2 class="section">5.4 GNU Linker Scripts</h2>
    1164 <a name="index-scripts_002c-linker"></a>
    1165 <a name="index-linker-scripts"></a>
    1166 <a name="index-GROUP_002c-linker-command"></a>
    1167 <a name="index-FILE_002c-linker-command"></a>
    1168 <a name="index-OUTPUT_005fFORMAT_002c-linker-command"></a>
    1169 <a name="index-TARGET_002c-linker-command"></a>
    1170 
    1171 <p>Because on many Linux systems some dynamic libraries (such as
    1172 &lsquo;<tt>/usr/lib/libc.so</tt>&rsquo;) are in fact GNU ld link scripts (horrible!),
     1195</P><P>
     1196
     1197For usage on Windows, see also tcc-win32.txt.
     1198</P><P>
     1199
     1200<HR SIZE="6">
     1201<A NAME="SEC20"></A>
     1202<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1203<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt; </A>]</TD>
     1204<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt; </A>]</TD>
     1205<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
     1206<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
     1207<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
     1208<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1209<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1210<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1211<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1212</TR></TABLE>
     1213<H2> 5.4 GNU Linker Scripts </H2>
     1214<!--docid::SEC20::-->
     1215<P>
     1216
     1217Because on many Linux systems some dynamic libraries (such as
     1218<TT>`/usr/lib/libc.so'</TT>) are in fact GNU ld link scripts (horrible!),
    11731219the TCC linker also supports a subset of GNU ld scripts.
    1174 </p>
    1175 <p>The <code>GROUP</code> and <code>FILE</code> commands are supported. <code>OUTPUT_FORMAT</code>
    1176 and <code>TARGET</code> are ignored.
    1177 </p>
    1178 <p>Example from &lsquo;<tt>/usr/lib/libc.so</tt>&rsquo;:
    1179 </p><table><tr><td>&nbsp;</td><td><pre class="example">/* GNU ld script
     1220</P><P>
     1221
     1222The <CODE>GROUP</CODE> and <CODE>FILE</CODE> commands are supported. <CODE>OUTPUT_FORMAT</CODE>
     1223and <CODE>TARGET</CODE> are ignored.
     1224</P><P>
     1225
     1226Example from <TT>`/usr/lib/libc.so'</TT>:
     1227<TABLE><tr><td>&nbsp;</td><td class=example><pre>/* GNU ld script
    11801228   Use the shared library, but some functions are only in
    11811229   the static library, so try that secondarily.  */
    11821230GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
    1183 </pre></td></tr></table>
    1184 
    1185 <hr size="6">
    1186 <a name="Bounds"></a>
    1187 <table cellpadding="1" cellspacing="1" border="0">
    1188 <tr><td valign="middle" align="left">[<a href="#GNU-Linker-Scripts" title="Previous section in reading order"> &lt; </a>]</td>
    1189 <td valign="middle" align="left">[<a href="#Libtcc" title="Next section in reading order"> &gt; </a>]</td>
    1190 <td valign="middle" align="left"> &nbsp; </td>
    1191 <td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1192 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    1193 <td valign="middle" align="left">[<a href="#Libtcc" title="Next chapter"> &gt;&gt; </a>]</td>
    1194 <td valign="middle" align="left"> &nbsp; </td>
    1195 <td valign="middle" align="left"> &nbsp; </td>
    1196 <td valign="middle" align="left"> &nbsp; </td>
    1197 <td valign="middle" align="left"> &nbsp; </td>
    1198 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1199 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1200 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1201 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1202 </tr></table>
    1203 <a name="TinyCC-Memory-and-Bound-checks"></a>
    1204 <h1 class="chapter">6. TinyCC Memory and Bound checks</h1>
    1205 <a name="index-bound-checks"></a>
    1206 <a name="index-memory-checks"></a>
    1207 
    1208 <p>This feature is activated with the &lsquo;<samp>-b</samp>&rsquo; (see section <a href="#Invoke">Command line invocation</a>).
    1209 </p>
    1210 <p>Note that pointer size is <em>unchanged</em> and that code generated
    1211 with bound checks is <em>fully compatible</em> with unchecked
     1231</pre></td></tr></table></P><P>
     1232
     1233<A NAME="Bounds"></A>
     1234<HR SIZE="6">
     1235<A NAME="SEC21"></A>
     1236<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1237<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt; </A>]</TD>
     1238<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt; </A>]</TD>
     1239<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt;&lt; </A>]</TD>
     1240<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     1241<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt;&gt; </A>]</TD>
     1242<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1243<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1244<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1245<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1246</TR></TABLE>
     1247<H1> 6. TinyCC Memory and Bound checks </H1>
     1248<!--docid::SEC21::-->
     1249<P>
     1250
     1251This feature is activated with the <SAMP>`-b'</SAMP> (see section <A HREF="tcc-doc.html#SEC2">2. Command line invocation</A>).
     1252</P><P>
     1253
     1254Note that pointer size is <EM>unchanged</EM> and that code generated
     1255with bound checks is <EM>fully compatible</EM> with unchecked
    12121256code. When a pointer comes from unchecked code, it is assumed to be
    12131257valid. Even very obscure C code with casts should work correctly.
    1214 </p>
    1215 <p>For more information about the ideas behind this method, see
    1216 <a href="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</a>.
    1217 </p>
    1218 <p>Here are some examples of caught errors:
    1219 </p>
    1220 <dl compact="compact">
    1221 <dt> Invalid range with standard string function:</dt>
    1222 <dd><table><tr><td>&nbsp;</td><td><pre class="example">{
     1258</P><P>
     1259
     1260For more information about the ideas behind this method, see
     1261<A HREF="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</A>.
     1262</P><P>
     1263
     1264Here are some examples of caught errors:
     1265</P><P>
     1266
     1267<DL COMPACT>
     1268
     1269<DT>Invalid range with standard string function:
     1270<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
    12231271    char tab[10];
    12241272    memset(tab, 0, 11);
    12251273}
    1226 </pre></td></tr></table>
    1227 
    1228 </dd>
    1229 <dt> Out of bounds-error in global or local arrays:</dt>
    1230 <dd><table><tr><td>&nbsp;</td><td><pre class="example">{
     1274</pre></td></tr></table><P>
     1275
     1276<DT>Out of bounds-error in global or local arrays:
     1277<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
    12311278    int tab[10];
    1232     for(i=0;i&lt;11;i++) {
     1279    for(i=0;i&#60;11;i++) {
    12331280        sum += tab[i];
    12341281    }
    12351282}
    1236 </pre></td></tr></table>
    1237 
    1238 </dd>
    1239 <dt> Out of bounds-error in malloc&rsquo;ed data:</dt>
    1240 <dd><table><tr><td>&nbsp;</td><td><pre class="example">{
     1283</pre></td></tr></table><P>
     1284
     1285<DT>Out of bounds-error in malloc'ed data:
     1286<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
    12411287    int *tab;
    12421288    tab = malloc(20 * sizeof(int));
    1243     for(i=0;i&lt;21;i++) {
     1289    for(i=0;i&#60;21;i++) {
    12441290        sum += tab4[i];
    12451291    }
    12461292    free(tab);
    12471293}
    1248 </pre></td></tr></table>
    1249 
    1250 </dd>
    1251 <dt> Access of freed memory:</dt>
    1252 <dd><table><tr><td>&nbsp;</td><td><pre class="example">{
     1294</pre></td></tr></table><P>
     1295
     1296<DT>Access of freed memory:
     1297<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
    12531298    int *tab;
    12541299    tab = malloc(20 * sizeof(int));
    12551300    free(tab);
    1256     for(i=0;i&lt;20;i++) {
     1301    for(i=0;i&#60;20;i++) {
    12571302        sum += tab4[i];
    12581303    }
    12591304}
    1260 </pre></td></tr></table>
    1261 
    1262 </dd>
    1263 <dt> Double free:</dt>
    1264 <dd><table><tr><td>&nbsp;</td><td><pre class="example">{
     1305</pre></td></tr></table><P>
     1306
     1307<DT>Double free:
     1308<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
    12651309    int *tab;
    12661310    tab = malloc(20 * sizeof(int));
     
    12681312    free(tab);
    12691313}
    1270 </pre></td></tr></table>
    1271 
    1272 </dd>
    1273 </dl>
    1274 
    1275 <hr size="6">
    1276 <a name="Libtcc"></a>
    1277 <table cellpadding="1" cellspacing="1" border="0">
    1278 <tr><td valign="middle" align="left">[<a href="#Bounds" title="Previous section in reading order"> &lt; </a>]</td>
    1279 <td valign="middle" align="left">[<a href="#devel" title="Next section in reading order"> &gt; </a>]</td>
    1280 <td valign="middle" align="left"> &nbsp; </td>
    1281 <td valign="middle" align="left">[<a href="#Bounds" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1282 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    1283 <td valign="middle" align="left">[<a href="#devel" title="Next chapter"> &gt;&gt; </a>]</td>
    1284 <td valign="middle" align="left"> &nbsp; </td>
    1285 <td valign="middle" align="left"> &nbsp; </td>
    1286 <td valign="middle" align="left"> &nbsp; </td>
    1287 <td valign="middle" align="left"> &nbsp; </td>
    1288 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1289 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1290 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1291 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1292 </tr></table>
    1293 <a name="The-libtcc-library"></a>
    1294 <h1 class="chapter">7. The <code>libtcc</code> library</h1>
    1295 
    1296 <p>The <code>libtcc</code> library enables you to use TCC as a backend for
     1314</pre></td></tr></table><P>
     1315
     1316</DL>
     1317<P>
     1318
     1319<A NAME="Libtcc"></A>
     1320<HR SIZE="6">
     1321<A NAME="SEC22"></A>
     1322<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1323<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt; </A>]</TD>
     1324<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt; </A>]</TD>
     1325<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt;&lt; </A>]</TD>
     1326<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     1327<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt;&gt; </A>]</TD>
     1328<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1329<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1330<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1331<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1332</TR></TABLE>
     1333<H1> 7. The <CODE>libtcc</CODE> library </H1>
     1334<!--docid::SEC22::-->
     1335<P>
     1336
     1337The <CODE>libtcc</CODE> library enables you to use TCC as a backend for
    12971338dynamic code generation.
    1298 </p>
    1299 <p>Read the &lsquo;<tt>libtcc.h</tt>&rsquo; to have an overview of the API. Read
    1300 &lsquo;<tt>libtcc_test.c</tt>&rsquo; to have a very simple example.
    1301 </p>
    1302 <p>The idea consists in giving a C string containing the program you want
    1303 to compile directly to <code>libtcc</code>. Then you can access to any global
     1339</P><P>
     1340
     1341Read the <TT>`libtcc.h'</TT> to have an overview of the API. Read
     1342<TT>`libtcc_test.c'</TT> to have a very simple example.
     1343</P><P>
     1344
     1345The idea consists in giving a C string containing the program you want
     1346to compile directly to <CODE>libtcc</CODE>. Then you can access to any global
    13041347symbol (function or variable) defined.
    1305 </p>
    1306 <hr size="6">
    1307 <a name="devel"></a>
    1308 <table cellpadding="1" cellspacing="1" border="0">
    1309 <tr><td valign="middle" align="left">[<a href="#Libtcc" title="Previous section in reading order"> &lt; </a>]</td>
    1310 <td valign="middle" align="left">[<a href="#File-reading" title="Next section in reading order"> &gt; </a>]</td>
    1311 <td valign="middle" align="left"> &nbsp; </td>
    1312 <td valign="middle" align="left">[<a href="#Libtcc" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1313 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    1314 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1315 <td valign="middle" align="left"> &nbsp; </td>
    1316 <td valign="middle" align="left"> &nbsp; </td>
    1317 <td valign="middle" align="left"> &nbsp; </td>
    1318 <td valign="middle" align="left"> &nbsp; </td>
    1319 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1320 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1321 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1322 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1323 </tr></table>
    1324 <a name="Developer_0027s-guide"></a>
    1325 <h1 class="chapter">8. Developer&rsquo;s guide</h1>
    1326 
    1327 <p>This chapter gives some hints to understand how TCC works. You can skip
     1348</P><P>
     1349
     1350<A NAME="devel"></A>
     1351<HR SIZE="6">
     1352<A NAME="SEC23"></A>
     1353<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1354<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt; </A>]</TD>
     1355<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &gt; </A>]</TD>
     1356<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
     1357<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     1358<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1359<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1360<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1361<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1362<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1363</TR></TABLE>
     1364<H1> 8. Developer's guide </H1>
     1365<!--docid::SEC23::-->
     1366<P>
     1367
     1368This chapter gives some hints to understand how TCC works. You can skip
    13281369it if you do not intend to modify the TCC code.
    1329 </p>
    1330 <hr size="6">
    1331 <a name="File-reading"></a>
    1332 <table cellpadding="1" cellspacing="1" border="0">
    1333 <tr><td valign="middle" align="left">[<a href="#devel" title="Previous section in reading order"> &lt; </a>]</td>
    1334 <td valign="middle" align="left">[<a href="#Lexer" title="Next section in reading order"> &gt; </a>]</td>
    1335 <td valign="middle" align="left"> &nbsp; </td>
    1336 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1337 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1338 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1339 <td valign="middle" align="left"> &nbsp; </td>
    1340 <td valign="middle" align="left"> &nbsp; </td>
    1341 <td valign="middle" align="left"> &nbsp; </td>
    1342 <td valign="middle" align="left"> &nbsp; </td>
    1343 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1344 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1345 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1346 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1347 </tr></table>
    1348 <h2 class="section">8.1 File reading</h2>
    1349 
    1350 <p>The <code>BufferedFile</code> structure contains the context needed to read a
    1351 file, including the current line number. <code>tcc_open()</code> opens a new
    1352 file and <code>tcc_close()</code> closes it. <code>inp()</code> returns the next
     1370</P><P>
     1371
     1372<HR SIZE="6">
     1373<A NAME="SEC24"></A>
     1374<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1375<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt; </A>]</TD>
     1376<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &gt; </A>]</TD>
     1377<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
     1378<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1379<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1380<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1381<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1382<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1383<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1384</TR></TABLE>
     1385<H2> 8.1 File reading </H2>
     1386<!--docid::SEC24::-->
     1387<P>
     1388
     1389The <CODE>BufferedFile</CODE> structure contains the context needed to read a
     1390file, including the current line number. <CODE>tcc_open()</CODE> opens a new
     1391file and <CODE>tcc_close()</CODE> closes it. <CODE>inp()</CODE> returns the next
    13531392character.
    1354 </p>
    1355 <hr size="6">
    1356 <a name="Lexer"></a>
    1357 <table cellpadding="1" cellspacing="1" border="0">
    1358 <tr><td valign="middle" align="left">[<a href="#File-reading" title="Previous section in reading order"> &lt; </a>]</td>
    1359 <td valign="middle" align="left">[<a href="#Parser" title="Next section in reading order"> &gt; </a>]</td>
    1360 <td valign="middle" align="left"> &nbsp; </td>
    1361 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1362 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1363 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1364 <td valign="middle" align="left"> &nbsp; </td>
    1365 <td valign="middle" align="left"> &nbsp; </td>
    1366 <td valign="middle" align="left"> &nbsp; </td>
    1367 <td valign="middle" align="left"> &nbsp; </td>
    1368 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1369 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1370 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1371 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1372 </tr></table>
    1373 <h2 class="section">8.2 Lexer</h2>
    1374 
    1375 <p><code>next()</code> reads the next token in the current
    1376 file. <code>next_nomacro()</code> reads the next token without macro
     1393</P><P>
     1394
     1395<HR SIZE="6">
     1396<A NAME="SEC25"></A>
     1397<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1398<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &lt; </A>]</TD>
     1399<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &gt; </A>]</TD>
     1400<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt;&lt; </A>]</TD>
     1401<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1402<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1403<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1404<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1405<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1406<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1407</TR></TABLE>
     1408<H2> 8.2 Lexer </H2>
     1409<!--docid::SEC25::-->
     1410<P>
     1411
     1412<CODE>next()</CODE> reads the next token in the current
     1413file. <CODE>next_nomacro()</CODE> reads the next token without macro
    13771414expansion.
    1378 </p>
    1379 <p><code>tok</code> contains the current token (see <code>TOK_xxx</code>)
    1380 constants. Identifiers and keywords are also keywords. <code>tokc</code>
     1415</P><P>
     1416
     1417<CODE>tok</CODE> contains the current token (see <CODE>TOK_xxx</CODE>)
     1418constants. Identifiers and keywords are also keywords. <CODE>tokc</CODE>
    13811419contains additional infos about the token (for example a constant value
    13821420if number or string token).
    1383 </p>
    1384 <hr size="6">
    1385 <a name="Parser"></a>
    1386 <table cellpadding="1" cellspacing="1" border="0">
    1387 <tr><td valign="middle" align="left">[<a href="#Lexer" title="Previous section in reading order"> &lt; </a>]</td>
    1388 <td valign="middle" align="left">[<a href="#Types" title="Next section in reading order"> &gt; </a>]</td>
    1389 <td valign="middle" align="left"> &nbsp; </td>
    1390 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1391 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1392 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1393 <td valign="middle" align="left"> &nbsp; </td>
    1394 <td valign="middle" align="left"> &nbsp; </td>
    1395 <td valign="middle" align="left"> &nbsp; </td>
    1396 <td valign="middle" align="left"> &nbsp; </td>
    1397 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1398 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1399 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1400 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1401 </tr></table>
    1402 <h2 class="section">8.3 Parser</h2>
    1403 
    1404 <p>The parser is hardcoded (yacc is not necessary). It does only one pass,
     1421</P><P>
     1422
     1423<HR SIZE="6">
     1424<A NAME="SEC26"></A>
     1425<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1426<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &lt; </A>]</TD>
     1427<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &gt; </A>]</TD>
     1428<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt;&lt; </A>]</TD>
     1429<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1430<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1431<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1432<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1433<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1434<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1435</TR></TABLE>
     1436<H2> 8.3 Parser </H2>
     1437<!--docid::SEC26::-->
     1438<P>
     1439
     1440The parser is hardcoded (yacc is not necessary). It does only one pass,
    14051441except:
    1406 </p>
    1407 <ul>
    1408 <li> For initialized arrays with unknown size, a first pass
     1442</P><P>
     1443
     1444<UL>
     1445
     1446<LI>For initialized arrays with unknown size, a first pass
    14091447is done to count the number of elements.
    1410 
    1411 </li><li> For architectures where arguments are evaluated in
     1448<P>
     1449
     1450<LI>For architectures where arguments are evaluated in
    14121451reverse order, a first pass is done to reverse the argument order.
    1413 
    1414 </li></ul>
    1415 
    1416 <hr size="6">
    1417 <a name="Types"></a>
    1418 <table cellpadding="1" cellspacing="1" border="0">
    1419 <tr><td valign="middle" align="left">[<a href="#Parser" title="Previous section in reading order"> &lt; </a>]</td>
    1420 <td valign="middle" align="left">[<a href="#Symbols" title="Next section in reading order"> &gt; </a>]</td>
    1421 <td valign="middle" align="left"> &nbsp; </td>
    1422 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1423 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1424 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1425 <td valign="middle" align="left"> &nbsp; </td>
    1426 <td valign="middle" align="left"> &nbsp; </td>
    1427 <td valign="middle" align="left"> &nbsp; </td>
    1428 <td valign="middle" align="left"> &nbsp; </td>
    1429 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1430 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1431 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1432 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1433 </tr></table>
    1434 <h2 class="section">8.4 Types</h2>
    1435 
    1436 <p>The types are stored in a single &rsquo;int&rsquo; variable. It was choosen in the
     1452<P>
     1453
     1454</UL>
     1455<P>
     1456
     1457<HR SIZE="6">
     1458<A NAME="SEC27"></A>
     1459<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1460<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt; </A>]</TD>
     1461<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &gt; </A>]</TD>
     1462<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt;&lt; </A>]</TD>
     1463<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1464<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1465<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1466<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1467<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1468<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1469</TR></TABLE>
     1470<H2> 8.4 Types </H2>
     1471<!--docid::SEC27::-->
     1472<P>
     1473
     1474The types are stored in a single 'int' variable. It was chosen in the
    14371475first stages of development when tcc was much simpler. Now, it may not
    14381476be the best solution.
    1439 </p>
    1440 <table><tr><td>&nbsp;</td><td><pre class="example">#define VT_INT        0  /* integer type */
     1477</P><P>
     1478
     1479<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_INT        0  /* integer type */
    14411480#define VT_BYTE       1  /* signed byte type */
    14421481#define VT_SHORT      2  /* short type */
     
    14601499#define VT_CONSTANT   0x0800  /* const modifier */
    14611500#define VT_VOLATILE   0x1000  /* volatile modifier */
    1462 #define VT_SIGNED     0x2000  /* signed type */
     1501#define VT_DEFSIGN    0x2000  /* signed type */
    14631502
    14641503#define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
    1465 </pre></td></tr></table>
    1466 
    1467 <p>When a reference to another type is needed (for pointers, functions and
    1468 structures), the <code>32 - VT_STRUCT_SHIFT</code> high order bits are used to
     1504</pre></td></tr></table></P><P>
     1505
     1506When a reference to another type is needed (for pointers, functions and
     1507structures), the <CODE>32 - VT_STRUCT_SHIFT</CODE> high order bits are used to
    14691508store an identifier reference.
    1470 </p>
    1471 <p>The <code>VT_UNSIGNED</code> flag can be set for chars, shorts, ints and long
     1509</P><P>
     1510
     1511The <CODE>VT_UNSIGNED</CODE> flag can be set for chars, shorts, ints and long
    14721512longs.
    1473 </p>
    1474 <p>Arrays are considered as pointers <code>VT_PTR</code> with the flag
    1475 <code>VT_ARRAY</code> set. Variable length arrays are considered as special
    1476 arrays and have flag <code>VT_VLA</code> set instead of <code>VT_ARRAY</code>.
    1477 </p>
    1478 <p>The <code>VT_BITFIELD</code> flag can be set for chars, shorts, ints and long
     1513</P><P>
     1514
     1515Arrays are considered as pointers <CODE>VT_PTR</CODE> with the flag
     1516<CODE>VT_ARRAY</CODE> set. Variable length arrays are considered as special
     1517arrays and have flag <CODE>VT_VLA</CODE> set instead of <CODE>VT_ARRAY</CODE>.
     1518</P><P>
     1519
     1520The <CODE>VT_BITFIELD</CODE> flag can be set for chars, shorts, ints and long
    14791521longs. If it is set, then the bitfield position is stored from bits
    14801522VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
    14811523from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
    1482 </p>
    1483 <p><code>VT_LONG</code> is never used except during parsing.
    1484 </p>
    1485 <p>During parsing, the storage of an object is also stored in the type
     1524</P><P>
     1525
     1526<CODE>VT_LONG</CODE> is never used except during parsing.
     1527</P><P>
     1528
     1529During parsing, the storage of an object is also stored in the type
    14861530integer:
    1487 </p>
    1488 <table><tr><td>&nbsp;</td><td><pre class="example">#define VT_EXTERN  0x00000080  /* extern definition */
     1531</P><P>
     1532
     1533<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_EXTERN  0x00000080  /* extern definition */
    14891534#define VT_STATIC  0x00000100  /* static variable */
    14901535#define VT_TYPEDEF 0x00000200  /* typedef definition */
     
    14931538#define VT_EXPORT  0x00008000  /* win32: data exported from dll */
    14941539#define VT_WEAK    0x00010000  /* win32: data exported from dll */
    1495 </pre></td></tr></table>
    1496 
    1497 <hr size="6">
    1498 <a name="Symbols"></a>
    1499 <table cellpadding="1" cellspacing="1" border="0">
    1500 <tr><td valign="middle" align="left">[<a href="#Types" title="Previous section in reading order"> &lt; </a>]</td>
    1501 <td valign="middle" align="left">[<a href="#Sections" title="Next section in reading order"> &gt; </a>]</td>
    1502 <td valign="middle" align="left"> &nbsp; </td>
    1503 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1504 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1505 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1506 <td valign="middle" align="left"> &nbsp; </td>
    1507 <td valign="middle" align="left"> &nbsp; </td>
    1508 <td valign="middle" align="left"> &nbsp; </td>
    1509 <td valign="middle" align="left"> &nbsp; </td>
    1510 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1511 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1512 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1513 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1514 </tr></table>
    1515 <h2 class="section">8.5 Symbols</h2>
    1516 
    1517 <p>All symbols are stored in hashed symbol stacks. Each symbol stack
    1518 contains <code>Sym</code> structures.
    1519 </p>
    1520 <p><code>Sym.v</code> contains the symbol name (remember
    1521 an idenfier is also a token, so a string is never necessary to store
    1522 it). <code>Sym.t</code> gives the type of the symbol. <code>Sym.r</code> is usually
    1523 the register in which the corresponding variable is stored. <code>Sym.c</code> is
     1540</pre></td></tr></table></P><P>
     1541
     1542<HR SIZE="6">
     1543<A NAME="SEC28"></A>
     1544<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1545<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt; </A>]</TD>
     1546<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &gt; </A>]</TD>
     1547<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt;&lt; </A>]</TD>
     1548<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1549<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1550<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1551<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1552<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1553<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1554</TR></TABLE>
     1555<H2> 8.5 Symbols </H2>
     1556<!--docid::SEC28::-->
     1557<P>
     1558
     1559All symbols are stored in hashed symbol stacks. Each symbol stack
     1560contains <CODE>Sym</CODE> structures.
     1561</P><P>
     1562
     1563<CODE>Sym.v</CODE> contains the symbol name (remember
     1564an identifier is also a token, so a string is never necessary to store
     1565it). <CODE>Sym.t</CODE> gives the type of the symbol. <CODE>Sym.r</CODE> is usually
     1566the register in which the corresponding variable is stored. <CODE>Sym.c</CODE> is
    15241567usually a constant associated to the symbol like its address for normal
    15251568symbols, and the number of entries for symbols representing arrays.
    1526 Variable length array types use <code>Sym.c</code> as a location on the stack
     1569Variable length array types use <CODE>Sym.c</CODE> as a location on the stack
    15271570which holds the runtime sizeof for the type.
    1528 </p>
    1529 <p>Four main symbol stacks are defined:
    1530 </p>
    1531 <dl compact="compact">
    1532 <dt> <code>define_stack</code></dt>
    1533 <dd><p>for the macros (<code>#define</code>s).
    1534 </p>
    1535 </dd>
    1536 <dt> <code>global_stack</code></dt>
    1537 <dd><p>for the global variables, functions and types.
    1538 </p>
    1539 </dd>
    1540 <dt> <code>local_stack</code></dt>
    1541 <dd><p>for the local variables, functions and types.
    1542 </p>
    1543 </dd>
    1544 <dt> <code>global_label_stack</code></dt>
    1545 <dd><p>for the local labels (for <code>goto</code>).
    1546 </p>
    1547 </dd>
    1548 <dt> <code>label_stack</code></dt>
    1549 <dd><p>for GCC block local labels (see the <code>__label__</code> keyword).
    1550 </p>
    1551 </dd>
    1552 </dl>
    1553 
    1554 <p><code>sym_push()</code> is used to add a new symbol in the local symbol
     1571</P><P>
     1572
     1573Four main symbol stacks are defined:
     1574</P><P>
     1575
     1576<DL COMPACT>
     1577
     1578<DT><CODE>define_stack</CODE>
     1579<DD>for the macros (<CODE>#define</CODE>s).
     1580<P>
     1581
     1582<DT><CODE>global_stack</CODE>
     1583<DD>for the global variables, functions and types.
     1584<P>
     1585
     1586<DT><CODE>local_stack</CODE>
     1587<DD>for the local variables, functions and types.
     1588<P>
     1589
     1590<DT><CODE>global_label_stack</CODE>
     1591<DD>for the local labels (for <CODE>goto</CODE>).
     1592<P>
     1593
     1594<DT><CODE>label_stack</CODE>
     1595<DD>for GCC block local labels (see the <CODE>__label__</CODE> keyword).
     1596<P>
     1597
     1598</DL>
     1599<P>
     1600
     1601<CODE>sym_push()</CODE> is used to add a new symbol in the local symbol
    15551602stack. If no local symbol stack is active, it is added in the global
    15561603symbol stack.
    1557 </p>
    1558 <p><code>sym_pop(st,b)</code> pops symbols from the symbol stack <var>st</var> until
    1559 the symbol <var>b</var> is on the top of stack. If <var>b</var> is NULL, the stack
     1604</P><P>
     1605
     1606<CODE>sym_pop(st,b)</CODE> pops symbols from the symbol stack <VAR>st</VAR> until
     1607the symbol <VAR>b</VAR> is on the top of stack. If <VAR>b</VAR> is NULL, the stack
    15601608is emptied.
    1561 </p>
    1562 <p><code>sym_find(v)</code> return the symbol associated to the identifier
    1563 <var>v</var>. The local stack is searched first from top to bottom, then the
     1609</P><P>
     1610
     1611<CODE>sym_find(v)</CODE> return the symbol associated to the identifier
     1612<VAR>v</VAR>. The local stack is searched first from top to bottom, then the
    15641613global stack.
    1565 </p>
    1566 <hr size="6">
    1567 <a name="Sections"></a>
    1568 <table cellpadding="1" cellspacing="1" border="0">
    1569 <tr><td valign="middle" align="left">[<a href="#Symbols" title="Previous section in reading order"> &lt; </a>]</td>
    1570 <td valign="middle" align="left">[<a href="#Code-generation" title="Next section in reading order"> &gt; </a>]</td>
    1571 <td valign="middle" align="left"> &nbsp; </td>
    1572 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1573 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1574 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1575 <td valign="middle" align="left"> &nbsp; </td>
    1576 <td valign="middle" align="left"> &nbsp; </td>
    1577 <td valign="middle" align="left"> &nbsp; </td>
    1578 <td valign="middle" align="left"> &nbsp; </td>
    1579 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1580 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1581 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1582 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1583 </tr></table>
    1584 <h2 class="section">8.6 Sections</h2>
    1585 
    1586 <p>The generated code and datas are written in sections. The structure
    1587 <code>Section</code> contains all the necessary information for a given
    1588 section. <code>new_section()</code> creates a new section. ELF file semantics
     1614</P><P>
     1615
     1616<HR SIZE="6">
     1617<A NAME="SEC29"></A>
     1618<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1619<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt; </A>]</TD>
     1620<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &gt; </A>]</TD>
     1621<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt;&lt; </A>]</TD>
     1622<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1623<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1624<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1625<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1626<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1627<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1628</TR></TABLE>
     1629<H2> 8.6 Sections </H2>
     1630<!--docid::SEC29::-->
     1631<P>
     1632
     1633The generated code and data are written in sections. The structure
     1634<CODE>Section</CODE> contains all the necessary information for a given
     1635section. <CODE>new_section()</CODE> creates a new section. ELF file semantics
    15891636is assumed for each section.
    1590 </p>
    1591 <p>The following sections are predefined:
    1592 </p>
    1593 <dl compact="compact">
    1594 <dt> <code>text_section</code></dt>
    1595 <dd><p>is the section containing the generated code. <var>ind</var> contains the
     1637</P><P>
     1638
     1639The following sections are predefined:
     1640</P><P>
     1641
     1642<DL COMPACT>
     1643
     1644<DT><CODE>text_section</CODE>
     1645<DD>is the section containing the generated code. <VAR>ind</VAR> contains the
    15961646current position in the code section.
    1597 </p>
    1598 </dd>
    1599 <dt> <code>data_section</code></dt>
    1600 <dd><p>contains initialized data
    1601 </p>
    1602 </dd>
    1603 <dt> <code>bss_section</code></dt>
    1604 <dd><p>contains uninitialized data
    1605 </p>
    1606 </dd>
    1607 <dt> <code>bounds_section</code></dt>
    1608 <dt> <code>lbounds_section</code></dt>
    1609 <dd><p>are used when bound checking is activated
    1610 </p>
    1611 </dd>
    1612 <dt> <code>stab_section</code></dt>
    1613 <dt> <code>stabstr_section</code></dt>
    1614 <dd><p>are used when debugging is actived to store debug information
    1615 </p>
    1616 </dd>
    1617 <dt> <code>symtab_section</code></dt>
    1618 <dt> <code>strtab_section</code></dt>
    1619 <dd><p>contain the exported symbols (currently only used for debugging).
    1620 </p>
    1621 </dd>
    1622 </dl>
    1623 
    1624 <hr size="6">
    1625 <a name="Code-generation"></a>
    1626 <table cellpadding="1" cellspacing="1" border="0">
    1627 <tr><td valign="middle" align="left">[<a href="#Sections" title="Previous section in reading order"> &lt; </a>]</td>
    1628 <td valign="middle" align="left">[<a href="#Introduction-2" title="Next section in reading order"> &gt; </a>]</td>
    1629 <td valign="middle" align="left"> &nbsp; </td>
    1630 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1631 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1632 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1633 <td valign="middle" align="left"> &nbsp; </td>
    1634 <td valign="middle" align="left"> &nbsp; </td>
    1635 <td valign="middle" align="left"> &nbsp; </td>
    1636 <td valign="middle" align="left"> &nbsp; </td>
    1637 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1638 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1639 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1640 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1641 </tr></table>
    1642 <h2 class="section">8.7 Code generation</h2>
    1643 <a name="index-code-generation"></a>
    1644 
    1645 <hr size="6">
    1646 <a name="Introduction-2"></a>
    1647 <table cellpadding="1" cellspacing="1" border="0">
    1648 <tr><td valign="middle" align="left">[<a href="#Code-generation" title="Previous section in reading order"> &lt; </a>]</td>
    1649 <td valign="middle" align="left">[<a href="#The-value-stack" title="Next section in reading order"> &gt; </a>]</td>
    1650 <td valign="middle" align="left"> &nbsp; </td>
    1651 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1652 <td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
    1653 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1654 <td valign="middle" align="left"> &nbsp; </td>
    1655 <td valign="middle" align="left"> &nbsp; </td>
    1656 <td valign="middle" align="left"> &nbsp; </td>
    1657 <td valign="middle" align="left"> &nbsp; </td>
    1658 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1659 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1660 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1661 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1662 </tr></table>
    1663 <h3 class="subsection">8.7.1 Introduction</h3>
    1664 
    1665 <p>The TCC code generator directly generates linked binary code in one
     1647<P>
     1648
     1649<DT><CODE>data_section</CODE>
     1650<DD>contains initialized data
     1651<P>
     1652
     1653<DT><CODE>bss_section</CODE>
     1654<DD>contains uninitialized data
     1655<P>
     1656
     1657<DT><CODE>bounds_section</CODE>
     1658<DD><DT><CODE>lbounds_section</CODE>
     1659<DD>are used when bound checking is activated
     1660<P>
     1661
     1662<DT><CODE>stab_section</CODE>
     1663<DD><DT><CODE>stabstr_section</CODE>
     1664<DD>are used when debugging is active to store debug information
     1665<P>
     1666
     1667<DT><CODE>symtab_section</CODE>
     1668<DD><DT><CODE>strtab_section</CODE>
     1669<DD>contain the exported symbols (currently only used for debugging).
     1670<P>
     1671
     1672</DL>
     1673<P>
     1674
     1675<HR SIZE="6">
     1676<A NAME="SEC30"></A>
     1677<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1678<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt; </A>]</TD>
     1679<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &gt; </A>]</TD>
     1680<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
     1681<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1682<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
     1683<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1684<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1685<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1686<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1687</TR></TABLE>
     1688<H2> 8.7 Code generation </H2>
     1689<!--docid::SEC30::-->
     1690<P>
     1691
     1692<HR SIZE="6">
     1693<A NAME="SEC31"></A>
     1694<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1695<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt; </A>]</TD>
     1696<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &gt; </A>]</TD>
     1697<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
     1698<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
     1699<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
     1700<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1701<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1702<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1703<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1704</TR></TABLE>
     1705<H3> 8.7.1 Introduction </H3>
     1706<!--docid::SEC31::-->
     1707<P>
     1708
     1709The TCC code generator directly generates linked binary code in one
    16661710pass. It is rather unusual these days (see gcc for example which
    16671711generates text assembly), but it can be very fast and surprisingly
    16681712little complicated.
    1669 </p>
    1670 <p>The TCC code generator is register based. Optimization is only done at
     1713</P><P>
     1714
     1715The TCC code generator is register based. Optimization is only done at
    16711716the expression level. No intermediate representation of expression is
    1672 kept except the current values stored in the <em>value stack</em>.
    1673 </p>
    1674 <p>On x86, three temporary registers are used. When more registers are
     1717kept except the current values stored in the <EM>value stack</EM>.
     1718</P><P>
     1719
     1720On x86, three temporary registers are used. When more registers are
    16751721needed, one register is spilled into a new temporary variable on the stack.
    1676 </p>
    1677 <hr size="6">
    1678 <a name="The-value-stack"></a>
    1679 <table cellpadding="1" cellspacing="1" border="0">
    1680 <tr><td valign="middle" align="left">[<a href="#Introduction-2" title="Previous section in reading order"> &lt; </a>]</td>
    1681 <td valign="middle" align="left">[<a href="#Manipulating-the-value-stack" title="Next section in reading order"> &gt; </a>]</td>
    1682 <td valign="middle" align="left"> &nbsp; </td>
    1683 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1684 <td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
    1685 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1686 <td valign="middle" align="left"> &nbsp; </td>
    1687 <td valign="middle" align="left"> &nbsp; </td>
    1688 <td valign="middle" align="left"> &nbsp; </td>
    1689 <td valign="middle" align="left"> &nbsp; </td>
    1690 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1691 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1692 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1693 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1694 </tr></table>
    1695 <h3 class="subsection">8.7.2 The value stack</h3>
    1696 <a name="index-value-stack_002c-introduction"></a>
    1697 
    1698 <p>When an expression is parsed, its value is pushed on the value stack
    1699 (<var>vstack</var>). The top of the value stack is <var>vtop</var>. Each value
    1700 stack entry is the structure <code>SValue</code>.
    1701 </p>
    1702 <p><code>SValue.t</code> is the type. <code>SValue.r</code> indicates how the value is
     1722</P><P>
     1723
     1724<HR SIZE="6">
     1725<A NAME="SEC32"></A>
     1726<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1727<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &lt; </A>]</TD>
     1728<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &gt; </A>]</TD>
     1729<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt;&lt; </A>]</TD>
     1730<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
     1731<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
     1732<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1733<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1734<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1735<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1736</TR></TABLE>
     1737<H3> 8.7.2 The value stack </H3>
     1738<!--docid::SEC32::-->
     1739<P>
     1740
     1741When an expression is parsed, its value is pushed on the value stack
     1742(<VAR>vstack</VAR>). The top of the value stack is <VAR>vtop</VAR>. Each value
     1743stack entry is the structure <CODE>SValue</CODE>.
     1744</P><P>
     1745
     1746<CODE>SValue.t</CODE> is the type. <CODE>SValue.r</CODE> indicates how the value is
    17031747currently stored in the generated code. It is usually a CPU register
    1704 index (<code>REG_xxx</code> constants), but additional values and flags are
     1748index (<CODE>REG_xxx</CODE> constants), but additional values and flags are
    17051749defined:
    1706 </p>
    1707 <table><tr><td>&nbsp;</td><td><pre class="example">#define VT_CONST     0x00f0
     1750</P><P>
     1751
     1752<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_CONST     0x00f0
    17081753#define VT_LLOCAL    0x00f1
    17091754#define VT_LOCAL     0x00f2
     
    17201765#define VT_LVAL_UNSIGNED 0x4000
    17211766#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
    1722 </pre></td></tr></table>
    1723 
    1724 <dl compact="compact">
    1725 <dt> <code>VT_CONST</code></dt>
    1726 <dd><p>indicates that the value is a constant. It is stored in the union
    1727 <code>SValue.c</code>, depending on its type.
    1728 </p>
    1729 </dd>
    1730 <dt> <code>VT_LOCAL</code></dt>
    1731 <dd><p>indicates a local variable pointer at offset <code>SValue.c.i</code> in the
     1767</pre></td></tr></table></P><P>
     1768
     1769<DL COMPACT>
     1770
     1771<DT><CODE>VT_CONST</CODE>
     1772<DD>indicates that the value is a constant. It is stored in the union
     1773<CODE>SValue.c</CODE>, depending on its type.
     1774<P>
     1775
     1776<DT><CODE>VT_LOCAL</CODE>
     1777<DD>indicates a local variable pointer at offset <CODE>SValue.c.i</CODE> in the
    17321778stack.
    1733 </p>
    1734 </dd>
    1735 <dt> <code>VT_CMP</code></dt>
    1736 <dd><p>indicates that the value is actually stored in the CPU flags (i.e. the
     1779<P>
     1780
     1781<DT><CODE>VT_CMP</CODE>
     1782<DD>indicates that the value is actually stored in the CPU flags (i.e. the
    17371783value is the consequence of a test). The value is either 0 or 1. The
    1738 actual CPU flags used is indicated in <code>SValue.c.i</code>.
    1739 </p>
    1740 <p>If any code is generated which destroys the CPU flags, this value MUST be
     1784actual CPU flags used is indicated in <CODE>SValue.c.i</CODE>.
     1785<P>
     1786
     1787If any code is generated which destroys the CPU flags, this value MUST be
    17411788put in a normal register.
    1742 </p>
    1743 </dd>
    1744 <dt> <code>VT_JMP</code></dt>
    1745 <dt> <code>VT_JMPI</code></dt>
    1746 <dd><p>indicates that the value is the consequence of a conditional jump. For VT_JMP,
     1789</P><P>
     1790
     1791<DT><CODE>VT_JMP</CODE>
     1792<DD><DT><CODE>VT_JMPI</CODE>
     1793<DD>indicates that the value is the consequence of a conditional jump. For VT_JMP,
    17471794it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
    1748 </p>
    1749 <p>These values are used to compile the <code>||</code> and <code>&amp;&amp;</code> logical
     1795<P>
     1796
     1797These values are used to compile the <CODE>||</CODE> and <CODE>&#38;&#38;</CODE> logical
    17501798operators.
    1751 </p>
    1752 <p>If any code is generated, this value MUST be put in a normal
    1753 register. Otherwise, the generated code won&rsquo;t be executed if the jump is
     1799</P><P>
     1800
     1801If any code is generated, this value MUST be put in a normal
     1802register. Otherwise, the generated code won't be executed if the jump is
    17541803taken.
    1755 </p>
    1756 </dd>
    1757 <dt> <code>VT_LVAL</code></dt>
    1758 <dd><p>is a flag indicating that the value is actually an lvalue (left value of
     1804</P><P>
     1805
     1806<DT><CODE>VT_LVAL</CODE>
     1807<DD>is a flag indicating that the value is actually an lvalue (left value of
    17591808an assignment). It means that the value stored is actually a pointer to
    17601809the wanted value.
    1761 </p>
    1762 <p>Understanding the use <code>VT_LVAL</code> is very important if you want to
     1810<P>
     1811
     1812Understanding the use <CODE>VT_LVAL</CODE> is very important if you want to
    17631813understand how TCC works.
    1764 </p>
    1765 </dd>
    1766 <dt> <code>VT_LVAL_BYTE</code></dt>
    1767 <dt> <code>VT_LVAL_SHORT</code></dt>
    1768 <dt> <code>VT_LVAL_UNSIGNED</code></dt>
    1769 <dd><p>if the lvalue has an integer type, then these flags give its real
     1814</P><P>
     1815
     1816<DT><CODE>VT_LVAL_BYTE</CODE>
     1817<DD><DT><CODE>VT_LVAL_SHORT</CODE>
     1818<DD><DT><CODE>VT_LVAL_UNSIGNED</CODE>
     1819<DD>if the lvalue has an integer type, then these flags give its real
    17701820type. The type alone is not enough in case of cast optimisations.
    1771 </p>
    1772 </dd>
    1773 <dt> <code>VT_LLOCAL</code></dt>
    1774 <dd><p>is a saved lvalue on the stack. <code>VT_LLOCAL</code> should be eliminated
    1775 ASAP because its semantics are rather complicated.
    1776 </p>
    1777 </dd>
    1778 <dt> <code>VT_MUSTCAST</code></dt>
    1779 <dd><p>indicates that a cast to the value type must be performed if the value
     1821<P>
     1822
     1823<DT><CODE>VT_LLOCAL</CODE>
     1824<DD>is a saved lvalue on the stack. <CODE>VT_LVAL</CODE> must also be set with
     1825<CODE>VT_LLOCAL</CODE>. <CODE>VT_LLOCAL</CODE> can arise when a <CODE>VT_LVAL</CODE> in
     1826a register has to be saved to the stack, or it can come from an
     1827architecture-specific calling convention.
     1828<P>
     1829
     1830<DT><CODE>VT_MUSTCAST</CODE>
     1831<DD>indicates that a cast to the value type must be performed if the value
    17801832is used (lazy casting).
    1781 </p>
    1782 </dd>
    1783 <dt> <code>VT_SYM</code></dt>
    1784 <dd><p>indicates that the symbol <code>SValue.sym</code> must be added to the constant.
    1785 </p>
    1786 </dd>
    1787 <dt> <code>VT_MUSTBOUND</code></dt>
    1788 <dt> <code>VT_BOUNDED</code></dt>
    1789 <dd><p>are only used for optional bound checking.
    1790 </p>
    1791 </dd>
    1792 </dl>
    1793 
    1794 <hr size="6">
    1795 <a name="Manipulating-the-value-stack"></a>
    1796 <table cellpadding="1" cellspacing="1" border="0">
    1797 <tr><td valign="middle" align="left">[<a href="#The-value-stack" title="Previous section in reading order"> &lt; </a>]</td>
    1798 <td valign="middle" align="left">[<a href="#CPU-dependent-code-generation" title="Next section in reading order"> &gt; </a>]</td>
    1799 <td valign="middle" align="left"> &nbsp; </td>
    1800 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1801 <td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
    1802 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1803 <td valign="middle" align="left"> &nbsp; </td>
    1804 <td valign="middle" align="left"> &nbsp; </td>
    1805 <td valign="middle" align="left"> &nbsp; </td>
    1806 <td valign="middle" align="left"> &nbsp; </td>
    1807 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1808 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1809 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1810 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1811 </tr></table>
    1812 <h3 class="subsection">8.7.3 Manipulating the value stack</h3>
    1813 <a name="index-value-stack"></a>
    1814 
    1815 <p><code>vsetc()</code> and <code>vset()</code> pushes a new value on the value
    1816 stack. If the previous <var>vtop</var> was stored in a very unsafe place(for
     1833<P>
     1834
     1835<DT><CODE>VT_SYM</CODE>
     1836<DD>indicates that the symbol <CODE>SValue.sym</CODE> must be added to the constant.
     1837<P>
     1838
     1839<DT><CODE>VT_MUSTBOUND</CODE>
     1840<DD><DT><CODE>VT_BOUNDED</CODE>
     1841<DD>are only used for optional bound checking.
     1842<P>
     1843
     1844</DL>
     1845<P>
     1846
     1847<HR SIZE="6">
     1848<A NAME="SEC33"></A>
     1849<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1850<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &lt; </A>]</TD>
     1851<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &gt; </A>]</TD>
     1852<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt;&lt; </A>]</TD>
     1853<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
     1854<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
     1855<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1856<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1857<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1858<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1859</TR></TABLE>
     1860<H3> 8.7.3 Manipulating the value stack </H3>
     1861<!--docid::SEC33::-->
     1862<P>
     1863
     1864<CODE>vsetc()</CODE> and <CODE>vset()</CODE> pushes a new value on the value
     1865stack. If the previous <VAR>vtop</VAR> was stored in a very unsafe place(for
    18171866example in the CPU flags), then some code is generated to put the
    1818 previous <var>vtop</var> in a safe storage.
    1819 </p>
    1820 <p><code>vpop()</code> pops <var>vtop</var>. In some cases, it also generates cleanup
     1867previous <VAR>vtop</VAR> in a safe storage.
     1868</P><P>
     1869
     1870<CODE>vpop()</CODE> pops <VAR>vtop</VAR>. In some cases, it also generates cleanup
    18211871code (for example if stacked floating point registers are used as on
    18221872x86).
    1823 </p>
    1824 <p>The <code>gv(rc)</code> function generates code to evaluate <var>vtop</var> (the
    1825 top value of the stack) into registers. <var>rc</var> selects in which
    1826 register class the value should be put. <code>gv()</code> is the <em>most
    1827 important function</em> of the code generator.
    1828 </p>
    1829 <p><code>gv2()</code> is the same as <code>gv()</code> but for the top two stack
     1873</P><P>
     1874
     1875The <CODE>gv(rc)</CODE> function generates code to evaluate <VAR>vtop</VAR> (the
     1876top value of the stack) into registers. <VAR>rc</VAR> selects in which
     1877register class the value should be put. <CODE>gv()</CODE> is the <EM>most
     1878important function</EM> of the code generator.
     1879</P><P>
     1880
     1881<CODE>gv2()</CODE> is the same as <CODE>gv()</CODE> but for the top two stack
    18301882entries.
    1831 </p>
    1832 <hr size="6">
    1833 <a name="CPU-dependent-code-generation"></a>
    1834 <table cellpadding="1" cellspacing="1" border="0">
    1835 <tr><td valign="middle" align="left">[<a href="#Manipulating-the-value-stack" title="Previous section in reading order"> &lt; </a>]</td>
    1836 <td valign="middle" align="left">[<a href="#Optimizations-done" title="Next section in reading order"> &gt; </a>]</td>
    1837 <td valign="middle" align="left"> &nbsp; </td>
    1838 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1839 <td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
    1840 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1841 <td valign="middle" align="left"> &nbsp; </td>
    1842 <td valign="middle" align="left"> &nbsp; </td>
    1843 <td valign="middle" align="left"> &nbsp; </td>
    1844 <td valign="middle" align="left"> &nbsp; </td>
    1845 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1846 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1847 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1848 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1849 </tr></table>
    1850 <h3 class="subsection">8.7.4 CPU dependent code generation</h3>
    1851 <a name="index-CPU-dependent"></a>
    1852 <p>See the &lsquo;<tt>i386-gen.c</tt>&rsquo; file to have an example.
    1853 </p>
    1854 <dl compact="compact">
    1855 <dt> <code>load()</code></dt>
    1856 <dd><p>must generate the code needed to load a stack value into a register.
    1857 </p>
    1858 </dd>
    1859 <dt> <code>store()</code></dt>
    1860 <dd><p>must generate the code needed to store a register into a stack value
     1883</P><P>
     1884
     1885<HR SIZE="6">
     1886<A NAME="SEC34"></A>
     1887<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1888<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt; </A>]</TD>
     1889<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt; </A>]</TD>
     1890<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
     1891<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
     1892<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
     1893<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1894<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1895<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1896<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1897</TR></TABLE>
     1898<H3> 8.7.4 CPU dependent code generation </H3>
     1899<!--docid::SEC34::-->
     1900See the <TT>`i386-gen.c'</TT> file to have an example.
     1901<P>
     1902
     1903<DL COMPACT>
     1904
     1905<DT><CODE>load()</CODE>
     1906<DD>must generate the code needed to load a stack value into a register.
     1907<P>
     1908
     1909<DT><CODE>store()</CODE>
     1910<DD>must generate the code needed to store a register into a stack value
    18611911lvalue.
    1862 </p>
    1863 </dd>
    1864 <dt> <code>gfunc_start()</code></dt>
    1865 <dt> <code>gfunc_param()</code></dt>
    1866 <dt> <code>gfunc_call()</code></dt>
    1867 <dd><p>should generate a function call
    1868 </p>
    1869 </dd>
    1870 <dt> <code>gfunc_prolog()</code></dt>
    1871 <dt> <code>gfunc_epilog()</code></dt>
    1872 <dd><p>should generate a function prolog/epilog.
    1873 </p>
    1874 </dd>
    1875 <dt> <code>gen_opi(op)</code></dt>
    1876 <dd><p>must generate the binary integer operation <var>op</var> on the two top
    1877 entries of the stack which are guaranted to contain integer types.
    1878 </p>
    1879 <p>The result value should be put on the stack.
    1880 </p>
    1881 </dd>
    1882 <dt> <code>gen_opf(op)</code></dt>
    1883 <dd><p>same as <code>gen_opi()</code> for floating point operations. The two top
    1884 entries of the stack are guaranted to contain floating point values of
     1912<P>
     1913
     1914<DT><CODE>gfunc_start()</CODE>
     1915<DD><DT><CODE>gfunc_param()</CODE>
     1916<DD><DT><CODE>gfunc_call()</CODE>
     1917<DD>should generate a function call
     1918<P>
     1919
     1920<DT><CODE>gfunc_prolog()</CODE>
     1921<DD><DT><CODE>gfunc_epilog()</CODE>
     1922<DD>should generate a function prolog/epilog.
     1923<P>
     1924
     1925<DT><CODE>gen_opi(op)</CODE>
     1926<DD>must generate the binary integer operation <VAR>op</VAR> on the two top
     1927entries of the stack which are guaranteed to contain integer types.
     1928<P>
     1929
     1930The result value should be put on the stack.
     1931</P><P>
     1932
     1933<DT><CODE>gen_opf(op)</CODE>
     1934<DD>same as <CODE>gen_opi()</CODE> for floating point operations. The two top
     1935entries of the stack are guaranteed to contain floating point values of
    18851936same types.
    1886 </p>
    1887 </dd>
    1888 <dt> <code>gen_cvt_itof()</code></dt>
    1889 <dd><p>integer to floating point conversion.
    1890 </p>
    1891 </dd>
    1892 <dt> <code>gen_cvt_ftoi()</code></dt>
    1893 <dd><p>floating point to integer conversion.
    1894 </p>
    1895 </dd>
    1896 <dt> <code>gen_cvt_ftof()</code></dt>
    1897 <dd><p>floating point to floating point of different size conversion.
    1898 </p>
    1899 </dd>
    1900 <dt> <code>gen_bounded_ptr_add()</code></dt>
    1901 <dt> <code>gen_bounded_ptr_deref()</code></dt>
    1902 <dd><p>are only used for bounds checking.
    1903 </p>
    1904 </dd>
    1905 </dl>
    1906 
    1907 <hr size="6">
    1908 <a name="Optimizations-done"></a>
    1909 <table cellpadding="1" cellspacing="1" border="0">
    1910 <tr><td valign="middle" align="left">[<a href="#CPU-dependent-code-generation" title="Previous section in reading order"> &lt; </a>]</td>
    1911 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next section in reading order"> &gt; </a>]</td>
    1912 <td valign="middle" align="left"> &nbsp; </td>
    1913 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1914 <td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
    1915 <td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
    1916 <td valign="middle" align="left"> &nbsp; </td>
    1917 <td valign="middle" align="left"> &nbsp; </td>
    1918 <td valign="middle" align="left"> &nbsp; </td>
    1919 <td valign="middle" align="left"> &nbsp; </td>
    1920 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1921 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1922 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1923 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1924 </tr></table>
    1925 <h2 class="section">8.8 Optimizations done</h2>
    1926 <a name="index-optimizations"></a>
    1927 <a name="index-constant-propagation"></a>
    1928 <a name="index-strength-reduction"></a>
    1929 <a name="index-comparison-operators"></a>
    1930 <a name="index-caching-processor-flags"></a>
    1931 <a name="index-flags_002c-caching"></a>
    1932 <a name="index-jump-optimization"></a>
    1933 <p>Constant propagation is done for all operations. Multiplications and
     1937<P>
     1938
     1939<DT><CODE>gen_cvt_itof()</CODE>
     1940<DD>integer to floating point conversion.
     1941<P>
     1942
     1943<DT><CODE>gen_cvt_ftoi()</CODE>
     1944<DD>floating point to integer conversion.
     1945<P>
     1946
     1947<DT><CODE>gen_cvt_ftof()</CODE>
     1948<DD>floating point to floating point of different size conversion.
     1949<P>
     1950
     1951<DT><CODE>gen_bounded_ptr_add()</CODE>
     1952<DD><DT><CODE>gen_bounded_ptr_deref()</CODE>
     1953<DD>are only used for bounds checking.
     1954<P>
     1955
     1956</DL>
     1957<P>
     1958
     1959<HR SIZE="6">
     1960<A NAME="SEC35"></A>
     1961<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1962<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt; </A>]</TD>
     1963<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36"> &gt; </A>]</TD>
     1964<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
     1965<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
     1966<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1967<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1968<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1969<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1970<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1971</TR></TABLE>
     1972<H2> 8.8 Optimizations done </H2>
     1973<!--docid::SEC35::-->
     1974Constant propagation is done for all operations. Multiplications and
    19341975divisions are optimized to shifts when appropriate. Comparison
    19351976operators are optimized by maintaining a special cache for the
    1936 processor flags. &amp;&amp;, || and ! are optimized by maintaining a special
    1937 &rsquo;jump target&rsquo; value. No other jump optimization is currently performed
     1977processor flags. &#38;&#38;, || and ! are optimized by maintaining a special
     1978'jump target' value. No other jump optimization is currently performed
    19381979because it would require to store the code in a more abstract fashion.
    1939 </p>
    1940 <hr size="6">
    1941 <a name="Concept-Index"></a>
    1942 <table cellpadding="1" cellspacing="1" border="0">
    1943 <tr><td valign="middle" align="left">[<a href="#Optimizations-done" title="Previous section in reading order"> &lt; </a>]</td>
    1944 <td valign="middle" align="left">[ &gt; ]</td>
    1945 <td valign="middle" align="left"> &nbsp; </td>
    1946 <td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
    1947 <td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
    1948 <td valign="middle" align="left">[ &gt;&gt; ]</td>
    1949 <td valign="middle" align="left"> &nbsp; </td>
    1950 <td valign="middle" align="left"> &nbsp; </td>
    1951 <td valign="middle" align="left"> &nbsp; </td>
    1952 <td valign="middle" align="left"> &nbsp; </td>
    1953 <td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    1954 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    1955 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    1956 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    1957 </tr></table>
    1958 <h1 class="unnumbered">Concept Index</h1>
    1959 <table><tr><th valign="top">Jump to: &nbsp; </th><td><a href="#Concept-Index_cp_symbol-1" class="summary-letter"><b>_</b></a>
    1960  &nbsp;
    1961 <br>
    1962 <a href="#Concept-Index_cp_letter-A" class="summary-letter"><b>A</b></a>
    1963  &nbsp;
    1964 <a href="#Concept-Index_cp_letter-B" class="summary-letter"><b>B</b></a>
    1965  &nbsp;
    1966 <a href="#Concept-Index_cp_letter-C" class="summary-letter"><b>C</b></a>
    1967  &nbsp;
    1968 <a href="#Concept-Index_cp_letter-D" class="summary-letter"><b>D</b></a>
    1969  &nbsp;
    1970 <a href="#Concept-Index_cp_letter-E" class="summary-letter"><b>E</b></a>
    1971  &nbsp;
    1972 <a href="#Concept-Index_cp_letter-F" class="summary-letter"><b>F</b></a>
    1973  &nbsp;
    1974 <a href="#Concept-Index_cp_letter-G" class="summary-letter"><b>G</b></a>
    1975  &nbsp;
    1976 <a href="#Concept-Index_cp_letter-I" class="summary-letter"><b>I</b></a>
    1977  &nbsp;
    1978 <a href="#Concept-Index_cp_letter-J" class="summary-letter"><b>J</b></a>
    1979  &nbsp;
    1980 <a href="#Concept-Index_cp_letter-L" class="summary-letter"><b>L</b></a>
    1981  &nbsp;
    1982 <a href="#Concept-Index_cp_letter-M" class="summary-letter"><b>M</b></a>
    1983  &nbsp;
    1984 <a href="#Concept-Index_cp_letter-O" class="summary-letter"><b>O</b></a>
    1985  &nbsp;
    1986 <a href="#Concept-Index_cp_letter-P" class="summary-letter"><b>P</b></a>
    1987  &nbsp;
    1988 <a href="#Concept-Index_cp_letter-Q" class="summary-letter"><b>Q</b></a>
    1989  &nbsp;
    1990 <a href="#Concept-Index_cp_letter-R" class="summary-letter"><b>R</b></a>
    1991  &nbsp;
    1992 <a href="#Concept-Index_cp_letter-S" class="summary-letter"><b>S</b></a>
    1993  &nbsp;
    1994 <a href="#Concept-Index_cp_letter-T" class="summary-letter"><b>T</b></a>
    1995  &nbsp;
    1996 <a href="#Concept-Index_cp_letter-U" class="summary-letter"><b>U</b></a>
    1997  &nbsp;
    1998 <a href="#Concept-Index_cp_letter-V" class="summary-letter"><b>V</b></a>
    1999  &nbsp;
    2000 <a href="#Concept-Index_cp_letter-W" class="summary-letter"><b>W</b></a>
    2001  &nbsp;
    2002 </td></tr></table>
    2003 <table border="0" class="index-cp">
    2004 <tr><td></td><th align="left">Index Entry</th><th align="left"> Section</th></tr>
    2005 <tr><td colspan="3"> <hr></td></tr>
    2006 <tr><th><a name="Concept-Index_cp_symbol-1">_</a></th><td></td><td></td></tr>
    2007 <tr><td></td><td valign="top"><a href="#index-_005f_005fasm_005f_005f">__asm__</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2008 <tr><td colspan="3"> <hr></td></tr>
    2009 <tr><th><a name="Concept-Index_cp_letter-A">A</a></th><td></td><td></td></tr>
    2010 <tr><td></td><td valign="top"><a href="#index-align-directive">align directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2011 <tr><td></td><td valign="top"><a href="#index-aligned-attribute">aligned attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2012 <tr><td></td><td valign="top"><a href="#index-ascii-directive">ascii directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2013 <tr><td></td><td valign="top"><a href="#index-asciz-directive">asciz directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2014 <tr><td></td><td valign="top"><a href="#index-assembler">assembler</a></td><td valign="top"><a href="#X86-Assembler">4.5 X86 Assembler</a></td></tr>
    2015 <tr><td></td><td valign="top"><a href="#index-assembler-directives">assembler directives</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2016 <tr><td></td><td valign="top"><a href="#index-assembly_002c-inline">assembly, inline</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2017 <tr><td colspan="3"> <hr></td></tr>
    2018 <tr><th><a name="Concept-Index_cp_letter-B">B</a></th><td></td><td></td></tr>
    2019 <tr><td></td><td valign="top"><a href="#index-bound-checks">bound checks</a></td><td valign="top"><a href="#Bounds">6. TinyCC Memory and Bound checks</a></td></tr>
    2020 <tr><td></td><td valign="top"><a href="#index-bss-directive">bss directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2021 <tr><td></td><td valign="top"><a href="#index-byte-directive">byte directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2022 <tr><td colspan="3"> <hr></td></tr>
    2023 <tr><th><a name="Concept-Index_cp_letter-C">C</a></th><td></td><td></td></tr>
    2024 <tr><td></td><td valign="top"><a href="#index-caching-processor-flags">caching processor flags</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2025 <tr><td></td><td valign="top"><a href="#index-cdecl-attribute">cdecl attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2026 <tr><td></td><td valign="top"><a href="#index-code-generation">code generation</a></td><td valign="top"><a href="#Code-generation">8.7 Code generation</a></td></tr>
    2027 <tr><td></td><td valign="top"><a href="#index-comparison-operators">comparison operators</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2028 <tr><td></td><td valign="top"><a href="#index-constant-propagation">constant propagation</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2029 <tr><td></td><td valign="top"><a href="#index-CPU-dependent">CPU dependent</a></td><td valign="top"><a href="#CPU-dependent-code-generation">8.7.4 CPU dependent code generation</a></td></tr>
    2030 <tr><td colspan="3"> <hr></td></tr>
    2031 <tr><th><a name="Concept-Index_cp_letter-D">D</a></th><td></td><td></td></tr>
    2032 <tr><td></td><td valign="top"><a href="#index-data-directive">data directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2033 <tr><td></td><td valign="top"><a href="#index-directives_002c-assembler">directives, assembler</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2034 <tr><td></td><td valign="top"><a href="#index-dllexport-attribute">dllexport attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2035 <tr><td colspan="3"> <hr></td></tr>
    2036 <tr><th><a name="Concept-Index_cp_letter-E">E</a></th><td></td><td></td></tr>
    2037 <tr><td></td><td valign="top"><a href="#index-ELF">ELF</a></td><td valign="top"><a href="#ELF-file-generation">5.1 ELF file generation</a></td></tr>
    2038 <tr><td colspan="3"> <hr></td></tr>
    2039 <tr><th><a name="Concept-Index_cp_letter-F">F</a></th><td></td><td></td></tr>
    2040 <tr><td></td><td valign="top"><a href="#index-FILE_002c-linker-command">FILE, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
    2041 <tr><td></td><td valign="top"><a href="#index-fill-directive">fill directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2042 <tr><td></td><td valign="top"><a href="#index-flags_002c-caching">flags, caching</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2043 <tr><td colspan="3"> <hr></td></tr>
    2044 <tr><th><a name="Concept-Index_cp_letter-G">G</a></th><td></td><td></td></tr>
    2045 <tr><td></td><td valign="top"><a href="#index-gas">gas</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2046 <tr><td></td><td valign="top"><a href="#index-global-directive">global directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2047 <tr><td></td><td valign="top"><a href="#index-globl-directive">globl directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2048 <tr><td></td><td valign="top"><a href="#index-GROUP_002c-linker-command">GROUP, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
    2049 <tr><td colspan="3"> <hr></td></tr>
    2050 <tr><th><a name="Concept-Index_cp_letter-I">I</a></th><td></td><td></td></tr>
    2051 <tr><td></td><td valign="top"><a href="#index-inline-assembly">inline assembly</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2052 <tr><td></td><td valign="top"><a href="#index-int-directive">int directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2053 <tr><td colspan="3"> <hr></td></tr>
    2054 <tr><th><a name="Concept-Index_cp_letter-J">J</a></th><td></td><td></td></tr>
    2055 <tr><td></td><td valign="top"><a href="#index-jump-optimization">jump optimization</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2056 <tr><td colspan="3"> <hr></td></tr>
    2057 <tr><th><a name="Concept-Index_cp_letter-L">L</a></th><td></td><td></td></tr>
    2058 <tr><td></td><td valign="top"><a href="#index-linker">linker</a></td><td valign="top"><a href="#linker">5. TinyCC Linker</a></td></tr>
    2059 <tr><td></td><td valign="top"><a href="#index-linker-scripts">linker scripts</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
    2060 <tr><td></td><td valign="top"><a href="#index-long-directive">long directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2061 <tr><td colspan="3"> <hr></td></tr>
    2062 <tr><th><a name="Concept-Index_cp_letter-M">M</a></th><td></td><td></td></tr>
    2063 <tr><td></td><td valign="top"><a href="#index-memory-checks">memory checks</a></td><td valign="top"><a href="#Bounds">6. TinyCC Memory and Bound checks</a></td></tr>
    2064 <tr><td colspan="3"> <hr></td></tr>
    2065 <tr><th><a name="Concept-Index_cp_letter-O">O</a></th><td></td><td></td></tr>
    2066 <tr><td></td><td valign="top"><a href="#index-optimizations">optimizations</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2067 <tr><td></td><td valign="top"><a href="#index-org-directive">org directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2068 <tr><td></td><td valign="top"><a href="#index-OUTPUT_005fFORMAT_002c-linker-command">OUTPUT_FORMAT, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
    2069 <tr><td colspan="3"> <hr></td></tr>
    2070 <tr><th><a name="Concept-Index_cp_letter-P">P</a></th><td></td><td></td></tr>
    2071 <tr><td></td><td valign="top"><a href="#index-packed-attribute">packed attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2072 <tr><td></td><td valign="top"><a href="#index-PE_002di386">PE-i386</a></td><td valign="top"><a href="#PE_002di386-file-generation">5.3 PE-i386 file generation</a></td></tr>
    2073 <tr><td></td><td valign="top"><a href="#index-previous-directive">previous directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2074 <tr><td colspan="3"> <hr></td></tr>
    2075 <tr><th><a name="Concept-Index_cp_letter-Q">Q</a></th><td></td><td></td></tr>
    2076 <tr><td></td><td valign="top"><a href="#index-quad-directive">quad directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2077 <tr><td colspan="3"> <hr></td></tr>
    2078 <tr><th><a name="Concept-Index_cp_letter-R">R</a></th><td></td><td></td></tr>
    2079 <tr><td></td><td valign="top"><a href="#index-regparm-attribute">regparm attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2080 <tr><td colspan="3"> <hr></td></tr>
    2081 <tr><th><a name="Concept-Index_cp_letter-S">S</a></th><td></td><td></td></tr>
    2082 <tr><td></td><td valign="top"><a href="#index-scripts_002c-linker">scripts, linker</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
    2083 <tr><td></td><td valign="top"><a href="#index-section-attribute">section attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2084 <tr><td></td><td valign="top"><a href="#index-section-directive">section directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2085 <tr><td></td><td valign="top"><a href="#index-short-directive">short directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2086 <tr><td></td><td valign="top"><a href="#index-skip-directive">skip directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2087 <tr><td></td><td valign="top"><a href="#index-space-directive">space directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2088 <tr><td></td><td valign="top"><a href="#index-stdcall-attribute">stdcall attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2089 <tr><td></td><td valign="top"><a href="#index-strength-reduction">strength reduction</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
    2090 <tr><td></td><td valign="top"><a href="#index-string-directive">string directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2091 <tr><td colspan="3"> <hr></td></tr>
    2092 <tr><th><a name="Concept-Index_cp_letter-T">T</a></th><td></td><td></td></tr>
    2093 <tr><td></td><td valign="top"><a href="#index-TARGET_002c-linker-command">TARGET, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
    2094 <tr><td></td><td valign="top"><a href="#index-text-directive">text directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2095 <tr><td colspan="3"> <hr></td></tr>
    2096 <tr><th><a name="Concept-Index_cp_letter-U">U</a></th><td></td><td></td></tr>
    2097 <tr><td></td><td valign="top"><a href="#index-unused-attribute">unused attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
    2098 <tr><td colspan="3"> <hr></td></tr>
    2099 <tr><th><a name="Concept-Index_cp_letter-V">V</a></th><td></td><td></td></tr>
    2100 <tr><td></td><td valign="top"><a href="#index-value-stack">value stack</a></td><td valign="top"><a href="#Manipulating-the-value-stack">8.7.3 Manipulating the value stack</a></td></tr>
    2101 <tr><td></td><td valign="top"><a href="#index-value-stack_002c-introduction">value stack, introduction</a></td><td valign="top"><a href="#The-value-stack">8.7.2 The value stack</a></td></tr>
    2102 <tr><td colspan="3"> <hr></td></tr>
    2103 <tr><th><a name="Concept-Index_cp_letter-W">W</a></th><td></td><td></td></tr>
    2104 <tr><td></td><td valign="top"><a href="#index-word-directive">word directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
    2105 <tr><td colspan="3"> <hr></td></tr>
    2106 </table>
    2107 <table><tr><th valign="top">Jump to: &nbsp; </th><td><a href="#Concept-Index_cp_symbol-1" class="summary-letter"><b>_</b></a>
    2108  &nbsp;
    2109 <br>
    2110 <a href="#Concept-Index_cp_letter-A" class="summary-letter"><b>A</b></a>
    2111  &nbsp;
    2112 <a href="#Concept-Index_cp_letter-B" class="summary-letter"><b>B</b></a>
    2113  &nbsp;
    2114 <a href="#Concept-Index_cp_letter-C" class="summary-letter"><b>C</b></a>
    2115  &nbsp;
    2116 <a href="#Concept-Index_cp_letter-D" class="summary-letter"><b>D</b></a>
    2117  &nbsp;
    2118 <a href="#Concept-Index_cp_letter-E" class="summary-letter"><b>E</b></a>
    2119  &nbsp;
    2120 <a href="#Concept-Index_cp_letter-F" class="summary-letter"><b>F</b></a>
    2121  &nbsp;
    2122 <a href="#Concept-Index_cp_letter-G" class="summary-letter"><b>G</b></a>
    2123  &nbsp;
    2124 <a href="#Concept-Index_cp_letter-I" class="summary-letter"><b>I</b></a>
    2125  &nbsp;
    2126 <a href="#Concept-Index_cp_letter-J" class="summary-letter"><b>J</b></a>
    2127  &nbsp;
    2128 <a href="#Concept-Index_cp_letter-L" class="summary-letter"><b>L</b></a>
    2129  &nbsp;
    2130 <a href="#Concept-Index_cp_letter-M" class="summary-letter"><b>M</b></a>
    2131  &nbsp;
    2132 <a href="#Concept-Index_cp_letter-O" class="summary-letter"><b>O</b></a>
    2133  &nbsp;
    2134 <a href="#Concept-Index_cp_letter-P" class="summary-letter"><b>P</b></a>
    2135  &nbsp;
    2136 <a href="#Concept-Index_cp_letter-Q" class="summary-letter"><b>Q</b></a>
    2137  &nbsp;
    2138 <a href="#Concept-Index_cp_letter-R" class="summary-letter"><b>R</b></a>
    2139  &nbsp;
    2140 <a href="#Concept-Index_cp_letter-S" class="summary-letter"><b>S</b></a>
    2141  &nbsp;
    2142 <a href="#Concept-Index_cp_letter-T" class="summary-letter"><b>T</b></a>
    2143  &nbsp;
    2144 <a href="#Concept-Index_cp_letter-U" class="summary-letter"><b>U</b></a>
    2145  &nbsp;
    2146 <a href="#Concept-Index_cp_letter-V" class="summary-letter"><b>V</b></a>
    2147  &nbsp;
    2148 <a href="#Concept-Index_cp_letter-W" class="summary-letter"><b>W</b></a>
    2149  &nbsp;
    2150 </td></tr></table>
    2151 
    2152 <hr size="6">
    2153 <a name="SEC_Contents"></a>
    2154 <table cellpadding="1" cellspacing="1" border="0">
    2155 <tr><td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    2156 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    2157 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    2158 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    2159 </tr></table>
    2160 <h1>Table of Contents</h1>
    2161 <div class="contents">
    2162 
    2163 <ul class="toc">
    2164   <li><a name="toc-Introduction-1" href="#Introduction">1. Introduction</a></li>
    2165   <li><a name="toc-Command-line-invocation" href="#Invoke">2. Command line invocation</a>
    2166   <ul class="toc">
    2167     <li><a name="toc-Quick-start" href="#Quick-start">2.1 Quick start</a></li>
    2168     <li><a name="toc-Option-summary" href="#Option-summary">2.2 Option summary</a></li>
    2169   </ul></li>
    2170   <li><a name="toc-C-language-support" href="#Clang">3. C language support</a>
    2171   <ul class="toc">
    2172     <li><a name="toc-ANSI-C" href="#ANSI-C">3.1 ANSI C</a></li>
    2173     <li><a name="toc-ISOC99-extensions" href="#ISOC99-extensions">3.2 ISOC99 extensions</a></li>
    2174     <li><a name="toc-GNU-C-extensions" href="#GNU-C-extensions">3.3 GNU C extensions</a></li>
    2175     <li><a name="toc-TinyCC-extensions" href="#TinyCC-extensions">3.4 TinyCC extensions</a></li>
    2176   </ul></li>
    2177   <li><a name="toc-TinyCC-Assembler" href="#asm">4. TinyCC Assembler</a>
    2178   <ul class="toc">
    2179     <li><a name="toc-Syntax" href="#Syntax">4.1 Syntax</a></li>
    2180     <li><a name="toc-Expressions" href="#Expressions">4.2 Expressions</a></li>
    2181     <li><a name="toc-Labels" href="#Labels">4.3 Labels</a></li>
    2182     <li><a name="toc-Directives" href="#Directives">4.4 Directives</a></li>
    2183     <li><a name="toc-X86-Assembler" href="#X86-Assembler">4.5 X86 Assembler</a></li>
    2184   </ul></li>
    2185   <li><a name="toc-TinyCC-Linker" href="#linker">5. TinyCC Linker</a>
    2186   <ul class="toc">
    2187     <li><a name="toc-ELF-file-generation" href="#ELF-file-generation">5.1 ELF file generation</a></li>
    2188     <li><a name="toc-ELF-file-loader" href="#ELF-file-loader">5.2 ELF file loader</a></li>
    2189     <li><a name="toc-PE_002di386-file-generation" href="#PE_002di386-file-generation">5.3 PE-i386 file generation</a></li>
    2190     <li><a name="toc-GNU-Linker-Scripts" href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></li>
    2191   </ul></li>
    2192   <li><a name="toc-TinyCC-Memory-and-Bound-checks" href="#Bounds">6. TinyCC Memory and Bound checks</a></li>
    2193   <li><a name="toc-The-libtcc-library" href="#Libtcc">7. The <code>libtcc</code> library</a></li>
    2194   <li><a name="toc-Developer_0027s-guide" href="#devel">8. Developer&rsquo;s guide</a>
    2195   <ul class="toc">
    2196     <li><a name="toc-File-reading" href="#File-reading">8.1 File reading</a></li>
    2197     <li><a name="toc-Lexer" href="#Lexer">8.2 Lexer</a></li>
    2198     <li><a name="toc-Parser" href="#Parser">8.3 Parser</a></li>
    2199     <li><a name="toc-Types" href="#Types">8.4 Types</a></li>
    2200     <li><a name="toc-Symbols" href="#Symbols">8.5 Symbols</a></li>
    2201     <li><a name="toc-Sections" href="#Sections">8.6 Sections</a></li>
    2202     <li><a name="toc-Code-generation" href="#Code-generation">8.7 Code generation</a>
    2203     <ul class="toc">
    2204       <li><a name="toc-Introduction-2" href="#Introduction-2">8.7.1 Introduction</a></li>
    2205       <li><a name="toc-The-value-stack" href="#The-value-stack">8.7.2 The value stack</a></li>
    2206       <li><a name="toc-Manipulating-the-value-stack" href="#Manipulating-the-value-stack">8.7.3 Manipulating the value stack</a></li>
    2207       <li><a name="toc-CPU-dependent-code-generation" href="#CPU-dependent-code-generation">8.7.4 CPU dependent code generation</a></li>
    2208     </ul></li>
    2209     <li><a name="toc-Optimizations-done" href="#Optimizations-done">8.8 Optimizations done</a></li>
    2210   </ul></li>
    2211   <li><a name="toc-Concept-Index" href="#Concept-Index">Concept Index</a></li>
    2212 </ul>
    2213 </div>
    2214 <hr size="1">
    2215 <a name="SEC_About"></a>
    2216 <table cellpadding="1" cellspacing="1" border="0">
    2217 <tr><td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
    2218 <td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
    2219 <td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
    2220 <td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
    2221 </tr></table>
    2222 <h1>About This Document</h1>
    2223 <p>
    2224   This document was generated by <em>Thomas Preud'homme</em> on <em>February 15, 2013</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.
    2225 </p>
    2226 <p>
    2227   The buttons in the navigation panels have the following meaning:
    2228 </p>
    2229 <table border="1">
    2230   <tr>
    2231     <th> Button </th>
    2232     <th> Name </th>
    2233     <th> Go to </th>
    2234     <th> From 1.2.3 go to</th>
    2235   </tr>
    2236   <tr>
    2237     <td align="center"> [ &lt; ] </td>
    2238     <td align="center">Back</td>
    2239     <td>Previous section in reading order</td>
    2240     <td>1.2.2</td>
    2241   </tr>
    2242   <tr>
    2243     <td align="center"> [ &gt; ] </td>
    2244     <td align="center">Forward</td>
    2245     <td>Next section in reading order</td>
    2246     <td>1.2.4</td>
    2247   </tr>
    2248   <tr>
    2249     <td align="center"> [ &lt;&lt; ] </td>
    2250     <td align="center">FastBack</td>
    2251     <td>Beginning of this chapter or previous chapter</td>
    2252     <td>1</td>
    2253   </tr>
    2254   <tr>
    2255     <td align="center"> [ Up ] </td>
    2256     <td align="center">Up</td>
    2257     <td>Up section</td>
    2258     <td>1.2</td>
    2259   </tr>
    2260   <tr>
    2261     <td align="center"> [ &gt;&gt; ] </td>
    2262     <td align="center">FastForward</td>
    2263     <td>Next chapter</td>
    2264     <td>2</td>
    2265   </tr>
    2266   <tr>
    2267     <td align="center"> [Top] </td>
    2268     <td align="center">Top</td>
    2269     <td>Cover (top) of document</td>
    2270     <td> &nbsp; </td>
    2271   </tr>
    2272   <tr>
    2273     <td align="center"> [Contents] </td>
    2274     <td align="center">Contents</td>
    2275     <td>Table of contents</td>
    2276     <td> &nbsp; </td>
    2277   </tr>
    2278   <tr>
    2279     <td align="center"> [Index] </td>
    2280     <td align="center">Index</td>
    2281     <td>Index</td>
    2282     <td> &nbsp; </td>
    2283   </tr>
    2284   <tr>
    2285     <td align="center"> [ ? ] </td>
    2286     <td align="center">About</td>
    2287     <td>About (help)</td>
    2288     <td> &nbsp; </td>
    2289   </tr>
    2290 </table>
    2291 
    2292 <p>
    2293   where the <strong> Example </strong> assumes that the current position is at <strong> Subsubsection One-Two-Three </strong> of a document of the following structure:
    2294 </p>
    2295 
    2296 <ul>
    2297   <li> 1. Section One
    2298     <ul>
    2299       <li>1.1 Subsection One-One
    2300         <ul>
    2301           <li>...</li>
    2302         </ul>
    2303       </li>
    2304       <li>1.2 Subsection One-Two
    2305         <ul>
    2306           <li>1.2.1 Subsubsection One-Two-One</li>
    2307           <li>1.2.2 Subsubsection One-Two-Two</li>
    2308           <li>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp;
    2309             <strong>&lt;== Current Position </strong></li>
    2310           <li>1.2.4 Subsubsection One-Two-Four</li>
    2311         </ul>
    2312       </li>
    2313       <li>1.3 Subsection One-Three
    2314         <ul>
    2315           <li>...</li>
    2316         </ul>
    2317       </li>
    2318       <li>1.4 Subsection One-Four</li>
    2319     </ul>
    2320   </li>
    2321 </ul>
    2322 
    2323 <hr size="1">
    2324 <p>
    2325  <font size="-1">
    2326   This document was generated by <em>Thomas Preud'homme</em> on <em>February 15, 2013</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.
    2327  </font>
    2328  <br>
    2329 
    2330 </p>
    2331 </body>
    2332 </html>
     1980<P>
     1981
     1982<HR SIZE="6">
     1983<A NAME="SEC36"></A>
     1984<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     1985<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt; </A>]</TD>
     1986<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt; ]</TD>
     1987<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
     1988<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
     1989<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
     1990<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     1991<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     1992<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     1993<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     1994</TR></TABLE>
     1995<H1> Concept Index </H1>
     1996<!--docid::SEC36::-->
     1997<table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
     1998 &nbsp;
     1999<BR>
     2000<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
     2001 &nbsp;
     2002<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
     2003 &nbsp;
     2004<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
     2005 &nbsp;
     2006<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
     2007 &nbsp;
     2008<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
     2009 &nbsp;
     2010<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
     2011 &nbsp;
     2012<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
     2013 &nbsp;
     2014<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
     2015 &nbsp;
     2016<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
     2017 &nbsp;
     2018<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
     2019 &nbsp;
     2020<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
     2021 &nbsp;
     2022<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
     2023 &nbsp;
     2024<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
     2025 &nbsp;
     2026<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
     2027 &nbsp;
     2028<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
     2029 &nbsp;
     2030<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
     2031 &nbsp;
     2032<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
     2033 &nbsp;
     2034<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
     2035 &nbsp;
     2036<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
     2037 &nbsp;
     2038<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
     2039 &nbsp;
     2040</td></tr></table><br><P></P>
     2041<TABLE border=0>
     2042<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR>
     2043<TR><TD COLSPAN=3> <HR></TD></TR>
     2044<TR><TH><A NAME="cp__"></A>_</TH><TD></TD><TD></TD></TR>
     2045<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX11">__asm__</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2046<TR><TD COLSPAN=3> <HR></TD></TR>
     2047<TR><TH><A NAME="cp_A"></A>A</TH><TD></TD><TD></TD></TR>
     2048<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">align directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2049<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX1">aligned attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2050<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">ascii directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2051<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">asciz directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2052<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A></TD></TR>
     2053<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">assembler directives</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2054<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX10">assembly, inline</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2055<TR><TD COLSPAN=3> <HR></TD></TR>
     2056<TR><TH><A NAME="cp_B"></A>B</TH><TD></TD><TD></TD></TR>
     2057<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">bound checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
     2058<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">bss directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2059<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">byte directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2060<TR><TD COLSPAN=3> <HR></TD></TR>
     2061<TR><TH><A NAME="cp_C"></A>C</TH><TD></TD><TD></TD></TR>
     2062<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">caching processor flags</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2063<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX5">cdecl attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2064<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">code generation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">8.7 Code generation</A></TD></TR>
     2065<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">comparison operators</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2066<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">constant propagation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2067<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">CPU dependent</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A></TD></TR>
     2068<TR><TD COLSPAN=3> <HR></TD></TR>
     2069<TR><TH><A NAME="cp_D"></A>D</TH><TD></TD><TD></TD></TR>
     2070<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">data directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2071<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">directives, assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2072<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX8">dllexport attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2073<TR><TD COLSPAN=3> <HR></TD></TR>
     2074<TR><TH><A NAME="cp_E"></A>E</TH><TD></TD><TD></TD></TR>
     2075<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">ELF</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A></TD></TR>
     2076<TR><TD COLSPAN=3> <HR></TD></TR>
     2077<TR><TH><A NAME="cp_F"></A>F</TH><TD></TD><TD></TD></TR>
     2078<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">FILE, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
     2079<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">fill directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2080<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">flags, caching</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2081<TR><TD COLSPAN=3> <HR></TD></TR>
     2082<TR><TH><A NAME="cp_G"></A>G</TH><TD></TD><TD></TD></TR>
     2083<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX12">gas</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2084<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">global directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2085<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">globl directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2086<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">GROUP, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
     2087<TR><TD COLSPAN=3> <HR></TD></TR>
     2088<TR><TH><A NAME="cp_I"></A>I</TH><TD></TD><TD></TD></TR>
     2089<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX9">inline assembly</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2090<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">int directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2091<TR><TD COLSPAN=3> <HR></TD></TR>
     2092<TR><TH><A NAME="cp_J"></A>J</TH><TD></TD><TD></TD></TR>
     2093<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">jump optimization</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2094<TR><TD COLSPAN=3> <HR></TD></TR>
     2095<TR><TH><A NAME="cp_L"></A>L</TH><TD></TD><TD></TD></TR>
     2096<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD></TR>
     2097<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">linker scripts</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
     2098<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">long directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2099<TR><TD COLSPAN=3> <HR></TD></TR>
     2100<TR><TH><A NAME="cp_M"></A>M</TH><TD></TD><TD></TD></TR>
     2101<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">memory checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
     2102<TR><TD COLSPAN=3> <HR></TD></TR>
     2103<TR><TH><A NAME="cp_O"></A>O</TH><TD></TD><TD></TD></TR>
     2104<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">optimizations</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2105<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">org directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2106<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">OUTPUT_FORMAT, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
     2107<TR><TD COLSPAN=3> <HR></TD></TR>
     2108<TR><TH><A NAME="cp_P"></A>P</TH><TD></TD><TD></TD></TR>
     2109<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX2">packed attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2110<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">PE-i386</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A></TD></TR>
     2111<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">previous directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2112<TR><TD COLSPAN=3> <HR></TD></TR>
     2113<TR><TH><A NAME="cp_Q"></A>Q</TH><TD></TD><TD></TD></TR>
     2114<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">quad directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2115<TR><TD COLSPAN=3> <HR></TD></TR>
     2116<TR><TH><A NAME="cp_R"></A>R</TH><TD></TD><TD></TD></TR>
     2117<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX7">regparm attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2118<TR><TD COLSPAN=3> <HR></TD></TR>
     2119<TR><TH><A NAME="cp_S"></A>S</TH><TD></TD><TD></TD></TR>
     2120<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">scripts, linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
     2121<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX3">section attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2122<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">section directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2123<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">short directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2124<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">skip directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2125<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">space directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2126<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX6">stdcall attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2127<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">strength reduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
     2128<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">string directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2129<TR><TD COLSPAN=3> <HR></TD></TR>
     2130<TR><TH><A NAME="cp_T"></A>T</TH><TD></TD><TD></TD></TR>
     2131<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">TARGET, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
     2132<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">text directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2133<TR><TD COLSPAN=3> <HR></TD></TR>
     2134<TR><TH><A NAME="cp_U"></A>U</TH><TD></TD><TD></TD></TR>
     2135<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX4">unused attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
     2136<TR><TD COLSPAN=3> <HR></TD></TR>
     2137<TR><TH><A NAME="cp_V"></A>V</TH><TD></TD><TD></TD></TR>
     2138<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">value stack</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A></TD></TR>
     2139<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">value stack, introduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A></TD></TR>
     2140<TR><TD COLSPAN=3> <HR></TD></TR>
     2141<TR><TH><A NAME="cp_W"></A>W</TH><TD></TD><TD></TD></TR>
     2142<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">word directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
     2143<TR><TD COLSPAN=3> <HR></TD></TR>
     2144</TABLE><P></P><table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
     2145 &nbsp;
     2146<BR>
     2147<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
     2148 &nbsp;
     2149<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
     2150 &nbsp;
     2151<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
     2152 &nbsp;
     2153<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
     2154 &nbsp;
     2155<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
     2156 &nbsp;
     2157<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
     2158 &nbsp;
     2159<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
     2160 &nbsp;
     2161<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
     2162 &nbsp;
     2163<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
     2164 &nbsp;
     2165<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
     2166 &nbsp;
     2167<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
     2168 &nbsp;
     2169<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
     2170 &nbsp;
     2171<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
     2172 &nbsp;
     2173<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
     2174 &nbsp;
     2175<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
     2176 &nbsp;
     2177<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
     2178 &nbsp;
     2179<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
     2180 &nbsp;
     2181<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
     2182 &nbsp;
     2183<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
     2184 &nbsp;
     2185<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
     2186 &nbsp;
     2187</td></tr></table><br><P>
     2188
     2189<HR SIZE="6">
     2190<A NAME="SEC_Contents"></A>
     2191<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     2192<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     2193<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     2194<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     2195<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     2196</TR></TABLE>
     2197<H1>Table of Contents</H1>
     2198<UL>
     2199<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
     2200<BR>
     2201<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
     2202<BR>
     2203<UL>
     2204<A NAME="TOC3" HREF="tcc-doc.html#SEC3">2.1 Quick start</A>
     2205<BR>
     2206<A NAME="TOC4" HREF="tcc-doc.html#SEC4">2.2 Option summary</A>
     2207<BR>
     2208</UL>
     2209<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
     2210<BR>
     2211<UL>
     2212<A NAME="TOC6" HREF="tcc-doc.html#SEC6">3.1 ANSI C</A>
     2213<BR>
     2214<A NAME="TOC7" HREF="tcc-doc.html#SEC7">3.2 ISOC99 extensions</A>
     2215<BR>
     2216<A NAME="TOC8" HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A>
     2217<BR>
     2218<A NAME="TOC9" HREF="tcc-doc.html#SEC9">3.4 TinyCC extensions</A>
     2219<BR>
     2220</UL>
     2221<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
     2222<BR>
     2223<UL>
     2224<A NAME="TOC11" HREF="tcc-doc.html#SEC11">4.1 Syntax</A>
     2225<BR>
     2226<A NAME="TOC12" HREF="tcc-doc.html#SEC12">4.2 Expressions</A>
     2227<BR>
     2228<A NAME="TOC13" HREF="tcc-doc.html#SEC13">4.3 Labels</A>
     2229<BR>
     2230<A NAME="TOC14" HREF="tcc-doc.html#SEC14">4.4 Directives</A>
     2231<BR>
     2232<A NAME="TOC15" HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A>
     2233<BR>
     2234</UL>
     2235<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
     2236<BR>
     2237<UL>
     2238<A NAME="TOC17" HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A>
     2239<BR>
     2240<A NAME="TOC18" HREF="tcc-doc.html#SEC18">5.2 ELF file loader</A>
     2241<BR>
     2242<A NAME="TOC19" HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A>
     2243<BR>
     2244<A NAME="TOC20" HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A>
     2245<BR>
     2246</UL>
     2247<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
     2248<BR>
     2249<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
     2250<BR>
     2251<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
     2252<BR>
     2253<UL>
     2254<A NAME="TOC24" HREF="tcc-doc.html#SEC24">8.1 File reading</A>
     2255<BR>
     2256<A NAME="TOC25" HREF="tcc-doc.html#SEC25">8.2 Lexer</A>
     2257<BR>
     2258<A NAME="TOC26" HREF="tcc-doc.html#SEC26">8.3 Parser</A>
     2259<BR>
     2260<A NAME="TOC27" HREF="tcc-doc.html#SEC27">8.4 Types</A>
     2261<BR>
     2262<A NAME="TOC28" HREF="tcc-doc.html#SEC28">8.5 Symbols</A>
     2263<BR>
     2264<A NAME="TOC29" HREF="tcc-doc.html#SEC29">8.6 Sections</A>
     2265<BR>
     2266<A NAME="TOC30" HREF="tcc-doc.html#SEC30">8.7 Code generation</A>
     2267<BR>
     2268<UL>
     2269<A NAME="TOC31" HREF="tcc-doc.html#SEC31">8.7.1 Introduction</A>
     2270<BR>
     2271<A NAME="TOC32" HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A>
     2272<BR>
     2273<A NAME="TOC33" HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A>
     2274<BR>
     2275<A NAME="TOC34" HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A>
     2276<BR>
     2277</UL>
     2278<A NAME="TOC35" HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A>
     2279<BR>
     2280</UL>
     2281<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
     2282<BR>
     2283</UL>
     2284<HR SIZE=1>
     2285<A NAME="SEC_OVERVIEW"></A>
     2286<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     2287<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     2288<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     2289<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     2290<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     2291</TR></TABLE>
     2292<H1>Short Table of Contents</H1>
     2293<BLOCKQUOTE>
     2294<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
     2295<BR>
     2296<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
     2297<BR>
     2298<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
     2299<BR>
     2300<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
     2301<BR>
     2302<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
     2303<BR>
     2304<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
     2305<BR>
     2306<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
     2307<BR>
     2308<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
     2309<BR>
     2310<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
     2311<BR>
     2312
     2313</BLOCKQUOTE>
     2314<HR SIZE=1>
     2315<A NAME="SEC_About"></A>
     2316<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
     2317<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
     2318<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
     2319<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
     2320<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
     2321</TR></TABLE>
     2322<H1>About this document</H1>
     2323This document was generated on <I>December, 17  2017</I>
     2324using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
     2325"><I>texi2html</I></A>
     2326<P></P> 
     2327The buttons in the navigation panels have the following meaning:
     2328<P></P>
     2329<table border = "1">
     2330<TR>
     2331<TH> Button </TH>
     2332<TH> Name </TH>
     2333<TH> Go to </TH>
     2334<TH> From 1.2.3 go to</TH>
     2335</TR>
     2336<TR>
     2337<TD ALIGN="CENTER">
     2338 [ &lt; ] </TD>
     2339<TD ALIGN="CENTER">
     2340Back
     2341</TD>
     2342<TD>
     2343previous section in reading order
     2344</TD>
     2345<TD>
     23461.2.2
     2347</TD>
     2348</TR>
     2349<TR>
     2350<TD ALIGN="CENTER">
     2351 [ &gt; ] </TD>
     2352<TD ALIGN="CENTER">
     2353Forward
     2354</TD>
     2355<TD>
     2356next section in reading order
     2357</TD>
     2358<TD>
     23591.2.4
     2360</TD>
     2361</TR>
     2362<TR>
     2363<TD ALIGN="CENTER">
     2364 [ &lt;&lt; ] </TD>
     2365<TD ALIGN="CENTER">
     2366FastBack
     2367</TD>
     2368<TD>
     2369previous or up-and-previous section
     2370</TD>
     2371<TD>
     23721.1
     2373</TD>
     2374</TR>
     2375<TR>
     2376<TD ALIGN="CENTER">
     2377 [ Up ] </TD>
     2378<TD ALIGN="CENTER">
     2379Up
     2380</TD>
     2381<TD>
     2382up section
     2383</TD>
     2384<TD>
     23851.2
     2386</TD>
     2387</TR>
     2388<TR>
     2389<TD ALIGN="CENTER">
     2390 [ &gt;&gt; ] </TD>
     2391<TD ALIGN="CENTER">
     2392FastForward
     2393</TD>
     2394<TD>
     2395next or up-and-next section
     2396</TD>
     2397<TD>
     23981.3
     2399</TD>
     2400</TR>
     2401<TR>
     2402<TD ALIGN="CENTER">
     2403 [Top] </TD>
     2404<TD ALIGN="CENTER">
     2405Top
     2406</TD>
     2407<TD>
     2408cover (top) of document
     2409</TD>
     2410<TD>
     2411 &nbsp;
     2412</TD>
     2413</TR>
     2414<TR>
     2415<TD ALIGN="CENTER">
     2416 [Contents] </TD>
     2417<TD ALIGN="CENTER">
     2418Contents
     2419</TD>
     2420<TD>
     2421table of contents
     2422</TD>
     2423<TD>
     2424 &nbsp;
     2425</TD>
     2426</TR>
     2427<TR>
     2428<TD ALIGN="CENTER">
     2429 [Index] </TD>
     2430<TD ALIGN="CENTER">
     2431Index
     2432</TD>
     2433<TD>
     2434concept index
     2435</TD>
     2436<TD>
     2437 &nbsp;
     2438</TD>
     2439</TR>
     2440<TR>
     2441<TD ALIGN="CENTER">
     2442 [ ? ] </TD>
     2443<TD ALIGN="CENTER">
     2444About
     2445</TD>
     2446<TD>
     2447this page
     2448</TD>
     2449<TD>
     2450 &nbsp;
     2451</TD>
     2452</TR>
     2453</TABLE>
     2454<P></P>
     2455where the <STRONG> Example </STRONG> assumes that the current position
     2456is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of
     2457the following structure:
     2458<UL>
     2459<LI> 1. Section One  </LI>
     2460<UL>
     2461<LI>1.1 Subsection One-One</LI>
     2462<UL>
     2463<LI> ... </LI>
     2464</UL>
     2465<LI>1.2 Subsection One-Two</LI>
     2466<UL>
     2467<LI>1.2.1 Subsubsection One-Two-One
     2468</LI><LI>1.2.2 Subsubsection One-Two-Two
     2469</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
     2470&lt;== Current Position </STRONG>
     2471</LI><LI>1.2.4 Subsubsection One-Two-Four
     2472</LI></UL>
     2473<LI>1.3 Subsection One-Three</LI>
     2474<UL>
     2475<LI> ... </LI>
     2476</UL>
     2477<LI>1.4 Subsection One-Four</LI>
     2478</UL>
     2479</UL>
     2480
     2481<HR SIZE=1>
     2482<BR> 
     2483<FONT SIZE="-1">
     2484This document was generated
     2485on <I>December, 17  2017</I>
     2486using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
     2487"><I>texi2html</I></A>
     2488
     2489</BODY>
     2490</HTML>
  • EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.texi

    r279 r331  
    177177@end example
    178178
    179 @item -dumpversion
    180 Print only the compiler version and nothing else.
    181 
    182179@item -v
    183180Display TCC version.
    184181
    185182@item -vv
    186 Show included files.  As sole argument, print search dirs (as below).
     183Show included files.  As sole argument, print search dirs.  -vvv shows tries too.
    187184
    188185@item -bench
    189186Display compilation statistics.
    190 
    191 @item -print-search-dirs
    192 Print the configured installation directory and a list of library
    193 and include directories tcc will search.
    194187
    195188@end table
     
    214207@item -Usym
    215208Undefine preprocessor symbol @samp{sym}.
     209
     210@item -E
     211Preprocess only, to stdout or file (with -o).
     212
    216213@end table
    217214
    218215Compilation flags:
    219216
    220 Note: each of the following warning options has a negative form beginning with
     217Note: each of the following options has a negative form beginning with
    221218@option{-fno-}.
    222219
     
    233230@item -fleading-underscore
    234231Add a leading underscore at the beginning of each C symbol.
     232
     233@item -fms-extensions
     234Allow a MS C compiler extensions to the language. Currently this
     235assumes a nested named structure declaration without an identifier
     236behaves like an unnamed one.
     237
     238@item -fdollars-in-identifiers
     239Allow dollar signs in identifiers
    235240
    236241@end table
     
    277282Link your program with dynamic library libxxx.so or static library
    278283libxxx.a. The library is searched in the paths specified by the
    279 @option{-L} option.
     284@option{-L} option and @env{LIBRARY_PATH} variable.
    280285
    281286@item -Bdir
     
    301306
    302307@item -Wl,-rpath=path
    303 Put custom seatch path for dynamic libraries into executable.
     308Put custom search path for dynamic libraries into executable.
     309
     310@item -Wl,--enable-new-dtags
     311When putting a custom search path for dynamic libraries into the executable,
     312create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
    304313
    305314@item -Wl,--oformat=fmt
     
    323332Set DT_SYMBOLIC tag.
    324333
     334@item -Wl,-(no-)whole-archive
     335Turn on/off linking of all objects in archives.
     336
    325337@end table
    326338
     
    339351that the generated code is slower and bigger in this case.
    340352
    341 Note: @option{-b} is only available on i386 for the moment.
     353Note: @option{-b} is only available on i386 when using libtcc for the moment.
    342354
    343355@item -bt N
     
    356368Use @file{depfile} as output for -MD.
    357369
     370@item -print-search-dirs
     371Print the configured installation directory and a list of library
     372and include directories tcc will search.
     373
     374@item -dumpversion
     375Print version.
     376
     377@end table
     378
     379Target specific options:
     380
     381@table @option
     382@item -mms-bitfields
     383Use an algorithm for bitfield alignment consistent with MSVC. Default is
     384gcc's algorithm.
     385
     386@item -mfloat-abi (ARM only)
     387Select the float ABI. Possible values: @code{softfp} and @code{hard}
     388
     389@item -mno-sse
     390Do not use sse registers on x86_64
     391
     392@item -m32, -m64
     393Pass command line to the i386/x86_64 cross compiler.
     394
    358395@end table
    359396
     
    362399@c man end
    363400
     401@c man begin ENVIRONMENT
     402Environment variables that affect how tcc operates.
     403
     404@table @option
     405
     406@item CPATH
     407@item C_INCLUDE_PATH
     408A colon-separated list of directories searched for include files,
     409directories given with @option{-I} are searched first.
     410
     411@item LIBRARY_PATH
     412A colon-separated list of directories searched for libraries for the
     413@option{-l} option, directories given with @option{-L} are searched first.
     414
     415@end table
     416
     417@c man end
     418
    364419@ignore
    365420
     
    368423
    369424@c man begin SEEALSO
     425cpp(1),
    370426gcc(1)
    371427@c man end
     
    389445
    390446TCC implements many features of the new C standard: ISO C99. Currently
    391 missing items are: complex and imaginary numbers and variable length
    392 arrays.
     447missing items are: complex and imaginary numbers.
    393448
    394449Currently implemented ISOC99 features:
    395450
    396451@itemize
     452
     453@item variable length arrays.
    397454
    398455@item 64 bit @code{long long} types are fully supported.
     
    597654@itemize
    598655
    599 @item @code{__TINYC__} is a predefined macro to @code{1} to
    600 indicate that you use TCC.
     656@item @code{__TINYC__} is a predefined macro to indicate that you use TCC.
    601657
    602658@item @code{#!} at the start of a line is ignored to allow scripting.
     
    614670Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
    615671assembler supports a gas-like syntax (GNU assembler). You can
    616 desactivate assembler support if you want a smaller TinyCC executable
     672deactivate assembler support if you want a smaller TinyCC executable
    617673(the C compiler does not rely on the assembler).
    618674
     
    703759@cindex ascii directive
    704760
    705 All directives are preceeded by a '.'. The following directives are
     761All directives are preceded by a '.'. The following directives are
    706762supported:
    707763
     
    922978@section Types
    923979
    924 The types are stored in a single 'int' variable. It was choosen in the
     980The types are stored in a single 'int' variable. It was chosen in the
    925981first stages of development when tcc was much simpler. Now, it may not
    926982be the best solution.
     
    9491005#define VT_CONSTANT   0x0800  /* const modifier */
    9501006#define VT_VOLATILE   0x1000  /* volatile modifier */
    951 #define VT_SIGNED     0x2000  /* signed type */
     1007#define VT_DEFSIGN    0x2000  /* signed type */
    9521008
    9531009#define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
     
    9911047
    9921048@code{Sym.v} contains the symbol name (remember
    993 an idenfier is also a token, so a string is never necessary to store
     1049an identifier is also a token, so a string is never necessary to store
    9941050it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
    9951051the register in which the corresponding variable is stored. @code{Sym.c} is
     
    10341090@section Sections
    10351091
    1036 The generated code and datas are written in sections. The structure
     1092The generated code and data are written in sections. The structure
    10371093@code{Section} contains all the necessary information for a given
    10381094section. @code{new_section()} creates a new section. ELF file semantics
     
    10591115@item stab_section
    10601116@itemx stabstr_section
    1061 are used when debugging is actived to store debug information
     1117are used when debugging is active to store debug information
    10621118
    10631119@item symtab_section
     
    11591215
    11601216@item VT_LLOCAL
    1161 is a saved lvalue on the stack. @code{VT_LLOCAL} should be eliminated
    1162 ASAP because its semantics are rather complicated.
     1217is a saved lvalue on the stack. @code{VT_LVAL} must also be set with
     1218@code{VT_LLOCAL}. @code{VT_LLOCAL} can arise when a @code{VT_LVAL} in
     1219a register has to be saved to the stack, or it can come from an
     1220architecture-specific calling convention.
    11631221
    11641222@item VT_MUSTCAST
     
    12191277@item gen_opi(op)
    12201278must generate the binary integer operation @var{op} on the two top
    1221 entries of the stack which are guaranted to contain integer types.
     1279entries of the stack which are guaranteed to contain integer types.
    12221280
    12231281The result value should be put on the stack.
     
    12251283@item gen_opf(op)
    12261284same as @code{gen_opi()} for floating point operations. The two top
    1227 entries of the stack are guaranted to contain floating point values of
     1285entries of the stack are guaranteed to contain floating point values of
    12281286same types.
    12291287
  • EcnlProtoTool/trunk/tcc-0.9.27/tcc.1

    r279 r331  
     1.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
     2.\"
     3.\" Standard preamble:
     4.\" ========================================================================
     5.de Sh \" Subsection heading
     6.br
     7.if t .Sp
     8.ne 5
     9.PP
     10\fB\\$1\fR
     11.PP
     12..
     13.de Sp \" Vertical space (when we can't use .PP)
     14.if t .sp .5v
     15.if n .sp
     16..
     17.de Vb \" Begin verbatim text
     18.ft CW
     19.nf
     20.ne \\$1
     21..
     22.de Ve \" End verbatim text
     23.ft R
     24.fi
     25..
     26.\" Set up some character translations and predefined strings.  \*(-- will
     27.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
     28.\" double quote, and \*(R" will give a right double quote.  | will give a
     29.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
     30.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
     31.\" expand to `' in nroff, nothing in troff, for use with C<>.
     32.tr \(*W-|\(bv\*(Tr
     33.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
     34.ie n \{\
     35.    ds -- \(*W-
     36.    ds PI pi
     37.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
     38.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
     39.    ds L" ""
     40.    ds R" ""
     41.    ds C` ""
     42.    ds C' ""
     43'br\}
     44.el\{\
     45.    ds -- \|\(em\|
     46.    ds PI \(*p
     47.    ds L" ``
     48.    ds R" ''
     49'br\}
     50.\"
     51.\" If the F register is turned on, we'll generate index entries on stderr for
     52.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
     53.\" entries marked with X<> in POD.  Of course, you'll have to process the
     54.\" output yourself in some meaningful fashion.
     55.if \nF \{\
     56.    de IX
     57.    tm Index:\\$1\t\\n%\t"\\$2"
     58..
     59.    nr % 0
     60.    rr F
     61.\}
     62.\"
     63.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
     64.\" way too many mistakes in technical documents.
     65.hy 0
     66.if n .na
     67.\"
     68.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
     69.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
     70.    \" fudge factors for nroff and troff
     71.if n \{\
     72.    ds #H 0
     73.    ds #V .8m
     74.    ds #F .3m
     75.    ds #[ \f1
     76.    ds #] \fP
     77.\}
     78.if t \{\
     79.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
     80.    ds #V .6m
     81.    ds #F 0
     82.    ds #[ \&
     83.    ds #] \&
     84.\}
     85.    \" simple accents for nroff and troff
     86.if n \{\
     87.    ds ' \&
     88.    ds ` \&
     89.    ds ^ \&
     90.    ds , \&
     91.    ds ~ ~
     92.    ds /
     93.\}
     94.if t \{\
     95.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
     96.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
     97.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
     98.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
     99.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
     100.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
     101.\}
     102.    \" troff and (daisy-wheel) nroff accents
     103.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
     104.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
     105.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
     106.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
     107.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
     108.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
     109.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
     110.ds ae a\h'-(\w'a'u*4/10)'e
     111.ds Ae A\h'-(\w'A'u*4/10)'E
     112.    \" corrections for vroff
     113.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
     114.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
     115.    \" for low resolution devices (crt and lpr)
     116.if \n(.H>23 .if \n(.V>19 \
     117\{\
     118.    ds : e
     119.    ds 8 ss
     120.    ds o a
     121.    ds d- d\h'-1'\(ga
     122.    ds D- D\h'-1'\(hy
     123.    ds th \o'bp'
     124.    ds Th \o'LP'
     125.    ds ae ae
     126.    ds Ae AE
     127.\}
     128.rm #[ #] #H #V #F C
     129.\" ========================================================================
     130.\"
     131.IX Title "TCC 1"
     132.TH TCC 1 "2018-01-07" "0.9.27" "Tiny C Compiler"
     133.SH "NAME"
     134tcc \- Tiny C Compiler
     135.SH "SYNOPSIS"
     136.IX Header "SYNOPSIS"
     137usage: tcc [options] [\fIinfile1\fR \fIinfile2\fR...] [\fB\-run\fR \fIinfile\fR \fIargs\fR...]
     138.SH "DESCRIPTION"
     139.IX Header "DESCRIPTION"
     140\&\s-1TCC\s0 options are a very much like gcc options. The main difference is that \s-1TCC\s0
     141can also execute directly the resulting program and give it runtime
     142arguments.
     143.PP
     144Here are some examples to understand the logic:
     145.ie n .IP """\f(CBtcc \-run a.c\f(CW""" 4
     146.el .IP "\f(CW\f(CBtcc \-run a.c\f(CW\fR" 4
     147.IX Item "tcc -run a.c"
     148Compile \fIa.c\fR and execute it directly
     149.ie n .IP """\f(CBtcc \-run a.c arg1\f(CW""" 4
     150.el .IP "\f(CW\f(CBtcc \-run a.c arg1\f(CW\fR" 4
     151.IX Item "tcc -run a.c arg1"
     152Compile a.c and execute it directly. arg1 is given as first argument to
     153the \f(CW\*(C`main()\*(C'\fR of a.c.
     154.ie n .IP """\f(CBtcc a.c \-run b.c arg1\f(CW""" 4
     155.el .IP "\f(CW\f(CBtcc a.c \-run b.c arg1\f(CW\fR" 4
     156.IX Item "tcc a.c -run b.c arg1"
     157Compile \fIa.c\fR and \fIb.c\fR, link them together and execute them. arg1 is given
     158as first argument to the \f(CW\*(C`main()\*(C'\fR of the resulting program.
     159.ie n .IP """\f(CBtcc \-o myprog a.c b.c\f(CW""" 4
     160.el .IP "\f(CW\f(CBtcc \-o myprog a.c b.c\f(CW\fR" 4
     161.IX Item "tcc -o myprog a.c b.c"
     162Compile \fIa.c\fR and \fIb.c\fR, link them and generate the executable \fImyprog\fR.
     163.ie n .IP """\f(CBtcc \-o myprog a.o b.o\f(CW""" 4
     164.el .IP "\f(CW\f(CBtcc \-o myprog a.o b.o\f(CW\fR" 4
     165.IX Item "tcc -o myprog a.o b.o"
     166link \fIa.o\fR and \fIb.o\fR together and generate the executable \fImyprog\fR.
     167.ie n .IP """\f(CBtcc \-c a.c\f(CW""" 4
     168.el .IP "\f(CW\f(CBtcc \-c a.c\f(CW\fR" 4
     169.IX Item "tcc -c a.c"
     170Compile \fIa.c\fR and generate object file \fIa.o\fR.
     171.ie n .IP """\f(CBtcc \-c asmfile.S\f(CW""" 4
     172.el .IP "\f(CW\f(CBtcc \-c asmfile.S\f(CW\fR" 4
     173.IX Item "tcc -c asmfile.S"
     174Preprocess with C preprocess and assemble \fIasmfile.S\fR and generate
     175object file \fIasmfile.o\fR.
     176.ie n .IP """\f(CBtcc \-c asmfile.s\f(CW""" 4
     177.el .IP "\f(CW\f(CBtcc \-c asmfile.s\f(CW\fR" 4
     178.IX Item "tcc -c asmfile.s"
     179Assemble (but not preprocess) \fIasmfile.s\fR and generate object file
     180\&\fIasmfile.o\fR.
     181.ie n .IP """\f(CBtcc \-r \-o ab.o a.c b.c\f(CW""" 4
     182.el .IP "\f(CW\f(CBtcc \-r \-o ab.o a.c b.c\f(CW\fR" 4
     183.IX Item "tcc -r -o ab.o a.c b.c"
     184Compile \fIa.c\fR and \fIb.c\fR, link them together and generate the object file \fIab.o\fR.
     185.PP
     186Scripting:
     187.PP
     188\&\s-1TCC\s0 can be invoked from \fIscripts\fR, just as shell scripts. You just
     189need to add \f(CW\*(C`#!/usr/local/bin/tcc \-run\*(C'\fR at the start of your C source:
     190.PP
     191.Vb 2
     192\&        #!/usr/local/bin/tcc -run
     193\&        #include <stdio.h>
     194.Ve
     195.PP
     196.Vb 5
     197\&        int main()
     198\&        {
     199\&            printf("Hello World\en");
     200\&            return 0;
     201\&        }
     202.Ve
     203.PP
     204\&\s-1TCC\s0 can read C source code from \fIstandard input\fR when \fB\-\fR is used in
     205place of \fBinfile\fR. Example:
     206.PP
     207.Vb 1
     208\&        echo 'main(){puts("hello");}' | tcc -run -
     209.Ve
     210.SH "OPTIONS"
     211.IX Header "OPTIONS"
     212.IP "\fB\-c\fR" 4
     213.IX Item "-c"
     214Generate an object file.
     215.IP "\fB\-o outfile\fR" 4
     216.IX Item "-o outfile"
     217Put object file, executable, or dll into output file \fIoutfile\fR.
     218.IP "\fB\-run source [args...]\fR" 4
     219.IX Item "-run source [args...]"
     220Compile file \fIsource\fR and run it with the command line arguments
     221\&\fIargs\fR. In order to be able to give more than one argument to a
     222script, several \s-1TCC\s0 options can be given \fIafter\fR the
     223\&\fB\-run\fR option, separated by spaces:
     224.Sp
     225.Vb 1
     226\&        tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
     227.Ve
     228.Sp
     229In a script, it gives the following header:
     230.Sp
     231.Vb 1
     232\&        #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
     233.Ve
     234.IP "\fB\-v\fR" 4
     235.IX Item "-v"
     236Display \s-1TCC\s0 version.
     237.IP "\fB\-vv\fR" 4
     238.IX Item "-vv"
     239Show included files.  As sole argument, print search dirs.  \-vvv shows tries too.
     240.IP "\fB\-bench\fR" 4
     241.IX Item "-bench"
     242Display compilation statistics.
     243.PP
     244Preprocessor options:
     245.IP "\fB\-Idir\fR" 4
     246.IX Item "-Idir"
     247Specify an additional include path. Include paths are searched in the
     248order they are specified.
     249.Sp
     250System include paths are always searched after. The default system
     251include paths are: \fI/usr/local/include\fR, \fI/usr/include\fR
     252and \fIPREFIX/lib/tcc/include\fR. (\fI\s-1PREFIX\s0\fR is usually
     253\&\fI/usr\fR or \fI/usr/local\fR).
     254.IP "\fB\-Dsym[=val]\fR" 4
     255.IX Item "-Dsym[=val]"
     256Define preprocessor symbol \fBsym\fR to
     257val. If val is not present, its value is \fB1\fR. Function-like macros can
     258also be defined: \fB\-DF(a)=a+1\fR
     259.IP "\fB\-Usym\fR" 4
     260.IX Item "-Usym"
     261Undefine preprocessor symbol \fBsym\fR.
     262.IP "\fB\-E\fR" 4
     263.IX Item "-E"
     264Preprocess only, to stdout or file (with \-o).
     265.PP
     266Compilation flags:
     267.PP
     268Note: each of the following options has a negative form beginning with
     269\&\fB\-fno\-\fR.
     270.IP "\fB\-funsigned\-char\fR" 4
     271.IX Item "-funsigned-char"
     272Let the \f(CW\*(C`char\*(C'\fR type be unsigned.
     273.IP "\fB\-fsigned\-char\fR" 4
     274.IX Item "-fsigned-char"
     275Let the \f(CW\*(C`char\*(C'\fR type be signed.
     276.IP "\fB\-fno\-common\fR" 4
     277.IX Item "-fno-common"
     278Do not generate common symbols for uninitialized data.
     279.IP "\fB\-fleading\-underscore\fR" 4
     280.IX Item "-fleading-underscore"
     281Add a leading underscore at the beginning of each C symbol.
     282.IP "\fB\-fms\-extensions\fR" 4
     283.IX Item "-fms-extensions"
     284Allow a \s-1MS\s0 C compiler extensions to the language. Currently this
     285assumes a nested named structure declaration without an identifier
     286behaves like an unnamed one.
     287.IP "\fB\-fdollars\-in\-identifiers\fR" 4
     288.IX Item "-fdollars-in-identifiers"
     289Allow dollar signs in identifiers
     290.PP
     291Warning options:
     292.IP "\fB\-w\fR" 4
     293.IX Item "-w"
     294Disable all warnings.
     295.PP
     296Note: each of the following warning options has a negative form beginning with
     297\&\fB\-Wno\-\fR.
     298.IP "\fB\-Wimplicit\-function\-declaration\fR" 4
     299.IX Item "-Wimplicit-function-declaration"
     300Warn about implicit function declaration.
     301.IP "\fB\-Wunsupported\fR" 4
     302.IX Item "-Wunsupported"
     303Warn about unsupported \s-1GCC\s0 features that are ignored by \s-1TCC\s0.
     304.IP "\fB\-Wwrite\-strings\fR" 4
     305.IX Item "-Wwrite-strings"
     306Make string constants be of type \f(CW\*(C`const char *\*(C'\fR instead of \f(CW\*(C`char
     307*\*(C'\fR.
     308.IP "\fB\-Werror\fR" 4
     309.IX Item "-Werror"
     310Abort compilation if warnings are issued.
     311.IP "\fB\-Wall\fR" 4
     312.IX Item "-Wall"
     313Activate all warnings, except \fB\-Werror\fR, \fB\-Wunusupported\fR and
     314\&\fB\-Wwrite\-strings\fR.
     315.PP
     316Linker options:
     317.IP "\fB\-Ldir\fR" 4
     318.IX Item "-Ldir"
     319Specify an additional static library path for the \fB\-l\fR option. The
     320default library paths are \fI/usr/local/lib\fR, \fI/usr/lib\fR and \fI/lib\fR.
     321.IP "\fB\-lxxx\fR" 4
     322.IX Item "-lxxx"
     323Link your program with dynamic library libxxx.so or static library
     324libxxx.a. The library is searched in the paths specified by the
     325\&\fB\-L\fR option and \fB\s-1LIBRARY_PATH\s0\fR variable.
     326.IP "\fB\-Bdir\fR" 4
     327.IX Item "-Bdir"
     328Set the path where the tcc internal libraries (and include files) can be
     329found (default is \fIPREFIX/lib/tcc\fR).
     330.IP "\fB\-shared\fR" 4
     331.IX Item "-shared"
     332Generate a shared library instead of an executable.
     333.IP "\fB\-soname name\fR" 4
     334.IX Item "-soname name"
     335set name for shared library to be used at runtime
     336.IP "\fB\-static\fR" 4
     337.IX Item "-static"
     338Generate a statically linked executable (default is a shared linked
     339executable).
     340.IP "\fB\-rdynamic\fR" 4
     341.IX Item "-rdynamic"
     342Export global symbols to the dynamic linker. It is useful when a library
     343opened with \f(CW\*(C`dlopen()\*(C'\fR needs to access executable symbols.
     344.IP "\fB\-r\fR" 4
     345.IX Item "-r"
     346Generate an object file combining all input files.
     347.IP "\fB\-Wl,\-rpath=path\fR" 4
     348.IX Item "-Wl,-rpath=path"
     349Put custom search path for dynamic libraries into executable.
     350.IP "\fB\-Wl,\-\-enable\-new\-dtags\fR" 4
     351.IX Item "-Wl,--enable-new-dtags"
     352When putting a custom search path for dynamic libraries into the executable,
     353create the new \s-1ELF\s0 dynamic tag \s-1DT_RUNPATH\s0 instead of the old legacy \s-1DT_RPATH\s0.
     354.IP "\fB\-Wl,\-\-oformat=fmt\fR" 4
     355.IX Item "-Wl,--oformat=fmt"
     356Use \fIfmt\fR as output format. The supported output formats are:
     357.RS 4
     358.ie n .IP """elf32\-i386""" 4
     359.el .IP "\f(CWelf32\-i386\fR" 4
     360.IX Item "elf32-i386"
     361\&\s-1ELF\s0 output format (default)
     362.ie n .IP """binary""" 4
     363.el .IP "\f(CWbinary\fR" 4
     364.IX Item "binary"
     365Binary image (only for executable output)
     366.ie n .IP """coff""" 4
     367.el .IP "\f(CWcoff\fR" 4
     368.IX Item "coff"
     369\&\s-1COFF\s0 output format (only for executable output for TMS320C67xx target)
     370.RE
     371.RS 4
     372.RE
     373.IP "\fB\-Wl,\-subsystem=console/gui/wince/...\fR" 4
     374.IX Item "-Wl,-subsystem=console/gui/wince/..."
     375Set type for \s-1PE\s0 (Windows) executables.
     376.IP "\fB\-Wl,\-[Ttext=# | section\-alignment=# | file\-alignment=# | image\-base=# | stack=#]\fR" 4
     377.IX Item "-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]"
     378Modify executable layout.
     379.IP "\fB\-Wl,\-Bsymbolic\fR" 4
     380.IX Item "-Wl,-Bsymbolic"
     381Set \s-1DT_SYMBOLIC\s0 tag.
     382.IP "\fB\-Wl,\-(no\-)whole\-archive\fR" 4
     383.IX Item "-Wl,-(no-)whole-archive"
     384Turn on/off linking of all objects in archives.
     385.PP
     386Debugger options:
     387.IP "\fB\-g\fR" 4
     388.IX Item "-g"
     389Generate run time debug information so that you get clear run time
     390error messages: \f(CW\*(C` test.c:68: in function 'test5()': dereferencing
     391invalid pointer\*(C'\fR instead of the laconic \f(CW\*(C`Segmentation
     392fault\*(C'\fR.
     393.IP "\fB\-b\fR" 4
     394.IX Item "-b"
     395Generate additional support code to check
     396memory allocations and array/pointer bounds. \fB\-g\fR is implied. Note
     397that the generated code is slower and bigger in this case.
     398.Sp
     399Note: \fB\-b\fR is only available on i386 when using libtcc for the moment.
     400.IP "\fB\-bt N\fR" 4
     401.IX Item "-bt N"
     402Display N callers in stack traces. This is useful with \fB\-g\fR or
     403\&\fB\-b\fR.
     404.PP
     405Misc options:
     406.IP "\fB\-MD\fR" 4
     407.IX Item "-MD"
     408Generate makefile fragment with dependencies.
     409.IP "\fB\-MF depfile\fR" 4
     410.IX Item "-MF depfile"
     411Use \fIdepfile\fR as output for \-MD.
     412.IP "\fB\-print\-search\-dirs\fR" 4
     413.IX Item "-print-search-dirs"
     414Print the configured installation directory and a list of library
     415and include directories tcc will search.
     416.IP "\fB\-dumpversion\fR" 4
     417.IX Item "-dumpversion"
     418Print version.
     419.PP
     420Target specific options:
     421.IP "\fB\-mms\-bitfields\fR" 4
     422.IX Item "-mms-bitfields"
     423Use an algorithm for bitfield alignment consistent with \s-1MSVC\s0. Default is
     424gcc's algorithm.
     425.IP "\fB\-mfloat\-abi (\s-1ARM\s0 only)\fR" 4
     426.IX Item "-mfloat-abi (ARM only)"
     427Select the float \s-1ABI\s0. Possible values: \f(CW\*(C`softfp\*(C'\fR and \f(CW\*(C`hard\*(C'\fR
     428.IP "\fB\-mno\-sse\fR" 4
     429.IX Item "-mno-sse"
     430Do not use sse registers on x86_64
     431.IP "\fB\-m32, \-m64\fR" 4
     432.IX Item "-m32, -m64"
     433Pass command line to the i386/x86_64 cross compiler.
     434.PP
     435Note: \s-1GCC\s0 options \fB\-Ox\fR, \fB\-fx\fR and \fB\-mx\fR are
     436ignored.
     437.SH "ENVIRONMENT"
     438.IX Header "ENVIRONMENT"
     439Environment variables that affect how tcc operates.
     440.IP "\fB\s-1CPATH\s0\fR" 4
     441.IX Item "CPATH"
     442.PD 0
     443.IP "\fBC_INCLUDE_PATH\fR" 4
     444.IX Item "C_INCLUDE_PATH"
     445.PD
     446A colon-separated list of directories searched for include files,
     447directories given with \fB\-I\fR are searched first.
     448.IP "\fB\s-1LIBRARY_PATH\s0\fR" 4
     449.IX Item "LIBRARY_PATH"
     450A colon-separated list of directories searched for libraries for the
     451\&\fB\-l\fR option, directories given with \fB\-L\fR are searched first.
     452.SH "SEE ALSO"
     453.IX Header "SEE ALSO"
     454\&\fIcpp\fR\|(1),
     455\&\fIgcc\fR\|(1)
     456.SH "AUTHOR"
     457.IX Header "AUTHOR"
     458Fabrice Bellard
  • EcnlProtoTool/trunk/tcc-0.9.27/tcc.c

    r321 r331  
    1919 */
    2020
    21 #ifdef ONE_SOURCE
    22 #include "libtcc.c"
     21#include "tcc.h"
     22#if ONE_SOURCE
     23# include "libtcc.c"
     24#endif
     25#include "tcctools.c"
     26
     27static const char help[] =
     28    "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
     29    "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
     30    "       tcc [options...] -run infile [arguments...]\n"
     31    "General options:\n"
     32    "  -c          compile only - generate an object file\n"
     33    "  -o outfile  set output filename\n"
     34    "  -run        run compiled source\n"
     35    "  -fflag      set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
     36    "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
     37    "  -w          disable all warnings\n"
     38    "  -v -vv      show version, show search paths or loaded files\n"
     39    "  -h -hh      show this, show more help\n"
     40    "  -bench      show compilation statistics\n"
     41    "  -           use stdin pipe as infile\n"
     42    "  @listfile   read arguments from listfile\n"
     43    "Preprocessor options:\n"
     44    "  -Idir       add include path 'dir'\n"
     45    "  -Dsym[=val] define 'sym' with value 'val'\n"
     46    "  -Usym       undefine 'sym'\n"
     47    "  -E          preprocess only\n"
     48    "Linker options:\n"
     49    "  -Ldir       add library path 'dir'\n"
     50    "  -llib       link with dynamic or static library 'lib'\n"
     51    "  -r          generate (relocatable) object file\n"
     52    "  -shared     generate a shared library/dll\n"
     53    "  -rdynamic   export all global symbols to dynamic linker\n"
     54    "  -soname     set name for shared library to be used at runtime\n"
     55    "  -Wl,-opt[=val]  set linker option (see tcc -hh)\n"
     56    "Debugger options:\n"
     57    "  -g          generate runtime debug info\n"
     58#ifdef CONFIG_TCC_BCHECK
     59    "  -b          compile with built-in memory and bounds checker (implies -g)\n"
     60#endif
     61#ifdef CONFIG_TCC_BACKTRACE
     62    "  -bt N       show N callers in stack traces\n"
     63#endif
     64    "Misc. options:\n"
     65    "  -x[c|a|n]   specify type of the next infile\n"
     66    "  -nostdinc   do not use standard system include paths\n"
     67    "  -nostdlib   do not link with standard crt and libraries\n"
     68    "  -Bdir       set tcc's private include/library dir\n"
     69    "  -MD         generate dependency file for make\n"
     70    "  -MF file    specify dependency file name\n"
     71    "  -m32/64     defer to i386/x86_64 cross compiler\n"
     72    "Tools:\n"
     73    "  create library  : tcc -ar [rcsv] lib.a files\n"
     74#ifdef TCC_TARGET_PE
     75    "  create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
     76#endif
     77    ;
     78
     79static const char help2[] =
     80    "Tiny C Compiler "TCC_VERSION" - More Options\n"
     81    "Special options:\n"
     82    "  -P -P1                        with -E: no/alternative #line output\n"
     83    "  -dD -dM                       with -E: output #define directives\n"
     84    "  -pthread                      same as -D_REENTRANT and -lpthread\n"
     85    "  -On                           same as -D__OPTIMIZE__ for n > 0\n"
     86    "  -Wp,-opt                      same as -opt\n"
     87    "  -include file                 include 'file' above each input file\n"
     88    "  -isystem dir                  add 'dir' to system include path\n"
     89    "  -static                       link to static libraries (not recommended)\n"
     90    "  -dumpversion                  print version\n"
     91    "  -print-search-dirs            print search paths\n"
     92    "  -dt                           with -run/-E: auto-define 'test_...' macros\n"
     93    "Ignored options:\n"
     94    "  --param  -pedantic  -pipe  -s  -std  -traditional\n"
     95    "-W... warnings:\n"
     96    "  all                           turn on some (*) warnings\n"
     97    "  error                         stop after first warning\n"
     98    "  unsupported                   warn about ignored options, pragmas, etc.\n"
     99    "  write-strings                 strings are const\n"
     100    "  implicit-function-declaration warn for missing prototype (*)\n"
     101    "-f[no-]... flags:\n"
     102    "  unsigned-char                 default char is unsigned\n"
     103    "  signed-char                   default char is signed\n"
     104    "  common                        use common section instead of bss\n"
     105    "  leading-underscore            decorate extern symbols\n"
     106    "  ms-extensions                 allow anonymous struct in struct\n"
     107    "  dollars-in-identifiers        allow '$' in C symbols\n"
     108    "-m... target specific options:\n"
     109    "  ms-bitfields                  use MSVC bitfield layout\n"
     110#ifdef TCC_TARGET_ARM
     111    "  float-abi                     hard/softfp on arm\n"
     112#endif
     113#ifdef TCC_TARGET_X86_64
     114    "  no-sse                        disable floats on x86_64\n"
     115#endif
     116    "-Wl,... linker options:\n"
     117    "  -nostdlib                     do not link with standard crt/libs\n"
     118    "  -[no-]whole-archive           load lib(s) fully/only as needed\n"
     119    "  -export-all-symbols           same as -rdynamic\n"
     120    "  -image-base= -Ttext=          set base address of executable\n"
     121    "  -section-alignment=           set section alignment in executable\n"
     122#ifdef TCC_TARGET_PE
     123    "  -file-alignment=              set PE file alignment\n"
     124    "  -stack=                       set PE stack reserve\n"
     125    "  -large-address-aware          set related PE option\n"
     126    "  -subsystem=[console/windows]  set PE subsystem\n"
     127    "  -oformat=[pe-* binary]        set executable output format\n"
     128    "Predefined macros:\n"
     129    "  tcc -E -dM - < nul\n"
    23130#else
    24 #include "tcc.h"
    25 #endif
    26 
    27 static void help(void)
    28 {
    29     printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
    30            "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
    31            "       tcc [options...] -run infile [arguments...]\n"
    32            "General options:\n"
    33            "  -c          compile only - generate an object file\n"
    34            "  -o outfile  set output filename\n"
    35            "  -run        run compiled source\n"
    36            "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
    37            "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
    38            "  -w          disable all warnings\n"
    39            "  -v          show version\n"
    40            "  -vv         show included files (as sole argument: show search paths)\n"
    41            "  -dumpversion\n"
    42            "  -bench      show compilation statistics\n"
    43            "Preprocessor options:\n"
    44            "  -E          preprocess only\n"
    45            "  -Idir       add include path 'dir'\n"
    46            "  -Dsym[=val] define 'sym' with value 'val'\n"
    47            "  -Usym       undefine 'sym'\n"
    48            "Linker options:\n"
    49            "  -Ldir       add library path 'dir'\n"
    50            "  -llib       link with dynamic or static library 'lib'\n"
    51            "  -pthread    link with -lpthread and -D_REENTRANT (POSIX Linux)\n"
    52            "  -r          generate (relocatable) object file\n"
    53            "  -rdynamic   export all global symbols to dynamic linker\n"
    54            "  -shared     generate a shared library\n"
    55            "  -soname     set name for shared library to be used at runtime\n"
    56            "  -static     static linking\n"
    57            "  -Wl,-opt[=val]  set linker option (see manual)\n"
    58            "Debugger options:\n"
    59            "  -g          generate runtime debug info\n"
    60 #ifdef CONFIG_TCC_BCHECK
    61            "  -b          compile with built-in memory and bounds checker (implies -g)\n"
    62 #endif
    63 #ifdef CONFIG_TCC_BACKTRACE
    64            "  -bt N       show N callers in stack traces\n"
    65 #endif
    66            "Misc options:\n"
    67            "  -nostdinc   do not use standard system include paths\n"
    68            "  -nostdlib   do not link with standard crt and libraries\n"
    69            "  -Bdir       use 'dir' as tcc internal library and include path\n"
    70            "  -MD         generate target dependencies for make\n"
    71            "  -MF depfile put generated dependencies here\n"
    72            );
    73 }
    74 
    75 /* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */
    76 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    77 #ifdef _WIN32
    78 #include <process.h>
    79 static int execvp_win32(const char *prog, char **argv)
    80 {
    81     int ret = spawnvp(P_NOWAIT, prog, (char const*const*)argv);
    82     if (-1 == ret)
    83         return ret;
    84     cwait(&ret, ret, WAIT_CHILD);
    85     exit(ret);
    86 }
    87 #define execvp execvp_win32
    88 #endif
    89 static void exec_other_tcc(TCCState *s, char **argv, const char *optarg)
    90 {
    91     char child_path[4096], *child_name; const char *target;
    92     switch (atoi(optarg)) {
     131    "  -rpath=                       set dynamic library search path\n"
     132    "  -enable-new-dtags             set DT_RUNPATH instead of DT_RPATH\n"
     133    "  -soname=                      set DT_SONAME elf tag\n"
     134    "  -Bsymbolic                    set DT_SYMBOLIC elf tag\n"
     135    "  -oformat=[elf32/64-* binary]  set executable output format\n"
     136    "  -init= -fini= -as-needed -O   (ignored)\n"
     137    "Predefined macros:\n"
     138    "  tcc -E -dM - < /dev/null\n"
     139#endif
     140    "See also the manual for more details.\n"
     141    ;
     142
     143static const char version[] =
     144    "tcc version "TCC_VERSION" ("
    93145#ifdef TCC_TARGET_I386
    94         case 32: break;
    95         case 64: target = "x86_64";
     146        "i386"
     147#elif defined TCC_TARGET_X86_64
     148        "x86_64"
     149#elif defined TCC_TARGET_C67
     150        "C67"
     151#elif defined TCC_TARGET_ARM
     152        "ARM"
     153#elif defined TCC_TARGET_ARM64
     154        "AArch64"
     155#endif
     156#ifdef TCC_ARM_HARDFLOAT
     157        " Hard Float"
     158#endif
     159#ifdef TCC_TARGET_PE
     160        " Windows"
     161#elif defined(TCC_TARGET_MACHO)
     162        " Darwin"
     163#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     164        " FreeBSD"
    96165#else
    97         case 64: break;
    98         case 32: target = "i386";
    99 #endif
    100             pstrcpy(child_path, sizeof child_path - 40, argv[0]);
    101             child_name = tcc_basename(child_path);
    102             strcpy(child_name, target);
    103 #ifdef TCC_TARGET_PE
    104             strcat(child_name, "-win32");
    105 #endif
    106             strcat(child_name, "-tcc");
    107             if (strcmp(argv[0], child_path)) {
    108                 if (s->verbose > 0)
    109                     printf("tcc: using '%s'\n", child_name), fflush(stdout);
    110                 execvp(argv[0] = child_path, argv);
    111             }
    112             tcc_error("'%s' not found", child_name);
    113         case 0: /* ignore -march etc. */
    114             break;
    115         default:
    116             tcc_warning("unsupported option \"-m%s\"", optarg);
    117     }
    118 }
    119 #else
    120 #define exec_other_tcc(s, argv, optarg)
    121 #endif
    122 
    123 static void gen_makedeps(TCCState *s, const char *target, const char *filename)
    124 {
    125     FILE *depout;
    126     char buf[1024], *ext;
     166        " Linux"
     167#endif
     168    ")\n"
     169    ;
     170
     171static void print_dirs(const char *msg, char **paths, int nb_paths)
     172{
    127173    int i;
    128 
    129     if (!filename) {
    130         /* compute filename automatically
    131          * dir/file.o -> dir/file.d             */
    132         pstrcpy(buf, sizeof(buf), target);
    133         ext = tcc_fileextension(buf);
    134         pstrcpy(ext, sizeof(buf) - (ext-buf), ".d");
    135         filename = buf;
    136     }
    137 
    138     if (s->verbose)
    139         printf("<- %s\n", filename);
    140 
    141     /* XXX return err codes instead of error() ? */
    142     depout = fopen(filename, "w");
    143     if (!depout)
    144         tcc_error("could not open '%s'", filename);
    145 
    146     fprintf(depout, "%s : \\\n", target);
    147     for (i=0; i<s->nb_target_deps; ++i)
    148         fprintf(depout, " %s \\\n", s->target_deps[i]);
    149     fprintf(depout, "\n");
    150     fclose(depout);
     174    printf("%s:\n%s", msg, nb_paths ? "" : "  -\n");
     175    for(i = 0; i < nb_paths; i++)
     176        printf("  %s\n", paths[i]);
     177}
     178
     179static void print_search_dirs(TCCState *s)
     180{
     181    printf("install: %s\n", s->tcc_lib_path);
     182    /* print_dirs("programs", NULL, 0); */
     183    print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
     184    print_dirs("libraries", s->library_paths, s->nb_library_paths);
     185    printf("libtcc1:\n  %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
     186#ifndef TCC_TARGET_PE
     187    print_dirs("crt", s->crt_paths, s->nb_crt_paths);
     188    printf("elfinterp:\n  %s\n",  DEFAULT_ELFINTERP(s));
     189#endif
     190}
     191
     192static void set_environment(TCCState *s)
     193{
     194    char * path;
     195
     196    path = getenv("C_INCLUDE_PATH");
     197    if(path != NULL) {
     198        tcc_add_sysinclude_path(s, path);
     199    }
     200    path = getenv("CPATH");
     201    if(path != NULL) {
     202        tcc_add_include_path(s, path);
     203    }
     204    path = getenv("LIBRARY_PATH");
     205    if(path != NULL) {
     206        tcc_add_library_path(s, path);
     207    }
    151208}
    152209
     
    159216    if (first_file && strcmp(first_file, "-"))
    160217        name = tcc_basename(first_file);
    161     pstrcpy(buf, sizeof(buf), name);
     218    snprintf(buf, sizeof(buf), "%s", name);
    162219    ext = tcc_fileextension(buf);
    163220#ifdef TCC_TARGET_PE
     
    169226    else
    170227#endif
    171     if (( (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) ||
    172           (s->output_type == TCC_OUTPUT_PREPROCESS) )
    173         && *ext)
     228    if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
    174229        strcpy(ext, ".o");
    175230    else
    176231        strcpy(buf, "a.out");
    177 
    178232    return tcc_strdup(buf);
    179233}
    180234
    181 static void print_paths(const char *msg, char **paths, int nb_paths)
    182 {
    183     int i;
    184     printf("%s:\n%s", msg, nb_paths ? "" : "  -\n");
    185     for(i = 0; i < nb_paths; i++)
    186         printf("  %s\n", paths[i]);
    187 }
    188 
    189 static void display_info(TCCState *s, int what)
    190 {
    191     switch (what) {
    192     case 0:
    193         printf("tcc version %s ("
    194 #ifdef TCC_TARGET_I386
    195         "i386"
    196 # ifdef TCC_TARGET_PE
    197         " Win32"
    198 # endif
    199 #elif defined TCC_TARGET_X86_64
    200         "x86-64"
    201 # ifdef TCC_TARGET_PE
    202         " Win64"
    203 # endif
    204 #elif defined TCC_TARGET_ARM
    205         "ARM"
    206 # ifdef TCC_ARM_HARDFLOAT
    207         " Hard Float"
    208 # endif
    209 # ifdef TCC_TARGET_PE
    210         " WinCE"
    211 # endif
    212 #endif
    213 #ifndef TCC_TARGET_PE
    214 # ifdef __linux
    215         " Linux"
    216 # endif
    217 #endif
    218         ")\n", TCC_VERSION);
    219         break;
    220     case 1:
    221         printf("install: %s/\n", s->tcc_lib_path);
    222         /* print_paths("programs", NULL, 0); */
    223         print_paths("crt", s->crt_paths, s->nb_crt_paths);
    224         print_paths("libraries", s->library_paths, s->nb_library_paths);
    225         print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths);
    226         printf("elfinterp:\n  %s\n",  CONFIG_TCC_ELFINTERP);
    227         break;
    228     }
    229 }
    230 
    231 static int64_t getclock_us(void)
    232 {
    233 #if 0//def _WIN32
    234     struct _timeb tb;
    235     _ftime(&tb);
    236     return (tb.time * 1000LL + tb.millitm) * 1000LL;
     235static unsigned getclock_ms(void)
     236{
     237#ifdef _WIN32
     238    return GetTickCount();
    237239#else
    238240    struct timeval tv;
    239241    gettimeofday(&tv, NULL);
    240     return tv.tv_sec * 1000000LL + tv.tv_usec;
    241 #endif
    242 }
    243 
    244 int tcc_main(int argc, char **argv)
     242    return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
     243#endif
     244}
     245
     246int tcc_main(int argc0, char **argv0)
    245247{
    246248    TCCState *s;
    247     int ret, optind, i, bench;
    248     int64_t start_time = 0;
    249     const char *first_file = NULL;
    250 
     249    int ret, opt, n = 0, t = 0;
     250    unsigned start_time = 0;
     251    const char *first_file;
     252    int argc; char **argv;
     253    FILE *ppfp = stdout;
     254
     255redo:
     256    argc = argc0, argv = argv0;
    251257    s = tcc_new();
    252     s->output_type = TCC_OUTPUT_EXE;
    253 
    254     optind = tcc_parse_args(s, argc - 1, argv + 1);
    255 
    256     if (optind == 0) {
    257         help();
    258         return 1;
    259     }
    260 
    261     if (s->option_m)
    262         exec_other_tcc(s, argv, s->option_m);
    263 
    264     if (s->verbose)
    265         display_info(s, 0);
    266 
    267     if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) {
    268         tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
    269         display_info(s, 1);
    270         return 0;
    271     }
    272 
    273     if (s->verbose && optind == 1)
    274         return 0;
    275 
    276     if (s->nb_files == 0)
    277         tcc_error("no input files\n");
    278 
    279     /* check -c consistency : only single file handled. XXX: checks file type */
    280     if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
    281         if (s->nb_libraries != 0)
    282             tcc_error("cannot specify libraries with -c");
    283         /* accepts only a single input file */
    284         if (s->nb_files != 1)
    285             tcc_error("cannot specify multiple files with -c");
    286     }
    287    
    288     if (s->output_type == TCC_OUTPUT_PREPROCESS) {
    289         if (!s->outfile) {
    290             s->ppfp = stdout;
     258    opt = tcc_parse_args(s, &argc, &argv, 1);
     259
     260    if ((n | t) == 0) {
     261        if (opt == OPT_HELP)
     262            return printf(help), 1;
     263        if (opt == OPT_HELP2)
     264            return printf(help2), 1;
     265        if (opt == OPT_M32 || opt == OPT_M64)
     266            tcc_tool_cross(s, argv, opt); /* never returns */
     267        if (s->verbose)
     268            printf(version);
     269        if (opt == OPT_AR)
     270            return tcc_tool_ar(s, argc, argv);
     271#ifdef TCC_TARGET_PE
     272        if (opt == OPT_IMPDEF)
     273            return tcc_tool_impdef(s, argc, argv);
     274#endif
     275        if (opt == OPT_V)
     276            return 0;
     277        if (opt == OPT_PRINT_DIRS) {
     278            /* initialize search dirs */
     279            set_environment(s);
     280            tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
     281            print_search_dirs(s);
     282            return 0;
     283        }
     284
     285        n = s->nb_files;
     286        if (n == 0)
     287            tcc_error("no input files\n");
     288
     289        if (s->output_type == TCC_OUTPUT_PREPROCESS) {
     290            if (s->outfile) {
     291                ppfp = fopen(s->outfile, "w");
     292                if (!ppfp)
     293                    tcc_error("could not write '%s'", s->outfile);
     294            }
     295        } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
     296            if (s->nb_libraries)
     297                tcc_error("cannot specify libraries with -c");
     298            if (n > 1 && s->outfile)
     299                tcc_error("cannot specify output file with -c many files");
    291300        } else {
    292             s->ppfp = fopen(s->outfile, "w");
    293             if (!s->ppfp)
    294                 tcc_error("could not write '%s'", s->outfile);
     301            if (s->option_pthread)
     302                tcc_set_options(s, "-lpthread");
    295303        }
    296     }
    297 
    298     bench = s->do_bench;
    299     if (bench)
    300         start_time = getclock_us();
    301 
     304
     305        if (s->do_bench)
     306            start_time = getclock_ms();
     307    }
     308
     309    set_environment(s);
     310    if (s->output_type == 0)
     311        s->output_type = TCC_OUTPUT_EXE;
    302312    tcc_set_output_type(s, s->output_type);
     313    s->ppfp = ppfp;
     314
     315    if ((s->output_type == TCC_OUTPUT_MEMORY
     316      || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
     317        s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
    303318
    304319    /* compile or add each files or library */
    305     for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
    306         const char *filename;
    307 
    308         filename = s->files[i];
    309         if (filename[0] == '-' && filename[1] == 'l') {
    310             if (tcc_add_library(s, filename + 2) < 0) {
    311                 tcc_error_noabort("cannot find '%s'", filename);
     320    for (first_file = NULL, ret = 0;;) {
     321        struct filespec *f = s->files[s->nb_files - n];
     322        s->filetype = f->type;
     323        s->alacarte_link = f->alacarte;
     324        if (f->type == AFF_TYPE_LIB) {
     325            if (tcc_add_library_err(s, f->name) < 0)
    312326                ret = 1;
    313             }
    314327        } else {
    315328            if (1 == s->verbose)
    316                 printf("-> %s\n", filename);
    317             if (tcc_add_file(s, filename) < 0)
     329                printf("-> %s\n", f->name);
     330            if (!first_file)
     331                first_file = f->name;
     332            if (tcc_add_file(s, f->name) < 0)
    318333                ret = 1;
    319             if (!first_file)
    320                 first_file = filename;
    321334        }
    322     }
    323 
    324     if (0 == ret) {
    325         if (bench)
    326             tcc_print_stats(s, getclock_us() - start_time);
    327 
     335        s->filetype = 0;
     336        s->alacarte_link = 1;
     337        if (--n == 0 || ret
     338            || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
     339            break;
     340    }
     341
     342    if (s->run_test) {
     343        t = 0;
     344    } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
     345        ;
     346    } else if (0 == ret) {
    328347        if (s->output_type == TCC_OUTPUT_MEMORY) {
    329348#ifdef TCC_IS_NATIVE
    330             ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind);
    331 #else
    332             tcc_error_noabort("-run is not available in a cross compiler");
    333             ret = 1;
    334 #endif
    335         } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
    336              if (s->outfile)
    337                 fclose(s->ppfp);
     349            ret = tcc_run(s, argc, argv);
     350#endif
    338351        } else {
    339352            if (!s->outfile)
    340353                s->outfile = default_outputfile(s, first_file);
    341             ret = !!tcc_output_file(s, s->outfile);
    342             /* dump collected dependencies */
    343             if (s->gen_deps && !ret)
     354            if (tcc_output_file(s, s->outfile))
     355                ret = 1;
     356            else if (s->gen_deps)
    344357                gen_makedeps(s, s->outfile, s->deps_outfile);
    345358        }
    346359    }
    347360
     361    if (s->do_bench && (n | t | ret) == 0)
     362        tcc_print_stats(s, getclock_ms() - start_time);
    348363    tcc_delete(s);
    349     if (bench)
    350         tcc_memstats();
     364    if (ret == 0 && n)
     365        goto redo; /* compile more files with -c */
     366    if (t)
     367        goto redo; /* run more tests with -dt -run */
     368    if (ppfp && ppfp != stdout)
     369        fclose(ppfp);
    351370    return ret;
    352371}
  • EcnlProtoTool/trunk/tcc-0.9.27/tcc.h

    r321 r331  
    11/*
    22 *  TCC - Tiny C Compiler
    3  * 
     3 *
    44 *  Copyright (c) 2001-2004 Fabrice Bellard
    55 *
     
    2525#include "config.h"
    2626
    27 #ifdef CONFIG_TCCBOOT
    28 #include "tccboot.h"
    29 #define CONFIG_TCC_STATIC
    30 #else
    31 
    3227#include <stdlib.h>
    3328#include <stdio.h>
     
    3631#include <errno.h>
    3732#include <math.h>
    38 #include <signal.h>
    39 #define SA_RESETHAND  0x80000000
    40 #define FPE_INTDIV 1
    41 #define FPE_FLTDIV 3
    42 typedef struct { int si_signo, si_errno, si_code; } siginfo_t;
    4333#include <fcntl.h>
    4434#include <setjmp.h>
     
    4838# include <unistd.h>
    4939# include <sys/time.h>
    50 /*# include <sys/ucontext.h>*/
    51 typedef struct __ucontext ucontext_t;
    52 /*# include <sys/mman.h>*/
    53 #define PROT_READ      1
    54 #define PROT_WRITE     2
    55 #define PROT_EXEC      4
    5640# ifndef CONFIG_TCC_STATIC
    5741#  include <dlfcn.h>
    5842# endif
    59 #else
    60 # include <unistd.h>
    61 # include <sys/time.h>
    62 # include <sys/ucontext.h>
    63 # include <sys/mman.h>
     43/* XXX: need to define this to use them in non ISOC99 context */
     44extern float strtof (const char *__nptr, char **__endptr);
     45extern long double strtold (const char *__nptr, char **__endptr);
     46#endif
     47
     48#ifdef _WIN32
     49# include <windows.h>
     50# include <io.h> /* open, close etc. */
     51# include <direct.h> /* getcwd */
     52# ifdef __GNUC__
    6453#  include <stdint.h>
     54# endif
    6555# define inline __inline
    66 # define inp next_inp
     56# define snprintf _snprintf
     57# define vsnprintf _vsnprintf
     58# ifndef __GNUC__
     59#  define strtold (long double)strtod
     60#  define strtof (float)strtod
     61#  define strtoll _strtoi64
     62#  define strtoull _strtoui64
     63# endif
    6764# ifdef LIBTCC_AS_DLL
    6865#  define LIBTCCAPI __declspec(dllexport)
    6966#  define PUB_FUNC LIBTCCAPI
    7067# endif
    71 #endif
    72 
    73 #endif /* !CONFIG_TCCBOOT */
     68# define inp next_inp /* inp is an intrinsic on msvc/mingw */
     69# ifdef _MSC_VER
     70#  pragma warning (disable : 4244)  // conversion from 'uint64_t' to 'int', possible loss of data
     71#  pragma warning (disable : 4267)  // conversion from 'size_t' to 'int', possible loss of data
     72#  pragma warning (disable : 4996)  // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
     73#  pragma warning (disable : 4018)  // signed/unsigned mismatch
     74#  pragma warning (disable : 4146)  // unary minus operator applied to unsigned type, result still unsigned
     75#  define ssize_t intptr_t
     76# endif
     77# undef CONFIG_TCC_STATIC
     78#endif
    7479
    7580#ifndef O_BINARY
     
    7782#endif
    7883
    79 #include "elf.h"
    80 #ifdef TCC_TARGET_X86_64
    81 # define ELFCLASSW ELFCLASS64
    82 # define ElfW(type) Elf##64##_##type
    83 # define ELFW(type) ELF##64##_##type
    84 # define ElfW_Rel ElfW(Rela)
    85 # define SHT_RELX SHT_RELA
    86 # define REL_SECTION_FMT ".rela%s"
    87 /* XXX: DLL with PLT would only work with x86-64 for now */
    88 # define TCC_OUTPUT_DLL_WITH_PLT
     84#ifndef offsetof
     85#define offsetof(type, field) ((size_t) &((type *)0)->field)
     86#endif
     87
     88#ifndef countof
     89#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
     90#endif
     91
     92#ifdef _MSC_VER
     93# define NORETURN __declspec(noreturn)
     94# define ALIGNED(x) __declspec(align(x))
    8995#else
    90 # define ELFCLASSW ELFCLASS32
    91 # define ElfW(type) Elf##32##_##type
    92 # define ELFW(type) ELF##32##_##type
    93 # define ElfW_Rel ElfW(Rel)
    94 # define SHT_RELX SHT_REL
    95 # define REL_SECTION_FMT ".rel%s"
    96 #endif
    97 
    98 /* target address type */
    99 #define addr_t ElfW(Addr)
    100 
    101 #include "stab.h"
    102 #include "libtcc.h"
     96# define NORETURN __attribute__((noreturn))
     97# define ALIGNED(x) __attribute__((aligned(x)))
     98#endif
     99
     100#ifdef _WIN32
     101# define IS_DIRSEP(c) (c == '/' || c == '\\')
     102# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
     103# define PATHCMP stricmp
     104# define PATHSEP ";"
     105#else
     106# define IS_DIRSEP(c) (c == '/')
     107# define IS_ABSPATH(p) IS_DIRSEP(p[0])
     108# define PATHCMP strcmp
     109# define PATHSEP ":"
     110#endif
     111
     112/* -------------------------------------------- */
    103113
    104114/* parser debug */
    105 //#define PARSE_DEBUG
     115/* #define PARSE_DEBUG */
    106116/* preprocessor debug */
    107 //#define PP_DEBUG
     117/* #define PP_DEBUG */
    108118/* include file debug */
    109 //#define INC_DEBUG
     119/* #define INC_DEBUG */
    110120/* memory leak debug */
    111 //#define MEM_DEBUG
     121/* #define MEM_DEBUG */
    112122/* assembler debug */
    113 //#define ASM_DEBUG
     123/* #define ASM_DEBUG */
    114124
    115125/* target selection */
    116 //#define TCC_TARGET_I386   /* i386 code generator */
    117 //#define TCC_TARGET_ARM    /* ARMv4 code generator */
    118 //#define TCC_TARGET_C67    /* TMS320C67xx code generator */
    119 //#define TCC_TARGET_X86_64 /* x86-64 code generator */
    120 //#define TCC_TARGET_IL   /* IL code generator */
     126/* #define TCC_TARGET_I386   *//* i386 code generator */
     127/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */
     128/* #define TCC_TARGET_ARM    *//* ARMv4 code generator */
     129/* #define TCC_TARGET_ARM64  *//* ARMv8 code generator */
     130/* #define TCC_TARGET_C67    *//* TMS320C67xx code generator */
    121131
    122132/* default target is I386 */
    123133#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
    124     !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) && \
    125     !defined(TCC_TARGET_IL)
    126 #define TCC_TARGET_I386
    127 #endif
    128 
    129 #if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
    130     !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
    131 #define CONFIG_TCC_BCHECK /* enable bound checking code */
    132 #endif
    133 
    134 /* define it to include assembler support */
    135 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
    136 #define CONFIG_TCC_ASM
    137 #endif
    138 
    139 /* object format selection */
    140 #if defined(TCC_TARGET_C67)
    141 #define TCC_TARGET_COFF
     134    !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \
     135    !defined(TCC_TARGET_X86_64)
     136# if defined __x86_64__ || defined _AMD64_
     137#  define TCC_TARGET_X86_64
     138# elif defined __arm__
     139#  define TCC_TARGET_ARM
     140#  define TCC_ARM_EABI
     141#  define TCC_ARM_HARDFLOAT
     142# elif defined __aarch64__
     143#  define TCC_TARGET_ARM64
     144# else
     145#  define TCC_TARGET_I386
     146# endif
     147# ifdef _WIN32
     148#  define TCC_TARGET_PE 1
     149# endif
    142150#endif
    143151
     
    150158# elif defined __arm__ && defined TCC_TARGET_ARM
    151159#  define TCC_IS_NATIVE
     160# elif defined __aarch64__ && defined TCC_TARGET_ARM64
     161#  define TCC_IS_NATIVE
    152162# endif
    153163#endif
     
    155165#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT
    156166# define CONFIG_TCC_BACKTRACE
     167# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) \
     168  && !defined TCC_UCLIBC && !defined TCC_MUSL
     169# define CONFIG_TCC_BCHECK /* enable bound checking code */
     170# endif
    157171#endif
    158172
     
    163177#endif
    164178#ifndef CONFIG_TCCDIR
    165 # define CONFIG_TCCDIR "."
     179# define CONFIG_TCCDIR "/usr/local/lib/tcc"
    166180#endif
    167181#ifndef CONFIG_LDDIR
    168182# define CONFIG_LDDIR "lib"
    169183#endif
     184#ifdef CONFIG_TRIPLET
     185# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET
     186# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s
     187#else
     188# define USE_TRIPLET(s) s
     189# define ALSO_TRIPLET(s) s
     190#endif
    170191
    171192/* path to find crt1.o, crti.o and crtn.o */
    172193#ifndef CONFIG_TCC_CRTPREFIX
    173 # define CONFIG_TCC_CRTPREFIX CONFIG_SYSROOT "/usr/" CONFIG_LDDIR
     194# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
    174195#endif
    175196
     
    179200#ifndef CONFIG_TCC_SYSINCLUDEPATHS
    180201# ifdef TCC_TARGET_PE
    181 #  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include;{B}/include/winapi"
    182 # elif defined CONFIG_MULTIARCHDIR
    183 #  define CONFIG_TCC_SYSINCLUDEPATHS \
    184         CONFIG_SYSROOT "/usr/local/include" \
    185     ":" CONFIG_SYSROOT "/usr/local/include/" CONFIG_MULTIARCHDIR \
    186     ":" CONFIG_SYSROOT "/usr/include" \
    187     ":" CONFIG_SYSROOT "/usr/include/" CONFIG_MULTIARCHDIR \
    188     ":" "{B}/include"
     202#  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
    189203# else
    190204#  define CONFIG_TCC_SYSINCLUDEPATHS \
    191         CONFIG_SYSROOT "/usr/local/include" \
    192     ":" CONFIG_SYSROOT "/usr/include" \
    193     ":" "{B}/include"
     205        "{B}/include" \
     206    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
     207    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
    194208# endif
    195209#endif
     
    201215# else
    202216#  define CONFIG_TCC_LIBPATHS \
    203         CONFIG_SYSROOT "/usr/" CONFIG_LDDIR \
    204     ":" CONFIG_SYSROOT "/" CONFIG_LDDIR \
    205     ":" CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR
     217        ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
     218    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
     219    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
    206220# endif
    207221#endif
     
    212226#  define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"
    213227# elif defined __FreeBSD_kernel__
    214 #  define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
    215 # elif defined TCC_ARM_HARDFLOAT
    216 #  define CONFIG_TCC_ELFINTERP "/lib/ld-linux-armhf.so.3"
    217 # elif defined TCC_ARM_EABI
    218 #  define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.3"
    219 # elif defined(TCC_TARGET_X86_64)
    220 #  define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
    221 # elif defined(TCC_UCLIBC)
    222 #  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0"
     228#  if defined(TCC_TARGET_X86_64)
     229#   define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"
     230#  else
     231#   define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
     232#  endif
     233# elif defined __DragonFly__
     234#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
     235# elif defined __NetBSD__
     236#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"
     237# elif defined __GNU__
     238#  define CONFIG_TCC_ELFINTERP "/lib/ld.so"
    223239# elif defined(TCC_TARGET_PE)
    224240#  define CONFIG_TCC_ELFINTERP "-"
    225 # else
    226 #  define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
     241# elif defined(TCC_UCLIBC)
     242#  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */
     243# elif defined TCC_TARGET_ARM64
     244#  if defined(TCC_MUSL)
     245#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"
     246#  else
     247#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
     248#  endif
     249# elif defined(TCC_TARGET_X86_64)
     250#  if defined(TCC_MUSL)
     251#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
     252#  else
     253#   define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
     254#  endif
     255# elif !defined(TCC_ARM_EABI)
     256#  if defined(TCC_MUSL)
     257#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
     258#  else
     259#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
     260#  endif
    227261# endif
    228262#endif
    229263
     264/* var elf_interp dans *-gen.c */
     265#ifdef CONFIG_TCC_ELFINTERP
     266# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
     267#else
     268# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
     269#endif
     270
     271/* (target specific) libtcc1.a */
     272#ifndef TCC_LIBTCC1
     273# define TCC_LIBTCC1 "libtcc1.a"
     274#endif
     275
    230276/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
    231 #define TCC_LIBGCC CONFIG_SYSROOT "/" CONFIG_LDDIR "/libgcc_s.so.1"
     277#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
     278#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
     279#endif
     280
     281/* -------------------------------------------- */
     282
     283#include "libtcc.h"
     284#include "elf.h"
     285#include "stab.h"
     286
     287/* -------------------------------------------- */
     288
     289#ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */
     290# define PUB_FUNC
     291#endif
     292
     293#ifndef ONE_SOURCE
     294# define ONE_SOURCE 1
     295#endif
     296
     297#if ONE_SOURCE
     298#define ST_INLN static inline
     299#define ST_FUNC static
     300#define ST_DATA static
     301#else
     302#define ST_INLN
     303#define ST_FUNC
     304#define ST_DATA extern
     305#endif
     306
     307#ifdef TCC_PROFILE /* profile all functions */
     308# define static
     309#endif
    232310
    233311/* -------------------------------------------- */
     
    237315#ifdef TCC_TARGET_I386
    238316# include "i386-gen.c"
     317# include "i386-link.c"
    239318#endif
    240319#ifdef TCC_TARGET_X86_64
    241320# include "x86_64-gen.c"
     321# include "x86_64-link.c"
    242322#endif
    243323#ifdef TCC_TARGET_ARM
    244324# include "arm-gen.c"
     325# include "arm-link.c"
     326# include "arm-asm.c"
     327#endif
     328#ifdef TCC_TARGET_ARM64
     329# include "arm64-gen.c"
     330# include "arm64-link.c"
    245331#endif
    246332#ifdef TCC_TARGET_C67
     333# define TCC_TARGET_COFF
    247334# include "coff.h"
    248335# include "c67-gen.c"
    249 #endif
    250 #ifdef TCC_TARGET_IL
    251 #include "il-gen.c"
     336# include "c67-link.c"
    252337#endif
    253338#undef TARGET_DEFS_ONLY
     339
     340/* -------------------------------------------- */
     341
     342#if PTR_SIZE == 8
     343# define ELFCLASSW ELFCLASS64
     344# define ElfW(type) Elf##64##_##type
     345# define ELFW(type) ELF##64##_##type
     346# define ElfW_Rel ElfW(Rela)
     347# define SHT_RELX SHT_RELA
     348# define REL_SECTION_FMT ".rela%s"
     349#else
     350# define ELFCLASSW ELFCLASS32
     351# define ElfW(type) Elf##32##_##type
     352# define ELFW(type) ELF##32##_##type
     353# define ElfW_Rel ElfW(Rel)
     354# define SHT_RELX SHT_REL
     355# define REL_SECTION_FMT ".rel%s"
     356#endif
     357/* target address type */
     358#define addr_t ElfW(Addr)
     359#define ElfSym ElfW(Sym)
     360
     361#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
     362# define LONG_SIZE 8
     363#else
     364# define LONG_SIZE 4
     365#endif
    254366
    255367/* -------------------------------------------- */
     
    259371#define VSTACK_SIZE         256
    260372#define STRING_MAX_SIZE     1024
     373#define TOKSTR_MAX_SIZE     256
    261374#define PACK_STACK_SIZE     8
    262375
    263 #define TOK_HASH_SIZE       8192 /* must be a power of two */
     376#define TOK_HASH_SIZE       16384 /* must be a power of two */
    264377#define TOK_ALLOC_INCR      512  /* must be a power of two */
    265378#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
     
    287400    void *data; /* either 'char *' or 'nwchar_t *' */
    288401    int size_allocated;
    289     void *data_allocated; /* if non NULL, data has been malloced */
    290402} CString;
    291403
     
    301413    double d;
    302414    float f;
    303     int i;
    304     unsigned int ui;
    305     unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
    306     long long ll;
    307     unsigned long long ull;
    308     struct CString *cstr;
    309     void *ptr;
     415    uint64_t i;
     416    struct {
     417        int size;
     418        const void *data;
     419    } str;
    310420    int tab[LDOUBLE_SIZE/4];
    311421} CValue;
     
    318428                              type. If not used, set to VT_CONST */
    319429    CValue c;              /* constant, if VT_CONST */
    320     struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
     430    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST), or if
     431                              result of unary() for an identifier. */
    321432} SValue;
     433
     434/* symbol attributes */
     435struct SymAttr {
     436    unsigned short
     437    aligned     : 5, /* alignment as log2+1 (0 == unspecified) */
     438    packed      : 1,
     439    weak        : 1,
     440    visibility  : 2,
     441    dllexport   : 1,
     442    dllimport   : 1,
     443    unused      : 5;
     444};
     445
     446/* function attributes or temporary attributes for parsing */
     447struct FuncAttr {
     448    unsigned
     449    func_call   : 3, /* calling convention (0..5), see below */
     450    func_type   : 2, /* FUNC_OLD/NEW/ELLIPSIS */
     451    func_args   : 8; /* PE __stdcall args */
     452};
     453
     454/* GNUC attribute definition */
     455typedef struct AttributeDef {
     456    struct SymAttr a;
     457    struct FuncAttr f;
     458    struct Section *section;
     459    int alias_target; /* token */
     460    int asm_label; /* associated asm label */
     461    char attr_mode; /* __attribute__((__mode__(...))) */
     462} AttributeDef;
    322463
    323464/* symbol management */
    324465typedef struct Sym {
    325     int v;    /* symbol token */
    326     char *asm_label;    /* associated asm label */
    327     long r;    /* associated register */
     466    int v; /* symbol token */
     467    unsigned short r; /* associated register or VT_CONST/VT_LOCAL and LVAL type */
     468    struct SymAttr a; /* symbol attributes */
    328469    union {
    329         long c;    /* associated number */
    330         int *d;   /* define token stream */
     470        struct {
     471            int c; /* associated number or Elf symbol index */
     472            union {
     473                int sym_scope; /* scope level for locals */
     474                int jnext; /* next jump label */
     475                struct FuncAttr f; /* function attributes */
     476                int auxtype; /* bitfield access type */
     477            };
     478        };
     479        long long enum_val; /* enum constant if IS_ENUM_VAL */
     480        int *d; /* define token stream */
    331481    };
    332     CType type;    /* associated type */
     482    CType type; /* associated type */
    333483    union {
    334         struct Sym *next; /* next related symbol */
    335         long jnext; /* next jump label */
     484        struct Sym *next; /* next related symbol (for fields and anoms) */
     485        int asm_label; /* associated asm label */
    336486    };
    337487    struct Sym *prev; /* prev symbol in stack */
     
    340490
    341491/* section definition */
    342 /* XXX: use directly ELF structure for parameters ? */
    343 /* special flag to indicate that the section should not be linked to
    344    the other ones */
    345 #define SHF_PRIVATE 0x80000000
    346 
    347 /* special flag, too */
    348 #define SECTION_ABS ((void *)1)
    349 
    350492typedef struct Section {
    351493    unsigned long data_offset; /* current data offset */
     
    365507    struct Section *link;    /* link to another section */
    366508    struct Section *reloc;   /* corresponding section for relocation, if any */
    367     struct Section *hash;     /* hash table for symbols */
    368     struct Section *next;
     509    struct Section *hash;    /* hash table for symbols */
     510    struct Section *prev;    /* previous section on section stack */
    369511    char name[1];           /* section name */
    370512} Section;
     
    376518} DLLReference;
    377519
    378 /* GNUC attribute definition */
    379 typedef struct AttributeDef {
    380     unsigned
    381       func_call     : 3, /* calling convention (0..5), see below */
    382       aligned       : 5, /* alignement (0..16) */
    383       packed        : 1,
    384       func_export   : 1,
    385       func_import   : 1,
    386       func_args     : 5,
    387       mode          : 4,
    388       weak          : 1,
    389       fill          : 11;
    390     struct Section *section;
    391     int alias_target;    /* token */
    392 } AttributeDef;
    393 
    394 /* gr: wrappers for casting sym->r for other purposes */
    395 #define FUNC_CALL(r) (((AttributeDef*)&(r))->func_call)
    396 #define FUNC_EXPORT(r) (((AttributeDef*)&(r))->func_export)
    397 #define FUNC_IMPORT(r) (((AttributeDef*)&(r))->func_import)
    398 #define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
    399 #define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
    400 #define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
    401 #define ATTR_MODE(r)  (((AttributeDef*)&(r))->mode)
    402 #define INT_ATTR(ad) (*(int*)(ad))
    403 
    404520/* -------------------------------------------------- */
    405521
     
    408524#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
    409525
    410 /* stored in 'Sym.c' field */
     526/* stored in 'Sym->f.func_type' field */
    411527#define FUNC_NEW       1 /* ansi function prototype */
    412528#define FUNC_OLD       2 /* old function prototype */
    413529#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
    414530
    415 /* stored in 'Sym.r' field */
     531/* stored in 'Sym->f.func_call' field */
    416532#define FUNC_CDECL     0 /* standard c call */
    417533#define FUNC_STDCALL   1 /* pascal c call */
     
    442558    struct BufferedFile *prev;
    443559    int line_num;    /* current line number - here to simplify code */
     560    int line_ref;    /* tcc -E: last printed line */
    444561    int ifndef_macro;  /* #ifndef macro / #endif search */
    445562    int ifndef_macro_saved; /* saved ifndef_macro */
    446563    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
     564    int include_next_index; /* next search path */
    447565    char filename[1024];    /* filename */
    448     unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
     566    char *true_filename; /* filename not modified by # line directive */
     567    unsigned char unget[4];
     568    unsigned char buffer[1]; /* extra size for CH_EOB char */
    449569} BufferedFile;
    450570
    451571#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
    452572#define CH_EOF   (-1)   /* end of file */
    453 
    454 /* parsing state (used to save parser state to reparse part of the
    455    source several times) */
    456 typedef struct ParseState {
    457     const int *macro_ptr;
    458     int line_num;
    459     int tok;
    460     CValue tokc;
    461 } ParseState;
    462573
    463574/* used to record tokens */
     
    465576    int *str;
    466577    int len;
     578    int lastlen;
    467579    int allocated_len;
    468580    int last_line_num;
     581    int save_line_num;
     582    /* used to chain token-strings with begin/end_macro() */
     583    struct TokenString *prev;
     584    const int *prev_ptr;
     585    char alloc;
    469586} TokenString;
    470587
    471588/* inline functions */
    472589typedef struct InlineFunc {
    473     int *token_str;
     590    TokenString *func_str;
    474591    Sym *sym;
    475592    char filename[1];
     
    480597typedef struct CachedInclude {
    481598    int ifndef_macro;
     599    int once;
    482600    int hash_next; /* -1 if none */
    483601    char filename[1]; /* path specified in #include */
    484602} CachedInclude;
    485603
    486 #define CACHED_INCLUDES_HASH_SIZE 512
     604#define CACHED_INCLUDES_HASH_SIZE 32
    487605
    488606#ifdef CONFIG_TCC_ASM
    489607typedef struct ExprValue {
    490     uint32_t v;
     608    uint64_t v;
    491609    Sym *sym;
     610    int pcrel;
    492611} ExprValue;
    493612
    494613#define MAX_ASM_OPERANDS 30
    495614typedef struct ASMOperand {
    496     int id; /* GCC 3 optionnal identifier (0 if number only supported */
     615    int id; /* GCC 3 optional identifier (0 if number only supported */
    497616    char *constraint;
    498617    char asm_str[16]; /* computed asm string for operand */
     
    508627#endif
    509628
     629/* extra symbol attributes (not in symbol table) */
    510630struct sym_attr {
    511     unsigned long got_offset;
     631    unsigned got_offset;
     632    unsigned plt_offset;
     633    int plt_sym;
     634    int dyn_index;
    512635#ifdef TCC_TARGET_ARM
    513636    unsigned char plt_thumb_stub:1;
     
    529652    char *soname; /* as specified on the command line (-soname) */
    530653    char *rpath; /* as specified on the command line (-Wl,-rpath=) */
     654    int enable_new_dtags; /* ditto, (-Wl,--enable-new-dtags) */
    531655
    532656    /* output type, see TCC_OUTPUT_XXX */
     
    538662    int char_is_unsigned;
    539663    int leading_underscore;
    540    
     664    int ms_extensions;  /* allow nested named struct w/o identifier behave like unnamed */
     665    int dollars_in_identifiers; /* allows '$' char in identifiers */
     666    int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
     667
    541668    /* warning switches */
    542669    int warn_write_strings;
     
    545672    int warn_none;
    546673    int warn_implicit_function_declaration;
     674    int warn_gcc_compat;
    547675
    548676    /* compile with debug symbol (and use them if error during execution) */
     
    552680    int do_bounds_check;
    553681#endif
     682#ifdef TCC_TARGET_ARM
     683    enum float_abi float_abi; /* float ABI of the generated code*/
     684#endif
     685    int run_test; /* nth test to run with -dt -run */
    554686
    555687    addr_t text_addr; /* address of text section */
    556688    int has_text_addr;
    557689
    558     unsigned long section_align; /* section alignment */
     690    unsigned section_align; /* section alignment */
    559691
    560692    char *init_symbol; /* symbols to call at load-time (not used currently) */
    561693    char *fini_symbol; /* symbols to call at unload-time (not used currently) */
    562    
     694
    563695#ifdef TCC_TARGET_I386
    564696    int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
     697#endif
     698#ifdef TCC_TARGET_X86_64
     699    int nosse; /* For -mno-sse support. */
    565700#endif
    566701
     
    583718    char **crt_paths;
    584719    int nb_crt_paths;
     720
     721    /* -include files */
     722    char **cmd_include_files;
     723    int nb_cmd_include_files;
    585724
    586725    /* error handling */
     
    593732    /* output file for preprocessing (-E) */
    594733    FILE *ppfp;
     734    enum {
     735        LINE_MACRO_OUTPUT_FORMAT_GCC,
     736        LINE_MACRO_OUTPUT_FORMAT_NONE,
     737        LINE_MACRO_OUTPUT_FORMAT_STD,
     738    LINE_MACRO_OUTPUT_FORMAT_P10 = 11
     739    } Pflag; /* -P switch */
     740    char dflag; /* -dX value */
    595741
    596742    /* for -MD/-MF: collected dependencies for this compilation */
     
    613759    int pack_stack[PACK_STACK_SIZE];
    614760    int *pack_stack_ptr;
     761    char **pragma_libs;
     762    int nb_pragma_libs;
    615763
    616764    /* inline functions are stored as token lists and compiled last
     
    629777    Section *got;
    630778    Section *plt;
    631     struct sym_attr *sym_attrs;
    632     int nb_sym_attrs;
    633     /* give the correspondance from symtab indexes to dynsym indexes */
    634     int *symtab_to_dynsym;
    635779
    636780    /* temporary dynamic symbol sections (for dll loading) */
     
    638782    /* exported dynamic symbol section */
    639783    Section *dynsym;
    640     /* copy of the gobal symtab_section variable */
     784    /* copy of the global symtab_section variable */
    641785    Section *symtab;
    642     /* tiny assembler state */
    643     Sym *asm_labels;
     786    /* extra attributes (eg. GOT/PLT value) for symtab symbols */
     787    struct sym_attr *sym_attrs;
     788    int nb_sym_attrs;
    644789
    645790#ifdef TCC_TARGET_PE
    646791    /* PE info */
    647792    int pe_subsystem;
     793    unsigned pe_characteristics;
    648794    unsigned pe_file_align;
    649795    unsigned pe_stack_size;
     796    addr_t pe_imagebase;
    650797# ifdef TCC_TARGET_X86_64
    651798    Section *uw_pdata;
     
    656803
    657804#ifdef TCC_IS_NATIVE
    658     /* for tcc_relocate */
    659     void *runtime_mem;
    660 # ifdef HAVE_SELINUX
    661     void *write_mem;
    662     unsigned long mem_size;
    663 # endif
    664 # if !defined TCC_TARGET_PE && (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM)
    665     /* write PLT and GOT here */
    666     char *runtime_plt_and_got;
    667     unsigned runtime_plt_and_got_offset;
    668 #  define TCC_HAS_RUNTIME_PLTGOT
    669 # endif
     805    const char *runtime_main;
     806    void **runtime_mem;
     807    int nb_runtime_mem;
    670808#endif
    671809
    672810    /* used by main and tcc_parse_args only */
    673     char **files; /* files seen on command line */
     811    struct filespec **files; /* files seen on command line */
    674812    int nb_files; /* number thereof */
    675813    int nb_libraries; /* number of libs thereof */
     814    int filetype;
    676815    char *outfile; /* output filename */
    677     char *option_m; /* only -m32/-m64 handled */
    678     int print_search_dirs; /* option */
    679816    int option_r; /* option -r */
    680817    int do_bench; /* option -bench */
    681818    int gen_deps; /* option -MD  */
    682819    char *deps_outfile; /* option -MF */
     820    int option_pthread; /* -pthread option */
     821    int argc;
     822    char **argv;
     823};
     824
     825struct filespec {
     826    char type;
     827    char alacarte;
     828    char name[1];
    683829};
    684830
     
    691837#define VT_JMP       0x0034  /* value is the consequence of jmp true (even) */
    692838#define VT_JMPI      0x0035  /* value is the consequence of jmp false (odd) */
    693 #define VT_REF       0x0040  /* value is pointer to structure rather than address */
    694839#define VT_LVAL      0x0100  /* var is an lvalue */
    695840#define VT_SYM       0x0200  /* a symbol value is added */
     
    707852/* types */
    708853#define VT_BTYPE       0x000f  /* mask for basic type */
    709 #define VT_INT              0  /* integer type */
     854#define VT_VOID             0  /* void type */
    710855#define VT_BYTE             1  /* signed byte type */
    711856#define VT_SHORT            2  /* short type */
    712 #define VT_VOID             3  /* void type */
    713 #define VT_PTR              4  /* pointer */
    714 #define VT_ENUM             5  /* enum definition */
     857#define VT_INT              3  /* integer type */
     858#define VT_LLONG            4  /* 64 bit integer */
     859#define VT_PTR              5  /* pointer */
    715860#define VT_FUNC             6  /* function type */
    716861#define VT_STRUCT           7  /* struct/union definition */
     
    719864#define VT_LDOUBLE         10  /* IEEE long double */
    720865#define VT_BOOL            11  /* ISOC99 boolean type */
    721 #define VT_LLONG           12  /* 64 bit integer */
    722 #define VT_LONG            13  /* long integer (NEVER USED as type, only
    723                                   during parsing) */
     866#define VT_QLONG           13  /* 128-bit integer. Only used for x86-64 ABI */
     867#define VT_QFLOAT          14  /* 128-bit float. Only used for x86-64 ABI */
     868
    724869#define VT_UNSIGNED    0x0010  /* unsigned type */
    725 #define VT_ARRAY       0x0020  /* array type (also has VT_PTR) */
    726 #define VT_BITFIELD    0x0040  /* bitfield modifier */
    727 #define VT_CONSTANT    0x0800  /* const modifier */
    728 #define VT_VOLATILE    0x1000  /* volatile modifier */
    729 #define VT_SIGNED      0x2000  /* signed type */
    730 #define VT_VLA     0x00020000  /* VLA type (also has VT_PTR and VT_ARRAY) */
     870#define VT_DEFSIGN     0x0020  /* explicitly signed or unsigned */
     871#define VT_ARRAY       0x0040  /* array type (also has VT_PTR) */
     872#define VT_BITFIELD    0x0080  /* bitfield modifier */
     873#define VT_CONSTANT    0x0100  /* const modifier */
     874#define VT_VOLATILE    0x0200  /* volatile modifier */
     875#define VT_VLA         0x0400  /* VLA type (also has VT_PTR and VT_ARRAY) */
     876#define VT_LONG        0x0800  /* long type (also has VT_INT rsp. VT_LLONG) */
    731877
    732878/* storage */
    733 #define VT_EXTERN  0x00000080  /* extern definition */
    734 #define VT_STATIC  0x00000100  /* static variable */
    735 #define VT_TYPEDEF 0x00000200  /* typedef definition */
    736 #define VT_INLINE  0x00000400  /* inline definition */
    737 #define VT_IMPORT  0x00004000  /* win32: extern data imported from dll */
    738 #define VT_EXPORT  0x00008000  /* win32: data exported from dll */
    739 #define VT_WEAK    0x00010000  /* weak symbol */
    740 
    741 #define VT_STRUCT_SHIFT 18     /* shift for bitfield shift values (max: 32 - 2*6) */
     879#define VT_EXTERN  0x00001000  /* extern definition */
     880#define VT_STATIC  0x00002000  /* static variable */
     881#define VT_TYPEDEF 0x00004000  /* typedef definition */
     882#define VT_INLINE  0x00008000  /* inline definition */
     883/* currently unused: 0x000[1248]0000  */
     884
     885#define VT_STRUCT_SHIFT 20     /* shift for bitfield shift values (32 - 2*6) */
     886#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)
     887#define BIT_POS(t) (((t) >> VT_STRUCT_SHIFT) & 0x3f)
     888#define BIT_SIZE(t) (((t) >> (VT_STRUCT_SHIFT + 6)) & 0x3f)
     889
     890#define VT_UNION    (1 << VT_STRUCT_SHIFT | VT_STRUCT)
     891#define VT_ENUM     (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */
     892#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
     893
     894#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
     895#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
     896#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)
    742897
    743898/* type mask (except storage) */
    744 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK)
    745 #define VT_TYPE (~(VT_STORAGE))
     899#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
     900#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
     901
     902/* symbol was created by tccasm.c first */
     903#define VT_ASM (VT_VOID | VT_UNSIGNED)
     904#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)
    746905
    747906/* token values */
     
    763922#define TOK_LAND  0xa0
    764923#define TOK_LOR   0xa1
    765 
    766924#define TOK_DEC   0xa2
    767925#define TOK_MID   0xa3 /* inc/dec, to void constant */
     
    770928#define TOK_UMOD  0xb1 /* unsigned modulo */
    771929#define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
    772 #define TOK_CINT   0xb3 /* number in tokc */
    773 #define TOK_CCHAR 0xb4 /* char constant in tokc */
    774 #define TOK_STR   0xb5 /* pointer to string in tokc */
    775 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
    776 #define TOK_LCHAR    0xb7
    777 #define TOK_LSTR     0xb8
    778 #define TOK_CFLOAT   0xb9 /* float constant */
    779 #define TOK_LINENUM  0xba /* line number info */
    780 #define TOK_CDOUBLE  0xc0 /* double constant */
    781 #define TOK_CLDOUBLE 0xc1 /* long double constant */
     930
     931/* tokens that carry values (in additional token string space / tokc) --> */
     932#define TOK_CCHAR   0xb3 /* char constant in tokc */
     933#define TOK_LCHAR   0xb4
     934#define TOK_CINT    0xb5 /* number in tokc */
     935#define TOK_CUINT   0xb6 /* unsigned int constant */
     936#define TOK_CLLONG  0xb7 /* long long constant */
     937#define TOK_CULLONG 0xb8 /* unsigned long long constant */
     938#define TOK_STR     0xb9 /* pointer to string in tokc */
     939#define TOK_LSTR    0xba
     940#define TOK_CFLOAT  0xbb /* float constant */
     941#define TOK_CDOUBLE 0xbc /* double constant */
     942#define TOK_CLDOUBLE 0xbd /* long double constant */
     943#define TOK_PPNUM   0xbe /* preprocessor number */
     944#define TOK_PPSTR   0xbf /* preprocessor string */
     945#define TOK_LINENUM 0xc0 /* line number info */
     946#define TOK_TWODOTS 0xa8 /* C++ token ? */
     947/* <-- */
     948
    782949#define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
    783950#define TOK_ADDC1    0xc3 /* add with carry generation */
     
    785952#define TOK_SUBC1    0xc5 /* add with carry generation */
    786953#define TOK_SUBC2    0xc6 /* add with carry use */
    787 #define TOK_CUINT    0xc8 /* unsigned int constant */
    788 #define TOK_CLLONG   0xc9 /* long long constant */
    789 #define TOK_CULLONG  0xca /* unsigned long long constant */
    790 #define TOK_ARROW    0xcb
    791 #define TOK_DOTS     0xcc /* three dots */
    792 #define TOK_SHR      0xcd /* unsigned shift right */
    793 #define TOK_PPNUM    0xce /* preprocessor number */
    794 #define TOK_NOSUBST  0xcf /* means following token has already been pp'd */
     954#define TOK_ARROW    0xc7
     955#define TOK_DOTS     0xc8 /* three dots */
     956#define TOK_SHR      0xc9 /* unsigned shift right */
     957#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
     958#define TOK_PLCHLDR  0xcb /* placeholder token as defined in C99 */
     959#define TOK_NOSUBST  0xcc /* means following token has already been pp'd */
     960#define TOK_PPJOIN   0xcd /* A '##' in the right position to mean pasting */
     961#define TOK_CLONG    0xce /* long constant */
     962#define TOK_CULONG   0xcf /* unsigned long constant */
    795963
    796964#define TOK_SHL   0x01 /* shift left */
    797965#define TOK_SAR   0x02 /* signed shift right */
    798  
    799 /* assignement operators : normal operator or 0x80 */
     966
     967/* assignment operators : normal operator or 0x80 */
    800968#define TOK_A_MOD 0xa5
    801969#define TOK_A_AND 0xa6
     
    809977#define TOK_A_SAR 0x82
    810978
    811 #ifndef offsetof
    812 #define offsetof(type, field) ((size_t) &((type *)0)->field)
    813 #endif
    814 
    815 #ifndef countof
    816 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
    817 #endif
    818 
    819979#define TOK_EOF       (-1)  /* end of file */
    820980#define TOK_LINEFEED  10    /* line feed */
    821981
    822 /* all identificators and strings have token above that */
     982/* all identifiers and strings have token above that */
    823983#define TOK_IDENT 256
    824984
    825985#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
    826986#define TOK_ASM_int TOK_INT
    827 #define TOK_ASM_weak TOK_WEAK1
     987#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
     988#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
     989#define TOK_ASMDIR_LAST TOK_ASMDIR_section
    828990
    829991#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
     
    8721034 DEF_FP1(x)
    8731035
    874 #define DEF_ASMTEST(x) \
    875  DEF_ASM(x ## o) \
    876  DEF_ASM(x ## no) \
    877  DEF_ASM(x ## b) \
    878  DEF_ASM(x ## c) \
    879  DEF_ASM(x ## nae) \
    880  DEF_ASM(x ## nb) \
    881  DEF_ASM(x ## nc) \
    882  DEF_ASM(x ## ae) \
    883  DEF_ASM(x ## e) \
    884  DEF_ASM(x ## z) \
    885  DEF_ASM(x ## ne) \
    886  DEF_ASM(x ## nz) \
    887  DEF_ASM(x ## be) \
    888  DEF_ASM(x ## na) \
    889  DEF_ASM(x ## nbe) \
    890  DEF_ASM(x ## a) \
    891  DEF_ASM(x ## s) \
    892  DEF_ASM(x ## ns) \
    893  DEF_ASM(x ## p) \
    894  DEF_ASM(x ## pe) \
    895  DEF_ASM(x ## np) \
    896  DEF_ASM(x ## po) \
    897  DEF_ASM(x ## l) \
    898  DEF_ASM(x ## nge) \
    899  DEF_ASM(x ## nl) \
    900  DEF_ASM(x ## ge) \
    901  DEF_ASM(x ## le) \
    902  DEF_ASM(x ## ng) \
    903  DEF_ASM(x ## nle) \
    904  DEF_ASM(x ## g)
    905 
    906 #endif // defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
     1036#define DEF_ASMTEST(x,suffix) \
     1037 DEF_ASM(x ## o ## suffix) \
     1038 DEF_ASM(x ## no ## suffix) \
     1039 DEF_ASM(x ## b ## suffix) \
     1040 DEF_ASM(x ## c ## suffix) \
     1041 DEF_ASM(x ## nae ## suffix) \
     1042 DEF_ASM(x ## nb ## suffix) \
     1043 DEF_ASM(x ## nc ## suffix) \
     1044 DEF_ASM(x ## ae ## suffix) \
     1045 DEF_ASM(x ## e ## suffix) \
     1046 DEF_ASM(x ## z ## suffix) \
     1047 DEF_ASM(x ## ne ## suffix) \
     1048 DEF_ASM(x ## nz ## suffix) \
     1049 DEF_ASM(x ## be ## suffix) \
     1050 DEF_ASM(x ## na ## suffix) \
     1051 DEF_ASM(x ## nbe ## suffix) \
     1052 DEF_ASM(x ## a ## suffix) \
     1053 DEF_ASM(x ## s ## suffix) \
     1054 DEF_ASM(x ## ns ## suffix) \
     1055 DEF_ASM(x ## p ## suffix) \
     1056 DEF_ASM(x ## pe ## suffix) \
     1057 DEF_ASM(x ## np ## suffix) \
     1058 DEF_ASM(x ## po ## suffix) \
     1059 DEF_ASM(x ## l ## suffix) \
     1060 DEF_ASM(x ## nge ## suffix) \
     1061 DEF_ASM(x ## nl ## suffix) \
     1062 DEF_ASM(x ## ge ## suffix) \
     1063 DEF_ASM(x ## le ## suffix) \
     1064 DEF_ASM(x ## ng ## suffix) \
     1065 DEF_ASM(x ## nle ## suffix) \
     1066 DEF_ASM(x ## g ## suffix)
     1067
     1068#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */
    9071069
    9081070enum tcc_token {
    909     TOK_LAST = TOK_IDENT - 1,
    910 #define DEF(id, str) id,
     1071    TOK_LAST = TOK_IDENT - 1
     1072#define DEF(id, str) ,id
    9111073#include "tcctok.h"
    9121074#undef DEF
    9131075};
    9141076
     1077/* keywords: tok >= TOK_IDENT && tok < TOK_UIDENT */
    9151078#define TOK_UIDENT TOK_DEFINE
    916 
    917 #if 0//def _WIN32
    918 #define snprintf _snprintf
    919 #define vsnprintf _vsnprintf
    920 #ifndef __GNUC__
    921   #define strtold (long double)strtod
    922   #define strtof (float)strtod
    923   #define strtoll _strtoi64
    924   #define strtoull _strtoui64
    925 #endif
    926 #else
    927 /* XXX: need to define this to use them in non ISOC99 context */
    928 extern float strtof (const char *__nptr, char **__endptr);
    929 extern long double strtold (const char *__nptr, char **__endptr);
    930 #endif
    931 
    932 #ifdef _WIN32
    933 #define IS_DIRSEP(c) (c == '/' || c == '\\')
    934 #define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
    935 #define PATHCMP stricmp
    936 #else
    937 #define IS_DIRSEP(c) (c == '/')
    938 #define IS_ABSPATH(p) IS_DIRSEP(p[0])
    939 #define PATHCMP strcmp
    940 #endif
    941 
    942 #ifdef TCC_TARGET_PE
    943 #define PATHSEP ';'
    944 #else
    945 #define PATHSEP ':'
    946 #endif
    947 
    948 /* space exlcuding newline */
    949 static inline int is_space(int ch)
    950 {
    951     return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
    952 }
    953 
    954 static inline int isid(int c)
    955 {
    956     return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
    957 }
    958 
    959 static inline int isnum(int c)
    960 {
    961     return c >= '0' && c <= '9';
    962 }
    963 
    964 static inline int isoct(int c)
    965 {
    966     return c >= '0' && c <= '7';
    967 }
    968 
    969 static inline int toup(int c)
    970 {
    971     return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
    972 }
    973 
    974 #ifndef PUB_FUNC
    975 # define PUB_FUNC
    976 #endif
    977 
    978 #ifdef ONE_SOURCE
    979 #define ST_INLN static inline
    980 #define ST_FUNC static
    981 #define ST_DATA static
    982 #else
    983 #define ST_INLN
    984 #define ST_FUNC
    985 #define ST_DATA extern
    986 #endif
    9871079
    9881080/* ------------ libtcc.c ------------ */
     
    9951087ST_DATA struct TCCState *tcc_state;
    9961088
    997 #ifdef MEM_DEBUG
    998 ST_DATA int mem_cur_size;
    999 ST_DATA int mem_max_size;
    1000 #endif
    1001 
    1002 #define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
    1003 #define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
    1004 #define AFF_PREPROCESS      0x0004 /* preprocess file */
    1005 
    10061089/* public functions currently used by the tcc main function */
    1007 PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
    1008 PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
    1009 PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num);
     1090ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
     1091ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
     1092ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
    10101093PUB_FUNC char *tcc_basename(const char *name);
    10111094PUB_FUNC char *tcc_fileextension (const char *name);
     1095
     1096#ifndef MEM_DEBUG
    10121097PUB_FUNC void tcc_free(void *ptr);
    10131098PUB_FUNC void *tcc_malloc(unsigned long size);
     
    10151100PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
    10161101PUB_FUNC char *tcc_strdup(const char *str);
     1102#else
     1103#define tcc_free(ptr)           tcc_free_debug(ptr)
     1104#define tcc_malloc(size)        tcc_malloc_debug(size, __FILE__, __LINE__)
     1105#define tcc_mallocz(size)       tcc_mallocz_debug(size, __FILE__, __LINE__)
     1106#define tcc_realloc(ptr,size)   tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
     1107#define tcc_strdup(str)         tcc_strdup_debug(str, __FILE__, __LINE__)
     1108PUB_FUNC void tcc_free_debug(void *ptr);
     1109PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
     1110PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
     1111PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
     1112PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
     1113#endif
     1114
    10171115#define free(p) use_tcc_free(p)
    10181116#define malloc(s) use_tcc_malloc(s)
     
    10201118#undef strdup
    10211119#define strdup(s) use_tcc_strdup(s)
    1022 PUB_FUNC void tcc_memstats(void);
     1120PUB_FUNC void tcc_memcheck(void);
    10231121PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
    1024 PUB_FUNC void tcc_error(const char *fmt, ...);
     1122PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
    10251123PUB_FUNC void tcc_warning(const char *fmt, ...);
    10261124
    10271125/* other utilities */
    1028 ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data);
     1126ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
    10291127ST_FUNC void dynarray_reset(void *pp, int *n);
    1030 ST_FUNC void cstr_ccat(CString *cstr, int ch);
    1031 ST_FUNC void cstr_cat(CString *cstr, const char *str);
     1128ST_INLN void cstr_ccat(CString *cstr, int ch);
     1129ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
    10321130ST_FUNC void cstr_wccat(CString *cstr, int ch);
    10331131ST_FUNC void cstr_new(CString *cstr);
     
    10351133ST_FUNC void cstr_reset(CString *cstr);
    10361134
    1037 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
    1038 ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
    1039 ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
    1040 ST_FUNC void section_reserve(Section *sec, unsigned long size);
    1041 ST_FUNC Section *find_section(TCCState *s1, const char *name);
    1042 
    1043 ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
    1044 ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
    1045 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
    1046 
    10471135ST_INLN void sym_free(Sym *sym);
    1048 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
     1136ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c);
    10491137ST_FUNC Sym *sym_find2(Sym *s, int v);
    10501138ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
    1051 ST_FUNC void sym_pop(Sym **ptop, Sym *b);
     1139ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
    10521140ST_INLN Sym *struct_find(int v);
    10531141ST_INLN Sym *sym_find(int v);
     
    10591147
    10601148ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
     1149/* flags: */
     1150#define AFF_PRINT_ERROR     0x10 /* print error if file not found */
     1151#define AFF_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
     1152#define AFF_TYPE_BIN        0x40 /* file to add is binary */
     1153/* s->filetype: */
     1154#define AFF_TYPE_NONE   0
     1155#define AFF_TYPE_C      1
     1156#define AFF_TYPE_ASM    2
     1157#define AFF_TYPE_ASMPP  3
     1158#define AFF_TYPE_LIB    4
     1159/* values from tcc_object_type(...) */
     1160#define AFF_BINTYPE_REL 1
     1161#define AFF_BINTYPE_DYN 2
     1162#define AFF_BINTYPE_AR  3
     1163#define AFF_BINTYPE_C67 4
     1164
     1165
    10611166ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
    10621167ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
    1063 
    1064 PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time);
    1065 PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv);
     1168ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
     1169PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
     1170PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
     1171PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
     1172#ifdef _WIN32
     1173ST_FUNC char *normalize_slashes(char *path);
     1174#endif
     1175
     1176/* tcc_parse_args return codes: */
     1177#define OPT_HELP 1
     1178#define OPT_HELP2 2
     1179#define OPT_V 3
     1180#define OPT_PRINT_DIRS 4
     1181#define OPT_AR 5
     1182#define OPT_IMPDEF 6
     1183#define OPT_M32 32
     1184#define OPT_M64 64
    10661185
    10671186/* ------------ tccpp.c ------------ */
     
    10911210                                        token. line feed is also
    10921211                                        returned at eof */
    1093 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
     1212#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */
    10941213#define PARSE_FLAG_SPACES     0x0010 /* next() returns space tokens (for -E) */
     1214#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */
     1215#define PARSE_FLAG_TOK_STR    0x0040 /* return parsed strings instead of TOK_PPSTR */
     1216
     1217/* isidnum_table flags: */
     1218#define IS_SPC 1
     1219#define IS_ID  2
     1220#define IS_NUM 4
    10951221
    10961222ST_FUNC TokenSym *tok_alloc(const char *str, int len);
    1097 ST_FUNC char *get_tok_str(int v, CValue *cv);
    1098 ST_FUNC void save_parse_state(ParseState *s);
    1099 ST_FUNC void restore_parse_state(ParseState *s);
     1223ST_FUNC const char *get_tok_str(int v, CValue *cv);
     1224ST_FUNC void begin_macro(TokenString *str, int alloc);
     1225ST_FUNC void end_macro(void);
     1226ST_FUNC int set_idnum(int c, int val);
    11001227ST_INLN void tok_str_new(TokenString *s);
    1101 ST_FUNC void tok_str_free(int *str);
     1228ST_FUNC TokenString *tok_str_alloc(void);
     1229ST_FUNC void tok_str_free(TokenString *s);
     1230ST_FUNC void tok_str_free_str(int *str);
    11021231ST_FUNC void tok_str_add(TokenString *s, int t);
    11031232ST_FUNC void tok_str_add_tok(TokenString *s);
     
    11081237ST_FUNC Sym *label_find(int v);
    11091238ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
    1110 ST_FUNC void label_pop(Sym **ptop, Sym *slast);
     1239ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
    11111240ST_FUNC void parse_define(void);
    11121241ST_FUNC void preprocess(int is_bof);
     
    11141243ST_FUNC void next(void);
    11151244ST_INLN void unget_tok(int last_tok);
    1116 ST_FUNC void preprocess_init(TCCState *s1);
    1117 ST_FUNC void preprocess_new(void);
     1245ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
     1246ST_FUNC void preprocess_end(TCCState *s1);
     1247ST_FUNC void tccpp_new(TCCState *s);
     1248ST_FUNC void tccpp_delete(TCCState *s);
    11181249ST_FUNC int tcc_preprocess(TCCState *s1);
    11191250ST_FUNC void skip(int c);
    1120 ST_FUNC void expect(const char *msg);
     1251ST_FUNC NORETURN void expect(const char *msg);
     1252
     1253/* space excluding newline */
     1254static inline int is_space(int ch) {
     1255    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
     1256}
     1257static inline int isid(int c) {
     1258    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
     1259}
     1260static inline int isnum(int c) {
     1261    return c >= '0' && c <= '9';
     1262}
     1263static inline int isoct(int c) {
     1264    return c >= '0' && c <= '7';
     1265}
     1266static inline int toup(int c) {
     1267    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
     1268}
    11211269
    11221270/* ------------ tccgen.c ------------ */
    1123 
    1124 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
    1125 ST_DATA Section *cur_text_section; /* current section where function code is generated */
    1126 #ifdef CONFIG_TCC_ASM
    1127 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
    1128 #endif
    1129 #ifdef CONFIG_TCC_BCHECK
    1130 /* bound check related sections */
    1131 ST_DATA Section *bounds_section; /* contains global data bound description */
    1132 ST_DATA Section *lbounds_section; /* contains local data bound description */
    1133 #endif
    1134 /* symbol sections */
    1135 ST_DATA Section *symtab_section, *strtab_section;
    1136 /* debug sections */
    1137 ST_DATA Section *stab_section, *stabstr_section;
    11381271
    11391272#define SYM_POOL_NB (8192 / sizeof(Sym))
     
    11481281ST_DATA Sym *define_stack;
    11491282ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
    1150 ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop;
     1283ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
    11511284#define vstack  (__vstack + 1)
    11521285ST_DATA int rsym, anon_sym, ind, loc;
     
    11561289ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
    11571290ST_DATA CType func_vt; /* current function return type (used by return instruction) */
     1291ST_DATA int func_var; /* true if current function is variadic */
    11581292ST_DATA int func_vc;
    11591293ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
    1160 ST_DATA char *funcname;
     1294ST_DATA const char *funcname;
     1295ST_DATA int g_debug;
     1296
     1297ST_FUNC void tcc_debug_start(TCCState *s1);
     1298ST_FUNC void tcc_debug_end(TCCState *s1);
     1299ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
     1300ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
     1301ST_FUNC void tcc_debug_line(TCCState *s1);
     1302
     1303ST_FUNC int tccgen_compile(TCCState *s1);
     1304ST_FUNC void free_inline_functions(TCCState *s);
     1305ST_FUNC void check_vstack(void);
    11611306
    11621307ST_INLN int is_float(int t);
    11631308ST_FUNC int ieee_finite(double d);
    11641309ST_FUNC void test_lvalue(void);
    1165 ST_FUNC void swap(int *p, int *q);
    11661310ST_FUNC void vpushi(int v);
     1311ST_FUNC ElfSym *elfsym(Sym *);
     1312ST_FUNC void update_storage(Sym *sym);
    11671313ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
    11681314ST_FUNC void vset(CType *type, int r, int v);
     
    11781324ST_FUNC void vpushv(SValue *v);
    11791325ST_FUNC void save_reg(int r);
     1326ST_FUNC void save_reg_upstack(int r, int n);
    11801327ST_FUNC int get_reg(int rc);
    11811328ST_FUNC void save_regs(int n);
     1329ST_FUNC void gaddrof(void);
    11821330ST_FUNC int gv(int rc);
    11831331ST_FUNC void gv2(int rc1, int rc2);
     
    11881336ST_FUNC void vstore(void);
    11891337ST_FUNC void inc(int post, int c);
     1338ST_FUNC void parse_mult_str (CString *astr, const char *msg);
    11901339ST_FUNC void parse_asm_str(CString *astr);
    11911340ST_FUNC int lvalue_type(int t);
     
    11961345ST_FUNC void gexpr(void);
    11971346ST_FUNC int expr_const(void);
    1198 ST_FUNC void gen_inline_functions(void);
    1199 ST_FUNC void decl(int l);
    12001347#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
    12011348ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
     1349#endif
     1350#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
     1351ST_FUNC int classify_x86_64_va_arg(CType *ty);
    12021352#endif
    12031353
     
    12181368} Stab_Sym;
    12191369
     1370ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
     1371ST_DATA Section *common_section;
     1372ST_DATA Section *cur_text_section; /* current section where function code is generated */
     1373#ifdef CONFIG_TCC_ASM
     1374ST_DATA Section *last_text_section; /* to handle .previous asm directive */
     1375#endif
     1376#ifdef CONFIG_TCC_BCHECK
     1377/* bound check related sections */
     1378ST_DATA Section *bounds_section; /* contains global data bound description */
     1379ST_DATA Section *lbounds_section; /* contains local data bound description */
     1380ST_FUNC void tccelf_bounds_new(TCCState *s);
     1381#endif
     1382/* symbol sections */
     1383ST_DATA Section *symtab_section;
     1384/* debug sections */
     1385ST_DATA Section *stab_section, *stabstr_section;
     1386
     1387ST_FUNC void tccelf_new(TCCState *s);
     1388ST_FUNC void tccelf_delete(TCCState *s);
     1389ST_FUNC void tccelf_stab_new(TCCState *s);
     1390ST_FUNC void tccelf_begin_file(TCCState *s1);
     1391ST_FUNC void tccelf_end_file(TCCState *s1);
     1392
     1393ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
     1394ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
     1395ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
     1396ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
     1397ST_FUNC void section_reserve(Section *sec, unsigned long size);
     1398ST_FUNC Section *find_section(TCCState *s1, const char *name);
    12201399ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
     1400
     1401ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
     1402ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
     1403#if PTR_SIZE == 4
     1404ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
     1405#endif
     1406ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
    12211407
    12221408ST_FUNC int put_elf_str(Section *s, const char *sym);
    12231409ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
    1224 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
     1410ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
    12251411ST_FUNC int find_elf_sym(Section *s, const char *name);
    12261412ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
     1413ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
    12271414
    12281415ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
     
    12311418ST_FUNC void put_stabd(int type, int other, int desc);
    12321419
    1233 ST_FUNC void relocate_common_syms(void);
    1234 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
     1420ST_FUNC void resolve_common_syms(TCCState *s1);
     1421ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
    12351422ST_FUNC void relocate_section(TCCState *s1, Section *s);
    12361423
    1237 ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
     1424ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
    12381425ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
    12391426ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
    12401427ST_FUNC void tcc_add_bcheck(TCCState *s1);
     1428ST_FUNC void tcc_add_runtime(TCCState *s1);
    12411429
    12421430ST_FUNC void build_got_entries(TCCState *s1);
    1243 ST_FUNC void tcc_add_runtime(TCCState *s1);
     1431ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
     1432ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);
    12441433
    12451434ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
    1246 #ifdef TCC_IS_NATIVE
     1435#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
    12471436ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
    12481437#endif
     
    12571446#endif
    12581447
     1448/* ------------ xxx-link.c ------------ */
     1449
     1450/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
     1451   that unknown relocation don't create a GOT or PLT entry */
     1452enum gotplt_entry {
     1453    NO_GOTPLT_ENTRY,    /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */
     1454    BUILD_GOT_ONLY,     /* only build GOT (eg. TPOFF relocs) */
     1455    AUTO_GOTPLT_ENTRY,  /* generate if sym is UNDEF */
     1456    ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
     1457};
     1458
     1459ST_FUNC int code_reloc (int reloc_type);
     1460ST_FUNC int gotplt_entry_type (int reloc_type);
     1461ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
     1462ST_FUNC void relocate_init(Section *sr);
     1463ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
     1464ST_FUNC void relocate_plt(TCCState *s1);
     1465
    12591466/* ------------ xxx-gen.c ------------ */
    12601467
    1261 #ifdef TCC_TARGET_X86_64
    1262 ST_DATA const int reg_classes[NB_REGS+7];
    1263 #else
    12641468ST_DATA const int reg_classes[NB_REGS];
    1265 #endif
    12661469
    12671470ST_FUNC void gsym_addr(int t, int a);
     
    12691472ST_FUNC void load(int r, SValue *sv);
    12701473ST_FUNC void store(int r, SValue *v);
     1474ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
    12711475ST_FUNC void gfunc_call(int nb_args);
    12721476ST_FUNC void gfunc_prolog(CType *func_type);
     
    12751479ST_FUNC void gjmp_addr(int a);
    12761480ST_FUNC int gtst(int inv, int t);
     1481#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
     1482ST_FUNC void gtst_addr(int inv, int a);
     1483#else
     1484#define gtst_addr(inv, a) gsym_addr(gtst(inv, 0), a)
     1485#endif
    12771486ST_FUNC void gen_opi(int op);
    12781487ST_FUNC void gen_opf(int op);
     
    12861495ST_FUNC void gen_cvt_itof(int t);
    12871496#endif
     1497ST_FUNC void gen_vla_sp_save(int addr);
     1498ST_FUNC void gen_vla_sp_restore(int addr);
     1499ST_FUNC void gen_vla_alloc(CType *type, int align);
     1500
     1501static inline uint16_t read16le(unsigned char *p) {
     1502    return p[0] | (uint16_t)p[1] << 8;
     1503}
     1504static inline void write16le(unsigned char *p, uint16_t x) {
     1505    p[0] = x & 255;  p[1] = x >> 8 & 255;
     1506}
     1507static inline uint32_t read32le(unsigned char *p) {
     1508  return read16le(p) | (uint32_t)read16le(p + 2) << 16;
     1509}
     1510static inline void write32le(unsigned char *p, uint32_t x) {
     1511    write16le(p, x);  write16le(p + 2, x >> 16);
     1512}
     1513static inline void add32le(unsigned char *p, int32_t x) {
     1514    write32le(p, read32le(p) + x);
     1515}
     1516static inline uint64_t read64le(unsigned char *p) {
     1517  return read32le(p) | (uint64_t)read32le(p + 4) << 32;
     1518}
     1519static inline void write64le(unsigned char *p, uint64_t x) {
     1520    write32le(p, x);  write32le(p + 4, x >> 32);
     1521}
     1522static inline void add64le(unsigned char *p, int64_t x) {
     1523    write64le(p, read64le(p) + x);
     1524}
    12881525
    12891526/* ------------ i386-gen.c ------------ */
    12901527#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    12911528ST_FUNC void g(int c);
    1292 ST_FUNC int oad(int c, int s);
    12931529ST_FUNC void gen_le16(int c);
    12941530ST_FUNC void gen_le32(int c);
     
    13061542ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
    13071543ST_FUNC void gen_opl(int op);
     1544#ifdef TCC_TARGET_PE
     1545ST_FUNC void gen_vla_result(int addr);
     1546#endif
    13081547#endif
    13091548
    13101549/* ------------ arm-gen.c ------------ */
    13111550#ifdef TCC_TARGET_ARM
    1312 ST_FUNC void arm_init_types(void);
    1313 ST_FUNC uint32_t encbranch(int pos, int addr, int fail);
     1551#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
     1552PUB_FUNC const char *default_elfinterp(struct TCCState *s);
     1553#endif
     1554ST_FUNC void arm_init(struct TCCState *s);
    13141555ST_FUNC void gen_cvt_itof1(int t);
     1556#endif
     1557
     1558/* ------------ arm64-gen.c ------------ */
     1559#ifdef TCC_TARGET_ARM64
     1560ST_FUNC void gen_cvt_sxtw(void);
     1561ST_FUNC void gen_opl(int op);
     1562ST_FUNC void gfunc_return(CType *func_type);
     1563ST_FUNC void gen_va_start(void);
     1564ST_FUNC void gen_va_arg(CType *t);
     1565ST_FUNC void gen_clear_cache(void);
    13151566#endif
    13161567
     
    13311582#ifdef CONFIG_TCC_ASM
    13321583ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
     1584ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
    13331585ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
    13341586ST_FUNC int asm_int_expr(TCCState *s1);
     
    13361588/* ------------ i386-asm.c ------------ */
    13371589ST_FUNC void gen_expr32(ExprValue *pe);
     1590#ifdef TCC_TARGET_X86_64
     1591ST_FUNC void gen_expr64(ExprValue *pe);
     1592#endif
    13381593ST_FUNC void asm_opcode(TCCState *s1, int opcode);
     1594ST_FUNC int asm_parse_regvar(int t);
    13391595ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
    13401596ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
     
    13481604ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
    13491605ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
     1606#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    13501607ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
     1608#endif
    13511609#ifdef TCC_TARGET_X86_64
    13521610ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
    13531611#endif
    1354 #endif
     1612PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
     1613/* symbol properties stored in Elf32_Sym->st_other */
     1614# define ST_PE_EXPORT 0x10
     1615# define ST_PE_IMPORT 0x20
     1616# define ST_PE_STDCALL 0x40
     1617#endif
     1618#define ST_ASM_SET 0x04
    13551619
    13561620/* ------------ tccrun.c ----------------- */
     
    13651629ST_FUNC void dlclose(void *p);
    13661630ST_FUNC const char *dlerror(void);
    1367 ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
    1368 #elif !defined _WIN32
    1369 ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
    1370 #endif
    1371 
     1631ST_FUNC void *dlsym(void *handle, const char *symbol);
     1632#endif
    13721633#ifdef CONFIG_TCC_BACKTRACE
    13731634ST_DATA int rt_num_callers;
     
    13761637ST_FUNC void tcc_set_num_callers(int n);
    13771638#endif
     1639ST_FUNC void tcc_run_free(TCCState *s1);
     1640#endif
     1641
     1642/* ------------ tcctools.c ----------------- */
     1643#if 0 /* included in tcc.c */
     1644ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
     1645#ifdef TCC_TARGET_PE
     1646ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
     1647#endif
     1648ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
     1649ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
    13781650#endif
    13791651
    13801652/********************************************************/
    13811653#undef ST_DATA
    1382 #ifdef ONE_SOURCE
     1654#if ONE_SOURCE
    13831655#define ST_DATA static
    13841656#else
  • EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c

    r321 r331  
    3232}
    3333
    34 ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
     34static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
     35static Sym* asm_new_label(TCCState *s1, int label, int is_local);
     36static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
     37
     38static Sym *asm_label_find(int v)
     39{
     40    Sym *sym = sym_find(v);
     41    while (sym && sym->sym_scope)
     42        sym = sym->prev_tok;
     43    return sym;
     44}
     45
     46static Sym *asm_label_push(int v)
     47{
     48    /* We always add VT_EXTERN, for sym definition that's tentative
     49       (for .set, removed for real defs), for mere references it's correct
     50       as is.  */
     51    Sym *sym = global_identifier_push(v, VT_ASM | VT_EXTERN | VT_STATIC, 0);
     52    sym->r = VT_CONST | VT_SYM;
     53    return sym;
     54}
     55
     56/* Return a symbol we can use inside the assembler, having name NAME.
     57   Symbols from asm and C source share a namespace.  If we generate
     58   an asm symbol it's also a (file-global) C symbol, but it's
     59   either not accessible by name (like "L.123"), or its type information
     60   is such that it's not usable without a proper C declaration.
     61
     62   Sometimes we need symbols accessible by name from asm, which
     63   are anonymous in C, in this case CSYM can be used to transfer
     64   all information from that symbol to the (possibly newly created)
     65   asm symbol.  */
     66ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
     67{
     68    Sym *sym = asm_label_find(name);
     69    if (!sym) {
     70        sym = asm_label_push(name);
     71        if (csym)
     72          sym->c = csym->c;
     73    }
     74    return sym;
     75}
     76
     77static Sym* asm_section_sym(TCCState *s1, Section *sec)
     78{
     79    char buf[100];
     80    int label = tok_alloc(buf,
     81        snprintf(buf, sizeof buf, "L.%s", sec->name)
     82        )->tok;
     83    Sym *sym = asm_label_find(label);
     84    return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
     85}
    3586
    3687/* We do not use the C expression parser to handle symbols. Maybe the
     
    4091{
    4192    Sym *sym;
    42     int op, n, label;
     93    int op, label;
     94    uint64_t n;
    4395    const char *p;
    4496
    4597    switch(tok) {
    4698    case TOK_PPNUM:
    47         p = tokc.cstr->data;
    48         n = strtoul(p, (char **)&p, 0);
     99        p = tokc.str.data;
     100        n = strtoull(p, (char **)&p, 0);
    49101        if (*p == 'b' || *p == 'f') {
    50102            /* backward or forward label */
    51103            label = asm_get_local_label_name(s1, n);
    52             sym = label_find(label);
     104            sym = asm_label_find(label);
    53105            if (*p == 'b') {
    54106                /* backward : find the last corresponding defined label */
    55                 if (sym && sym->r == 0)
     107                if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))
    56108                    sym = sym->prev_tok;
    57109                if (!sym)
     
    59111            } else {
    60112                /* forward */
    61                 if (!sym || sym->r) {
     113                if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
    62114                    /* if the last label is defined, then define a new one */
    63                     sym = label_push(&s1->asm_labels, label, 0);
    64                     sym->type.t = VT_STATIC | VT_VOID;
     115                    sym = asm_label_push(label);
    65116                }
    66117            }
    67             pe->v = 0;
    68             pe->sym = sym;
     118            pe->v = 0;
     119            pe->sym = sym;
     120            pe->pcrel = 0;
    69121        } else if (*p == '\0') {
    70122            pe->v = n;
    71123            pe->sym = NULL;
     124            pe->pcrel = 0;
    72125        } else {
    73126            tcc_error("invalid number syntax");
     
    95148        pe->v = tokc.i;
    96149        pe->sym = NULL;
     150        pe->pcrel = 0;
    97151        next();
    98152        break;
     
    102156        skip(')');
    103157        break;
     158    case '.':
     159        pe->v = ind;
     160        pe->sym = asm_section_sym(s1, cur_text_section);
     161        pe->pcrel = 0;
     162        next();
     163        break;
    104164    default:
    105165        if (tok >= TOK_IDENT) {
     166            ElfSym *esym;
    106167            /* label case : if the label was not found, add one */
    107             sym = label_find(tok);
    108             if (!sym) {
    109                 sym = label_push(&s1->asm_labels, tok, 0);
    110                 /* NOTE: by default, the symbol is global */
    111                 sym->type.t = VT_VOID;
    112             }
    113             if (sym->r == SHN_ABS) {
     168            sym = get_asm_sym(tok, NULL);
     169            esym = elfsym(sym);
     170            if (esym && esym->st_shndx == SHN_ABS) {
    114171                /* if absolute symbol, no need to put a symbol value */
    115                 pe->v = sym->jnext;
     172                pe->v = esym->st_value;
    116173                pe->sym = NULL;
     174                pe->pcrel = 0;
    117175            } else {
    118176                pe->v = 0;
    119177                pe->sym = sym;
     178                pe->pcrel = 0;
    120179            }
    121180            next();
     
    220279            /* NOTE: we are less powerful than gas in that case
    221280               because we store only one symbol in the expression */
    222             if (!pe->sym && !e2.sym) {
    223                 /* OK */
    224             } else if (pe->sym && !e2.sym) {
    225                 /* OK */
    226             } else if (pe->sym && e2.sym) {
    227                 if (pe->sym == e2.sym) {
    228                     /* OK */
    229                 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
    230                     /* we also accept defined symbols in the same section */
    231                     pe->v += pe->sym->jnext - e2.sym->jnext;
    232                 } else {
    233                     goto cannot_relocate;
    234                 }
    235                 pe->sym = NULL; /* same symbols can be substracted to NULL */
    236             } else {
    237             cannot_relocate:
    238                 tcc_error("invalid operation with label");
    239             }
    240         }
     281            if (!e2.sym) {
     282                /* OK */
     283            } else if (pe->sym == e2.sym) {
     284                /* OK */
     285                pe->sym = NULL; /* same symbols can be subtracted to NULL */
     286            } else {
     287                ElfSym *esym1, *esym2;
     288                esym1 = elfsym(pe->sym);
     289                esym2 = elfsym(e2.sym);
     290                if (esym1 && esym1->st_shndx == esym2->st_shndx
     291                    && esym1->st_shndx != SHN_UNDEF) {
     292                    /* we also accept defined symbols in the same section */
     293                    pe->v += esym1->st_value - esym2->st_value;
     294                    pe->sym = NULL;
     295                } else if (esym2->st_shndx == cur_text_section->sh_num) {
     296                    /* When subtracting a defined symbol in current section
     297                       this actually makes the value PC-relative.  */
     298                    pe->v -= esym2->st_value - ind - 4;
     299                    pe->pcrel = 1;
     300                    e2.sym = NULL;
     301                } else {
     302cannot_relocate:
     303                    tcc_error("invalid operation with label");
     304                }
     305            }
     306        }
     307    }
     308}
     309
     310static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
     311{
     312    int op;
     313    ExprValue e2;
     314
     315    asm_expr_sum(s1, pe);
     316    for(;;) {
     317        op = tok;
     318        if (op != TOK_EQ && op != TOK_NE
     319            && (op > TOK_GT || op < TOK_ULE))
     320            break;
     321        next();
     322        asm_expr_sum(s1, &e2);
     323        if (pe->sym || e2.sym)
     324            tcc_error("invalid operation with label");
     325        switch(op) {
     326        case TOK_EQ:
     327            pe->v = pe->v == e2.v;
     328            break;
     329        case TOK_NE:
     330            pe->v = pe->v != e2.v;
     331            break;
     332        case TOK_LT:
     333            pe->v = (int64_t)pe->v < (int64_t)e2.v;
     334            break;
     335        case TOK_GE:
     336            pe->v = (int64_t)pe->v >= (int64_t)e2.v;
     337            break;
     338        case TOK_LE:
     339            pe->v = (int64_t)pe->v <= (int64_t)e2.v;
     340            break;
     341        case TOK_GT:
     342            pe->v = (int64_t)pe->v > (int64_t)e2.v;
     343            break;
     344        default:
     345            break;
     346        }
     347        /* GAS compare results are -1/0 not 1/0.  */
     348        pe->v = -(int64_t)pe->v;
    241349    }
    242350}
     
    244352ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
    245353{
    246     asm_expr_sum(s1, pe);
     354    asm_expr_cmp(s1, pe);
    247355}
    248356
     
    256364}
    257365
    258 /* NOTE: the same name space as C labels is used to avoid using too
    259    much memory when storing labels in TokenStrings */
    260 static void asm_new_label1(TCCState *s1, int label, int is_local,
     366static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
    261367                           int sh_num, int value)
    262368{
    263369    Sym *sym;
    264 
    265     sym = label_find(label);
     370    ElfSym *esym;
     371
     372    sym = asm_label_find(label);
    266373    if (sym) {
    267         if (sym->r) {
     374        esym = elfsym(sym);
     375        /* A VT_EXTERN symbol, even if it has a section is considered
     376           overridable.  This is how we "define" .set targets.  Real
     377           definitions won't have VT_EXTERN set.  */
     378        if (esym && esym->st_shndx != SHN_UNDEF) {
    268379            /* the label is already defined */
    269             if (!is_local) {
    270                 tcc_error("assembler label '%s' already defined",
    271                       get_tok_str(label, NULL));
    272             } else {
    273                 /* redefinition of local labels is possible */
     380            if (IS_ASM_SYM(sym)
     381                && (is_local == 1 || (sym->type.t & VT_EXTERN)))
    274382                goto new_label;
    275             }
     383            if (!(sym->type.t & VT_EXTERN))
     384                tcc_error("assembler label '%s' already defined",
     385                          get_tok_str(label, NULL));
    276386        }
    277387    } else {
    278388    new_label:
    279         sym = label_push(&s1->asm_labels, label, 0);
    280         sym->type.t = VT_STATIC | VT_VOID;
    281     }
    282     sym->r = sh_num;
    283     sym->jnext = value;
    284 }
    285 
    286 static void asm_new_label(TCCState *s1, int label, int is_local)
    287 {
    288     asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
    289 }
    290 
    291 static void asm_free_labels(TCCState *st)
    292 {
    293     Sym *s, *s1;
    294     Section *sec;
    295    
    296     for(s = st->asm_labels; s != NULL; s = s1) {
    297         s1 = s->prev;
    298         /* define symbol value in object file */
    299         if (s->r) {
    300             if (s->r == SHN_ABS)
    301                 sec = SECTION_ABS;
    302             else
    303                 sec = st->sections[s->r];
    304             put_extern_sym2(s, sec, s->jnext, 0, 0);
    305         }
    306         /* remove label */
    307         table_ident[s->v - TOK_IDENT]->sym_label = NULL;
    308         sym_free(s);
    309     }
    310     st->asm_labels = NULL;
     389        sym = asm_label_push(label);
     390    }
     391    if (!sym->c)
     392      put_extern_sym2(sym, SHN_UNDEF, 0, 0, 0);
     393    esym = elfsym(sym);
     394    esym->st_shndx = sh_num;
     395    esym->st_value = value;
     396    if (is_local != 2)
     397        sym->type.t &= ~VT_EXTERN;
     398    return sym;
     399}
     400
     401static Sym* asm_new_label(TCCState *s1, int label, int is_local)
     402{
     403    return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
     404}
     405
     406/* Set the value of LABEL to that of some expression (possibly
     407   involving other symbols).  LABEL can be overwritten later still.  */
     408static Sym* set_symbol(TCCState *s1, int label)
     409{
     410    long n;
     411    ExprValue e;
     412    Sym *sym;
     413    ElfSym *esym;
     414    next();
     415    asm_expr(s1, &e);
     416    n = e.v;
     417    esym = elfsym(e.sym);
     418    if (esym)
     419        n += esym->st_value;
     420    sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
     421    elfsym(sym)->st_other |= ST_ASM_SET;
     422    return sym;
    311423}
    312424
     
    325437}
    326438
    327 static void asm_parse_directive(TCCState *s1)
     439static void push_section(TCCState *s1, const char *name)
     440{
     441    Section *sec = find_section(s1, name);
     442    sec->prev = cur_text_section;
     443    use_section1(s1, sec);
     444}
     445
     446static void pop_section(TCCState *s1)
     447{
     448    Section *prev = cur_text_section->prev;
     449    if (!prev)
     450        tcc_error(".popsection without .pushsection");
     451    cur_text_section->prev = NULL;
     452    use_section1(s1, prev);
     453}
     454
     455static void asm_parse_directive(TCCState *s1, int global)
    328456{
    329457    int n, offset, v, size, tok1;
     
    332460
    333461    /* assembler directive */
    334     next();
    335462    sec = cur_text_section;
    336463    switch(tok) {
    337     case TOK_ASM_align:
    338     case TOK_ASM_skip:
    339     case TOK_ASM_space:
     464    case TOK_ASMDIR_align:
     465    case TOK_ASMDIR_balign:
     466    case TOK_ASMDIR_p2align:
     467    case TOK_ASMDIR_skip:
     468    case TOK_ASMDIR_space:
    340469        tok1 = tok;
    341470        next();
    342471        n = asm_int_expr(s1);
    343         if (tok1 == TOK_ASM_align) {
     472        if (tok1 == TOK_ASMDIR_p2align)
     473        {
     474            if (n < 0 || n > 30)
     475                tcc_error("invalid p2align, must be between 0 and 30");
     476            n = 1 << n;
     477            tok1 = TOK_ASMDIR_align;
     478        }
     479        if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
    344480            if (n < 0 || (n & (n-1)) != 0)
    345481                tcc_error("alignment must be a positive power of two");
     
    350486                sec->sh_addralign = n;
    351487        } else {
     488            if (n < 0)
     489                n = 0;
    352490            size = n;
    353491        }
     
    365503        ind += size;
    366504        break;
    367     case TOK_ASM_quad:
     505    case TOK_ASMDIR_quad:
     506#ifdef TCC_TARGET_X86_64
     507        size = 8;
     508        goto asm_data;
     509#else
    368510        next();
    369511        for(;;) {
     
    371513            const char *p;
    372514
    373             p = tokc.cstr->data;
     515            p = tokc.str.data;
    374516            if (tok != TOK_PPNUM) {
    375517            error_constant:
     
    392534        }
    393535        break;
    394     case TOK_ASM_byte:
     536#endif
     537    case TOK_ASMDIR_byte:
    395538        size = 1;
    396539        goto asm_data;
    397     case TOK_ASM_word:
    398     case TOK_SHORT:
     540    case TOK_ASMDIR_word:
     541    case TOK_ASMDIR_short:
    399542        size = 2;
    400543        goto asm_data;
    401     case TOK_LONG:
    402     case TOK_INT:
     544    case TOK_ASMDIR_long:
     545    case TOK_ASMDIR_int:
    403546        size = 4;
    404547    asm_data:
     
    410553                if (size == 4) {
    411554                    gen_expr32(&e);
     555#ifdef TCC_TARGET_X86_64
     556                } else if (size == 8) {
     557                    gen_expr64(&e);
     558#endif
    412559                } else {
    413560                    if (e.sym)
     
    426573        }
    427574        break;
    428     case TOK_ASM_fill:
     575    case TOK_ASMDIR_fill:
    429576        {
    430577            int repeat, size, val, i, j;
     
    468615        }
    469616        break;
    470     case TOK_ASM_org:
     617    case TOK_ASMDIR_rept:
     618        {
     619            int repeat;
     620            TokenString *init_str;
     621            next();
     622            repeat = asm_int_expr(s1);
     623            init_str = tok_str_alloc();
     624            while (next(), tok != TOK_ASMDIR_endr) {
     625                if (tok == CH_EOF)
     626                    tcc_error("we at end of file, .endr not found");
     627                tok_str_add_tok(init_str);
     628            }
     629            tok_str_add(init_str, -1);
     630            tok_str_add(init_str, 0);
     631            begin_macro(init_str, 1);
     632            while (repeat-- > 0) {
     633                tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
     634                                      global);
     635                macro_ptr = init_str->str;
     636            }
     637            end_macro();
     638            next();
     639            break;
     640        }
     641    case TOK_ASMDIR_org:
    471642        {
    472643            unsigned long n;
    473             next();
    474             /* XXX: handle section symbols too */
    475             n = asm_int_expr(s1);
     644            ExprValue e;
     645            ElfSym *esym;
     646            next();
     647            asm_expr(s1, &e);
     648            n = e.v;
     649            esym = elfsym(e.sym);
     650            if (esym) {
     651                if (esym->st_shndx != cur_text_section->sh_num)
     652                  expect("constant or same-section symbol");
     653                n += esym->st_value;
     654            }
    476655            if (n < ind)
    477656                tcc_error("attempt to .org backwards");
     
    481660        }
    482661        break;
    483     case TOK_ASM_globl:
    484     case TOK_ASM_global:
    485     case TOK_ASM_weak:
    486     tok1 = tok;
     662    case TOK_ASMDIR_set:
     663        next();
     664        tok1 = tok;
     665        next();
     666        /* Also accept '.set stuff', but don't do anything with this.
     667           It's used in GAS to set various features like '.set mips16'.  */
     668        if (tok == ',')
     669            set_symbol(s1, tok1);
     670        break;
     671    case TOK_ASMDIR_globl:
     672    case TOK_ASMDIR_global:
     673    case TOK_ASMDIR_weak:
     674    case TOK_ASMDIR_hidden:
     675        tok1 = tok;
    487676        do {
    488677            Sym *sym;
    489 
    490             next();
    491             sym = label_find(tok);
    492             if (!sym) {
    493                 sym = label_push(&s1->asm_labels, tok, 0);
    494                 sym->type.t = VT_VOID;
    495             }
    496             sym->type.t &= ~VT_STATIC;
    497             if (tok1 == TOK_ASM_weak)
    498                 sym->type.t |= VT_WEAK;
     678            next();
     679            sym = get_asm_sym(tok, NULL);
     680            if (tok1 != TOK_ASMDIR_hidden)
     681                sym->type.t &= ~VT_STATIC;
     682            if (tok1 == TOK_ASMDIR_weak)
     683                sym->a.weak = 1;
     684            else if (tok1 == TOK_ASMDIR_hidden)
     685                sym->a.visibility = STV_HIDDEN;
     686            update_storage(sym);
    499687            next();
    500688        } while (tok == ',');
    501689        break;
    502     case TOK_ASM_string:
    503     case TOK_ASM_ascii:
    504     case TOK_ASM_asciz:
     690    case TOK_ASMDIR_string:
     691    case TOK_ASMDIR_ascii:
     692    case TOK_ASMDIR_asciz:
    505693        {
    506694            const uint8_t *p;
     
    512700                if (tok != TOK_STR)
    513701                    expect("string constant");
    514                 p = tokc.cstr->data;
    515                 size = tokc.cstr->size;
    516                 if (t == TOK_ASM_ascii && size > 0)
     702                p = tokc.str.data;
     703                size = tokc.str.size;
     704                if (t == TOK_ASMDIR_ascii && size > 0)
    517705                    size--;
    518706                for(i = 0; i < size; i++)
     
    527715        }
    528716        break;
    529     case TOK_ASM_text:
    530     case TOK_ASM_data:
    531     case TOK_ASM_bss:
     717    case TOK_ASMDIR_text:
     718    case TOK_ASMDIR_data:
     719    case TOK_ASMDIR_bss:
    532720        {
    533721            char sname[64];
     
    539727                next();
    540728            }
    541             sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
     729            if (n)
     730                sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);
     731            else
     732                sprintf(sname, "%s", get_tok_str(tok1, NULL));
    542733            use_section(s1, sname);
    543734        }
    544735        break;
    545     case TOK_ASM_file:
     736    case TOK_ASMDIR_file:
    546737        {
    547738            char filename[512];
     
    551742
    552743            if (tok == TOK_STR)
    553                 pstrcat(filename, sizeof(filename), tokc.cstr->data);
     744                pstrcat(filename, sizeof(filename), tokc.str.data);
    554745            else
    555746                pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
     
    561752        }
    562753        break;
    563     case TOK_ASM_ident:
     754    case TOK_ASMDIR_ident:
    564755        {
    565756            char ident[256];
     
    569760
    570761            if (tok == TOK_STR)
    571                 pstrcat(ident, sizeof(ident), tokc.cstr->data);
     762                pstrcat(ident, sizeof(ident), tokc.str.data);
    572763            else
    573764                pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
     
    579770        }
    580771        break;
    581     case TOK_ASM_size:
     772    case TOK_ASMDIR_size:
    582773        {
    583774            Sym *sym;
    584775
    585776            next();
    586             sym = label_find(tok);
     777            sym = asm_label_find(tok);
    587778            if (!sym) {
    588779                tcc_error("label not found: %s", get_tok_str(tok, NULL));
    589780            }
    590781
    591             next();
    592             skip(',');
    593782            /* XXX .size name,label2-label1 */
    594783            if (s1->warn_unsupported)
    595784                tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
    596785
    597             while (tok != '\n' && tok != CH_EOF) {
     786            next();
     787            skip(',');
     788            while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
    598789                next();
    599790            }
    600791        }
    601792        break;
    602     case TOK_ASM_type:
     793    case TOK_ASMDIR_type:
    603794        {
    604795            Sym *sym;
     
    606797
    607798            next();
    608             sym = label_find(tok);
    609             if (!sym) {
    610                 sym = label_push(&s1->asm_labels, tok, 0);
    611                 sym->type.t = VT_VOID;
    612             }
    613 
     799            sym = get_asm_sym(tok, NULL);
    614800            next();
    615801            skip(',');
    616802            if (tok == TOK_STR) {
    617                 newtype = tokc.cstr->data;
     803                newtype = tokc.str.data;
    618804            } else {
    619805                if (tok == '@' || tok == '%')
    620                     skip(tok);
     806                    next();
    621807                newtype = get_tok_str(tok, NULL);
    622808            }
    623809
    624810            if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
    625                 sym->type.t = VT_FUNC;
     811                sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
    626812            }
    627813            else if (s1->warn_unsupported)
     
    632818        }
    633819        break;
    634     case TOK_SECTION1:
     820    case TOK_ASMDIR_pushsection:
     821    case TOK_ASMDIR_section:
    635822        {
    636823            char sname[256];
    637 
     824            int old_nb_section = s1->nb_sections;
     825
     826            tok1 = tok;
    638827            /* XXX: support more options */
    639828            next();
     
    641830            while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
    642831                if (tok == TOK_STR)
    643                     pstrcat(sname, sizeof(sname), tokc.cstr->data);
     832                    pstrcat(sname, sizeof(sname), tokc.str.data);
    644833                else
    645834                    pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
     
    652841                    expect("string constant");
    653842                next();
     843                if (tok == ',') {
     844                    next();
     845                    if (tok == '@' || tok == '%')
     846                        next();
     847                    next();
     848                }
    654849            }
    655850            last_text_section = cur_text_section;
    656             use_section(s1, sname);
    657         }
    658         break;
    659     case TOK_ASM_previous:
     851            if (tok1 == TOK_ASMDIR_section)
     852                use_section(s1, sname);
     853            else
     854                push_section(s1, sname);
     855            /* If we just allocated a new section reset its alignment to
     856               1.  new_section normally acts for GCC compatibility and
     857               sets alignment to PTR_SIZE.  The assembler behaves different. */
     858            if (old_nb_section != s1->nb_sections)
     859                cur_text_section->sh_addralign = 1;
     860        }
     861        break;
     862    case TOK_ASMDIR_previous:
    660863        {
    661864            Section *sec;
     
    668871        }
    669872        break;
     873    case TOK_ASMDIR_popsection:
     874        next();
     875        pop_section(s1);
     876        break;
    670877#ifdef TCC_TARGET_I386
    671     case TOK_ASM_code16:
     878    case TOK_ASMDIR_code16:
    672879        {
    673880            next();
     
    675882        }
    676883        break;
    677     case TOK_ASM_code32:
     884    case TOK_ASMDIR_code32:
    678885        {
    679886            next();
     
    684891#ifdef TCC_TARGET_X86_64
    685892    /* added for compatibility with GAS */
    686     case TOK_ASM_code64:
     893    case TOK_ASMDIR_code64:
    687894        next();
    688895        break;
     
    696903
    697904/* assemble a file */
    698 static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
     905static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
    699906{
    700907    int opcode;
    701 
    702 #if 0
    703     /* print stats about opcodes */
    704     {
    705         const ASMInstr *pa;
    706         int freq[4];
    707         int op_vals[500];
    708         int nb_op_vals, i, j;
    709 
    710         nb_op_vals = 0;
    711         memset(freq, 0, sizeof(freq));
    712         for(pa = asm_instrs; pa->sym != 0; pa++) {
    713             freq[pa->nb_ops]++;
    714             for(i=0;i<pa->nb_ops;i++) {
    715                 for(j=0;j<nb_op_vals;j++) {
    716                     if (pa->op_type[i] == op_vals[j])
    717                         goto found;
    718                 }
    719                 op_vals[nb_op_vals++] = pa->op_type[i];
    720             found: ;
    721             }
    722         }
    723         for(i=0;i<nb_op_vals;i++) {
    724             int v = op_vals[i];
    725             if ((v & (v - 1)) != 0)
    726                 printf("%3d: %08x\n", i, v);
    727         }
    728         printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
    729                sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
    730                freq[0], freq[1], freq[2], freq[3]);
    731     }
    732 #endif
    733 
    734     /* XXX: undefine C labels */
    735 
    736     ch = file->buf_ptr[0];
    737     tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
    738     parse_flags = PARSE_FLAG_ASM_COMMENTS;
     908    int saved_parse_flags = parse_flags;
     909
     910    parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
    739911    if (do_preprocess)
    740912        parse_flags |= PARSE_FLAG_PREPROCESS;
    741     next();
    742913    for(;;) {
     914        next();
    743915        if (tok == TOK_EOF)
    744916            break;
     917        /* generate line number info */
     918        if (global && s1->do_debug)
     919            tcc_debug_line(s1);
    745920        parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
    746921    redo:
     
    749924            while (tok != TOK_LINEFEED)
    750925                next();
    751         } else if (tok == '.') {
    752             asm_parse_directive(s1);
     926        } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
     927            asm_parse_directive(s1, global);
    753928        } else if (tok == TOK_PPNUM) {
    754929            const char *p;
    755930            int n;
    756             p = tokc.cstr->data;
     931            p = tokc.str.data;
    757932            n = strtoul(p, (char **)&p, 10);
    758933            if (*p != '\0')
     
    773948                goto redo;
    774949            } else if (tok == '=') {
    775                 int n;
    776                 next();
    777                 n = asm_int_expr(s1);
    778                 asm_new_label1(s1, opcode, 0, SHN_ABS, n);
     950                set_symbol(s1, opcode);
    779951                goto redo;
    780952            } else {
     
    783955        }
    784956        /* end of line */
    785         if (tok != ';' && tok != TOK_LINEFEED){
     957        if (tok != ';' && tok != TOK_LINEFEED)
    786958            expect("end of line");
    787         }
    788959        parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
    789         next();
    790     }
    791 
    792     asm_free_labels(s1);
    793 
     960    }
     961
     962    parse_flags = saved_parse_flags;
    794963    return 0;
    795964}
     
    798967ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
    799968{
    800     Sym *define_start;
    801969    int ret;
    802 
    803     preprocess_init(s1);
    804 
     970    tcc_debug_start(s1);
    805971    /* default section is text */
    806972    cur_text_section = text_section;
    807973    ind = cur_text_section->data_offset;
    808 
    809     define_start = define_stack;
    810 
    811     /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
    812        symbols can be safely used */
    813     put_elf_sym(symtab_section, 0, 0,
    814                 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
    815                 SHN_ABS, file->filename);
    816 
    817     ret = tcc_assemble_internal(s1, do_preprocess);
    818 
     974    nocode_wanted = 0;
     975    ret = tcc_assemble_internal(s1, do_preprocess, 1);
    819976    cur_text_section->data_offset = ind;
    820 
    821     free_defines(define_start);
    822 
     977    tcc_debug_end(s1);
    823978    return ret;
    824979}
     
    830985   C preprocessing. NOTE: str is modified by modifying the '\0' at the
    831986   end */
    832 static void tcc_assemble_inline(TCCState *s1, char *str, int len)
    833 {
    834     int saved_parse_flags;
    835     const int *saved_macro_ptr;
    836 
    837     saved_parse_flags = parse_flags;
    838     saved_macro_ptr = macro_ptr;
     987static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
     988{
     989    const int *saved_macro_ptr = macro_ptr;
     990    int dotid = set_idnum('.', IS_ID);
    839991
    840992    tcc_open_bf(s1, ":asm:", len);
    841993    memcpy(file->buffer, str, len);
    842 
    843994    macro_ptr = NULL;
    844     tcc_assemble_internal(s1, 0);
     995    tcc_assemble_internal(s1, 0, global);
    845996    tcc_close();
    846997
    847     parse_flags = saved_parse_flags;
     998    set_idnum('.', dotid);
    848999    macro_ptr = saved_macro_ptr;
    8491000}
     
    8911042
    8921043static void subst_asm_operands(ASMOperand *operands, int nb_operands,
    893                                int nb_outputs,
    8941044                               CString *out_str, CString *in_str)
    8951045{
     
    9101060            modifier = 0;
    9111061            if (*str == 'c' || *str == 'n' ||
    912                 *str == 'b' || *str == 'w' || *str == 'h')
     1062                *str == 'b' || *str == 'w' || *str == 'h' || *str == 'k' ||
     1063                *str == 'q' ||
     1064                /* P in GCC would add "@PLT" to symbol refs in PIC mode,
     1065                   and make literal operands not be decorated with '$'.  */
     1066                *str == 'P')
    9131067                modifier = *str++;
    9141068            index = find_constraint(operands, nb_operands, str, &str);
     
    9421096        nb_operands = *nb_operands_ptr;
    9431097        for(;;) {
     1098            CString astr;
    9441099            if (nb_operands >= MAX_ASM_OPERANDS)
    9451100                tcc_error("too many asm operands");
     
    9541109                skip(']');
    9551110            }
    956             if (tok != TOK_STR)
    957                 expect("string constant");
    958             op->constraint = tcc_malloc(tokc.cstr->size);
    959             strcpy(op->constraint, tokc.cstr->data);
    960             next();
     1111            parse_mult_str(&astr, "string constant");
     1112            op->constraint = tcc_malloc(astr.size);
     1113            strcpy(op->constraint, astr.data);
     1114            cstr_free(&astr);
    9611115            skip('(');
    9621116            gexpr();
    9631117            if (is_output) {
    964                 test_lvalue();
     1118                if (!(vtop->type.t & VT_ARRAY))
     1119                    test_lvalue();
    9651120            } else {
    9661121                /* we want to avoid LLOCAL case, except when the 'm'
     
    10241179                        if (tok != TOK_STR)
    10251180                            expect("string constant");
    1026                         asm_clobber(clobber_regs, tokc.cstr->data);
     1181                        asm_clobber(clobber_regs, tokc.str.data);
    10271182                        next();
    10281183                        if (tok == ',') {
     
    10551210#endif
    10561211    if (must_subst) {
    1057         subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
     1212        subst_asm_operands(operands, nb_operands, &astr1, &astr);
    10581213        cstr_free(&astr);
    10591214    } else {
     
    10691224
    10701225    /* assemble the string with tcc internal assembler */
    1071     tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
     1226    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0);
    10721227
    10731228    /* restore the current C token */
     
    10911246{
    10921247    CString astr;
    1093 
     1248    int saved_nocode_wanted = nocode_wanted;
     1249
     1250    /* Global asm blocks are always emitted.  */
     1251    nocode_wanted = 0;
    10941252    next();
    10951253    parse_asm_str(&astr);
     
    11071265
    11081266    /* assemble the string with tcc internal assembler */
    1109     tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
     1267    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1);
    11101268   
    11111269    cur_text_section->data_offset = ind;
     
    11151273
    11161274    cstr_free(&astr);
     1275    nocode_wanted = saved_nocode_wanted;
    11171276}
    11181277#endif /* CONFIG_TCC_ASM */
  • EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c

    r321 r331  
    11/*
    22 *  ELF file handling for TCC
    3  * 
     3 *
    44 *  Copyright (c) 2001-2004 Fabrice Bellard
    55 *
     
    2121#include "tcc.h"
    2222
     23/* Define this to get some debug output during relocation processing.  */
     24#undef DEBUG_RELOC
     25
     26/********************************************************/
     27/* global variables */
     28
     29ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
     30ST_DATA Section *common_section;
     31ST_DATA Section *cur_text_section; /* current section where function code is generated */
     32#ifdef CONFIG_TCC_ASM
     33ST_DATA Section *last_text_section; /* to handle .previous asm directive */
     34#endif
     35#ifdef CONFIG_TCC_BCHECK
     36/* bound check related sections */
     37ST_DATA Section *bounds_section; /* contains global data bound description */
     38ST_DATA Section *lbounds_section; /* contains local data bound description */
     39#endif
     40/* symbol sections */
     41ST_DATA Section *symtab_section;
     42/* debug sections */
     43ST_DATA Section *stab_section, *stabstr_section;
     44
     45/* XXX: avoid static variable */
    2346static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
     47
     48/* special flag to indicate that the section should not be linked to the other ones */
     49#define SHF_PRIVATE 0x80000000
     50/* section is dynsymtab_section */
     51#define SHF_DYNSYM 0x40000000
     52
     53/* ------------------------------------------------------------------------- */
     54
     55ST_FUNC void tccelf_new(TCCState *s)
     56{
     57    /* no section zero */
     58    dynarray_add(&s->sections, &s->nb_sections, NULL);
     59
     60    /* create standard sections */
     61    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
     62    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
     63    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
     64    common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
     65    common_section->sh_num = SHN_COMMON;
     66
     67    /* symbols are always generated for linking stage */
     68    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
     69                                ".strtab",
     70                                ".hashtab", SHF_PRIVATE);
     71    s->symtab = symtab_section;
     72
     73    /* private symbol table for dynamic symbols */
     74    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
     75                                      ".dynstrtab",
     76                                      ".dynhashtab", SHF_PRIVATE);
     77    get_sym_attr(s, 0, 1);
     78}
     79
     80#ifdef CONFIG_TCC_BCHECK
     81ST_FUNC void tccelf_bounds_new(TCCState *s)
     82{
     83    /* create bounds sections */
     84    bounds_section = new_section(s, ".bounds",
     85                                 SHT_PROGBITS, SHF_ALLOC);
     86    lbounds_section = new_section(s, ".lbounds",
     87                                  SHT_PROGBITS, SHF_ALLOC);
     88}
     89#endif
     90
     91ST_FUNC void tccelf_stab_new(TCCState *s)
     92{
     93    stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
     94    stab_section->sh_entsize = sizeof(Stab_Sym);
     95    stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
     96    put_elf_str(stabstr_section, "");
     97    stab_section->link = stabstr_section;
     98    /* put first entry */
     99    put_stabs("", 0, 0, 0, 0);
     100}
     101
     102static void free_section(Section *s)
     103{
     104    tcc_free(s->data);
     105}
     106
     107ST_FUNC void tccelf_delete(TCCState *s1)
     108{
     109    int i;
     110
     111    /* free all sections */
     112    for(i = 1; i < s1->nb_sections; i++)
     113        free_section(s1->sections[i]);
     114    dynarray_reset(&s1->sections, &s1->nb_sections);
     115
     116    for(i = 0; i < s1->nb_priv_sections; i++)
     117        free_section(s1->priv_sections[i]);
     118    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
     119
     120    /* free any loaded DLLs */
     121#ifdef TCC_IS_NATIVE
     122    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
     123        DLLReference *ref = s1->loaded_dlls[i];
     124        if ( ref->handle )
     125# ifdef _WIN32
     126            FreeLibrary((HMODULE)ref->handle);
     127# else
     128            dlclose(ref->handle);
     129# endif
     130    }
     131#endif
     132    /* free loaded dlls array */
     133    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
     134    tcc_free(s1->sym_attrs);
     135
     136    symtab_section = NULL; /* for tccrun.c:rt_printline() */
     137}
     138
     139/* save section data state */
     140ST_FUNC void tccelf_begin_file(TCCState *s1)
     141{
     142    Section *s; int i;
     143    for (i = 1; i < s1->nb_sections; i++) {
     144        s = s1->sections[i];
     145        s->sh_offset = s->data_offset;
     146    }
     147    /* disable symbol hashing during compilation */
     148    s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
     149#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
     150    s1->uw_sym = 0;
     151#endif
     152}
     153
     154/* At the end of compilation, convert any UNDEF syms to global, and merge
     155   with previously existing symbols */
     156ST_FUNC void tccelf_end_file(TCCState *s1)
     157{
     158    Section *s = s1->symtab;
     159    int first_sym, nb_syms, *tr, i;
     160
     161    first_sym = s->sh_offset / sizeof (ElfSym);
     162    nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
     163    s->data_offset = s->sh_offset;
     164    s->link->data_offset = s->link->sh_offset;
     165    s->hash = s->reloc, s->reloc = NULL;
     166    tr = tcc_mallocz(nb_syms * sizeof *tr);
     167
     168    for (i = 0; i < nb_syms; ++i) {
     169        ElfSym *sym = (ElfSym*)s->data + first_sym + i;
     170        if (sym->st_shndx == SHN_UNDEF
     171            && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
     172            sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
     173        tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
     174            sym->st_other, sym->st_shndx, s->link->data + sym->st_name);
     175    }
     176    /* now update relocations */
     177    for (i = 1; i < s1->nb_sections; i++) {
     178        Section *sr = s1->sections[i];
     179        if (sr->sh_type == SHT_RELX && sr->link == s) {
     180            ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
     181            ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
     182            for (; rel < rel_end; ++rel) {
     183                int n = ELFW(R_SYM)(rel->r_info) - first_sym;
     184                //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
     185                rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
     186            }
     187        }
     188    }
     189    tcc_free(tr);
     190}
     191
     192ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
     193{
     194    Section *sec;
     195
     196    sec = tcc_mallocz(sizeof(Section) + strlen(name));
     197    strcpy(sec->name, name);
     198    sec->sh_type = sh_type;
     199    sec->sh_flags = sh_flags;
     200    switch(sh_type) {
     201    case SHT_HASH:
     202    case SHT_REL:
     203    case SHT_RELA:
     204    case SHT_DYNSYM:
     205    case SHT_SYMTAB:
     206    case SHT_DYNAMIC:
     207        sec->sh_addralign = 4;
     208        break;
     209    case SHT_STRTAB:
     210        sec->sh_addralign = 1;
     211        break;
     212    default:
     213        sec->sh_addralign =  PTR_SIZE; /* gcc/pcc default alignment */
     214        break;
     215    }
     216
     217    if (sh_flags & SHF_PRIVATE) {
     218        dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
     219    } else {
     220        sec->sh_num = s1->nb_sections;
     221        dynarray_add(&s1->sections, &s1->nb_sections, sec);
     222    }
     223
     224    return sec;
     225}
     226
     227ST_FUNC Section *new_symtab(TCCState *s1,
     228                           const char *symtab_name, int sh_type, int sh_flags,
     229                           const char *strtab_name,
     230                           const char *hash_name, int hash_sh_flags)
     231{
     232    Section *symtab, *strtab, *hash;
     233    int *ptr, nb_buckets;
     234
     235    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
     236    symtab->sh_entsize = sizeof(ElfW(Sym));
     237    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
     238    put_elf_str(strtab, "");
     239    symtab->link = strtab;
     240    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
     241
     242    nb_buckets = 1;
     243
     244    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
     245    hash->sh_entsize = sizeof(int);
     246    symtab->hash = hash;
     247    hash->link = symtab;
     248
     249    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
     250    ptr[0] = nb_buckets;
     251    ptr[1] = 1;
     252    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
     253    return symtab;
     254}
     255
     256/* realloc section and set its content to zero */
     257ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
     258{
     259    unsigned long size;
     260    unsigned char *data;
     261
     262    size = sec->data_allocated;
     263    if (size == 0)
     264        size = 1;
     265    while (size < new_size)
     266        size = size * 2;
     267    data = tcc_realloc(sec->data, size);
     268    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
     269    sec->data = data;
     270    sec->data_allocated = size;
     271}
     272
     273/* reserve at least 'size' bytes aligned per 'align' in section
     274   'sec' from current offset, and return the aligned offset */
     275ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
     276{
     277    size_t offset, offset1;
     278
     279    offset = (sec->data_offset + align - 1) & -align;
     280    offset1 = offset + size;
     281    if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
     282        section_realloc(sec, offset1);
     283    sec->data_offset = offset1;
     284    if (align > sec->sh_addralign)
     285        sec->sh_addralign = align;
     286    return offset;
     287}
     288
     289/* reserve at least 'size' bytes in section 'sec' from
     290   sec->data_offset. */
     291ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
     292{
     293    size_t offset = section_add(sec, size, 1);
     294    return sec->data + offset;
     295}
     296
     297/* reserve at least 'size' bytes from section start */
     298ST_FUNC void section_reserve(Section *sec, unsigned long size)
     299{
     300    if (size > sec->data_allocated)
     301        section_realloc(sec, size);
     302    if (size > sec->data_offset)
     303        sec->data_offset = size;
     304}
     305
     306/* return a reference to a section, and create it if it does not
     307   exists */
     308ST_FUNC Section *find_section(TCCState *s1, const char *name)
     309{
     310    Section *sec;
     311    int i;
     312    for(i = 1; i < s1->nb_sections; i++) {
     313        sec = s1->sections[i];
     314        if (!strcmp(name, sec->name))
     315            return sec;
     316    }
     317    /* sections are created as PROGBITS */
     318    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
     319}
     320
     321/* ------------------------------------------------------------------------- */
    24322
    25323ST_FUNC int put_elf_str(Section *s, const char *sym)
     
    31329    offset = s->data_offset;
    32330    ptr = section_ptr_add(s, len);
    33     memcpy(ptr, sym, len);
     331    memmove(ptr, sym, len);
    34332    return offset;
    35333}
     
    39337{
    40338    unsigned long h = 0, g;
    41    
     339
    42340    while (*name) {
    43341        h = (h << 4) + *name++;
     
    56354    ElfW(Sym) *sym;
    57355    int *ptr, *hash, nb_syms, sym_index, h;
    58     char *strtab;
     356    unsigned char *strtab;
    59357
    60358    strtab = s->link->data;
    61359    nb_syms = s->data_offset / sizeof(ElfW(Sym));
     360
     361    if (!nb_buckets)
     362        nb_buckets = ((int*)s->hash->data)[0];
    62363
    63364    s->hash->data_offset = 0;
     
    92393    ElfW(Sym) *sym;
    93394    Section *hs;
    94    
     395
    95396    sym = section_ptr_add(s, sizeof(ElfW(Sym)));
    96     if (name)
     397    if (name && name[0])
    97398        name_offset = put_elf_str(s->link, name);
    98399    else
     
    111412        ptr = section_ptr_add(hs, sizeof(int));
    112413        base = (int *)hs->data;
    113         /* only add global or weak symbols */
     414        /* only add global or weak symbols. */
    114415        if (ELFW(ST_BIND)(info) != STB_LOCAL) {
    115416            /* add another hashing entry */
    116417            nbuckets = base[0];
    117             h = elf_hash(name) % nbuckets;
     418            h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
    118419            *ptr = base[2 + h];
    119420            base[2 + h] = sym_index;
     
    132433}
    133434
    134 /* find global ELF symbol 'name' and return its index. Return 0 if not
    135    found. */
    136435ST_FUNC int find_elf_sym(Section *s, const char *name)
    137436{
     
    140439    int nbuckets, sym_index, h;
    141440    const char *name1;
    142    
     441
    143442    hs = s->hash;
    144443    if (!hs)
    145444        return 0;
    146445    nbuckets = ((int *)hs->data)[0];
    147     h = elf_hash(name) % nbuckets;
     446    h = elf_hash((unsigned char *) name) % nbuckets;
    148447    sym_index = ((int *)hs->data)[2 + h];
    149448    while (sym_index != 0) {
    150449        sym = &((ElfW(Sym) *)s->data)[sym_index];
    151         name1 = s->link->data + sym->st_name;
     450        name1 = (char *) s->link->data + sym->st_name;
    152451        if (!strcmp(name, name1))
    153452            return sym_index;
     
    179478}
    180479
    181 #ifdef TCC_IS_NATIVE
     480#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
    182481/* return elf symbol value or error */
    183482ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
    184483{
    185     return (void*)get_elf_sym_addr(s, name, 1);
     484    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
    186485}
    187486#endif
     
    189488/* add an elf symbol : check if it is already defined and patch
    190489   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
    191 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
    192                        int info, int other, int sh_num, const char *name)
     490ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
     491                       int info, int other, int shndx, const char *name)
    193492{
    194493    ElfW(Sym) *esym;
     
    199498    sym_type = ELFW(ST_TYPE)(info);
    200499    sym_vis = ELFW(ST_VISIBILITY)(other);
    201        
     500
    202501    if (sym_bind != STB_LOCAL) {
    203502        /* we search global or weak symbols */
     
    206505            goto do_def;
    207506        esym = &((ElfW(Sym) *)s->data)[sym_index];
     507        if (esym->st_value == value && esym->st_size == size && esym->st_info == info
     508            && esym->st_other == other && esym->st_shndx == shndx)
     509            return sym_index;
    208510        if (esym->st_shndx != SHN_UNDEF) {
    209511            esym_bind = ELFW(ST_BIND)(esym->st_info);
     
    221523                             | new_vis;
    222524            other = esym->st_other; /* in case we have to patch esym */
    223             if (sh_num == SHN_UNDEF) {
     525            if (shndx == SHN_UNDEF) {
    224526                /* ignore adding of undefined symbol if the
    225527                   corresponding symbol is already defined */
     
    233535            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
    234536                /* ignore hidden symbols after */
    235             } else if (esym->st_shndx == SHN_COMMON
    236                     && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
    237                 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
    238                    No idea if this is the correct solution ... */
     537            } else if ((esym->st_shndx == SHN_COMMON
     538                            || esym->st_shndx == bss_section->sh_num)
     539                        && (shndx < SHN_LORESERVE
     540                            && shndx != bss_section->sh_num)) {
     541                /* data symbol gets precedence over common/bss */
    239542                goto do_patch;
    240             } else if (s == tcc_state->dynsymtab_section) {
     543            } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
     544                /* data symbol keeps precedence over common/bss */
     545            } else if (s->sh_flags & SHF_DYNSYM) {
    241546                /* we accept that two DLL define the same symbol */
     547            } else if (esym->st_other & ST_ASM_SET) {
     548                /* If the existing symbol came from an asm .set
     549                   we can override.  */
     550                goto do_patch;
    242551            } else {
    243552#if 0
    244553                printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
    245                        sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
     554                       sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
    246555#endif
    247556                tcc_error_noabort("'%s' defined twice", name);
     
    250559        do_patch:
    251560            esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
    252             esym->st_shndx = sh_num;
     561            esym->st_shndx = shndx;
    253562            new_undef_sym = 1;
    254563            esym->st_value = value;
     
    258567    } else {
    259568    do_def:
    260         sym_index = put_elf_sym(s, value, size, 
    261                                 ELFW(ST_INFO)(sym_bind, sym_type), other, 
    262                                 sh_num, name);
     569        sym_index = put_elf_sym(s, value, size,
     570                                ELFW(ST_INFO)(sym_bind, sym_type), other,
     571                                shndx, name);
    263572    }
    264573    return sym_index;
     
    266575
    267576/* put relocation */
    268 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
    269                           int type, int symbol)
     577ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
     578                            int type, int symbol, addr_t addend)
    270579{
    271580    char buf[256];
     
    288597    rel->r_offset = offset;
    289598    rel->r_info = ELFW(R_INFO)(symbol, type);
    290 #ifdef TCC_TARGET_X86_64
    291     rel->r_addend = 0;
    292 #endif
     599#if SHT_RELX == SHT_RELA
     600    rel->r_addend = addend;
     601#else
     602    if (addend)
     603        tcc_error("non-zero addend on REL architecture");
     604#endif
     605}
     606
     607ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
     608                           int type, int symbol)
     609{
     610    put_elf_reloca(symtab, s, offset, type, symbol, 0);
     611}
     612
     613/* Remove relocations for section S->reloc starting at oldrelocoffset
     614   that are to the same place, retaining the last of them.  As side effect
     615   the relocations are sorted.  Possibly reduces the number of relocs.  */
     616ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
     617{
     618    Section *sr = s->reloc;
     619    ElfW_Rel *r, *dest;
     620    ssize_t a;
     621    ElfW(Addr) addr;
     622
     623    if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
     624      return;
     625    /* The relocs we're dealing with are the result of initializer parsing.
     626       So they will be mostly in order and there aren't many of them.
     627       Secondly we need a stable sort (which qsort isn't).  We use
     628       a simple insertion sort.  */
     629    for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
     630        ssize_t i = a - sizeof(*r);
     631        addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
     632        for (; i >= (ssize_t)oldrelocoffset &&
     633               ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
     634            ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
     635            *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
     636            *(ElfW_Rel*)(sr->data + i) = tmp;
     637        }
     638    }
     639
     640    r = (ElfW_Rel*)(sr->data + oldrelocoffset);
     641    dest = r;
     642    for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
     643        if (dest->r_offset != r->r_offset)
     644          dest++;
     645        *dest = *r;
     646    }
     647    sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
    293648}
    294649
     
    312667}
    313668
    314 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, 
     669ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
    315670                        unsigned long value, Section *sec, int sym_index)
    316671{
    317672    put_stabs(str, type, other, desc, value);
    318     put_elf_reloc(symtab_section, stab_section, 
     673    put_elf_reloc(symtab_section, stab_section,
    319674                  stab_section->data_offset - sizeof(unsigned int),
    320675                  R_DATA_32, sym_index);
     
    331686}
    332687
    333 /* In an ELF file symbol table, the local symbols must appear below
    334    the global and weak ones. Since TCC cannot sort it while generating
    335    the code, we must do it after. All the relocation tables are also
    336    modified to take into account the symbol table sorting */
    337 static void sort_syms(TCCState *s1, Section *s)
    338 {
    339     int *old_to_new_syms;
    340     ElfW(Sym) *new_syms;
    341     int nb_syms, i;
    342     ElfW(Sym) *p, *q;
    343     ElfW_Rel *rel, *rel_end;
    344     Section *sr;
    345     int type, sym_index;
    346 
    347     nb_syms = s->data_offset / sizeof(ElfW(Sym));
    348     new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
    349     old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
    350 
    351     /* first pass for local symbols */
    352     p = (ElfW(Sym) *)s->data;
    353     q = new_syms;
    354     for(i = 0; i < nb_syms; i++) {
    355         if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
    356             old_to_new_syms[i] = q - new_syms;
    357             *q++ = *p;
    358         }
    359         p++;
    360     }
    361     /* save the number of local symbols in section header */
    362     s->sh_info = q - new_syms;
    363 
    364     /* then second pass for non local symbols */
    365     p = (ElfW(Sym) *)s->data;
    366     for(i = 0; i < nb_syms; i++) {
    367         if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
    368             old_to_new_syms[i] = q - new_syms;
    369             *q++ = *p;
    370         }
    371         p++;
    372     }
    373    
    374     /* we copy the new symbols to the old */
    375     memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
    376     tcc_free(new_syms);
    377 
    378     /* now we modify all the relocations */
    379     for(i = 1; i < s1->nb_sections; i++) {
    380         sr = s1->sections[i];
    381         if (sr->sh_type == SHT_RELX && sr->link == s) {
    382             rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    383             for(rel = (ElfW_Rel *)sr->data;
    384                 rel < rel_end;
    385                 rel++) {
    386                 sym_index = ELFW(R_SYM)(rel->r_info);
    387                 type = ELFW(R_TYPE)(rel->r_info);
    388                 sym_index = old_to_new_syms[sym_index];
    389                 rel->r_info = ELFW(R_INFO)(sym_index, type);
    390             }
    391         }
    392     }
    393    
    394     tcc_free(old_to_new_syms);
    395 }
    396 
    397 /* relocate common symbols in the .bss section */
    398 ST_FUNC void relocate_common_syms(void)
    399 {
    400     ElfW(Sym) *sym, *sym_end;
    401     unsigned long offset, align;
    402    
    403     sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
    404     for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    405         sym < sym_end;
    406         sym++) {
    407         if (sym->st_shndx == SHN_COMMON) {
    408             /* align symbol */
    409             align = sym->st_value;
    410             offset = bss_section->data_offset;
    411             offset = (offset + align - 1) & -align;
    412             sym->st_value = offset;
    413             sym->st_shndx = bss_section->sh_num;
    414             offset += sym->st_size;
    415             bss_section->data_offset = offset;
    416         }
    417     }
    418 }
    419 
    420 /* relocate symbol table, resolve undefined symbols if do_resolve is
    421    true and output error if undefined symbol. */
    422 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
    423 {
    424     ElfW(Sym) *sym, *esym, *sym_end;
    425     int sym_bind, sh_num, sym_index;
    426     const char *name;
    427 
    428     sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
    429     for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    430         sym < sym_end;
    431         sym++) {
    432         sh_num = sym->st_shndx;
    433         if (sh_num == SHN_UNDEF) {
    434             name = strtab_section->data + sym->st_name;
    435             if (do_resolve) {
    436 #if defined TCC_IS_NATIVE && !defined _WIN32
    437                 void *addr;
    438                 name = symtab_section->link->data + sym->st_name;
    439                 addr = resolve_sym(s1, name);
    440                 if (addr) {
    441                     sym->st_value = (addr_t)addr;
    442                     goto found;
    443                 }
    444 #endif
    445             } else if (s1->dynsym) {
    446                 /* if dynamic symbol exist, then use it */
    447                 sym_index = find_elf_sym(s1->dynsym, name);
    448                 if (sym_index) {
    449                     esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
    450                     sym->st_value = esym->st_value;
    451                     goto found;
    452                 }
    453             }
    454             /* XXX: _fp_hw seems to be part of the ABI, so we ignore
    455                it */
    456             if (!strcmp(name, "_fp_hw"))
    457                 goto found;
    458             /* only weak symbols are accepted to be undefined. Their
    459                value is zero */
    460             sym_bind = ELFW(ST_BIND)(sym->st_info);
    461             if (sym_bind == STB_WEAK) {
    462                 sym->st_value = 0;
    463             } else {
    464                 tcc_error_noabort("undefined symbol '%s'", name);
    465             }
    466         } else if (sh_num < SHN_LORESERVE) {
    467             /* add section base */
    468             sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
    469         }
    470     found: ;
    471     }
    472 }
    473 
    474 #ifdef TCC_HAS_RUNTIME_PLTGOT
    475 #ifdef TCC_TARGET_X86_64
    476 #define JMP_TABLE_ENTRY_SIZE 14
    477 static addr_t add_jmp_table(TCCState *s1, addr_t val)
    478 {
    479     char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
    480     s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
    481     /* jmp *0x0(%rip) */
    482     p[0] = 0xff;
    483     p[1] = 0x25;
    484     *(int *)(p + 2) = 0;
    485     *(addr_t *)(p + 6) = val;
    486     return (addr_t)p;
    487 }
    488 
    489 static addr_t add_got_table(TCCState *s1, addr_t val)
    490 {
    491     addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
    492     s1->runtime_plt_and_got_offset += sizeof(addr_t);
    493     *p = val;
    494     return (addr_t)p;
    495 }
    496 #elif defined TCC_TARGET_ARM
    497 #define JMP_TABLE_ENTRY_SIZE 8
    498 static addr_t add_jmp_table(TCCState *s1, int val)
    499 {
    500     uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
    501     s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
    502     /* ldr pc, [pc, #-4] */
    503     p[0] = 0xE51FF004;
    504     p[1] = val;
    505     return (addr_t)p;
    506 }
    507 #endif
    508 #endif /* def TCC_HAS_RUNTIME_PLTGOT */
    509 
    510 /* relocate a given section (CPU dependent) */
    511 ST_FUNC void relocate_section(TCCState *s1, Section *s)
    512 {
    513     Section *sr;
    514     ElfW_Rel *rel, *rel_end, *qrel;
    515     ElfW(Sym) *sym;
    516     int type, sym_index;
    517     unsigned char *ptr;
    518     addr_t val, addr;
    519 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    520     int esym_index;
    521 #endif
    522 
    523     sr = s->reloc;
    524     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    525     qrel = (ElfW_Rel *)sr->data;
    526     for(rel = qrel;
    527         rel < rel_end;
    528         rel++) {
    529         ptr = s->data + rel->r_offset;
    530 
    531         sym_index = ELFW(R_SYM)(rel->r_info);
    532         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    533         val = sym->st_value;
    534 #ifdef TCC_TARGET_X86_64
    535         val += rel->r_addend;
    536 #endif
    537         type = ELFW(R_TYPE)(rel->r_info);
    538         addr = s->sh_addr + rel->r_offset;
    539 
    540         /* CPU specific */
    541         switch(type) {
    542 #if defined(TCC_TARGET_I386)
    543         case R_386_32:
    544             if (s1->output_type == TCC_OUTPUT_DLL) {
    545                 esym_index = s1->symtab_to_dynsym[sym_index];
    546                 qrel->r_offset = rel->r_offset;
    547                 if (esym_index) {
    548                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
    549                     qrel++;
    550                     break;
    551                 } else {
    552                     qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
    553                     qrel++;
    554                 }
    555             }
    556             *(int *)ptr += val;
    557             break;
    558         case R_386_PC32:
    559             if (s1->output_type == TCC_OUTPUT_DLL) {
    560                 /* DLL relocation */
    561                 esym_index = s1->symtab_to_dynsym[sym_index];
    562                 if (esym_index) {
    563                     qrel->r_offset = rel->r_offset;
    564                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
    565                     qrel++;
    566                     break;
    567                 }
    568             }
    569             *(int *)ptr += val - addr;
    570             break;
    571         case R_386_PLT32:
    572             *(int *)ptr += val - addr;
    573             break;
    574         case R_386_GLOB_DAT:
    575         case R_386_JMP_SLOT:
    576             *(int *)ptr = val;
    577             break;
    578         case R_386_GOTPC:
    579             *(int *)ptr += s1->got->sh_addr - addr;
    580             break;
    581         case R_386_GOTOFF:
    582             *(int *)ptr += val - s1->got->sh_addr;
    583             break;
    584         case R_386_GOT32:
    585             /* we load the got offset */
    586             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
    587             break;
    588         case R_386_16:
    589             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
    590             output_file:
    591             tcc_error("can only produce 16-bit binary files");
    592             }
    593             *(short *)ptr += val;
    594             break;
    595         case R_386_PC16:
    596             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
    597             goto output_file;
    598             *(short *)ptr += val - addr;
    599             break;
    600 #elif defined(TCC_TARGET_ARM)
    601         case R_ARM_PC24:
    602         case R_ARM_CALL:
    603         case R_ARM_JUMP24:
    604         case R_ARM_PLT32:
    605             {
    606                 int x, is_thumb, is_call, h, blx_avail;
    607                 x = (*(int *)ptr)&0xffffff;
    608                 (*(int *)ptr) &= 0xff000000;
    609                 if (x & 0x800000)
    610                     x -= 0x1000000;
    611                 x <<= 2;
    612                 blx_avail = (TCC_ARM_VERSION >= 5);
    613                 is_thumb = val & 1;
    614                 is_call = (type == R_ARM_CALL);
    615                 x += val - addr;
    616                 h = x & 2;
    617 #ifdef TCC_HAS_RUNTIME_PLTGOT
    618                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
    619                     if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
    620                         if (!(x & 3) || !blx_avail || !is_call) {
    621                             x += add_jmp_table(s1, val) - val; /* add veneer */
    622                             is_thumb = 0; /* Veneer uses ARM instructions */
    623                         }
    624                 }
    625 #endif
    626                 if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
    627                     if (!(x & 3) || !blx_avail || !is_call)
    628                         tcc_error("can't relocate value at %x",addr);
    629                 x >>= 2;
    630                 x &= 0xffffff;
    631                 /* Only reached if blx is avail and it is a call */
    632                 if (is_thumb) {
    633                     x |= h << 24;
    634                     (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
    635                 }
    636                 (*(int *)ptr) |= x;
    637             }
    638             break;
    639         /* Since these relocations only concern Thumb-2 and blx instruction was
    640            introduced before Thumb-2, we can assume blx is available and not
    641            guard its use */
    642         case R_ARM_THM_CALL:
    643         case R_ARM_THM_JUMP24:
    644             {
    645                 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
    646                 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
    647                 Section *plt;
    648 
    649                 /* weak reference */
    650                 if (sym->st_shndx == SHN_UNDEF &&
    651                     ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
    652                     break;
    653 
    654                 /* Get initial offset */
    655                 hi = (*(uint16_t *)ptr);
    656                 lo = (*(uint16_t *)(ptr+2));
    657                 s = (hi >> 10) & 1;
    658                 j1 = (lo >> 13) & 1;
    659                 j2 = (lo >> 11) & 1;
    660                 i1 = (j1 ^ s) ^ 1;
    661                 i2 = (j2 ^ s) ^ 1;
    662                 imm10 = hi & 0x3ff;
    663                 imm11 = lo & 0x7ff;
    664                 x = (s << 24) | (i1 << 23) | (i2 << 22) |
    665                     (imm10 << 12) | (imm11 << 1);
    666                 if (x & 0x01000000)
    667                     x -= 0x02000000;
    668 
    669                 /* Relocation infos */
    670                 to_thumb = val & 1;
    671                 plt = s1->plt;
    672                 to_plt = (val >= plt->sh_addr) &&
    673                          (val < plt->sh_addr + plt->data_offset);
    674                 is_call = (type == R_ARM_THM_CALL);
    675 
    676                 /* Compute final offset */
    677                 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
    678                     x -= 4;
    679                 x += val - addr;
    680                 if (!to_thumb && is_call) {
    681                     blx_bit = 0; /* bl -> blx */
    682                     x = (x + 3) & -4; /* Compute offset from aligned PC */
    683                 }
    684 
    685                 /* Check that relocation is possible
    686                    * offset must not be out of range
    687                    * if target is to be entered in arm mode:
    688                      - bit 1 must not set
    689                      - instruction must be a call (bl) or a jump to PLT */
    690                 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
    691                     if (to_thumb || (val & 2) || (!is_call && !to_plt))
    692                         tcc_error("can't relocate value at %x",addr);
    693 
    694                 /* Compute and store final offset */
    695                 s = (x >> 24) & 1;
    696                 i1 = (x >> 23) & 1;
    697                 i2 = (x >> 22) & 1;
    698                 j1 = s ^ (i1 ^ 1);
    699                 j2 = s ^ (i2 ^ 1);
    700                 imm10 = (x >> 12) & 0x3ff;
    701                 imm11 = (x >> 1) & 0x7ff;
    702                 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
    703                                      (s << 10) | imm10);
    704                 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
    705                                 (j1 << 13) | blx_bit | (j2 << 11) |
    706                                 imm11);
    707             }
    708             break;
    709         case R_ARM_MOVT_ABS:
    710         case R_ARM_MOVW_ABS_NC:
    711             {
    712                 int x, imm4, imm12;
    713                 if (type == R_ARM_MOVT_ABS)
    714                     val >>= 16;
    715                 imm12 = val & 0xfff;
    716                 imm4 = (val >> 12) & 0xf;
    717                 x = (imm4 << 16) | imm12;
    718                 if (type == R_ARM_THM_MOVT_ABS)
    719                     *(int *)ptr |= x;
    720                 else
    721                     *(int *)ptr += x;
    722         }
    723             break;
    724         case R_ARM_THM_MOVT_ABS:
    725         case R_ARM_THM_MOVW_ABS_NC:
    726             {
    727                 int x, i, imm4, imm3, imm8;
    728                 if (type == R_ARM_THM_MOVT_ABS)
    729                     val >>= 16;
    730                 imm8 = val & 0xff;
    731                 imm3 = (val >> 8) & 0x7;
    732                 i = (val >> 11) & 1;
    733                 imm4 = (val >> 12) & 0xf;
    734                 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
    735                 if (type == R_ARM_THM_MOVT_ABS)
    736                     *(int *)ptr |= x;
    737                 else
    738                     *(int *)ptr += x;
    739         }
    740             break;
    741         case R_ARM_PREL31:
    742             {
    743                 int x;
    744                 x = (*(int *)ptr) & 0x7fffffff;
    745                 (*(int *)ptr) &= 0x80000000;
    746                 x = (x * 2) / 2;
    747                 x += val - addr;
    748                 if((x^(x>>1))&0x40000000)
    749                     tcc_error("can't relocate value at %x",addr);
    750                 (*(int *)ptr) |= x & 0x7fffffff;
    751             }
    752         case R_ARM_ABS32:
    753             *(int *)ptr += val;
    754             break;
    755         case R_ARM_REL32:
    756             *(int *)ptr += val - addr;
    757             break;
    758         case R_ARM_BASE_PREL:
    759             *(int *)ptr += s1->got->sh_addr - addr;
    760             break;
    761         case R_ARM_GOTOFF32:
    762             *(int *)ptr += val - s1->got->sh_addr;
    763             break;
    764         case R_ARM_GOT_BREL:
    765             /* we load the got offset */
    766             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
    767             break;
    768         case R_ARM_COPY:
    769             break;
    770         case R_ARM_V4BX:
    771             /* trade Thumb support for ARMv4 support */
    772             if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
    773                 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
    774             break;
    775         default:
    776             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
    777                 type, (unsigned)addr, ptr, (unsigned)val);
    778             break;
    779 #elif defined(TCC_TARGET_C67)
    780         case R_C60_32:
    781             *(int *)ptr += val;
    782             break;
    783         case R_C60LO16:
    784             {
    785                 uint32_t orig;
    786                
    787                 /* put the low 16 bits of the absolute address */
    788                 // add to what is already there
    789                
    790                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
    791                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
    792                
    793                 //patch both at once - assumes always in pairs Low - High
    794                
    795                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
    796                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
    797             }
    798             break;
    799         case R_C60HI16:
    800             break;
    801         default:
    802             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
    803                 type, (unsigned)addr, ptr, (unsigned)val);
    804             break;
    805 #elif defined(TCC_TARGET_X86_64)
    806         case R_X86_64_64:
    807             if (s1->output_type == TCC_OUTPUT_DLL) {
    808                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
    809                 qrel->r_addend = *(long long *)ptr + val;
    810                 qrel++;
    811             }
    812             *(long long *)ptr += val;
    813             break;
    814         case R_X86_64_32:
    815         case R_X86_64_32S:
    816             if (s1->output_type == TCC_OUTPUT_DLL) {
    817                 /* XXX: this logic may depend on TCC's codegen
    818                    now TCC uses R_X86_64_32 even for a 64bit pointer */
    819                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
    820                 qrel->r_addend = *(int *)ptr + val;
    821                 qrel++;
    822             }
    823             *(int *)ptr += val;
    824             break;
    825 
    826         case R_X86_64_PC32:
    827             if (s1->output_type == TCC_OUTPUT_DLL) {
    828                 /* DLL relocation */
    829                 esym_index = s1->symtab_to_dynsym[sym_index];
    830                 if (esym_index) {
    831                     qrel->r_offset = rel->r_offset;
    832                     qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
    833                     qrel->r_addend = *(int *)ptr;
    834                     qrel++;
    835                     break;
    836                 }
    837             }
    838             /* fall through */
    839         case R_X86_64_PLT32: {
    840             long long diff;
    841             diff = (long long)val - addr;
    842             if (diff <= -2147483647 || diff > 2147483647) {
    843 #ifdef TCC_HAS_RUNTIME_PLTGOT
    844                 /* XXX: naive support for over 32bit jump */
    845                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
    846                     val = (add_jmp_table(s1, val - rel->r_addend) +
    847                            rel->r_addend);
    848                     diff = val - addr;
    849                 }
    850 #endif
    851                 if (diff <= -2147483647 || diff > 2147483647) {
    852                     tcc_error("internal error: relocation failed");
    853                 }
    854             }
    855             *(int *)ptr += diff;
    856         }
    857             break;
    858         case R_X86_64_GLOB_DAT:
    859         case R_X86_64_JUMP_SLOT:
    860             /* They don't need addend */
    861             *(int *)ptr = val - rel->r_addend;
    862             break;
    863         case R_X86_64_GOTPCREL:
    864 #ifdef TCC_HAS_RUNTIME_PLTGOT
    865             if (s1->output_type == TCC_OUTPUT_MEMORY) {
    866                 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
    867                 *(int *)ptr += val - addr;
    868                 break;
    869             }
    870 #endif
    871             *(int *)ptr += (s1->got->sh_addr - addr +
    872                             s1->sym_attrs[sym_index].got_offset - 4);
    873             break;
    874         case R_X86_64_GOTTPOFF:
    875             *(int *)ptr += val - s1->got->sh_addr;
    876             break;
    877         case R_X86_64_GOT32:
    878             /* we load the got offset */
    879             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
    880             break;
    881 #elif  defined(TCC_TARGET_IL)
    882 #else
    883 #error unsupported processor
    884 #endif
    885         }
    886     }
    887     /* if the relocation is allocated, we change its symbol table */
    888     if (sr->sh_flags & SHF_ALLOC)
    889         sr->link = s1->dynsym;
    890 }
    891 
    892 /* relocate relocation table in 'sr' */
    893 static void relocate_rel(TCCState *s1, Section *sr)
    894 {
    895     Section *s;
    896     ElfW_Rel *rel, *rel_end;
    897    
    898     s = s1->sections[sr->sh_info];
    899     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    900     for(rel = (ElfW_Rel *)sr->data;
    901         rel < rel_end;
    902         rel++) {
    903         rel->r_offset += s->sh_addr;
    904     }
    905 }
    906 
    907 /* count the number of dynamic relocations so that we can reserve
    908    their space */
    909 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
    910 {
    911     ElfW_Rel *rel, *rel_end;
    912     int sym_index, esym_index, type, count;
    913 
    914     count = 0;
    915     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    916     for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
    917         sym_index = ELFW(R_SYM)(rel->r_info);
    918         type = ELFW(R_TYPE)(rel->r_info);
    919         switch(type) {
    920 #if defined(TCC_TARGET_I386)
    921         case R_386_32:
    922 #elif defined(TCC_TARGET_X86_64)
    923         case R_X86_64_32:
    924         case R_X86_64_32S:
    925         case R_X86_64_64:
    926 #endif
    927             count++;
    928             break;
    929 #if defined(TCC_TARGET_I386)
    930         case R_386_PC32:
    931 #elif defined(TCC_TARGET_X86_64)
    932         case R_X86_64_PC32:
    933 #endif
    934             esym_index = s1->symtab_to_dynsym[sym_index];
    935             if (esym_index)
    936                 count++;
    937             break;
    938         default:
    939             break;
    940         }
    941     }
    942     if (count) {
    943         /* allocate the section */
    944         sr->sh_flags |= SHF_ALLOC;
    945         sr->sh_size = count * sizeof(ElfW_Rel);
    946     }
    947     return count;
    948 }
    949 
    950 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
     688ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
    951689{
    952690    int n;
     
    954692
    955693    if (index >= s1->nb_sym_attrs) {
     694        if (!alloc)
     695            return s1->sym_attrs;
    956696        /* find immediately bigger power of 2 and reallocate array */
    957697        n = 1;
     
    967707}
    968708
    969 /* XXX: suppress that */
    970 static void put32(unsigned char *p, uint32_t val)
    971 {
    972     p[0] = val;
    973     p[1] = val >> 8;
    974     p[2] = val >> 16;
    975     p[3] = val >> 24;
    976 }
    977 
    978 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
    979     defined(TCC_TARGET_X86_64)
    980 static uint32_t get32(unsigned char *p)
    981 {
    982     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
    983 }
    984 #endif
     709/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
     710   using variable <elem> */
     711#define for_each_elem(sec, startoff, elem, type) \
     712    for (elem = (type *) sec->data + startoff; \
     713         elem < (type *) (sec->data + sec->data_offset); elem++)
     714
     715/* In an ELF file symbol table, the local symbols must appear below
     716   the global and weak ones. Since TCC cannot sort it while generating
     717   the code, we must do it after. All the relocation tables are also
     718   modified to take into account the symbol table sorting */
     719static void sort_syms(TCCState *s1, Section *s)
     720{
     721    int *old_to_new_syms;
     722    ElfW(Sym) *new_syms;
     723    int nb_syms, i;
     724    ElfW(Sym) *p, *q;
     725    ElfW_Rel *rel;
     726    Section *sr;
     727    int type, sym_index;
     728
     729    nb_syms = s->data_offset / sizeof(ElfW(Sym));
     730    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
     731    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
     732
     733    /* first pass for local symbols */
     734    p = (ElfW(Sym) *)s->data;
     735    q = new_syms;
     736    for(i = 0; i < nb_syms; i++) {
     737        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
     738            old_to_new_syms[i] = q - new_syms;
     739            *q++ = *p;
     740        }
     741        p++;
     742    }
     743    /* save the number of local symbols in section header */
     744    if( s->sh_size )    /* this 'if' makes IDA happy */
     745        s->sh_info = q - new_syms;
     746
     747    /* then second pass for non local symbols */
     748    p = (ElfW(Sym) *)s->data;
     749    for(i = 0; i < nb_syms; i++) {
     750        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
     751            old_to_new_syms[i] = q - new_syms;
     752            *q++ = *p;
     753        }
     754        p++;
     755    }
     756
     757    /* we copy the new symbols to the old */
     758    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
     759    tcc_free(new_syms);
     760
     761    /* now we modify all the relocations */
     762    for(i = 1; i < s1->nb_sections; i++) {
     763        sr = s1->sections[i];
     764        if (sr->sh_type == SHT_RELX && sr->link == s) {
     765            for_each_elem(sr, 0, rel, ElfW_Rel) {
     766                sym_index = ELFW(R_SYM)(rel->r_info);
     767                type = ELFW(R_TYPE)(rel->r_info);
     768                sym_index = old_to_new_syms[sym_index];
     769                rel->r_info = ELFW(R_INFO)(sym_index, type);
     770            }
     771        }
     772    }
     773
     774    tcc_free(old_to_new_syms);
     775}
     776
     777/* relocate symbol table, resolve undefined symbols if do_resolve is
     778   true and output error if undefined symbol. */
     779ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
     780{
     781    ElfW(Sym) *sym;
     782    int sym_bind, sh_num;
     783    const char *name;
     784
     785    for_each_elem(symtab, 1, sym, ElfW(Sym)) {
     786        sh_num = sym->st_shndx;
     787        if (sh_num == SHN_UNDEF) {
     788            name = (char *) s1->symtab->link->data + sym->st_name;
     789            /* Use ld.so to resolve symbol for us (for tcc -run) */
     790            if (do_resolve) {
     791#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
     792                void *addr = dlsym(RTLD_DEFAULT, name);
     793                if (addr) {
     794                    sym->st_value = (addr_t) addr;
     795#ifdef DEBUG_RELOC
     796                    printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
     797#endif
     798                    goto found;
     799                }
     800#endif
     801            /* if dynamic symbol exist, it will be used in relocate_section */
     802            } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
     803                goto found;
     804            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
     805               it */
     806            if (!strcmp(name, "_fp_hw"))
     807                goto found;
     808            /* only weak symbols are accepted to be undefined. Their
     809               value is zero */
     810            sym_bind = ELFW(ST_BIND)(sym->st_info);
     811            if (sym_bind == STB_WEAK)
     812                sym->st_value = 0;
     813            else
     814                tcc_error_noabort("undefined symbol '%s'", name);
     815        } else if (sh_num < SHN_LORESERVE) {
     816            /* add section base */
     817            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
     818        }
     819    found: ;
     820    }
     821}
     822
     823/* relocate a given section (CPU dependent) by applying the relocations
     824   in the associated relocation section */
     825ST_FUNC void relocate_section(TCCState *s1, Section *s)
     826{
     827    Section *sr = s->reloc;
     828    ElfW_Rel *rel;
     829    ElfW(Sym) *sym;
     830    int type, sym_index;
     831    unsigned char *ptr;
     832    addr_t tgt, addr;
     833
     834    relocate_init(sr);
     835
     836    for_each_elem(sr, 0, rel, ElfW_Rel) {
     837        ptr = s->data + rel->r_offset;
     838        sym_index = ELFW(R_SYM)(rel->r_info);
     839        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
     840        type = ELFW(R_TYPE)(rel->r_info);
     841        tgt = sym->st_value;
     842#if SHT_RELX == SHT_RELA
     843        tgt += rel->r_addend;
     844#endif
     845        addr = s->sh_addr + rel->r_offset;
     846        relocate(s1, rel, type, ptr, addr, tgt);
     847    }
     848    /* if the relocation is allocated, we change its symbol table */
     849    if (sr->sh_flags & SHF_ALLOC)
     850        sr->link = s1->dynsym;
     851}
     852
     853/* relocate relocation table in 'sr' */
     854static void relocate_rel(TCCState *s1, Section *sr)
     855{
     856    Section *s;
     857    ElfW_Rel *rel;
     858
     859    s = s1->sections[sr->sh_info];
     860    for_each_elem(sr, 0, rel, ElfW_Rel)
     861        rel->r_offset += s->sh_addr;
     862}
     863
     864/* count the number of dynamic relocations so that we can reserve
     865   their space */
     866static int prepare_dynamic_rel(TCCState *s1, Section *sr)
     867{
     868    ElfW_Rel *rel;
     869    int sym_index, type, count;
     870
     871    count = 0;
     872    for_each_elem(sr, 0, rel, ElfW_Rel) {
     873        sym_index = ELFW(R_SYM)(rel->r_info);
     874        type = ELFW(R_TYPE)(rel->r_info);
     875        switch(type) {
     876#if defined(TCC_TARGET_I386)
     877        case R_386_32:
     878            if (!get_sym_attr(s1, sym_index, 0)->dyn_index
     879                && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
     880                /* don't fixup unresolved (weak) symbols */
     881                rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
     882                break;
     883            }
     884#elif defined(TCC_TARGET_X86_64)
     885        case R_X86_64_32:
     886        case R_X86_64_32S:
     887        case R_X86_64_64:
     888#endif
     889            count++;
     890            break;
     891#if defined(TCC_TARGET_I386)
     892        case R_386_PC32:
     893#elif defined(TCC_TARGET_X86_64)
     894        case R_X86_64_PC32:
     895#endif
     896            if (get_sym_attr(s1, sym_index, 0)->dyn_index)
     897                count++;
     898            break;
     899        default:
     900            break;
     901        }
     902    }
     903    if (count) {
     904        /* allocate the section */
     905        sr->sh_flags |= SHF_ALLOC;
     906        sr->sh_size = count * sizeof(ElfW_Rel);
     907    }
     908    return count;
     909}
    985910
    986911static void build_got(TCCState *s1)
    987912{
    988     unsigned char *ptr;
    989 
    990913    /* if no got, then create it */
    991914    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
    992915    s1->got->sh_entsize = 4;
    993     add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
     916    set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
    994917                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
    995     ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
    996 #if PTR_SIZE == 4
    997     /* keep space for _DYNAMIC pointer, if present */
    998     put32(ptr, 0);
    999     /* two dummy got entries */
    1000     put32(ptr + 4, 0);
    1001     put32(ptr + 8, 0);
    1002 #else
    1003     /* keep space for _DYNAMIC pointer, if present */
    1004     put32(ptr, 0);
    1005     put32(ptr + 4, 0);
    1006     /* two dummy got entries */
    1007     put32(ptr + 8, 0);
    1008     put32(ptr + 12, 0);
    1009     put32(ptr + 16, 0);
    1010     put32(ptr + 20, 0);
    1011 #endif
    1012 }
    1013 
    1014 /* put a got entry corresponding to a symbol in symtab_section. 'size'
    1015    and 'info' can be modifed if more precise info comes from the DLL */
    1016 static void put_got_entry(TCCState *s1,
    1017                           int reloc_type, unsigned long size, int info,
    1018                           int sym_index)
    1019 {
    1020     int index;
     918    /* keep space for _DYNAMIC pointer and two dummy got entries */
     919    section_ptr_add(s1->got, 3 * PTR_SIZE);
     920}
     921
     922/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
     923   in s1->symtab. When creating the dynamic symbol table entry for the GOT
     924   relocation, use 'size' and 'info' for the corresponding symbol metadata.
     925   Returns the offset of the GOT or (if any) PLT entry. */
     926static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
     927                                       unsigned long size,
     928                                       int info, int sym_index)
     929{
     930    int need_plt_entry;
    1021931    const char *name;
    1022932    ElfW(Sym) *sym;
    1023     unsigned long offset;
    1024     int *ptr;
    1025 
    1026     if (!s1->got)
    1027         build_got(s1);
    1028 
    1029     /* if a got entry already exists for that symbol, no need to add one */
    1030     if (sym_index < s1->nb_sym_attrs &&
    1031         s1->sym_attrs[sym_index].got_offset)
    1032         return;
    1033 
    1034     alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
     933    struct sym_attr *attr;
     934    unsigned got_offset;
     935    char plt_name[100];
     936    int len;
     937
     938    need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
     939    attr = get_sym_attr(s1, sym_index, 1);
     940
     941    /* In case a function is both called and its address taken 2 GOT entries
     942       are created, one for taking the address (GOT) and the other for the PLT
     943       entry (PLTGOT).  */
     944    if (need_plt_entry ? attr->plt_offset : attr->got_offset)
     945        return attr;
     946
     947    /* create the GOT entry */
     948    got_offset = s1->got->data_offset;
     949    section_ptr_add(s1->got, PTR_SIZE);
     950
     951    /* Create the GOT relocation that will insert the address of the object or
     952       function of interest in the GOT entry. This is a static relocation for
     953       memory output (dlsym will give us the address of symbols) and dynamic
     954       relocation otherwise (executable and DLLs). The relocation should be
     955       done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
     956       associated to a PLT entry) but is currently done at load time for an
     957       unknown reason. */
     958
     959    sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
     960    name = (char *) symtab_section->link->data + sym->st_name;
    1035961
    1036962    if (s1->dynsym) {
    1037         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1038         name = symtab_section->link->data + sym->st_name;
    1039         offset = sym->st_value;
    1040 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
    1041         if (reloc_type ==
    1042 #ifdef TCC_TARGET_X86_64
    1043             R_X86_64_JUMP_SLOT
    1044 #else
    1045             R_386_JMP_SLOT
    1046 #endif
    1047             ) {
    1048             Section *plt;
    1049             uint8_t *p;
    1050             int modrm;
    1051 
    1052 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
    1053             modrm = 0x25;
    1054 #else
    1055             /* if we build a DLL, we add a %ebx offset */
    1056             if (s1->output_type == TCC_OUTPUT_DLL)
    1057                 modrm = 0xa3;
    1058             else
    1059                 modrm = 0x25;
    1060 #endif
    1061 
    1062             /* add a PLT entry */
    1063             plt = s1->plt;
    1064             if (plt->data_offset == 0) {
    1065                 /* first plt entry */
    1066                 p = section_ptr_add(plt, 16);
    1067                 p[0] = 0xff; /* pushl got + PTR_SIZE */
    1068                 p[1] = modrm + 0x10;
    1069                 put32(p + 2, PTR_SIZE);
    1070                 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
    1071                 p[7] = modrm;
    1072                 put32(p + 8, PTR_SIZE * 2);
    1073             }
    1074 
    1075             p = section_ptr_add(plt, 16);
    1076             p[0] = 0xff; /* jmp *(got + x) */
    1077             p[1] = modrm;
    1078             put32(p + 2, s1->got->data_offset);
    1079             p[6] = 0x68; /* push $xxx */
    1080             put32(p + 7, (plt->data_offset - 32) >> 1);
    1081             p[11] = 0xe9; /* jmp plt_start */
    1082             put32(p + 12, -(plt->data_offset));
    1083 
    1084             /* the symbol is modified so that it will be relocated to
    1085                the PLT */
    1086 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
    1087             if (s1->output_type == TCC_OUTPUT_EXE)
    1088 #endif
    1089                 offset = plt->data_offset - 16;
    1090         }
    1091 #elif defined(TCC_TARGET_ARM)
    1092         if (reloc_type == R_ARM_JUMP_SLOT) {
    1093             Section *plt;
    1094             uint8_t *p;
    1095            
    1096             /* if we build a DLL, we add a %ebx offset */
    1097             if (s1->output_type == TCC_OUTPUT_DLL)
    1098                 tcc_error("DLLs unimplemented!");
    1099 
    1100             /* add a PLT entry */
    1101             plt = s1->plt;
    1102             if (plt->data_offset == 0) {
    1103                 /* first plt entry */
    1104                 p = section_ptr_add(plt, 16);
    1105                 put32(p     , 0xe52de004);
    1106                 put32(p +  4, 0xe59fe010);
    1107                 put32(p +  8, 0xe08fe00e);
    1108                 put32(p + 12, 0xe5bef008);
    1109             }
    1110 
    1111             if (s1->sym_attrs[sym_index].plt_thumb_stub) {
    1112                 p = section_ptr_add(plt, 20);
    1113                 put32(p  , 0x4778); // bx pc
    1114                 put32(p+2, 0x46c0); // nop
    1115                 p += 4;
    1116             } else
    1117                 p = section_ptr_add(plt, 16);
    1118             put32(p  , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
    1119             put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
    1120             put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset
    1121             put32(p+12, s1->got->data_offset);
    1122 
    1123             /* the symbol is modified so that it will be relocated to
    1124                the PLT */
    1125             if (s1->output_type == TCC_OUTPUT_EXE)
    1126                 offset = plt->data_offset - 16;
    1127         }
    1128 #elif defined(TCC_TARGET_C67)
    1129         tcc_error("C67 got not implemented");
    1130 #elif  defined(TCC_TARGET_IL)
    1131         tcc_error("IL got not implemented");
    1132 #else
    1133 #error unsupported CPU
    1134 #endif
    1135         index = put_elf_sym(s1->dynsym, offset,
    1136                             size, info, 0, sym->st_shndx, name);
    1137         /* put a got entry */
    1138         put_elf_reloc(s1->dynsym, s1->got,
    1139                       s1->got->data_offset,
    1140                       reloc_type, index);
    1141     }
    1142     ptr = section_ptr_add(s1->got, PTR_SIZE);
    1143     *ptr = 0;
     963        if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
     964            /* Hack alarm.  We don't want to emit dynamic symbols
     965               and symbol based relocs for STB_LOCAL symbols, but rather
     966               want to resolve them directly.  At this point the symbol
     967               values aren't final yet, so we must defer this.  We will later
     968               have to create a RELATIVE reloc anyway, so we misuse the
     969               relocation slot to smuggle the symbol reference until
     970               fill_local_got_entries.  Not that the sym_index is
     971               relative to symtab_section, not s1->dynsym!  Nevertheless
     972               we use s1->dyn_sym so that if this is the first call
     973               that got->reloc is correctly created.  Also note that
     974               RELATIVE relocs are not normally created for the .got,
     975               so the types serves as a marker for later (and is retained
     976               also for the final output, which is okay because then the
     977               got is just normal data).  */
     978            put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
     979                          sym_index);
     980        } else {
     981            if (0 == attr->dyn_index)
     982                attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
     983                                              info, 0, sym->st_shndx, name);
     984            put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
     985                          attr->dyn_index);
     986        }
     987    } else {
     988        put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
     989                      sym_index);
     990    }
     991
     992    if (need_plt_entry) {
     993        if (!s1->plt) {
     994            s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
     995                                  SHF_ALLOC | SHF_EXECINSTR);
     996            s1->plt->sh_entsize = 4;
     997        }
     998
     999        attr->plt_offset = create_plt_entry(s1, got_offset, attr);
     1000
     1001        /* create a symbol 'sym@plt' for the PLT jump vector */
     1002        len = strlen(name);
     1003        if (len > sizeof plt_name - 5)
     1004            len = sizeof plt_name - 5;
     1005        memcpy(plt_name, name, len);
     1006        strcpy(plt_name + len, "@plt");
     1007        attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
     1008            ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
     1009
     1010    } else {
     1011        attr->got_offset = got_offset;
     1012    }
     1013
     1014    return attr;
    11441015}
    11451016
     
    11481019{
    11491020    Section *s;
    1150     ElfW_Rel *rel, *rel_end;
     1021    ElfW_Rel *rel;
    11511022    ElfW(Sym) *sym;
    1152     int i, type, reloc_type, sym_index;
     1023    int i, type, gotplt_entry, reloc_type, sym_index;
     1024    struct sym_attr *attr;
    11531025
    11541026    for(i = 1; i < s1->nb_sections; i++) {
     
    11591031        if (s->link != symtab_section)
    11601032            continue;
    1161         rel_end = (ElfW_Rel *)(s->data + s->data_offset);
    1162         for(rel = (ElfW_Rel *)s->data;
    1163             rel < rel_end;
    1164             rel++) {
     1033        for_each_elem(s, 0, rel, ElfW_Rel) {
    11651034            type = ELFW(R_TYPE)(rel->r_info);
    1166             switch(type) {
    1167 #if defined(TCC_TARGET_I386)
    1168             case R_386_GOT32:
    1169             case R_386_GOTOFF:
    1170             case R_386_GOTPC:
    1171             case R_386_PLT32:
    1172                 if (!s1->got)
    1173                     build_got(s1);
    1174                 if (type == R_386_GOT32 || type == R_386_PLT32) {
    1175                     sym_index = ELFW(R_SYM)(rel->r_info);
    1176                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1177                     /* look at the symbol got offset. If none, then add one */
    1178                     if (type == R_386_GOT32)
    1179                         reloc_type = R_386_GLOB_DAT;
    1180                     else
    1181                         reloc_type = R_386_JMP_SLOT;
    1182                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1183                                   sym_index);
    1184                 }
    1185                 break;
    1186 #elif defined(TCC_TARGET_ARM)
    1187             case R_ARM_GOT_BREL:
    1188             case R_ARM_GOTOFF32:
    1189             case R_ARM_BASE_PREL:
    1190             case R_ARM_PLT32:
    1191                 if (!s1->got)
    1192                     build_got(s1);
    1193                 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
    1194                     sym_index = ELFW(R_SYM)(rel->r_info);
    1195                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1196                     /* look at the symbol got offset. If none, then add one */
    1197                     if (type == R_ARM_GOT_BREL)
    1198                         reloc_type = R_ARM_GLOB_DAT;
    1199                     else
    1200                         reloc_type = R_ARM_JUMP_SLOT;
    1201                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1202                                   sym_index);
    1203                 }
    1204                 break;
    1205 #elif defined(TCC_TARGET_C67)
    1206             case R_C60_GOT32:
    1207             case R_C60_GOTOFF:
    1208             case R_C60_GOTPC:
    1209             case R_C60_PLT32:
    1210                 if (!s1->got)
    1211                     build_got(s1);
    1212                 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
    1213                     sym_index = ELFW(R_SYM)(rel->r_info);
    1214                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1215                     /* look at the symbol got offset. If none, then add one */
    1216                     if (type == R_C60_GOT32)
    1217                         reloc_type = R_C60_GLOB_DAT;
    1218                     else
    1219                         reloc_type = R_C60_JMP_SLOT;
    1220                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1221                                   sym_index);
    1222                 }
    1223                 break;
    1224 #elif defined(TCC_TARGET_X86_64)
    1225             case R_X86_64_GOT32:
    1226             case R_X86_64_GOTTPOFF:
    1227             case R_X86_64_GOTPCREL:
    1228             case R_X86_64_PLT32:
    1229                 if (!s1->got)
    1230                     build_got(s1);
    1231                 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
    1232                     type == R_X86_64_PLT32) {
    1233                     sym_index = ELFW(R_SYM)(rel->r_info);
    1234                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1235                     /* look at the symbol got offset. If none, then add one */
    1236                     if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
    1237                         reloc_type = R_X86_64_GLOB_DAT;
    1238                     else
    1239                         reloc_type = R_X86_64_JUMP_SLOT;
    1240                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1241                                   sym_index);
    1242                 }
    1243                 break;
    1244 #elif  defined(TCC_TARGET_IL)
    1245 #else
    1246 #error unsupported CPU
    1247 #endif
    1248             default:
    1249                 break;
    1250             }
    1251         }
    1252     }
    1253 }
    1254 
    1255 ST_FUNC Section *new_symtab(TCCState *s1,
    1256                            const char *symtab_name, int sh_type, int sh_flags,
    1257                            const char *strtab_name,
    1258                            const char *hash_name, int hash_sh_flags)
    1259 {
    1260     Section *symtab, *strtab, *hash;
    1261     int *ptr, nb_buckets;
    1262 
    1263     symtab = new_section(s1, symtab_name, sh_type, sh_flags);
    1264     symtab->sh_entsize = sizeof(ElfW(Sym));
    1265     strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
    1266     put_elf_str(strtab, "");
    1267     symtab->link = strtab;
    1268     put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
    1269    
    1270     nb_buckets = 1;
    1271 
    1272     hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
    1273     hash->sh_entsize = sizeof(int);
    1274     symtab->hash = hash;
    1275     hash->link = symtab;
    1276 
    1277     ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
    1278     ptr[0] = nb_buckets;
    1279     ptr[1] = 1;
    1280     memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
    1281     return symtab;
     1035            gotplt_entry = gotplt_entry_type(type);
     1036            sym_index = ELFW(R_SYM)(rel->r_info);
     1037            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
     1038
     1039            if (gotplt_entry == NO_GOTPLT_ENTRY) {
     1040                continue;
     1041            }
     1042
     1043            /* Automatically create PLT/GOT [entry] if it is an undefined
     1044               reference (resolved at runtime), or the symbol is absolute,
     1045               probably created by tcc_add_symbol, and thus on 64-bit
     1046               targets might be too far from application code.  */
     1047            if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
     1048                if (sym->st_shndx == SHN_UNDEF) {
     1049                    ElfW(Sym) *esym;
     1050                    int dynindex;
     1051                    if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
     1052                        continue;
     1053                    /* Relocations for UNDEF symbols would normally need
     1054                       to be transferred into the executable or shared object.
     1055                       If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
     1056                       But TCC doesn't do that (at least for exes), so we
     1057                       need to resolve all such relocs locally.  And that
     1058                       means PLT slots for functions in DLLs and COPY relocs for
     1059                       data symbols.  COPY relocs were generated in
     1060                       bind_exe_dynsyms (and the symbol adjusted to be defined),
     1061                       and for functions we were generated a dynamic symbol
     1062                       of function type.  */
     1063                    if (s1->dynsym) {
     1064                        /* dynsym isn't set for -run :-/  */
     1065                        dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
     1066                        esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
     1067                        if (dynindex
     1068                            && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
     1069                                || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
     1070                                    && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
     1071                            goto jmp_slot;
     1072                    }
     1073                } else if (!(sym->st_shndx == SHN_ABS
     1074#ifndef TCC_TARGET_ARM
     1075                        && PTR_SIZE == 8
     1076#endif
     1077                        ))
     1078                    continue;
     1079            }
     1080
     1081#ifdef TCC_TARGET_X86_64
     1082            if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
     1083                (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
     1084                 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) {
     1085                rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
     1086                continue;
     1087            }
     1088#endif
     1089            if (code_reloc(type)) {
     1090            jmp_slot:
     1091                reloc_type = R_JMP_SLOT;
     1092            } else
     1093                reloc_type = R_GLOB_DAT;
     1094
     1095            if (!s1->got)
     1096                build_got(s1);
     1097
     1098            if (gotplt_entry == BUILD_GOT_ONLY)
     1099                continue;
     1100
     1101            attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
     1102                                 sym_index);
     1103
     1104            if (reloc_type == R_JMP_SLOT)
     1105                rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
     1106        }
     1107    }
    12821108}
    12831109
     
    12911117}
    12921118
     1119#ifndef TCC_TARGET_PE
    12931120static void add_init_array_defines(TCCState *s1, const char *section_name)
    12941121{
     
    12971124    char sym_start[1024];
    12981125    char sym_end[1024];
    1299    
     1126
    13001127    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
    13011128    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
     
    13091136    }
    13101137
    1311     add_elf_sym(symtab_section,
     1138    set_elf_sym(symtab_section,
    13121139                0, 0,
    13131140                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13141141                s->sh_num, sym_start);
    1315     add_elf_sym(symtab_section,
     1142    set_elf_sym(symtab_section,
    13161143                end_offset, 0,
    13171144                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13181145                s->sh_num, sym_end);
    13191146}
    1320 
    1321 ST_FUNC void tcc_add_bcheck(TCCState *s1)
    1322 {
    1323 #ifdef CONFIG_TCC_BCHECK
    1324     unsigned long *ptr;
    1325     Section *init_section;
    1326     unsigned char *pinit;
    1327     int sym_index;
    1328 
    1329     if (0 == s1->do_bounds_check)
    1330         return;
    1331 
    1332     /* XXX: add an object file to do that */
    1333     ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
    1334     *ptr = 0;
    1335     add_elf_sym(symtab_section, 0, 0,
    1336                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    1337                 bounds_section->sh_num, "__bounds_start");
    1338 #ifdef TCC_TARGET_I386
    1339     if (s1->output_type != TCC_OUTPUT_MEMORY) {
    1340         /* add 'call __bound_init()' in .init section */
    1341         init_section = find_section(s1, ".init");
    1342         pinit = section_ptr_add(init_section, 5);
    1343         pinit[0] = 0xe8;
    1344         put32(pinit + 1, -4);
    1345         sym_index = find_elf_sym(symtab_section, "__bound_init");
    1346         put_elf_reloc(symtab_section, init_section,
    1347                       init_section->data_offset - 4, R_386_PC32, sym_index);
    1348     }
    1349 #endif
    1350 #endif
    1351 }
    1352 
    1353 static inline int tcc_add_support(TCCState *s1, const char *filename)
     1147#endif
     1148
     1149static int tcc_add_support(TCCState *s1, const char *filename)
    13541150{
    13551151    char buf[1024];
     
    13581154}
    13591155
     1156ST_FUNC void tcc_add_bcheck(TCCState *s1)
     1157{
     1158#ifdef CONFIG_TCC_BCHECK
     1159    addr_t *ptr;
     1160    int sym_index;
     1161
     1162    if (0 == s1->do_bounds_check)
     1163        return;
     1164    /* XXX: add an object file to do that */
     1165    ptr = section_ptr_add(bounds_section, sizeof(*ptr));
     1166    *ptr = 0;
     1167    set_elf_sym(symtab_section, 0, 0,
     1168                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     1169                bounds_section->sh_num, "__bounds_start");
     1170    /* pull bcheck.o from libtcc1.a */
     1171    sym_index = set_elf_sym(symtab_section, 0, 0,
     1172                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     1173                SHN_UNDEF, "__bound_init");
     1174    if (s1->output_type != TCC_OUTPUT_MEMORY) {
     1175        /* add 'call __bound_init()' in .init section */
     1176        Section *init_section = find_section(s1, ".init");
     1177        unsigned char *pinit = section_ptr_add(init_section, 5);
     1178        pinit[0] = 0xe8;
     1179        write32le(pinit + 1, -4);
     1180        put_elf_reloc(symtab_section, init_section,
     1181            init_section->data_offset - 4, R_386_PC32, sym_index);
     1182            /* R_386_PC32 = R_X86_64_PC32 = 2 */
     1183    }
     1184#endif
     1185}
     1186
    13601187/* add tcc runtime libraries */
    13611188ST_FUNC void tcc_add_runtime(TCCState *s1)
    13621189{
    13631190    tcc_add_bcheck(s1);
    1364 
     1191    tcc_add_pragma_libs(s1);
    13651192    /* add libc */
    13661193    if (!s1->nostdlib) {
    1367         tcc_add_library(s1, "c");
    1368 #ifdef CONFIG_USE_LIBGCC
    1369         tcc_add_file(s1, TCC_LIBGCC);
    1370 #elif !defined WITHOUT_LIBTCC
    1371         tcc_add_support(s1, "libtcc1.a");
    1372 #endif
     1194        tcc_add_library_err(s1, "c");
     1195#ifdef TCC_LIBGCC
     1196        if (!s1->static_link) {
     1197            if (TCC_LIBGCC[0] == '/')
     1198                tcc_add_file(s1, TCC_LIBGCC);
     1199            else
     1200                tcc_add_dll(s1, TCC_LIBGCC, 0);
     1201        }
     1202#endif
     1203        tcc_add_support(s1, TCC_LIBTCC1);
    13731204        /* add crt end if not memory output */
    13741205        if (s1->output_type != TCC_OUTPUT_MEMORY)
     
    13801211   sections are filled (for example after allocating common
    13811212   symbols)) */
    1382 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
     1213static void tcc_add_linker_symbols(TCCState *s1)
    13831214{
    13841215    char buf[1024];
     
    13861217    Section *s;
    13871218
    1388     add_elf_sym(symtab_section,
     1219    set_elf_sym(symtab_section,
    13891220                text_section->data_offset, 0,
    13901221                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13911222                text_section->sh_num, "_etext");
    1392     add_elf_sym(symtab_section,
     1223    set_elf_sym(symtab_section,
    13931224                data_section->data_offset, 0,
    13941225                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13951226                data_section->sh_num, "_edata");
    1396     add_elf_sym(symtab_section,
     1227    set_elf_sym(symtab_section,
    13971228                bss_section->data_offset, 0,
    13981229                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13991230                bss_section->sh_num, "_end");
     1231#ifndef TCC_TARGET_PE
    14001232    /* horrible new standard ldscript defines */
    14011233    add_init_array_defines(s1, ".preinit_array");
    14021234    add_init_array_defines(s1, ".init_array");
    14031235    add_init_array_defines(s1, ".fini_array");
    1404    
     1236#endif
     1237
    14051238    /* add start and stop symbols for sections whose name can be
    14061239       expressed in C */
     
    14231256            }
    14241257            snprintf(buf, sizeof(buf), "__start_%s", s->name);
    1425             add_elf_sym(symtab_section,
     1258            set_elf_sym(symtab_section,
    14261259                        0, 0,
    14271260                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    14281261                        s->sh_num, buf);
    14291262            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
    1430             add_elf_sym(symtab_section,
     1263            set_elf_sym(symtab_section,
    14311264                        s->data_offset, 0,
    14321265                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     
    14371270}
    14381271
     1272ST_FUNC void resolve_common_syms(TCCState *s1)
     1273{
     1274    ElfW(Sym) *sym;
     1275
     1276    /* Allocate common symbols in BSS.  */
     1277    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
     1278        if (sym->st_shndx == SHN_COMMON) {
     1279            /* symbol alignment is in st_value for SHN_COMMONs */
     1280            sym->st_value = section_add(bss_section, sym->st_size,
     1281                                        sym->st_value);
     1282            sym->st_shndx = bss_section->sh_num;
     1283        }
     1284    }
     1285
     1286    /* Now assign linker provided symbols their value.  */
     1287    tcc_add_linker_symbols(s1);
     1288}
     1289
    14391290static void tcc_output_binary(TCCState *s1, FILE *f,
    1440                               const int *section_order)
     1291                              const int *sec_order)
    14411292{
    14421293    Section *s;
     
    14451296    offset = 0;
    14461297    for(i=1;i<s1->nb_sections;i++) {
    1447         s = s1->sections[section_order[i]];
     1298        s = s1->sections[sec_order[i]];
    14481299        if (s->sh_type != SHT_NOBITS &&
    14491300            (s->sh_flags & SHF_ALLOC)) {
     
    14591310}
    14601311
    1461 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1462 #define HAVE_PHDR       1
    1463 #define EXTRA_RELITEMS  14
    1464 
    1465 /* move the relocation value from .dynsym to .got */
    1466 void patch_dynsym_undef(TCCState *s1, Section *s)
    1467 {
    1468     uint32_t *gotd = (void *)s1->got->data;
    1469     ElfW(Sym) *sym, *sym_end;
    1470 
    1471     gotd += 3;  // dummy entries in .got
    1472     /* relocate symbols in .dynsym */
    1473     sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
    1474     for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) {
    1475         if (sym->st_shndx == SHN_UNDEF) {
    1476             *gotd++ = sym->st_value + 6; // XXX 6 is magic ?
    1477             sym->st_value = 0;
     1312ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
     1313{
     1314    int sym_index = ELFW(R_SYM) (rel->r_info);
     1315    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
     1316    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
     1317    unsigned offset = attr->got_offset;
     1318
     1319    if (0 == offset)
     1320        return;
     1321    section_reserve(s1->got, offset + PTR_SIZE);
     1322#ifdef TCC_TARGET_X86_64
     1323    write64le(s1->got->data + offset, sym->st_value);
     1324#else
     1325    write32le(s1->got->data + offset, sym->st_value);
     1326#endif
     1327}
     1328
     1329/* Perform relocation to GOT or PLT entries */
     1330ST_FUNC void fill_got(TCCState *s1)
     1331{
     1332    Section *s;
     1333    ElfW_Rel *rel;
     1334    int i;
     1335
     1336    for(i = 1; i < s1->nb_sections; i++) {
     1337        s = s1->sections[i];
     1338        if (s->sh_type != SHT_RELX)
     1339            continue;
     1340        /* no need to handle got relocations */
     1341        if (s->link != symtab_section)
     1342            continue;
     1343        for_each_elem(s, 0, rel, ElfW_Rel) {
     1344            switch (ELFW(R_TYPE) (rel->r_info)) {
     1345                case R_X86_64_GOT32:
     1346                case R_X86_64_GOTPCREL:
     1347                case R_X86_64_GOTPCRELX:
     1348                case R_X86_64_REX_GOTPCRELX:
     1349                case R_X86_64_PLT32:
     1350                    fill_got_entry(s1, rel);
     1351                    break;
     1352            }
     1353        }
     1354    }
     1355}
     1356
     1357/* See put_got_entry for a description.  This is the second stage
     1358   where GOT references to local defined symbols are rewritten.  */
     1359static void fill_local_got_entries(TCCState *s1)
     1360{
     1361    ElfW_Rel *rel;
     1362    for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
     1363        if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
     1364            int sym_index = ELFW(R_SYM) (rel->r_info);
     1365            ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
     1366            struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
     1367            unsigned offset = attr->got_offset;
     1368            if (offset != rel->r_offset - s1->got->sh_addr)
     1369              tcc_error_noabort("huh");
     1370            rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
     1371#if SHT_RELX == SHT_RELA
     1372            rel->r_addend = sym->st_value;
     1373#else
     1374            /* All our REL architectures also happen to be 32bit LE.  */
     1375            write32le(s1->got->data + offset, sym->st_value);
     1376#endif
    14781377        }
    14791378    }
    14801379}
    1481 #else
    1482 #define HAVE_PHDR       0
    1483 #define EXTRA_RELITEMS  9
    1484 
    1485 /* zero plt offsets of weak symbols in .dynsym */
    1486 void patch_dynsym_undef(TCCState *s1, Section *s)
    1487 {
    1488     ElfW(Sym) *sym, *sym_end;
    1489 
    1490     sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
    1491     for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
    1492         if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
    1493             sym->st_value = 0;
    1494 }
    1495 #endif
    1496 
    1497 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
    1498 {
    1499         int sym_index = ELFW(R_SYM) (rel->r_info);
    1500         ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
    1501         unsigned long offset;
    1502 
    1503         if (sym_index >= s1->nb_sym_attrs)
    1504                 return;
    1505         offset = s1->sym_attrs[sym_index].got_offset;
    1506         section_reserve(s1->got, offset + PTR_SIZE);
    1507 #ifdef TCC_TARGET_X86_64
    1508         /* only works for x86-64 */
    1509         put32(s1->got->data + offset + 4, sym->st_value >> 32);
    1510 #endif
    1511         put32(s1->got->data + offset, sym->st_value & 0xffffffff);
    1512 }
    1513 
    1514 ST_FUNC void fill_got(TCCState *s1)
    1515 {
    1516         Section *s;
    1517         ElfW_Rel *rel, *rel_end;
    1518         int i;
    1519 
    1520         for(i = 1; i < s1->nb_sections; i++) {
    1521                 s = s1->sections[i];
    1522                 if (s->sh_type != SHT_RELX)
    1523                         continue;
    1524                 /* no need to handle got relocations */
    1525                 if (s->link != symtab_section)
    1526                         continue;
    1527                 rel_end = (ElfW_Rel *) (s->data + s->data_offset);
    1528                 for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
    1529                         switch (ELFW(R_TYPE) (rel->r_info)) {
    1530                         case R_X86_64_GOT32:
    1531                         case R_X86_64_GOTPCREL:
    1532                         case R_X86_64_PLT32:
    1533                                 fill_got_entry(s1, rel);
    1534                                 break;
    1535                         }
    1536                 }
    1537         }
    1538 }
    1539 
    1540 
    1541 /* output an ELF file */
    1542 /* XXX: suppress unneeded sections */
    1543 static int elf_output_file(TCCState *s1, const char *filename)
    1544 {
    1545     ElfW(Ehdr) ehdr;
    1546     FILE *f;
    1547     int fd, mode, ret;
    1548     int *section_order;
    1549     int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
    1550     long long tmp;
    1551     addr_t addr;
    1552     Section *strsec, *s;
    1553     ElfW(Shdr) shdr, *sh;
    1554     ElfW(Phdr) *phdr, *ph;
    1555     Section *interp, *dynamic, *dynstr;
    1556     unsigned long saved_dynamic_data_offset;
    1557     ElfW(Sym) *sym;
    1558     int type, file_type;
    1559     addr_t rel_addr, rel_size;
    1560 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1561     addr_t bss_addr, bss_size;
    1562 #endif
    1563 
    1564     file_type = s1->output_type;
    1565     s1->nb_errors = 0;
    1566 
    1567     if (file_type != TCC_OUTPUT_OBJ) {
    1568         tcc_add_runtime(s1);
    1569     }
    1570 
    1571     phdr = NULL;
    1572     section_order = NULL;
    1573     interp = NULL;
    1574     dynamic = NULL;
    1575     dynstr = NULL; /* avoid warning */
    1576     saved_dynamic_data_offset = 0; /* avoid warning */
    1577    
    1578     if (file_type != TCC_OUTPUT_OBJ) {
    1579         relocate_common_syms();
    1580 
    1581         tcc_add_linker_symbols(s1);
    1582 
    1583         if (!s1->static_link) {
    1584             const char *name;
    1585             int sym_index, index;
    1586             ElfW(Sym) *esym, *sym_end;
    1587 
    1588             if (file_type == TCC_OUTPUT_EXE) {
    1589                 char *ptr;
    1590                 /* allow override the dynamic loader */
    1591                 const char *elfint = getenv("LD_SO");
    1592                 if (elfint == NULL)
    1593                     elfint = CONFIG_TCC_ELFINTERP;
    1594                 /* add interpreter section only if executable */
    1595                 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
    1596                 interp->sh_addralign = 1;
    1597                 ptr = section_ptr_add(interp, 1+strlen(elfint));
    1598                 strcpy(ptr, elfint);
    1599             }
    1600 
    1601             /* add dynamic symbol table */
    1602             s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
    1603                                     ".dynstr",
    1604                                     ".hash", SHF_ALLOC);
    1605             dynstr = s1->dynsym->link;
    1606            
    1607             /* add dynamic section */
    1608             dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
    1609                                   SHF_ALLOC | SHF_WRITE);
    1610             dynamic->link = dynstr;
    1611             dynamic->sh_entsize = sizeof(ElfW(Dyn));
    1612        
    1613             /* add PLT */
    1614             s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
    1615                                   SHF_ALLOC | SHF_EXECINSTR);
    1616             s1->plt->sh_entsize = 4;
    1617 
    1618             build_got(s1);
    1619 
    1620             /* scan for undefined symbols and see if they are in the
    1621                dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
    1622                is found, then we add it in the PLT. If a symbol
    1623                STT_OBJECT is found, we add it in the .bss section with
    1624                a suitable relocation */
    1625             sym_end = (ElfW(Sym) *)(symtab_section->data +
    1626                                     symtab_section->data_offset);
    1627             if (file_type == TCC_OUTPUT_EXE) {
    1628                 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    1629                     sym < sym_end;
    1630                     sym++) {
    1631                     if (sym->st_shndx == SHN_UNDEF) {
    1632                         name = symtab_section->link->data + sym->st_name;
    1633                         sym_index = find_elf_sym(s1->dynsymtab_section, name);
    1634                         if (sym_index) {
    1635                             esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
    1636                             type = ELFW(ST_TYPE)(esym->st_info);
    1637                             if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
    1638                                 /* Indirect functions shall have STT_FUNC type
    1639                                  * in executable dynsym section. Indeed, a dlsym
    1640                                  * call following a lazy resolution would pick
    1641                                  * the symbol value from the executable dynsym
    1642                                  * entry which would contain the address of the
    1643                                  * function wanted by the caller of dlsym
    1644                                  * instead of the address of the function that
    1645                                  * would return that address */
    1646                                 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
    1647                                               ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
    1648                                               sym - (ElfW(Sym) *)symtab_section->data);
    1649                             } else if (type == STT_OBJECT) {
    1650                                 unsigned long offset;
    1651                                 ElfW(Sym) *dynsym, *dynsym_end;
    1652                                 offset = bss_section->data_offset;
    1653                                 /* XXX: which alignment ? */
    1654                                 offset = (offset + 16 - 1) & -16;
    1655                                 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
    1656                                                     esym->st_info, 0,
    1657                                                     bss_section->sh_num, name);
    1658                                 // Ensure R_COPY works for weak symbol aliases
    1659                                 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
    1660                                     dynsym_end = (ElfW(Sym) *)
    1661                                                  (s1->dynsymtab_section->data +
    1662                                                   s1->dynsymtab_section->data_offset);
    1663                                     for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
    1664                                         dynsym < dynsym_end; dynsym++) {
    1665                                         if ((dynsym->st_value == esym->st_value)
    1666                                            && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
    1667                                             char *dynname;
    1668                                             dynname = s1->dynsymtab_section->link->data
    1669                                                       + dynsym->st_name;
    1670                                             put_elf_sym(s1->dynsym, offset,
    1671                                                         dynsym->st_size,
    1672                                                         dynsym->st_info, 0,
    1673                                                         bss_section->sh_num,
    1674                                                         dynname);
    1675                                             break;
    1676                                         }
    1677                                     }
    1678                                 }
    1679                                 put_elf_reloc(s1->dynsym, bss_section,
    1680                                               offset, R_COPY, index);
    1681                                 offset += esym->st_size;
    1682                                 bss_section->data_offset = offset;
    1683                             }
    1684                         } else {
    1685                                 /* STB_WEAK undefined symbols are accepted */
    1686                                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
    1687                                    it */
    1688                             if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
    1689                                 !strcmp(name, "_fp_hw")) {
    1690                             } else {
    1691                                 tcc_error_noabort("undefined symbol '%s'", name);
    1692                             }
    1693                         }
    1694                     } else if (s1->rdynamic &&
    1695                                ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    1696                         /* if -rdynamic option, then export all non
    1697                            local symbols */
    1698                         name = symtab_section->link->data + sym->st_name;
    1699                         put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
    1700                                     sym->st_info, 0,
    1701                                     sym->st_shndx, name);
    1702                     }
    1703                 }
    1704            
    1705                 if (s1->nb_errors)
    1706                     goto fail;
    1707 
    1708                 /* now look at unresolved dynamic symbols and export
    1709                    corresponding symbol */
    1710                 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
    1711                                         s1->dynsymtab_section->data_offset);
    1712                 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
    1713                     esym < sym_end;
    1714                     esym++) {
    1715                     if (esym->st_shndx == SHN_UNDEF) {
    1716                         name = s1->dynsymtab_section->link->data + esym->st_name;
    1717                         sym_index = find_elf_sym(symtab_section, name);
    1718                         if (sym_index) {
    1719                             /* XXX: avoid adding a symbol if already
    1720                                present because of -rdynamic ? */
    1721                             sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1722                             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
    1723                                         sym->st_info, 0,
    1724                                         sym->st_shndx, name);
    1725                         } else {
    1726                             if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
    1727                                 /* weak symbols can stay undefined */
    1728                             } else {
    1729                                 tcc_warning("undefined dynamic symbol '%s'", name);
     1380
     1381/* Bind symbols of executable: resolve undefined symbols from exported symbols
     1382   in shared libraries and export non local defined symbols to shared libraries
     1383   if -rdynamic switch was given on command line */
     1384static void bind_exe_dynsyms(TCCState *s1)
     1385{
     1386    const char *name;
     1387    int sym_index, index;
     1388    ElfW(Sym) *sym, *esym;
     1389    int type;
     1390
     1391    /* Resolve undefined symbols from dynamic symbols. When there is a match:
     1392       - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
     1393       - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
     1394    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
     1395        if (sym->st_shndx == SHN_UNDEF) {
     1396            name = (char *) symtab_section->link->data + sym->st_name;
     1397            sym_index = find_elf_sym(s1->dynsymtab_section, name);
     1398            if (sym_index) {
     1399                esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
     1400                type = ELFW(ST_TYPE)(esym->st_info);
     1401                if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
     1402                    /* Indirect functions shall have STT_FUNC type in executable
     1403                     * dynsym section. Indeed, a dlsym call following a lazy
     1404                     * resolution would pick the symbol value from the
     1405                     * executable dynsym entry which would contain the address
     1406                     * of the function wanted by the caller of dlsym instead of
     1407                     * the address of the function that would return that
     1408                     * address */
     1409                    int dynindex
     1410                      = put_elf_sym(s1->dynsym, 0, esym->st_size,
     1411                                    ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
     1412                                    name);
     1413                    int index = sym - (ElfW(Sym) *) symtab_section->data;
     1414                    get_sym_attr(s1, index, 1)->dyn_index = dynindex;
     1415                } else if (type == STT_OBJECT) {
     1416                    unsigned long offset;
     1417                    ElfW(Sym) *dynsym;
     1418                    offset = bss_section->data_offset;
     1419                    /* XXX: which alignment ? */
     1420                    offset = (offset + 16 - 1) & -16;
     1421                    set_elf_sym (s1->symtab, offset, esym->st_size,
     1422                                 esym->st_info, 0, bss_section->sh_num, name);
     1423                    index = put_elf_sym(s1->dynsym, offset, esym->st_size,
     1424                                        esym->st_info, 0, bss_section->sh_num,
     1425                                        name);
     1426
     1427                    /* Ensure R_COPY works for weak symbol aliases */
     1428                    if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
     1429                        for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
     1430                            if ((dynsym->st_value == esym->st_value)
     1431                                && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
     1432                                char *dynname = (char *) s1->dynsymtab_section->link->data
     1433                                                + dynsym->st_name;
     1434                                put_elf_sym(s1->dynsym, offset, dynsym->st_size,
     1435                                            dynsym->st_info, 0,
     1436                                            bss_section->sh_num, dynname);
     1437                                break;
    17301438                            }
    17311439                        }
    17321440                    }
     1441
     1442                    put_elf_reloc(s1->dynsym, bss_section,
     1443                                  offset, R_COPY, index);
     1444                    offset += esym->st_size;
     1445                    bss_section->data_offset = offset;
    17331446                }
    17341447            } else {
    1735                 int nb_syms;
    1736                 /* shared library case : we simply export all the global symbols */
    1737                 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
    1738                 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
    1739                 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    1740                     sym < sym_end;
    1741                     sym++) {
    1742                     if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    1743 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
    1744                         if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC ||
    1745                             ELFW(ST_TYPE)(sym->st_info) == STT_GNU_IFUNC)
    1746                             && sym->st_shndx == SHN_UNDEF) {
    1747                             int visibility = ELFW(ST_BIND)(sym->st_info);
    1748                             put_got_entry(s1, R_JMP_SLOT, sym->st_size,
    1749                                           ELFW(ST_INFO)(visibility,STT_FUNC),
    1750                                           sym - (ElfW(Sym) *)symtab_section->data);
    1751                         }
    1752                         else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
    1753                             put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
    1754                                           sym->st_info,
    1755                                           sym - (ElfW(Sym) *)symtab_section->data);
    1756                         }
    1757                         else
    1758 #endif
    1759                         {
    1760                             name = symtab_section->link->data + sym->st_name;
    1761                             index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
    1762                                                 sym->st_info, 0,
    1763                                                 sym->st_shndx, name);
    1764                             s1->symtab_to_dynsym[sym -
    1765                                                  (ElfW(Sym) *)symtab_section->data] =
    1766                                 index;
    1767                         }
    1768                     }
     1448                /* STB_WEAK undefined symbols are accepted */
     1449                /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
     1450                if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
     1451                    !strcmp(name, "_fp_hw")) {
     1452                } else {
     1453                    tcc_error_noabort("undefined symbol '%s'", name);
    17691454                }
    17701455            }
    1771 
    1772             build_got_entries(s1);
    1773        
    1774             /* add a list of needed dlls */
    1775             for(i = 0; i < s1->nb_loaded_dlls; i++) {
    1776                 DLLReference *dllref = s1->loaded_dlls[i];
    1777                 if (dllref->level == 0)
    1778                     put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
    1779             }
    1780 
    1781             if (s1->rpath)
    1782                 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
    1783 
    1784             /* XXX: currently, since we do not handle PIC code, we
    1785                must relocate the readonly segments */
    1786             if (file_type == TCC_OUTPUT_DLL) {
    1787                 if (s1->soname)
    1788                     put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
    1789                 put_dt(dynamic, DT_TEXTREL, 0);
    1790             }
    1791 
    1792             if (s1->symbolic)
    1793                 put_dt(dynamic, DT_SYMBOLIC, 0);
    1794 
    1795             /* add necessary space for other entries */
    1796             saved_dynamic_data_offset = dynamic->data_offset;
    1797             dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
    1798         } else {
    1799             /* still need to build got entries in case of static link */
    1800             build_got_entries(s1);
    1801         }
    1802     }
    1803 
    1804     memset(&ehdr, 0, sizeof(ehdr));
    1805 
    1806     /* we add a section for symbols */
    1807     strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
    1808     put_elf_str(strsec, "");
    1809    
    1810     /* compute number of sections */
    1811     shnum = s1->nb_sections;
    1812 
    1813     /* this array is used to reorder sections in the output file */
    1814     section_order = tcc_malloc(sizeof(int) * shnum);
    1815     section_order[0] = 0;
    1816     sh_order_index = 1;
    1817    
    1818     /* compute number of program headers */
    1819     switch(file_type) {
    1820     default:
    1821     case TCC_OUTPUT_OBJ:
    1822         phnum = 0;
    1823         break;
    1824     case TCC_OUTPUT_EXE:
    1825         if (!s1->static_link)
    1826             phnum = 4 + HAVE_PHDR;
    1827         else
    1828             phnum = 2;
    1829         break;
    1830     case TCC_OUTPUT_DLL:
    1831         phnum = 3;
    1832         break;
    1833     }
    1834 
    1835     /* allocate strings for section names and decide if an unallocated
    1836        section should be output */
    1837     /* NOTE: the strsec section comes last, so its size is also
    1838        correct ! */
     1456        } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
     1457            /* if -rdynamic option, then export all non local symbols */
     1458            name = (char *) symtab_section->link->data + sym->st_name;
     1459            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
     1460                        0, sym->st_shndx, name);
     1461        }
     1462    }
     1463}
     1464
     1465/* Bind symbols of libraries: export all non local symbols of executable that
     1466   are referenced by shared libraries. The reason is that the dynamic loader
     1467   search symbol first in executable and then in libraries. Therefore a
     1468   reference to a symbol already defined by a library can still be resolved by
     1469   a symbol in the executable. */
     1470static void bind_libs_dynsyms(TCCState *s1)
     1471{
     1472    const char *name;
     1473    int sym_index;
     1474    ElfW(Sym) *sym, *esym;
     1475
     1476    for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
     1477        name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
     1478        sym_index = find_elf_sym(symtab_section, name);
     1479        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
     1480        if (sym_index && sym->st_shndx != SHN_UNDEF
     1481            && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
     1482            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
     1483                sym->st_info, 0, sym->st_shndx, name);
     1484        } else if (esym->st_shndx == SHN_UNDEF) {
     1485            /* weak symbols can stay undefined */
     1486            if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
     1487                tcc_warning("undefined dynamic symbol '%s'", name);
     1488        }
     1489    }
     1490}
     1491
     1492/* Export all non local symbols. This is used by shared libraries so that the
     1493   non local symbols they define can resolve a reference in another shared
     1494   library or in the executable. Correspondingly, it allows undefined local
     1495   symbols to be resolved by other shared libraries or by the executable. */
     1496static void export_global_syms(TCCState *s1)
     1497{
     1498    int dynindex, index;
     1499    const char *name;
     1500    ElfW(Sym) *sym;
     1501
     1502    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
     1503        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
     1504            name = (char *) symtab_section->link->data + sym->st_name;
     1505            dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
     1506                                   sym->st_info, 0, sym->st_shndx, name);
     1507            index = sym - (ElfW(Sym) *) symtab_section->data;
     1508            get_sym_attr(s1, index, 1)->dyn_index = dynindex;
     1509        }
     1510    }
     1511}
     1512
     1513/* Allocate strings for section names and decide if an unallocated section
     1514   should be output.
     1515   NOTE: the strsec section comes last, so its size is also correct ! */
     1516static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
     1517{
     1518    int i;
     1519    Section *s;
     1520    int textrel = 0;
     1521
     1522    /* Allocate strings for section names */
    18391523    for(i = 1; i < s1->nb_sections; i++) {
    18401524        s = s1->sections[i];
    1841         s->sh_name = put_elf_str(strsec, s->name);
    1842 #if 0 //gr       
    1843         printf("section: f=%08x t=%08x i=%08x %s %s\n",
    1844                s->sh_flags,
    1845                s->sh_type,
    1846                s->sh_info,
    1847                s->name,
    1848                s->reloc ? s->reloc->name : "n"
    1849                );
    1850 #endif
    18511525        /* when generating a DLL, we include relocations but we may
    18521526           patch them */
    1853         if (file_type == TCC_OUTPUT_DLL &&
    1854             s->sh_type == SHT_RELX &&
    1855             !(s->sh_flags & SHF_ALLOC)) {
    1856             /* //gr: avoid bogus relocs for empty (debug) sections */
    1857             if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
    1858                 prepare_dynamic_rel(s1, s);
    1859             else if (s1->do_debug)
    1860                 s->sh_size = s->data_offset;
     1527        if (file_type == TCC_OUTPUT_DLL &&
     1528            s->sh_type == SHT_RELX &&
     1529            !(s->sh_flags & SHF_ALLOC) &&
     1530            (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
     1531            prepare_dynamic_rel(s1, s)) {
     1532                if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
     1533                    textrel = 1;
    18611534        } else if (s1->do_debug ||
    1862             file_type == TCC_OUTPUT_OBJ || 
     1535            file_type == TCC_OUTPUT_OBJ ||
    18631536            (s->sh_flags & SHF_ALLOC) ||
    1864             i == (s1->nb_sections - 1)) {
     1537            i == (s1->nb_sections - 1)) {
    18651538            /* we output all sections if debug or object file */
    18661539            s->sh_size = s->data_offset;
    18671540        }
    1868     }
    1869 
    1870     /* allocate program segment headers */
    1871     phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
    1872        
    1873     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
     1541        if (s->sh_size || (s->sh_flags & SHF_ALLOC))
     1542            s->sh_name = put_elf_str(strsec, s->name);
     1543    }
     1544    strsec->sh_size = strsec->data_offset;
     1545    return textrel;
     1546}
     1547
     1548/* Info to be copied in dynamic section */
     1549struct dyn_inf {
     1550    Section *dynamic;
     1551    Section *dynstr;
     1552    unsigned long data_offset;
     1553    addr_t rel_addr;
     1554    addr_t rel_size;
     1555#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     1556    addr_t bss_addr;
     1557    addr_t bss_size;
     1558#endif
     1559};
     1560
     1561/* Assign sections to segments and decide how are sections laid out when loaded
     1562   in memory. This function also fills corresponding program headers. */
     1563static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
     1564                           Section *interp, Section* strsec,
     1565                           struct dyn_inf *dyninf, int *sec_order)
     1566{
     1567    int i, j, k, file_type, sh_order_index, file_offset;
     1568    unsigned long s_align;
     1569    long long tmp;
     1570    addr_t addr;
     1571    ElfW(Phdr) *ph;
     1572    Section *s;
     1573
     1574    file_type = s1->output_type;
     1575    sh_order_index = 1;
     1576    file_offset = 0;
     1577    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
    18741578        file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
    1875     } else {
    1876         file_offset = 0;
    1877     }
     1579    s_align = ELF_PAGE_SIZE;
     1580    if (s1->section_align)
     1581        s_align = s1->section_align;
     1582
    18781583    if (phnum > 0) {
    1879         /* compute section to program header mapping */
    1880         if (s1->has_text_addr) {
     1584        if (s1->has_text_addr) {
    18811585            int a_offset, p_offset;
    18821586            addr = s1->text_addr;
    18831587            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
    18841588               ELF_PAGE_SIZE */
    1885             a_offset = (int) (addr & (s1->section_align - 1));
    1886             p_offset = file_offset & (s1->section_align - 1);
    1887             if (a_offset < p_offset) 
    1888                 a_offset += s1->section_align;
     1589            a_offset = (int) (addr & (s_align - 1));
     1590            p_offset = file_offset & (s_align - 1);
     1591            if (a_offset < p_offset)
     1592                a_offset += s_align;
    18891593            file_offset += (a_offset - p_offset);
    18901594        } else {
     
    18941598                addr = ELF_START_ADDR;
    18951599            /* compute address after headers */
    1896             addr += (file_offset & (s1->section_align - 1));
    1897         }
    1898        
     1600            addr += (file_offset & (s_align - 1));
     1601        }
     1602
     1603        ph = &phdr[0];
     1604        /* Leave one program headers for the program interpreter and one for
     1605           the program header table itself if needed. These are done later as
     1606           they require section layout to be done first. */
     1607        if (interp)
     1608            ph += 2;
     1609
    18991610        /* dynamic relocation table information, for .dynamic section */
    1900         rel_size = 0;
    1901         rel_addr = 0;
    1902 
     1611        dyninf->rel_addr = dyninf->rel_size = 0;
    19031612#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1904         bss_addr = bss_size = 0;
    1905 #endif
    1906         /* leave one program header for the program interpreter */
    1907         ph = &phdr[0];
    1908         if (interp)
    1909             ph += 1 + HAVE_PHDR;
     1613        dyninf->bss_addr = dyninf->bss_size = 0;
     1614#endif
    19101615
    19111616        for(j = 0; j < 2; j++) {
     
    19151620            else
    19161621                ph->p_flags = PF_R | PF_W;
    1917             ph->p_align = s1->section_align;
    1918            
    1919             /* we do the following ordering: interp, symbol tables,
    1920                relocations, progbits, nobits */
     1622            ph->p_align = s_align;
     1623
     1624            /* Decide the layout of sections loaded in memory. This must
     1625               be done before program headers are filled since they contain
     1626               info about the layout. We do the following ordering: interp,
     1627               symbol tables, relocations, progbits, nobits */
    19211628            /* XXX: do faster and simpler sorting */
    19221629            for(k = 0; k < 5; k++) {
     
    19251632                    /* compute if section should be included */
    19261633                    if (j == 0) {
    1927                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
     1634                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
    19281635                            SHF_ALLOC)
    19291636                            continue;
    19301637                    } else {
    1931                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
     1638                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
    19321639                            (SHF_ALLOC | SHF_WRITE))
    19331640                            continue;
     
    19511658                            continue;
    19521659                    }
    1953                     section_order[sh_order_index++] = i;
     1660                    sec_order[sh_order_index++] = i;
    19541661
    19551662                    /* section matches: we align it and add its size */
    19561663                    tmp = addr;
    1957                     addr = (addr + s->sh_addralign - 1) & 
     1664                    addr = (addr + s->sh_addralign - 1) &
    19581665                        ~(s->sh_addralign - 1);
    19591666                    file_offset += (int) ( addr - tmp );
    19601667                    s->sh_offset = file_offset;
    19611668                    s->sh_addr = addr;
    1962                    
     1669
    19631670                    /* update program header infos */
    19641671                    if (ph->p_offset == 0) {
     
    19701677                    if (s->sh_type == SHT_RELX) {
    19711678#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1972                         if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { // rel_size == 0) {
    1973                             rel_addr = addr;
    1974                             rel_size += s->sh_size;     // XXX only first rel.
    1975                         }
    1976                         if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { // rel_size == 0) {
    1977                             bss_addr = addr;
    1978                             bss_size = s->sh_size;      // XXX only first rel.
    1979                         }
     1679                        if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
     1680                            dyninf->rel_addr = addr;
     1681                            dyninf->rel_size += s->sh_size; /* XXX only first rel. */
     1682                        }
     1683                        if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
     1684                            dyninf->bss_addr = addr;
     1685                            dyninf->bss_size = s->sh_size; /* XXX only first rel. */
     1686                        }
    19801687#else
    1981                         if (rel_size == 0)
    1982                             rel_addr = addr;
    1983                         rel_size += s->sh_size;
     1688                        if (dyninf->rel_size == 0)
     1689                            dyninf->rel_addr = addr;
     1690                        dyninf->rel_size += s->sh_size;
    19841691#endif
    19851692                    }
     
    19891696                }
    19901697            }
     1698            if (j == 0) {
     1699                /* Make the first PT_LOAD segment include the program
     1700                   headers itself (and the ELF header as well), it'll
     1701                   come out with same memory use but will make various
     1702                   tools like binutils strip work better.  */
     1703                ph->p_offset &= ~(ph->p_align - 1);
     1704                ph->p_vaddr &= ~(ph->p_align - 1);
     1705                ph->p_paddr &= ~(ph->p_align - 1);
     1706            }
    19911707            ph->p_filesz = file_offset - ph->p_offset;
    19921708            ph->p_memsz = addr - ph->p_vaddr;
     
    19961712                    /* if in the middle of a page, we duplicate the page in
    19971713                       memory so that one copy is RX and the other is RW */
    1998                     if ((addr & (s1->section_align - 1)) != 0)
    1999                         addr += s1->section_align;
     1714                    if ((addr & (s_align - 1)) != 0)
     1715                        addr += s_align;
    20001716                } else {
    2001                     addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
    2002                     file_offset = (file_offset + s1->section_align - 1) &
    2003                         ~(s1->section_align - 1);
     1717                    addr = (addr + s_align - 1) & ~(s_align - 1);
     1718                    file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
    20041719                }
    20051720            }
    20061721        }
    2007 
    2008         /* if interpreter, then add corresponing program header */
    2009         if (interp) {
    2010             ph = &phdr[0];
    2011 
    2012 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    2013             {
    2014                 int len = phnum * sizeof(ElfW(Phdr));
    2015 
    2016                 ph->p_type = PT_PHDR;
    2017                 ph->p_offset = sizeof(ElfW(Ehdr));
    2018                 ph->p_vaddr = interp->sh_addr - len;
    2019                 ph->p_paddr = ph->p_vaddr;
    2020                 ph->p_filesz = ph->p_memsz = len;
    2021                 ph->p_flags = PF_R | PF_X;
    2022                 ph->p_align = 4; // interp->sh_addralign;
    2023                 ph++;
    2024             }
    2025 #endif
    2026 
    2027             ph->p_type = PT_INTERP;
    2028             ph->p_offset = interp->sh_offset;
    2029             ph->p_vaddr = interp->sh_addr;
    2030             ph->p_paddr = ph->p_vaddr;
    2031             ph->p_filesz = interp->sh_size;
    2032             ph->p_memsz = interp->sh_size;
    2033             ph->p_flags = PF_R;
    2034             ph->p_align = interp->sh_addralign;
    2035         }
    2036        
    2037         /* if dynamic section, then add corresponing program header */
    2038         if (dynamic) {
    2039             ElfW(Sym) *sym_end;
    2040 
    2041             ph = &phdr[phnum - 1];
    2042            
    2043             ph->p_type = PT_DYNAMIC;
    2044             ph->p_offset = dynamic->sh_offset;
    2045             ph->p_vaddr = dynamic->sh_addr;
    2046             ph->p_paddr = ph->p_vaddr;
    2047             ph->p_filesz = dynamic->sh_size;
    2048             ph->p_memsz = dynamic->sh_size;
    2049             ph->p_flags = PF_R | PF_W;
    2050             ph->p_align = dynamic->sh_addralign;
    2051 
    2052             /* put GOT dynamic section address */
    2053             put32(s1->got->data, dynamic->sh_addr);
    2054 
    2055             /* relocate the PLT */
    2056             if (file_type == TCC_OUTPUT_EXE
    2057 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
    2058                 || file_type == TCC_OUTPUT_DLL
    2059 #endif
    2060                 ) {
    2061                 uint8_t *p, *p_end;
    2062 
    2063                 p = s1->plt->data;
    2064                 p_end = p + s1->plt->data_offset;
    2065                 if (p < p_end) {
    2066 #if defined(TCC_TARGET_I386)
    2067                     put32(p + 2, get32(p + 2) + s1->got->sh_addr);
    2068                     put32(p + 8, get32(p + 8) + s1->got->sh_addr);
    2069                     p += 16;
    2070                     while (p < p_end) {
    2071                         put32(p + 2, get32(p + 2) + s1->got->sh_addr);
    2072                         p += 16;
    2073                     }
    2074 #elif defined(TCC_TARGET_X86_64)
    2075                     int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
    2076                     put32(p + 2, get32(p + 2) + x);
    2077                     put32(p + 8, get32(p + 8) + x - 6);
    2078                     p += 16;
    2079                     while (p < p_end) {
    2080                         put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
    2081                         p += 16;
    2082                     }
    2083 #elif defined(TCC_TARGET_ARM)
    2084                     int x;
    2085                     x=s1->got->sh_addr - s1->plt->sh_addr - 12;
    2086                     p += 16;
    2087                     while (p < p_end) {
    2088                         if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
    2089                             p += 4;
    2090                         put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
    2091                         p += 16;
    2092                     }
    2093 #elif defined(TCC_TARGET_C67)
    2094                     /* XXX: TODO */
    2095 #elif  defined(TCC_TARGET_IL)
    2096 #else
    2097 #error unsupported CPU
    2098 #endif
    2099                 }
    2100             }
    2101 
    2102             /* relocate symbols in .dynsym */
    2103             sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
    2104             for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
    2105                 sym < sym_end;
    2106                 sym++) {
    2107                 if (sym->st_shndx == SHN_UNDEF) {
    2108                     /* relocate to the PLT if the symbol corresponds
    2109                        to a PLT entry */
    2110                     if (sym->st_value)
    2111                         sym->st_value += s1->plt->sh_addr;
    2112                 } else if (sym->st_shndx < SHN_LORESERVE) {
    2113                     /* do symbol relocation */
    2114                     sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
    2115                 }
    2116             }
    2117 
    2118             /* put dynamic section entries */
    2119             dynamic->data_offset = saved_dynamic_data_offset;
    2120             put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
    2121             put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
    2122             put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
    2123             put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
    2124             put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
    2125 #ifdef TCC_TARGET_X86_64
    2126             put_dt(dynamic, DT_RELA, rel_addr);
    2127             put_dt(dynamic, DT_RELASZ, rel_size);
    2128             put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
    2129 #else
    2130 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    2131             put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
    2132             put_dt(dynamic, DT_PLTRELSZ, rel_size);
    2133             put_dt(dynamic, DT_JMPREL, rel_addr);
    2134             put_dt(dynamic, DT_PLTREL, DT_REL);
    2135             put_dt(dynamic, DT_REL, bss_addr);
    2136             put_dt(dynamic, DT_RELSZ, bss_size);
    2137 #else
    2138             put_dt(dynamic, DT_REL, rel_addr);
    2139             put_dt(dynamic, DT_RELSZ, rel_size);
    2140             put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
    2141 #endif
    2142 #endif
    2143             if (s1->do_debug)
    2144                 put_dt(dynamic, DT_DEBUG, 0);
    2145             put_dt(dynamic, DT_NULL, 0);
    2146         }
    2147 
    2148         ehdr.e_phentsize = sizeof(ElfW(Phdr));
    2149         ehdr.e_phnum = phnum;
    2150         ehdr.e_phoff = sizeof(ElfW(Ehdr));
    21511722    }
    21521723
     
    21561727        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
    21571728            continue;
    2158         section_order[sh_order_index++] = i;
    2159        
    2160         file_offset = (file_offset + s->sh_addralign - 1) & 
     1729        sec_order[sh_order_index++] = i;
     1730
     1731        file_offset = (file_offset + s->sh_addralign - 1) &
    21611732            ~(s->sh_addralign - 1);
    21621733        s->sh_offset = file_offset;
     
    21641735            file_offset += s->sh_size;
    21651736    }
    2166    
    2167     /* if building executable or DLL, then relocate each section
    2168        except the GOT which is already relocated */
    2169     if (file_type != TCC_OUTPUT_OBJ) {
    2170         relocate_syms(s1, 0);
    2171 
    2172         if (s1->nb_errors != 0) {
    2173         fail:
    2174             ret = -1;
    2175             goto the_end;
    2176         }
    2177 
    2178         /* relocate sections */
    2179         /* XXX: ignore sections with allocated relocations ? */
    2180         for(i = 1; i < s1->nb_sections; i++) {
    2181             s = s1->sections[i];
    2182             if (s->reloc && s != s1->got)
    2183                 relocate_section(s1, s);
    2184         }
    2185 
    2186         /* relocate relocation entries if the relocation tables are
    2187            allocated in the executable */
    2188         for(i = 1; i < s1->nb_sections; i++) {
    2189             s = s1->sections[i];
    2190             if ((s->sh_flags & SHF_ALLOC) &&
    2191                 s->sh_type == SHT_RELX) {
    2192                 relocate_rel(s1, s);
    2193             }
    2194         }
    2195 
    2196         /* get entry point address */
    2197         if (file_type == TCC_OUTPUT_EXE)
    2198             ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
    2199         else
    2200             ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
    2201     }
    2202     if (file_type == TCC_OUTPUT_EXE && s1->static_link)
    2203         fill_got(s1);
    2204 
    2205     /* write elf file */
     1737
     1738    return file_offset;
     1739}
     1740
     1741static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
     1742                                 Section *dynamic)
     1743{
     1744    ElfW(Phdr) *ph;
     1745
     1746    /* if interpreter, then add corresponding program header */
     1747    if (interp) {
     1748        ph = &phdr[0];
     1749
     1750        ph->p_type = PT_PHDR;
     1751        ph->p_offset = sizeof(ElfW(Ehdr));
     1752        ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
     1753        ph->p_vaddr = interp->sh_addr - ph->p_filesz;
     1754        ph->p_paddr = ph->p_vaddr;
     1755        ph->p_flags = PF_R | PF_X;
     1756        ph->p_align = 4; /* interp->sh_addralign; */
     1757        ph++;
     1758
     1759        ph->p_type = PT_INTERP;
     1760        ph->p_offset = interp->sh_offset;
     1761        ph->p_vaddr = interp->sh_addr;
     1762        ph->p_paddr = ph->p_vaddr;
     1763        ph->p_filesz = interp->sh_size;
     1764        ph->p_memsz = interp->sh_size;
     1765        ph->p_flags = PF_R;
     1766        ph->p_align = interp->sh_addralign;
     1767    }
     1768
     1769    /* if dynamic section, then add corresponding program header */
     1770    if (dynamic) {
     1771        ph = &phdr[phnum - 1];
     1772
     1773        ph->p_type = PT_DYNAMIC;
     1774        ph->p_offset = dynamic->sh_offset;
     1775        ph->p_vaddr = dynamic->sh_addr;
     1776        ph->p_paddr = ph->p_vaddr;
     1777        ph->p_filesz = dynamic->sh_size;
     1778        ph->p_memsz = dynamic->sh_size;
     1779        ph->p_flags = PF_R | PF_W;
     1780        ph->p_align = dynamic->sh_addralign;
     1781    }
     1782}
     1783
     1784/* Fill the dynamic section with tags describing the address and size of
     1785   sections */
     1786static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
     1787{
     1788    Section *dynamic = dyninf->dynamic;
     1789
     1790    /* put dynamic section entries */
     1791    put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
     1792    put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
     1793    put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
     1794    put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
     1795    put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
     1796#if PTR_SIZE == 8
     1797    put_dt(dynamic, DT_RELA, dyninf->rel_addr);
     1798    put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
     1799    put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
     1800#else
     1801#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     1802    put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
     1803    put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
     1804    put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
     1805    put_dt(dynamic, DT_PLTREL, DT_REL);
     1806    put_dt(dynamic, DT_REL, dyninf->bss_addr);
     1807    put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
     1808#else
     1809    put_dt(dynamic, DT_REL, dyninf->rel_addr);
     1810    put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
     1811    put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
     1812#endif
     1813#endif
     1814    if (s1->do_debug)
     1815        put_dt(dynamic, DT_DEBUG, 0);
     1816    put_dt(dynamic, DT_NULL, 0);
     1817}
     1818
     1819/* Relocate remaining sections and symbols (that is those not related to
     1820   dynamic linking) */
     1821static int final_sections_reloc(TCCState *s1)
     1822{
     1823    int i;
     1824    Section *s;
     1825
     1826    relocate_syms(s1, s1->symtab, 0);
     1827
     1828    if (s1->nb_errors != 0)
     1829        return -1;
     1830
     1831    /* relocate sections */
     1832    /* XXX: ignore sections with allocated relocations ? */
     1833    for(i = 1; i < s1->nb_sections; i++) {
     1834        s = s1->sections[i];
     1835#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
     1836        if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
     1837        /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
     1838        checking is removed */
     1839#else
     1840        if (s->reloc && s != s1->got)
     1841        /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
     1842#endif
     1843            relocate_section(s1, s);
     1844    }
     1845
     1846    /* relocate relocation entries if the relocation tables are
     1847       allocated in the executable */
     1848    for(i = 1; i < s1->nb_sections; i++) {
     1849        s = s1->sections[i];
     1850        if ((s->sh_flags & SHF_ALLOC) &&
     1851            s->sh_type == SHT_RELX) {
     1852            relocate_rel(s1, s);
     1853        }
     1854    }
     1855    return 0;
     1856}
     1857
     1858/* Create an ELF file on disk.
     1859   This function handle ELF specific layout requirements */
     1860static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
     1861                           int file_offset, int *sec_order)
     1862{
     1863    int i, shnum, offset, size, file_type;
     1864    Section *s;
     1865    ElfW(Ehdr) ehdr;
     1866    ElfW(Shdr) shdr, *sh;
     1867
     1868    file_type = s1->output_type;
     1869    shnum = s1->nb_sections;
     1870
     1871    memset(&ehdr, 0, sizeof(ehdr));
     1872
     1873    if (phnum > 0) {
     1874        ehdr.e_phentsize = sizeof(ElfW(Phdr));
     1875        ehdr.e_phnum = phnum;
     1876        ehdr.e_phoff = sizeof(ElfW(Ehdr));
     1877    }
     1878
     1879    /* align to 4 */
     1880    file_offset = (file_offset + 3) & -4;
     1881
     1882    /* fill header */
     1883    ehdr.e_ident[0] = ELFMAG0;
     1884    ehdr.e_ident[1] = ELFMAG1;
     1885    ehdr.e_ident[2] = ELFMAG2;
     1886    ehdr.e_ident[3] = ELFMAG3;
     1887    ehdr.e_ident[4] = ELFCLASSW;
     1888    ehdr.e_ident[5] = ELFDATA2LSB;
     1889    ehdr.e_ident[6] = EV_CURRENT;
     1890#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
     1891    /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
     1892    ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
     1893#endif
     1894#ifdef TCC_TARGET_ARM
     1895#ifdef TCC_ARM_EABI
     1896    ehdr.e_ident[EI_OSABI] = 0;
     1897    ehdr.e_flags = EF_ARM_EABI_VER4;
     1898    if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
     1899        ehdr.e_flags |= EF_ARM_HASENTRY;
     1900    if (s1->float_abi == ARM_HARD_FLOAT)
     1901        ehdr.e_flags |= EF_ARM_VFP_FLOAT;
     1902    else
     1903        ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
     1904#else
     1905    ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
     1906#endif
     1907#endif
     1908    switch(file_type) {
     1909    default:
     1910    case TCC_OUTPUT_EXE:
     1911        ehdr.e_type = ET_EXEC;
     1912        ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
     1913        break;
     1914    case TCC_OUTPUT_DLL:
     1915        ehdr.e_type = ET_DYN;
     1916        ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
     1917        break;
     1918    case TCC_OUTPUT_OBJ:
     1919        ehdr.e_type = ET_REL;
     1920        break;
     1921    }
     1922    ehdr.e_machine = EM_TCC_TARGET;
     1923    ehdr.e_version = EV_CURRENT;
     1924    ehdr.e_shoff = file_offset;
     1925    ehdr.e_ehsize = sizeof(ElfW(Ehdr));
     1926    ehdr.e_shentsize = sizeof(ElfW(Shdr));
     1927    ehdr.e_shnum = shnum;
     1928    ehdr.e_shstrndx = shnum - 1;
     1929
     1930    fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
     1931    fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
     1932    offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
     1933
     1934    sort_syms(s1, symtab_section);
     1935    for(i = 1; i < s1->nb_sections; i++) {
     1936        s = s1->sections[sec_order[i]];
     1937        if (s->sh_type != SHT_NOBITS) {
     1938            while (offset < s->sh_offset) {
     1939                fputc(0, f);
     1940                offset++;
     1941            }
     1942            size = s->sh_size;
     1943            if (size)
     1944                fwrite(s->data, 1, size, f);
     1945            offset += size;
     1946        }
     1947    }
     1948
     1949    /* output section headers */
     1950    while (offset < ehdr.e_shoff) {
     1951        fputc(0, f);
     1952        offset++;
     1953    }
     1954
     1955    for(i = 0; i < s1->nb_sections; i++) {
     1956        sh = &shdr;
     1957        memset(sh, 0, sizeof(ElfW(Shdr)));
     1958        s = s1->sections[i];
     1959        if (s) {
     1960            sh->sh_name = s->sh_name;
     1961            sh->sh_type = s->sh_type;
     1962            sh->sh_flags = s->sh_flags;
     1963            sh->sh_entsize = s->sh_entsize;
     1964            sh->sh_info = s->sh_info;
     1965            if (s->link)
     1966                sh->sh_link = s->link->sh_num;
     1967            sh->sh_addralign = s->sh_addralign;
     1968            sh->sh_addr = s->sh_addr;
     1969            sh->sh_offset = s->sh_offset;
     1970            sh->sh_size = s->sh_size;
     1971        }
     1972        fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
     1973    }
     1974}
     1975
     1976/* Write an elf, coff or "binary" file */
     1977static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
     1978                              ElfW(Phdr) *phdr, int file_offset, int *sec_order)
     1979{
     1980    int fd, mode, file_type;
     1981    FILE *f;
     1982
     1983    file_type = s1->output_type;
    22061984    if (file_type == TCC_OUTPUT_OBJ)
    22071985        mode = 0666;
     
    22091987        mode = 0777;
    22101988    unlink(filename);
    2211     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
     1989    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
    22121990    if (fd < 0) {
    22131991        tcc_error_noabort("could not write '%s'", filename);
    2214         goto fail;
     1992        return -1;
    22151993    }
    22161994    f = fdopen(fd, "wb");
     
    22191997
    22201998#ifdef TCC_TARGET_COFF
    2221     if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
     1999    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
    22222000        tcc_output_coff(s1, f);
    2223     } else
    2224 #endif
    2225     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
    2226         sort_syms(s1, symtab_section);
    2227        
    2228         /* align to 4 */
    2229         file_offset = (file_offset + 3) & -4;
    2230    
    2231         /* fill header */
    2232         ehdr.e_ident[0] = ELFMAG0;
    2233         ehdr.e_ident[1] = ELFMAG1;
    2234         ehdr.e_ident[2] = ELFMAG2;
    2235         ehdr.e_ident[3] = ELFMAG3;
    2236         ehdr.e_ident[4] = ELFCLASSW;
    2237         ehdr.e_ident[5] = ELFDATA2LSB;
    2238         ehdr.e_ident[6] = EV_CURRENT;
    2239 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    2240         ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
    2241 #endif
    2242 #ifdef TCC_TARGET_ARM
    2243 #ifdef TCC_ARM_EABI
    2244         ehdr.e_ident[EI_OSABI] = 0;
    2245         ehdr.e_flags = 4 << 24;
    2246 #else
    2247         ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
    2248 #endif
    2249 #endif
    2250         switch(file_type) {
    2251         default:
    2252         case TCC_OUTPUT_EXE:
    2253             ehdr.e_type = ET_EXEC;
    2254             break;
    2255         case TCC_OUTPUT_DLL:
    2256             ehdr.e_type = ET_DYN;
    2257             break;
    2258         case TCC_OUTPUT_OBJ:
    2259             ehdr.e_type = ET_REL;
    2260             break;
    2261         }
    2262         ehdr.e_machine = EM_TCC_TARGET;
    2263         ehdr.e_version = EV_CURRENT;
    2264         ehdr.e_shoff = file_offset;
    2265         ehdr.e_ehsize = sizeof(ElfW(Ehdr));
    2266         ehdr.e_shentsize = sizeof(ElfW(Shdr));
    2267         ehdr.e_shnum = shnum;
    2268         ehdr.e_shstrndx = shnum - 1;
    2269        
    2270         fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
    2271         fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
    2272         offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
    2273 
    2274         for(i=1;i<s1->nb_sections;i++) {
    2275             s = s1->sections[section_order[i]];
    2276             if (s->sh_type != SHT_NOBITS) {
    2277                 if (s->sh_type == SHT_DYNSYM)
    2278                     patch_dynsym_undef(s1, s);
    2279                 while (offset < s->sh_offset) {
    2280                     fputc(0, f);
    2281                     offset++;
     2001    else
     2002#endif
     2003    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
     2004        tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
     2005    else
     2006        tcc_output_binary(s1, f, sec_order);
     2007    fclose(f);
     2008
     2009    return 0;
     2010}
     2011
     2012/* Sort section headers by assigned sh_addr, remove sections
     2013   that we aren't going to output.  */
     2014static void tidy_section_headers(TCCState *s1, int *sec_order)
     2015{
     2016    int i, nnew, l, *backmap;
     2017    Section **snew, *s;
     2018    ElfW(Sym) *sym;
     2019
     2020    snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
     2021    backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
     2022    for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
     2023        s = s1->sections[sec_order[i]];
     2024        if (!i || s->sh_name) {
     2025            backmap[sec_order[i]] = nnew;
     2026            snew[nnew] = s;
     2027            ++nnew;
     2028        } else {
     2029            backmap[sec_order[i]] = 0;
     2030            snew[--l] = s;
     2031        }
     2032    }
     2033    for (i = 0; i < nnew; i++) {
     2034        s = snew[i];
     2035        if (s) {
     2036            s->sh_num = i;
     2037            if (s->sh_type == SHT_RELX)
     2038                s->sh_info = backmap[s->sh_info];
     2039        }
     2040    }
     2041
     2042    for_each_elem(symtab_section, 1, sym, ElfW(Sym))
     2043        if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
     2044            sym->st_shndx = backmap[sym->st_shndx];
     2045    if( !s1->static_link ) {
     2046        for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
     2047            if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
     2048                sym->st_shndx = backmap[sym->st_shndx];
     2049    }
     2050    for (i = 0; i < s1->nb_sections; i++)
     2051        sec_order[i] = i;
     2052    tcc_free(s1->sections);
     2053    s1->sections = snew;
     2054    s1->nb_sections = nnew;
     2055    tcc_free(backmap);
     2056}
     2057
     2058/* Output an elf, coff or binary file */
     2059/* XXX: suppress unneeded sections */
     2060static int elf_output_file(TCCState *s1, const char *filename)
     2061{
     2062    int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
     2063    struct dyn_inf dyninf = {0};
     2064    ElfW(Phdr) *phdr;
     2065    ElfW(Sym) *sym;
     2066    Section *strsec, *interp, *dynamic, *dynstr;
     2067    int textrel;
     2068
     2069    file_type = s1->output_type;
     2070    s1->nb_errors = 0;
     2071    ret = -1;
     2072    phdr = NULL;
     2073    sec_order = NULL;
     2074    interp = dynamic = dynstr = NULL; /* avoid warning */
     2075    textrel = 0;
     2076
     2077    if (file_type != TCC_OUTPUT_OBJ) {
     2078        /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
     2079        tcc_add_runtime(s1);
     2080        resolve_common_syms(s1);
     2081
     2082        if (!s1->static_link) {
     2083            if (file_type == TCC_OUTPUT_EXE) {
     2084                char *ptr;
     2085                /* allow override the dynamic loader */
     2086                const char *elfint = getenv("LD_SO");
     2087                if (elfint == NULL)
     2088                    elfint = DEFAULT_ELFINTERP(s1);
     2089                /* add interpreter section only if executable */
     2090                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
     2091                interp->sh_addralign = 1;
     2092                ptr = section_ptr_add(interp, 1 + strlen(elfint));
     2093                strcpy(ptr, elfint);
     2094            }
     2095
     2096            /* add dynamic symbol table */
     2097            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
     2098                                    ".dynstr",
     2099                                    ".hash", SHF_ALLOC);
     2100            dynstr = s1->dynsym->link;
     2101
     2102            /* add dynamic section */
     2103            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
     2104                                  SHF_ALLOC | SHF_WRITE);
     2105            dynamic->link = dynstr;
     2106            dynamic->sh_entsize = sizeof(ElfW(Dyn));
     2107
     2108            build_got(s1);
     2109
     2110            if (file_type == TCC_OUTPUT_EXE) {
     2111                bind_exe_dynsyms(s1);
     2112                if (s1->nb_errors)
     2113                    goto the_end;
     2114                bind_libs_dynsyms(s1);
     2115            } else {
     2116                /* shared library case: simply export all global symbols */
     2117                export_global_syms(s1);
     2118            }
     2119        }
     2120        build_got_entries(s1);
     2121    }
     2122
     2123    /* we add a section for symbols */
     2124    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
     2125    put_elf_str(strsec, "");
     2126
     2127    /* Allocate strings for section names */
     2128    textrel = alloc_sec_names(s1, file_type, strsec);
     2129
     2130    if (dynamic) {
     2131        /* add a list of needed dlls */
     2132        for(i = 0; i < s1->nb_loaded_dlls; i++) {
     2133            DLLReference *dllref = s1->loaded_dlls[i];
     2134            if (dllref->level == 0)
     2135                put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
     2136        }
     2137
     2138        if (s1->rpath)
     2139            put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
     2140                   put_elf_str(dynstr, s1->rpath));
     2141
     2142        if (file_type == TCC_OUTPUT_DLL) {
     2143            if (s1->soname)
     2144                put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
     2145            /* XXX: currently, since we do not handle PIC code, we
     2146               must relocate the readonly segments */
     2147            if (textrel)
     2148                put_dt(dynamic, DT_TEXTREL, 0);
     2149        }
     2150
     2151        if (s1->symbolic)
     2152            put_dt(dynamic, DT_SYMBOLIC, 0);
     2153
     2154        dyninf.dynamic = dynamic;
     2155        dyninf.dynstr = dynstr;
     2156        /* remember offset and reserve space for 2nd call below */
     2157        dyninf.data_offset = dynamic->data_offset;
     2158        fill_dynamic(s1, &dyninf);
     2159        dynamic->sh_size = dynamic->data_offset;
     2160        dynstr->sh_size = dynstr->data_offset;
     2161    }
     2162
     2163    /* compute number of program headers */
     2164    if (file_type == TCC_OUTPUT_OBJ)
     2165        phnum = 0;
     2166    else if (file_type == TCC_OUTPUT_DLL)
     2167        phnum = 3;
     2168    else if (s1->static_link)
     2169        phnum = 2;
     2170    else
     2171        phnum = 5;
     2172
     2173    /* allocate program segment headers */
     2174    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
     2175
     2176    /* compute number of sections */
     2177    shnum = s1->nb_sections;
     2178
     2179    /* this array is used to reorder sections in the output file */
     2180    sec_order = tcc_malloc(sizeof(int) * shnum);
     2181    sec_order[0] = 0;
     2182
     2183    /* compute section to program header mapping */
     2184    file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
     2185                                  sec_order);
     2186
     2187    /* Fill remaining program header and finalize relocation related to dynamic
     2188       linking. */
     2189    if (file_type != TCC_OUTPUT_OBJ) {
     2190        fill_unloadable_phdr(phdr, phnum, interp, dynamic);
     2191        if (dynamic) {
     2192            dynamic->data_offset = dyninf.data_offset;
     2193            fill_dynamic(s1, &dyninf);
     2194
     2195            /* put in GOT the dynamic section address and relocate PLT */
     2196            write32le(s1->got->data, dynamic->sh_addr);
     2197            if (file_type == TCC_OUTPUT_EXE
     2198                || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
     2199                relocate_plt(s1);
     2200
     2201            /* relocate symbols in .dynsym now that final addresses are known */
     2202            for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
     2203                if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
     2204                    /* do symbol relocation */
     2205                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
    22822206                }
    2283                 size = s->sh_size;
    2284                 fwrite(s->data, 1, size, f);
    2285                 offset += size;
    2286             }
    2287         }
    2288 
    2289         /* output section headers */
    2290         while (offset < ehdr.e_shoff) {
    2291             fputc(0, f);
    2292             offset++;
    2293         }
    2294    
    2295         for(i=0;i<s1->nb_sections;i++) {
    2296             sh = &shdr;
    2297             memset(sh, 0, sizeof(ElfW(Shdr)));
    2298             s = s1->sections[i];
    2299             if (s) {
    2300                 sh->sh_name = s->sh_name;
    2301                 sh->sh_type = s->sh_type;
    2302                 sh->sh_flags = s->sh_flags;
    2303                 sh->sh_entsize = s->sh_entsize;
    2304                 sh->sh_info = s->sh_info;
    2305                 if (s->link)
    2306                     sh->sh_link = s->link->sh_num;
    2307                 sh->sh_addralign = s->sh_addralign;
    2308                 sh->sh_addr = s->sh_addr;
    2309                 sh->sh_offset = s->sh_offset;
    2310                 sh->sh_size = s->sh_size;
    2311             }
    2312             fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
    2313         }
    2314     } else {
    2315         tcc_output_binary(s1, f, section_order);
    2316     }
    2317     fclose(f);
    2318 
    2319     ret = 0;
     2207            }
     2208        }
     2209
     2210        /* if building executable or DLL, then relocate each section
     2211           except the GOT which is already relocated */
     2212        ret = final_sections_reloc(s1);
     2213        if (ret)
     2214            goto the_end;
     2215        tidy_section_headers(s1, sec_order);
     2216
     2217        /* Perform relocation to GOT or PLT entries */
     2218        if (file_type == TCC_OUTPUT_EXE && s1->static_link)
     2219            fill_got(s1);
     2220        else if (s1->got)
     2221            fill_local_got_entries(s1);
     2222    }
     2223
     2224    /* Create the ELF file with name 'filename' */
     2225    ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
     2226    s1->nb_sections = shnum;
    23202227 the_end:
    2321     tcc_free(s1->symtab_to_dynsym);
    2322     tcc_free(section_order);
     2228    tcc_free(sec_order);
    23232229    tcc_free(phdr);
    2324     tcc_free(s1->sym_attrs);
    23252230    return ret;
    23262231}
     
    23342239    } else
    23352240#endif
    2336     {
    23372241        ret = elf_output_file(s, filename);
    2338     }
    23392242    return ret;
    23402243}
     
    23572260} SectionMergeInfo;
    23582261
     2262ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
     2263{
     2264    int size = read(fd, h, sizeof *h);
     2265    if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
     2266        if (h->e_type == ET_REL)
     2267            return AFF_BINTYPE_REL;
     2268        if (h->e_type == ET_DYN)
     2269            return AFF_BINTYPE_DYN;
     2270    } else if (size >= 8) {
     2271        if (0 == memcmp(h, ARMAG, 8))
     2272            return AFF_BINTYPE_AR;
     2273#ifdef TCC_TARGET_COFF
     2274        if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
     2275            return AFF_BINTYPE_C67;
     2276#endif
     2277    }
     2278    return 0;
     2279}
     2280
    23592281/* load an object file and merge it with current files */
    23602282/* XXX: handle correctly stab (debug) info */
    2361 ST_FUNC int tcc_load_object_file(TCCState *s1, 
     2283ST_FUNC int tcc_load_object_file(TCCState *s1,
    23622284                                int fd, unsigned long file_offset)
    2363 { 
     2285{
    23642286    ElfW(Ehdr) ehdr;
    23652287    ElfW(Shdr) *shdr, *sh;
    2366     int size, i, j, offset, offseti, nb_syms, sym_index, ret;
     2288    int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
    23672289    unsigned char *strsec, *strtab;
    23682290    int *old_to_new_syms;
     
    23702292    SectionMergeInfo *sm_table, *sm;
    23712293    ElfW(Sym) *sym, *symtab;
    2372     ElfW_Rel *rel, *rel_end;
     2294    ElfW_Rel *rel;
    23732295    Section *s;
    23742296
     
    23782300    stab_index = stabstr_index = 0;
    23792301
    2380     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
    2381         goto fail1;
    2382     if (ehdr.e_ident[0] != ELFMAG0 ||
    2383         ehdr.e_ident[1] != ELFMAG1 ||
    2384         ehdr.e_ident[2] != ELFMAG2 ||
    2385         ehdr.e_ident[3] != ELFMAG3)
    2386         goto fail1;
    2387     /* test if object file */
    2388     if (ehdr.e_type != ET_REL)
     2302    lseek(fd, file_offset, SEEK_SET);
     2303    if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
    23892304        goto fail1;
    23902305    /* test CPU specific stuff */
     
    23962311    }
    23972312    /* read sections */
    2398     shdr = load_data(fd, file_offset + ehdr.e_shoff, 
     2313    shdr = load_data(fd, file_offset + ehdr.e_shoff,
    23992314                     sizeof(ElfW(Shdr)) * ehdr.e_shnum);
    24002315    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
    2401    
     2316
    24022317    /* load section names */
    24032318    sh = &shdr[ehdr.e_shstrndx];
     
    24092324    strtab = NULL;
    24102325    nb_syms = 0;
     2326    seencompressed = 0;
    24112327    for(i = 1; i < ehdr.e_shnum; i++) {
    24122328        sh = &shdr[i];
     
    24262342            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
    24272343        }
    2428     }
    2429        
     2344        if (sh->sh_flags & SHF_COMPRESSED)
     2345            seencompressed = 1;
     2346    }
     2347
    24302348    /* now examine each section and try to merge its content with the
    24312349       ones in memory */
     
    24352353            continue;
    24362354        sh = &shdr[i];
    2437         sh_name = strsec + sh->sh_name;
     2355        sh_name = (char *) strsec + sh->sh_name;
    24382356        /* ignore sections types we do not handle */
    24392357        if (sh->sh_type != SHT_PROGBITS &&
    2440             sh->sh_type != SHT_RELX && 
     2358            sh->sh_type != SHT_RELX &&
    24412359#ifdef TCC_ARM_EABI
    24422360            sh->sh_type != SHT_ARM_EXIDX &&
    24432361#endif
    2444             sh->sh_type != SHT_NOBITS && 
     2362            sh->sh_type != SHT_NOBITS &&
    24452363            sh->sh_type != SHT_PREINIT_ARRAY &&
    24462364            sh->sh_type != SHT_INIT_ARRAY &&
     
    24492367            )
    24502368            continue;
     2369        if (seencompressed
     2370            && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1)
     2371                || (sh->sh_type == SHT_RELX
     2372                    && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name,
     2373                                ".debug_", sizeof(".debug_")-1))))
     2374          continue;
    24512375        if (sh->sh_addralign < 1)
    24522376            sh->sh_addralign = 1;
     
    24552379            s = s1->sections[j];
    24562380            if (!strcmp(s->name, sh_name)) {
    2457                 if (!strncmp(sh_name, ".gnu.linkonce", 
     2381                if (!strncmp(sh_name, ".gnu.linkonce",
    24582382                             sizeof(".gnu.linkonce") - 1)) {
    24592383                    /* if a 'linkonce' section is already present, we
     
    24692393        }
    24702394        /* not found: create new section */
    2471         s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
     2395        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
    24722396        /* take as much info as possible from the section. sh_link and
    24732397           sh_info will be updated later */
     
    25142438    }
    25152439
    2516     /* //gr relocate stab strings */
     2440    /* gr relocate stab strings */
    25172441    if (stab_index && stabstr_index) {
    25182442        Stab_Sym *a, *b;
     
    25222446        b = (Stab_Sym *)(s->data + s->data_offset);
    25232447        o = sm_table[stabstr_index].offset;
    2524         while (a < b) 
     2448        while (a < b)
    25252449            a->n_strx += o, a++;
    25262450    }
     
    25562480                   correct relocations */
    25572481                if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    2558                     name = strtab + sym->st_name;
     2482                    name = (char *) strtab + sym->st_name;
    25592483                    sym_index = find_elf_sym(symtab_section, name);
    25602484                    if (sym_index)
     
    25722496        }
    25732497        /* add symbol */
    2574         name = strtab + sym->st_name;
    2575         sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
    2576                                 sym->st_info, sym->st_other, 
     2498        name = (char *) strtab + sym->st_name;
     2499        sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
     2500                                sym->st_info, sym->st_other,
    25772501                                sym->st_shndx, name);
    25782502        old_to_new_syms[i] = sym_index;
     
    25902514            /* take relocation offset information */
    25912515            offseti = sm_table[sh->sh_info].offset;
    2592             rel_end = (ElfW_Rel *)(s->data + s->data_offset);
    2593             for(rel = (ElfW_Rel *)(s->data + offset);
    2594                 rel < rel_end;
    2595                 rel++) {
     2516            for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
    25962517                int type;
    25972518                unsigned sym_index;
     
    26242545                   instructions. Other case of instructions referencing a PLT
    26252546                   entry require to add a Thumb stub before the PLT entry to
    2626                    switch to ARM mode. We set bit 0 of the got offset of a
    2627                    symbol to indicate such a case. */
     2547                   switch to ARM mode. We set bit plt_thumb_stub of the
     2548                   attribute of a symbol to indicate such a case. */
    26282549                if (type == R_ARM_THM_JUMP24)
    2629                     alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
     2550                    get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
    26302551#endif
    26312552            }
     
    26352556        }
    26362557    }
    2637    
     2558
    26382559    ret = 0;
    26392560 the_end:
     
    26622583}
    26632584
     2585static long get_be64(const uint8_t *b)
     2586{
     2587  long long ret = get_be32(b);
     2588  ret = (ret << 32) | (unsigned)get_be32(b+4);
     2589  return (long)ret;
     2590}
     2591
    26642592/* load only the objects which resolve undefined symbols */
    2665 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
    2666 {
    2667     int i, bound, nsyms, sym_index, off, ret;
     2593static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
     2594{
     2595    long i, bound, nsyms, sym_index, off, ret;
    26682596    uint8_t *data;
    26692597    const char *ar_names, *p;
     
    26742602    if (read(fd, data, size) != size)
    26752603        goto fail;
    2676     nsyms = get_be32(data);
    2677     ar_index = data + 4;
    2678     ar_names = ar_index + nsyms * 4;
     2604    nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
     2605    ar_index = data + entrysize;
     2606    ar_names = (char *) ar_index + nsyms * entrysize;
    26792607
    26802608    do {
     
    26852613                sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    26862614                if(sym->st_shndx == SHN_UNDEF) {
    2687                     off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
    2688 #if 0
    2689                     printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
    2690 #endif
     2615                    off = (entrysize == 4
     2616                           ? get_be32(ar_index + i * 4)
     2617                           : get_be64(ar_index + i * 8))
     2618                          + sizeof(ArchiveHeader);
    26912619                    ++bound;
    2692                     lseek(fd, off, SEEK_SET);
    26932620                    if(tcc_load_object_file(s1, fd, off) < 0) {
    26942621                    fail:
     
    27182645    /* skip magic which was already checked */
    27192646    read(fd, magic, sizeof(magic));
    2720    
     2647
    27212648    for(;;) {
    27222649        len = read(fd, &hdr, sizeof(hdr));
     
    27362663        }
    27372664        ar_name[i + 1] = '\0';
    2738         //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
    27392665        file_offset = lseek(fd, 0, SEEK_CUR);
    27402666        /* align to even */
     
    27432669            /* coff symbol table : we handle it */
    27442670            if(s1->alacarte_link)
    2745                 return tcc_load_alacarte(s1, fd, size);
    2746         } else if (!strcmp(ar_name, "//") ||
    2747                    !strcmp(ar_name, "__.SYMDEF") ||
    2748                    !strcmp(ar_name, "__.SYMDEF/") ||
    2749                    !strcmp(ar_name, "ARFILENAMES/")) {
    2750             /* skip symbol table or archive names */
     2671                return tcc_load_alacarte(s1, fd, size, 4);
     2672        } else if (!strcmp(ar_name, "/SYM64/")) {
     2673            if(s1->alacarte_link)
     2674                return tcc_load_alacarte(s1, fd, size, 8);
    27512675        } else {
    2752             if (tcc_load_object_file(s1, fd, file_offset) < 0)
    2753                 return -1;
     2676            ElfW(Ehdr) ehdr;
     2677            if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
     2678                if (tcc_load_object_file(s1, fd, file_offset) < 0)
     2679                    return -1;
     2680            }
    27542681        }
    27552682        lseek(fd, file_offset + size, SEEK_SET);
     
    27632690   the generated ELF file) */
    27642691ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
    2765 { 
     2692{
    27662693    ElfW(Ehdr) ehdr;
    27672694    ElfW(Shdr) *shdr, *sh, *sh1;
     
    27722699    const char *name, *soname;
    27732700    DLLReference *dllref;
    2774    
     2701
    27752702    read(fd, &ehdr, sizeof(ehdr));
    27762703
     
    28072734        }
    28082735    }
    2809    
     2736
    28102737    /* compute the real library name */
    28112738    soname = tcc_basename(filename);
    2812        
     2739
    28132740    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
    28142741        if (dt->d_tag == DT_SONAME) {
    2815             soname = dynstr + dt->d_un.d_val;
     2742            soname = (char *) dynstr + dt->d_un.d_val;
    28162743        }
    28172744    }
     
    28282755        }
    28292756    }
    2830    
    2831     //    printf("loading dll '%s'\n", soname);
    28322757
    28332758    /* add the dll and its level */
     
    28352760    dllref->level = level;
    28362761    strcpy(dllref->name, soname);
    2837     dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
     2762    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
    28382763
    28392764    /* add dynamic symbols in dynsym_section */
     
    28422767        if (sym_bind == STB_LOCAL)
    28432768            continue;
    2844         name = dynstr + sym->st_name;
    2845         add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
     2769        name = (char *) dynstr + sym->st_name;
     2770        set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
    28462771                    sym->st_info, sym->st_other, sym->st_shndx, name);
    28472772    }
     
    28512776        switch(dt->d_tag) {
    28522777        case DT_NEEDED:
    2853             name = dynstr + dt->d_un.d_val;
     2778            name = (char *) dynstr + dt->d_un.d_val;
    28542779            for(j = 0; j < s1->nb_loaded_dlls; j++) {
    28552780                dllref = s1->loaded_dlls[j];
     
    29062831        }
    29072832        break;
     2833    case '\\':
     2834        ch = handle_eob();
     2835        if (ch != '\\')
     2836            goto redo;
     2837        /* fall through */
    29082838    /* case 'a' ... 'z': */
    29092839    case 'a':
     
    29612891       case 'Z':
    29622892    case '_':
    2963     case '\\':
    29642893    case '.':
    29652894    case '$':
     
    29892918        break;
    29902919    }
    2991 #if 0
    2992     printf("tok=%c %d\n", c, c);
    2993     if (c == LD_TOK_NAME)
    2994         printf("  name=%s\n", name);
    2995 #endif
    29962920    return c;
    29972921}
     
    29992923static int ld_add_file(TCCState *s1, const char filename[])
    30002924{
    3001     int ret;
    3002 
    3003     ret = tcc_add_file_internal(s1, filename, 0);
    3004     if (ret)
    3005         ret = tcc_add_dll(s1, filename, 0);
    3006     return ret;
     2925    if (filename[0] == '/') {
     2926        if (CONFIG_SYSROOT[0] == '\0'
     2927            && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
     2928            return 0;
     2929        filename = tcc_basename(filename);
     2930    }
     2931    return tcc_add_dll(s1, filename, 0);
    30072932}
    30082933
     
    30662991                if (group) {
    30672992                    /* Add the filename *and* the libname to avoid future conversions */
    3068                     dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
     2993                    dynarray_add(&libs, &nblibs, tcc_strdup(filename));
    30692994                    if (libname[0] != '\0')
    3070                         dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
     2995                        dynarray_add(&libs, &nblibs, tcc_strdup(libname));
    30712996                }
    30722997            }
     
    30973022    char filename[1024];
    30983023    int t, ret;
    3099    
    3100     ch = file->buf_ptr[0];
     3024
    31013025    ch = handle_eob();
    31023026    for(;;) {
     
    31323056    return 0;
    31333057}
    3134 #endif /* ndef TCC_TARGET_PE */
     3058#endif /* !TCC_TARGET_PE */
  • EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c

    r321 r331  
    3131ST_DATA int rsym, anon_sym, ind, loc;
    3232
    33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
    34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
    35 #ifdef CONFIG_TCC_ASM
    36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
    37 #endif
    38 #ifdef CONFIG_TCC_BCHECK
    39 /* bound check related sections */
    40 ST_DATA Section *bounds_section; /* contains global data bound description */
    41 ST_DATA Section *lbounds_section; /* contains local data bound description */
    42 #endif
    43 /* symbol sections */
    44 ST_DATA Section *symtab_section, *strtab_section;
    45 /* debug sections */
    46 ST_DATA Section *stab_section, *stabstr_section;
    4733ST_DATA Sym *sym_free_first;
    4834ST_DATA void **sym_pools;
     
    5137ST_DATA Sym *global_stack;
    5238ST_DATA Sym *local_stack;
    53 ST_DATA Sym *scope_stack_bottom;
    5439ST_DATA Sym *define_stack;
    5540ST_DATA Sym *global_label_stack;
    5641ST_DATA Sym *local_label_stack;
    57 
    58 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
     42static int local_scope;
     43static int in_sizeof;
     44static int section_sym;
     45
     46ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
     47ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
     48ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
     49
     50ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
    5951
    6052ST_DATA int const_wanted; /* true if constant wanted */
    61 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
     53ST_DATA int nocode_wanted; /* no code generation wanted */
     54#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
     55#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
    6256ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
    6357ST_DATA CType func_vt; /* current function return type (used by return instruction) */
     58ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
    6459ST_DATA int func_vc;
    6560ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
    66 ST_DATA char *funcname;
    67 
    68 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
     61ST_DATA const char *funcname;
     62ST_DATA int g_debug;
     63
     64ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
     65
     66ST_DATA struct switch_t {
     67    struct case_t {
     68        int64_t v1, v2;
     69        int sym;
     70    } **p; int n; /* list of case ranges */
     71    int def_sym; /* default symbol */
     72} *cur_switch; /* current switch */
    6973
    7074/* ------------------------------------------------------------------------- */
     75
    7176static void gen_cast(CType *type);
     77static void gen_cast_s(int t);
    7278static inline CType *pointed_type(CType *type);
    7379static int is_compatible_types(CType *type1, CType *type2);
    7480static int parse_btype(CType *type, AttributeDef *ad);
    75 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
     81static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
    7682static void parse_expr_type(CType *type);
     83static void init_putv(CType *type, Section *sec, unsigned long c);
    7784static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
    78 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
    79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
    80 static int decl0(int l, int is_for_loop_init);
     85static void block(int *bsym, int *csym, int is_expr);
     86static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
     87static void decl(int l);
     88static int decl0(int l, int is_for_loop_init, Sym *);
    8189static void expr_eq(void);
    82 static void unary_type(CType *type);
    8390static void vla_runtime_type_size(CType *type, int *a);
    84 static int is_compatible_parameter_types(CType *type1, CType *type2);
    85 static void expr_type(CType *type);
     91static void vla_sp_restore(void);
     92static void vla_sp_restore_root(void);
     93static int is_compatible_unqualified_types(CType *type1, CType *type2);
     94static inline int64_t expr_const64(void);
     95static void vpush64(int ty, unsigned long long v);
     96static void vpush(CType *type);
     97static int gvtst(int inv, int t);
     98static void gen_inline_functions(TCCState *s);
     99static void skip_or_save_block(TokenString **str);
     100static void gv_dup(void);
    86101
    87102ST_INLN int is_float(int t)
     
    89104    int bt;
    90105    bt = t & VT_BTYPE;
    91     return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
     106    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
    92107}
    93108
     
    97112ST_FUNC int ieee_finite(double d)
    98113{
    99     int *p = (int *)&d;
     114    int p[4];
     115    memcpy(p, &d, sizeof(double));
    100116    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
    101117}
     118
     119/* compiling intel long double natively */
     120#if (defined __i386__ || defined __x86_64__) \
     121    && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
     122# define TCC_IS_NATIVE_387
     123#endif
    102124
    103125ST_FUNC void test_lvalue(void)
     
    106128        expect("lvalue");
    107129}
     130
     131ST_FUNC void check_vstack(void)
     132{
     133    if (pvtop != vtop)
     134        tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
     135}
     136
     137/* ------------------------------------------------------------------------- */
     138/* vstack debugging aid */
     139
     140#if 0
     141void pv (const char *lbl, int a, int b)
     142{
     143    int i;
     144    for (i = a; i < a + b; ++i) {
     145        SValue *p = &vtop[-i];
     146        printf("%s vtop[-%d] : type.t:%04x  r:%04x  r2:%04x  c.i:%d\n",
     147            lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
     148    }
     149}
     150#endif
     151
     152/* ------------------------------------------------------------------------- */
     153/* start of translation unit info */
     154ST_FUNC void tcc_debug_start(TCCState *s1)
     155{
     156    if (s1->do_debug) {
     157        char buf[512];
     158
     159        /* file info: full path + filename */
     160        section_sym = put_elf_sym(symtab_section, 0, 0,
     161                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
     162                                  text_section->sh_num, NULL);
     163        getcwd(buf, sizeof(buf));
     164#ifdef _WIN32
     165        normalize_slashes(buf);
     166#endif
     167        pstrcat(buf, sizeof(buf), "/");
     168        put_stabs_r(buf, N_SO, 0, 0,
     169                    text_section->data_offset, text_section, section_sym);
     170        put_stabs_r(file->filename, N_SO, 0, 0,
     171                    text_section->data_offset, text_section, section_sym);
     172        last_ind = 0;
     173        last_line_num = 0;
     174    }
     175
     176    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
     177       symbols can be safely used */
     178    put_elf_sym(symtab_section, 0, 0,
     179                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
     180                SHN_ABS, file->filename);
     181}
     182
     183/* put end of translation unit info */
     184ST_FUNC void tcc_debug_end(TCCState *s1)
     185{
     186    if (!s1->do_debug)
     187        return;
     188    put_stabs_r(NULL, N_SO, 0, 0,
     189        text_section->data_offset, text_section, section_sym);
     190
     191}
     192
     193/* generate line number info */
     194ST_FUNC void tcc_debug_line(TCCState *s1)
     195{
     196    if (!s1->do_debug)
     197        return;
     198    if ((last_line_num != file->line_num || last_ind != ind)) {
     199        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
     200        last_ind = ind;
     201        last_line_num = file->line_num;
     202    }
     203}
     204
     205/* put function symbol */
     206ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
     207{
     208    char buf[512];
     209
     210    if (!s1->do_debug)
     211        return;
     212
     213    /* stabs info */
     214    /* XXX: we put here a dummy type */
     215    snprintf(buf, sizeof(buf), "%s:%c1",
     216             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
     217    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
     218                cur_text_section, sym->c);
     219    /* //gr gdb wants a line at the function */
     220    put_stabn(N_SLINE, 0, file->line_num, 0);
     221
     222    last_ind = 0;
     223    last_line_num = 0;
     224}
     225
     226/* put function size */
     227ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
     228{
     229    if (!s1->do_debug)
     230        return;
     231    put_stabn(N_FUN, 0, 0, size);
     232}
     233
     234/* ------------------------------------------------------------------------- */
     235ST_FUNC int tccgen_compile(TCCState *s1)
     236{
     237    cur_text_section = NULL;
     238    funcname = "";
     239    anon_sym = SYM_FIRST_ANOM;
     240    section_sym = 0;
     241    const_wanted = 0;
     242    nocode_wanted = 0x80000000;
     243
     244    /* define some often used types */
     245    int_type.t = VT_INT;
     246    char_pointer_type.t = VT_BYTE;
     247    mk_pointer(&char_pointer_type);
     248#if PTR_SIZE == 4
     249    size_type.t = VT_INT | VT_UNSIGNED;
     250    ptrdiff_type.t = VT_INT;
     251#elif LONG_SIZE == 4
     252    size_type.t = VT_LLONG | VT_UNSIGNED;
     253    ptrdiff_type.t = VT_LLONG;
     254#else
     255    size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
     256    ptrdiff_type.t = VT_LONG | VT_LLONG;
     257#endif
     258    func_old_type.t = VT_FUNC;
     259    func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
     260    func_old_type.ref->f.func_call = FUNC_CDECL;
     261    func_old_type.ref->f.func_type = FUNC_OLD;
     262
     263    tcc_debug_start(s1);
     264
     265#ifdef TCC_TARGET_ARM
     266    arm_init(s1);
     267#endif
     268
     269#ifdef INC_DEBUG
     270    printf("%s: **** new file\n", file->filename);
     271#endif
     272
     273    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
     274    next();
     275    decl(VT_CONST);
     276    gen_inline_functions(s1);
     277    check_vstack();
     278    /* end of translation unit info */
     279    tcc_debug_end(s1);
     280    return 0;
     281}
     282
     283/* ------------------------------------------------------------------------- */
     284ST_FUNC ElfSym *elfsym(Sym *s)
     285{
     286  if (!s || !s->c)
     287    return NULL;
     288  return &((ElfSym *)symtab_section->data)[s->c];
     289}
     290
     291/* apply storage attributes to Elf symbol */
     292ST_FUNC void update_storage(Sym *sym)
     293{
     294    ElfSym *esym;
     295    int sym_bind, old_sym_bind;
     296
     297    esym = elfsym(sym);
     298    if (!esym)
     299        return;
     300
     301    if (sym->a.visibility)
     302        esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
     303            | sym->a.visibility;
     304
     305    if (sym->type.t & VT_STATIC)
     306        sym_bind = STB_LOCAL;
     307    else if (sym->a.weak)
     308        sym_bind = STB_WEAK;
     309    else
     310        sym_bind = STB_GLOBAL;
     311    old_sym_bind = ELFW(ST_BIND)(esym->st_info);
     312    if (sym_bind != old_sym_bind) {
     313        esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
     314    }
     315
     316#ifdef TCC_TARGET_PE
     317    if (sym->a.dllimport)
     318        esym->st_other |= ST_PE_IMPORT;
     319    if (sym->a.dllexport)
     320        esym->st_other |= ST_PE_EXPORT;
     321#endif
     322
     323#if 0
     324    printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
     325        get_tok_str(sym->v, NULL),
     326        sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
     327        sym->a.visibility,
     328        sym->a.dllexport,
     329        sym->a.dllimport
     330        );
     331#endif
     332}
     333
     334/* ------------------------------------------------------------------------- */
     335/* update sym->c so that it points to an external symbol in section
     336   'section' with value 'value' */
     337
     338ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
     339                            addr_t value, unsigned long size,
     340                            int can_add_underscore)
     341{
     342    int sym_type, sym_bind, info, other, t;
     343    ElfSym *esym;
     344    const char *name;
     345    char buf1[256];
     346#ifdef CONFIG_TCC_BCHECK
     347    char buf[32];
     348#endif
     349
     350    if (!sym->c) {
     351        name = get_tok_str(sym->v, NULL);
     352#ifdef CONFIG_TCC_BCHECK
     353        if (tcc_state->do_bounds_check) {
     354            /* XXX: avoid doing that for statics ? */
     355            /* if bound checking is activated, we change some function
     356               names by adding the "__bound" prefix */
     357            switch(sym->v) {
     358#ifdef TCC_TARGET_PE
     359            /* XXX: we rely only on malloc hooks */
     360            case TOK_malloc:
     361            case TOK_free:
     362            case TOK_realloc:
     363            case TOK_memalign:
     364            case TOK_calloc:
     365#endif
     366            case TOK_memcpy:
     367            case TOK_memmove:
     368            case TOK_memset:
     369            case TOK_strlen:
     370            case TOK_strcpy:
     371            case TOK_alloca:
     372                strcpy(buf, "__bound_");
     373                strcat(buf, name);
     374                name = buf;
     375                break;
     376            }
     377        }
     378#endif
     379        t = sym->type.t;
     380        if ((t & VT_BTYPE) == VT_FUNC) {
     381            sym_type = STT_FUNC;
     382        } else if ((t & VT_BTYPE) == VT_VOID) {
     383            sym_type = STT_NOTYPE;
     384        } else {
     385            sym_type = STT_OBJECT;
     386        }
     387        if (t & VT_STATIC)
     388            sym_bind = STB_LOCAL;
     389        else
     390            sym_bind = STB_GLOBAL;
     391        other = 0;
     392#ifdef TCC_TARGET_PE
     393        if (sym_type == STT_FUNC && sym->type.ref) {
     394            Sym *ref = sym->type.ref;
     395            if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
     396                sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
     397                name = buf1;
     398                other |= ST_PE_STDCALL;
     399                can_add_underscore = 0;
     400            }
     401        }
     402#endif
     403        if (tcc_state->leading_underscore && can_add_underscore) {
     404            buf1[0] = '_';
     405            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
     406            name = buf1;
     407        }
     408        if (sym->asm_label)
     409            name = get_tok_str(sym->asm_label, NULL);
     410        info = ELFW(ST_INFO)(sym_bind, sym_type);
     411        sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
     412    } else {
     413        esym = elfsym(sym);
     414        esym->st_value = value;
     415        esym->st_size = size;
     416        esym->st_shndx = sh_num;
     417    }
     418    update_storage(sym);
     419}
     420
     421ST_FUNC void put_extern_sym(Sym *sym, Section *section,
     422                           addr_t value, unsigned long size)
     423{
     424    int sh_num = section ? section->sh_num : SHN_UNDEF;
     425    put_extern_sym2(sym, sh_num, value, size, 1);
     426}
     427
     428/* add a new relocation entry to symbol 'sym' in section 's' */
     429ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
     430                     addr_t addend)
     431{
     432    int c = 0;
     433
     434    if (nocode_wanted && s == cur_text_section)
     435        return;
     436
     437    if (sym) {
     438        if (0 == sym->c)
     439            put_extern_sym(sym, NULL, 0, 0);
     440        c = sym->c;
     441    }
     442
     443    /* now we can add ELF relocation info */
     444    put_elf_reloca(symtab_section, s, offset, type, c, addend);
     445}
     446
     447#if PTR_SIZE == 4
     448ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
     449{
     450    greloca(s, sym, offset, type, 0);
     451}
     452#endif
    108453
    109454/* ------------------------------------------------------------------------- */
     
    131476{
    132477    Sym *sym;
     478#ifndef SYM_DEBUG
    133479    sym = sym_free_first;
    134480    if (!sym)
     
    136482    sym_free_first = sym->next;
    137483    return sym;
     484#else
     485    sym = tcc_malloc(sizeof(Sym));
     486    return sym;
     487#endif
    138488}
    139489
    140490ST_INLN void sym_free(Sym *sym)
    141491{
     492#ifndef SYM_DEBUG
    142493    sym->next = sym_free_first;
    143     tcc_free(sym->asm_label);
    144494    sym_free_first = sym;
     495#else
     496    tcc_free(sym);
     497#endif
    145498}
    146499
    147500/* push, without hashing */
    148 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
     501ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
    149502{
    150503    Sym *s;
    151     if (ps == &local_stack) {
    152         for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
    153             if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
    154                 tcc_error("incompatible types for redefinition of '%s'",
    155                           get_tok_str(v, NULL));
    156     }
    157     s = *ps;
     504
    158505    s = sym_malloc();
    159     s->asm_label = NULL;
     506    memset(s, 0, sizeof *s);
    160507    s->v = v;
    161508    s->type.t = t;
    162     s->type.ref = NULL;
    163 #ifdef _WIN64
    164     s->d = NULL;
    165 #endif
    166509    s->c = c;
    167     s->next = NULL;
    168510    /* add in stack */
    169511    s->prev = *ps;
     
    179521        if (s->v == v)
    180522            return s;
     523        else if (s->v == -1)
     524            return NULL;
    181525        s = s->prev;
    182526    }
     
    226570        s->prev_tok = *ps;
    227571        *ps = s;
     572        s->sym_scope = local_scope;
     573        if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope)
     574            tcc_error("redeclaration of '%s'",
     575                get_tok_str(v & ~SYM_STRUCT, NULL));
    228576    }
    229577    return s;
     
    240588        /* modify the top most local identifier, so that
    241589           sym_identifier will point to 's' when popped */
    242         while (*ps != NULL)
     590        while (*ps != NULL && (*ps)->sym_scope)
    243591            ps = &(*ps)->prev_tok;
    244         s->prev_tok = NULL;
     592        s->prev_tok = *ps;
    245593        *ps = s;
    246594    }
     
    248596}
    249597
    250 /* pop symbols until top reaches 'b' */
    251 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
     598/* pop symbols until top reaches 'b'.  If KEEP is non-zero don't really
     599   pop them yet from the list, but do remove them from the token array.  */
     600ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
    252601{
    253602    Sym *s, *ss, **ps;
     
    269618            *ps = s->prev_tok;
    270619        }
    271         sym_free(s);
     620        if (!keep)
     621            sym_free(s);
    272622        s = ss;
    273623    }
    274     *ptop = b;
    275 }
    276 
    277 static void weaken_symbol(Sym *sym)
    278 {
    279     sym->type.t |= VT_WEAK;
    280     if (sym->c > 0) {
    281         int esym_type;
    282         ElfW(Sym) *esym;
    283        
    284         esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    285         esym_type = ELFW(ST_TYPE)(esym->st_info);
    286         esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
    287     }
     624    if (!keep)
     625        *ptop = b;
    288626}
    289627
    290628/* ------------------------------------------------------------------------- */
    291629
    292 ST_FUNC void swap(int *p, int *q)
    293 {
    294     int t;
    295     t = *p;
    296     *p = *q;
    297     *q = t;
    298 }
    299 
    300630static void vsetc(CType *type, int r, CValue *vc)
    301631{
     
    303633
    304634    if (vtop >= vstack + (VSTACK_SIZE - 1))
    305         tcc_error("memory full");
     635        tcc_error("memory full (vstack)");
    306636    /* cannot let cpu flags if other instruction are generated. Also
    307637       avoid leaving VT_JMP anywhere except on the top of the stack
    308        because it would complicate the code generator. */
    309     if (vtop >= vstack) {
     638       because it would complicate the code generator.
     639
     640       Don't do this when nocode_wanted.  vtop might come from
     641       !nocode_wanted regions (see 88_codeopt.c) and transforming
     642       it to a register without actually generating code is wrong
     643       as their value might still be used for real.  All values
     644       we push under nocode_wanted will eventually be popped
     645       again, so that the VT_CMP/VT_JMP value will be in vtop
     646       when code is unsuppressed again.
     647
     648       Same logic below in vswap(); */
     649    if (vtop >= vstack && !nocode_wanted) {
    310650        v = vtop->r & VT_VALMASK;
    311651        if (v == VT_CMP || (v & ~1) == VT_JMP)
    312652            gv(RC_INT);
    313653    }
     654
    314655    vtop++;
    315656    vtop->type = *type;
     
    317658    vtop->r2 = VT_CONST;
    318659    vtop->c = *vc;
     660    vtop->sym = NULL;
     661}
     662
     663ST_FUNC void vswap(void)
     664{
     665    SValue tmp;
     666    /* cannot vswap cpu flags. See comment at vsetc() above */
     667    if (vtop >= vstack && !nocode_wanted) {
     668        int v = vtop->r & VT_VALMASK;
     669        if (v == VT_CMP || (v & ~1) == VT_JMP)
     670            gv(RC_INT);
     671    }
     672    tmp = vtop[0];
     673    vtop[0] = vtop[-1];
     674    vtop[-1] = tmp;
     675}
     676
     677/* pop stack value */
     678ST_FUNC void vpop(void)
     679{
     680    int v;
     681    v = vtop->r & VT_VALMASK;
     682#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
     683    /* for x86, we need to pop the FP stack */
     684    if (v == TREG_ST0) {
     685        o(0xd8dd); /* fstp %st(0) */
     686    } else
     687#endif
     688    if (v == VT_JMP || v == VT_JMPI) {
     689        /* need to put correct jump if && or || without test */
     690        gsym(vtop->c.i);
     691    }
     692    vtop--;
    319693}
    320694
    321695/* push constant of type "type" with useless value */
    322 void vpush(CType *type)
    323 {
    324     CValue cval;
    325     vsetc(type, VT_CONST, &cval);
     696ST_FUNC void vpush(CType *type)
     697{
     698    vset(type, VT_CONST, 0);
    326699}
    327700
     
    335708
    336709/* push a pointer sized constant */
    337 static void vpushs(long long v)
     710static void vpushs(addr_t v)
    338711{
    339712  CValue cval;
    340   if (PTR_SIZE == 4)
    341     cval.i = (int)v;
    342   else
    343     cval.ull = v;
     713  cval.i = v;
    344714  vsetc(&size_type, VT_CONST, &cval);
    345715}
    346716
    347717/* push arbitrary 64bit constant */
    348 void vpush64(int ty, unsigned long long v)
     718ST_FUNC void vpush64(int ty, unsigned long long v)
    349719{
    350720    CValue cval;
     
    352722    ctype.t = ty;
    353723    ctype.ref = NULL;
    354     cval.ull = v;
     724    cval.i = v;
    355725    vsetc(&ctype, VT_CONST, &cval);
    356726}
     
    360730{
    361731    vpush64(VT_LLONG, v);
     732}
     733
     734ST_FUNC void vset(CType *type, int r, int v)
     735{
     736    CValue cval;
     737
     738    cval.i = v;
     739    vsetc(type, r, &cval);
     740}
     741
     742static void vseti(int r, int v)
     743{
     744    CType type;
     745    type.t = VT_INT;
     746    type.ref = NULL;
     747    vset(&type, r, v);
     748}
     749
     750ST_FUNC void vpushv(SValue *v)
     751{
     752    if (vtop >= vstack + (VSTACK_SIZE - 1))
     753        tcc_error("memory full (vstack)");
     754    vtop++;
     755    *vtop = *v;
     756}
     757
     758static void vdup(void)
     759{
     760    vpushv(vtop);
     761}
     762
     763/* rotate n first stack elements to the bottom
     764   I1 ... In -> I2 ... In I1 [top is right]
     765*/
     766ST_FUNC void vrotb(int n)
     767{
     768    int i;
     769    SValue tmp;
     770
     771    tmp = vtop[-n + 1];
     772    for(i=-n+1;i!=0;i++)
     773        vtop[i] = vtop[i+1];
     774    vtop[0] = tmp;
     775}
     776
     777/* rotate the n elements before entry e towards the top
     778   I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
     779 */
     780ST_FUNC void vrote(SValue *e, int n)
     781{
     782    int i;
     783    SValue tmp;
     784
     785    tmp = *e;
     786    for(i = 0;i < n - 1; i++)
     787        e[-i] = e[-i - 1];
     788    e[-n + 1] = tmp;
     789}
     790
     791/* rotate n first stack elements to the top
     792   I1 ... In -> In I1 ... I(n-1)  [top is right]
     793 */
     794ST_FUNC void vrott(int n)
     795{
     796    vrote(vtop, n);
     797}
     798
     799/* push a symbol value of TYPE */
     800static inline void vpushsym(CType *type, Sym *sym)
     801{
     802    CValue cval;
     803    cval.i = 0;
     804    vsetc(type, VT_CONST | VT_SYM, &cval);
     805    vtop->sym = sym;
    362806}
    363807
     
    379823static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
    380824{
    381     CValue cval;
    382 
    383     cval.ul = 0;
    384     vsetc(type, VT_CONST | VT_SYM, &cval);
    385     vtop->sym = get_sym_ref(type, sec, offset, size);
     825    vpushsym(type, get_sym_ref(type, sec, offset, size)); 
    386826}
    387827
     
    397837        s->type.ref = type->ref;
    398838        s->r = r | VT_CONST | VT_SYM;
     839    } else if (IS_ASM_SYM(s)) {
     840        s->type.t = type->t | (s->type.t & VT_EXTERN);
     841        s->type.ref = type->ref;
     842        update_storage(s);
    399843    }
    400844    return s;
    401845}
    402846
    403 /* define a new external reference to a symbol 'v' with alternate asm
    404    name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
    405    is no alternate name (most cases) */
    406 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
     847/* Merge some type attributes.  */
     848static void patch_type(Sym *sym, CType *type)
     849{
     850    if (!(type->t & VT_EXTERN)) {
     851        if (!(sym->type.t & VT_EXTERN))
     852            tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
     853        sym->type.t &= ~VT_EXTERN;
     854    }
     855
     856    if (IS_ASM_SYM(sym)) {
     857        /* stay static if both are static */
     858        sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
     859        sym->type.ref = type->ref;
     860    }
     861
     862    if (!is_compatible_types(&sym->type, type)) {
     863        tcc_error("incompatible types for redefinition of '%s'",
     864                  get_tok_str(sym->v, NULL));
     865
     866    } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
     867        int static_proto = sym->type.t & VT_STATIC;
     868        /* warn if static follows non-static function declaration */
     869        if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
     870            tcc_warning("static storage ignored for redefinition of '%s'",
     871                get_tok_str(sym->v, NULL));
     872
     873        if (0 == (type->t & VT_EXTERN)) {
     874            /* put complete type, use static from prototype */
     875            sym->type.t = (type->t & ~VT_STATIC) | static_proto;
     876            if (type->t & VT_INLINE)
     877                sym->type.t = type->t;
     878            sym->type.ref = type->ref;
     879        }
     880
     881    } else {
     882        if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
     883            /* set array size if it was omitted in extern declaration */
     884            if (sym->type.ref->c < 0)
     885                sym->type.ref->c = type->ref->c;
     886            else if (sym->type.ref->c != type->ref->c)
     887                tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
     888        }
     889        if ((type->t ^ sym->type.t) & VT_STATIC)
     890            tcc_warning("storage mismatch for redefinition of '%s'",
     891                get_tok_str(sym->v, NULL));
     892    }
     893}
     894
     895
     896/* Merge some storage attributes.  */
     897static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
     898{
     899    if (type)
     900        patch_type(sym, type);
     901
     902#ifdef TCC_TARGET_PE
     903    if (sym->a.dllimport != ad->a.dllimport)
     904        tcc_error("incompatible dll linkage for redefinition of '%s'",
     905            get_tok_str(sym->v, NULL));
     906    sym->a.dllexport |= ad->a.dllexport;
     907#endif
     908    sym->a.weak |= ad->a.weak;
     909    if (ad->a.visibility) {
     910        int vis = sym->a.visibility;
     911        int vis2 = ad->a.visibility;
     912        if (vis == STV_DEFAULT)
     913            vis = vis2;
     914        else if (vis2 != STV_DEFAULT)
     915            vis = (vis < vis2) ? vis : vis2;
     916        sym->a.visibility = vis;
     917    }
     918    if (ad->a.aligned)
     919        sym->a.aligned = ad->a.aligned;
     920    if (ad->asm_label)
     921        sym->asm_label = ad->asm_label;
     922    update_storage(sym);
     923}
     924
     925/* define a new external reference to a symbol 'v' */
     926static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
    407927{
    408928    Sym *s;
    409 
    410929    s = sym_find(v);
    411930    if (!s) {
    412931        /* push forward reference */
    413932        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
    414         s->asm_label = asm_label;
    415933        s->type.t |= VT_EXTERN;
    416     } else if (s->type.ref == func_old_type.ref) {
    417         s->type.ref = type->ref;
    418         s->r = r | VT_CONST | VT_SYM;
    419         s->type.t |= VT_EXTERN;
    420     } else if (!is_compatible_types(&s->type, type)) {
    421         tcc_error("incompatible types for redefinition of '%s'",
    422               get_tok_str(v, NULL));
     934        s->a = ad->a;
     935        s->sym_scope = 0;
     936    } else {
     937        if (s->type.ref == func_old_type.ref) {
     938            s->type.ref = type->ref;
     939            s->r = r | VT_CONST | VT_SYM;
     940            s->type.t |= VT_EXTERN;
     941        }
     942        patch_storage(s, ad, type);
    423943    }
    424944    return s;
     
    428948ST_FUNC void vpush_global_sym(CType *type, int v)
    429949{
    430     Sym *sym;
    431     CValue cval;
    432 
    433     sym = external_global_sym(v, type, 0);
    434     cval.ul = 0;
    435     vsetc(type, VT_CONST | VT_SYM, &cval);
    436     vtop->sym = sym;
    437 }
    438 
    439 ST_FUNC void vset(CType *type, int r, int v)
    440 {
    441     CValue cval;
    442 
    443     cval.i = v;
    444     vsetc(type, r, &cval);
    445 }
    446 
    447 static void vseti(int r, int v)
    448 {
    449     CType type;
    450     type.t = VT_INT;
    451     type.ref = 0;
    452     vset(&type, r, v);
    453 }
    454 
    455 ST_FUNC void vswap(void)
    456 {
    457     SValue tmp;
    458     /* cannot let cpu flags if other instruction are generated. Also
    459        avoid leaving VT_JMP anywhere except on the top of the stack
    460        because it would complicate the code generator. */
    461     if (vtop >= vstack) {
    462         int v = vtop->r & VT_VALMASK;
    463         if (v == VT_CMP || (v & ~1) == VT_JMP)
    464             gv(RC_INT);
    465     }
    466     tmp = vtop[0];
    467     vtop[0] = vtop[-1];
    468     vtop[-1] = tmp;
    469 
    470 /* XXX: +2% overall speed possible with optimized memswap
    471  *
    472  *  memswap(&vtop[0], &vtop[1], sizeof *vtop);
    473  */
    474 }
    475 
    476 ST_FUNC void vpushv(SValue *v)
    477 {
    478     if (vtop >= vstack + (VSTACK_SIZE - 1))
    479         tcc_error("memory full");
    480     vtop++;
    481     *vtop = *v;
    482 }
    483 
    484 static void vdup(void)
    485 {
    486     vpushv(vtop);
     950    vpushsym(type, external_global_sym(v, type, 0));
     951}
     952
     953/* save registers up to (vtop - n) stack entry */
     954ST_FUNC void save_regs(int n)
     955{
     956    SValue *p, *p1;
     957    for(p = vstack, p1 = vtop - n; p <= p1; p++)
     958        save_reg(p->r);
    487959}
    488960
     
    490962ST_FUNC void save_reg(int r)
    491963{
     964    save_reg_upstack(r, 0);
     965}
     966
     967/* save r to the memory stack, and mark it as being free,
     968   if seen up to (vtop - n) stack entry */
     969ST_FUNC void save_reg_upstack(int r, int n)
     970{
    492971    int l, saved, size, align;
    493     SValue *p, sv;
     972    SValue *p, *p1, sv;
    494973    CType *type;
     974
     975    if ((r &= VT_VALMASK) >= VT_CONST)
     976        return;
     977    if (nocode_wanted)
     978        return;
    495979
    496980    /* modify all stack values */
    497981    saved = 0;
    498982    l = 0;
    499     for(p=vstack;p<=vtop;p++) {
     983    for(p = vstack, p1 = vtop - n; p <= p1; p++) {
    500984        if ((p->r & VT_VALMASK) == r ||
    501985            ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
     
    508992                if ((p->r & VT_LVAL) ||
    509993                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
    510 #ifdef TCC_TARGET_X86_64
     994#if PTR_SIZE == 8
    511995                    type = &char_pointer_type;
    512996#else
     
    5171001                sv.type.t = type->t;
    5181002                sv.r = VT_LOCAL | VT_LVAL;
    519                 sv.c.ul = loc;
     1003                sv.c.i = loc;
    5201004                store(r, &sv);
    5211005#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
     
    5251009                }
    5261010#endif
    527 #ifndef TCC_TARGET_X86_64
     1011#if PTR_SIZE == 4
    5281012                /* special long long case */
    5291013                if ((type->t & VT_BTYPE) == VT_LLONG) {
    530                     sv.c.ul += 4;
     1014                    sv.c.i += 4;
    5311015                    store(p->r2, &sv);
    5321016                }
     
    5391023                /* also clear the bounded flag because the
    5401024                   relocation address of the function was stored in
    541                    p->c.ul */
     1025                   p->c.i */
    5421026                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
    5431027            } else {
     
    5451029            }
    5461030            p->r2 = VT_CONST;
    547             p->c.ul = l;
     1031            p->c.i = l;
    5481032        }
    5491033    }
     
    5841068    for(r=0;r<NB_REGS;r++) {
    5851069        if (reg_classes[r] & rc) {
     1070            if (nocode_wanted)
     1071                return r;
    5861072            for(p=vstack;p<=vtop;p++) {
    5871073                if ((p->r & VT_VALMASK) == r ||
     
    6131099}
    6141100
    615 /* save registers up to (vtop - n) stack entry */
    616 ST_FUNC void save_regs(int n)
    617 {
    618     int r;
    619     SValue *p, *p1;
    620     p1 = vtop - n;
    621     for(p = vstack;p <= p1; p++) {
    622         r = p->r & VT_VALMASK;
    623         if (r < VT_CONST) {
    624             save_reg(r);
    625         }
    626     }
    627 }
    628 
    629 /* move register 's' to 'r', and flush previous value of r to memory
     1101/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
    6301102   if needed */
    631 static void move_reg(int r, int s)
     1103static void move_reg(int r, int s, int t)
    6321104{
    6331105    SValue sv;
     
    6351107    if (r != s) {
    6361108        save_reg(r);
    637         sv.type.t = VT_INT;
     1109        sv.type.t = t;
     1110        sv.type.ref = NULL;
    6381111        sv.r = s;
    639         sv.c.ul = 0;
     1112        sv.c.i = 0;
    6401113        load(r, &sv);
    6411114    }
     
    6431116
    6441117/* get address of vtop (vtop MUST BE an lvalue) */
    645 static void gaddrof(void)
    646 {
    647     if (vtop->r & VT_REF)
    648         gv(RC_INT);
     1118ST_FUNC void gaddrof(void)
     1119{
    6491120    vtop->r &= ~VT_LVAL;
    6501121    /* tricky: if saved lvalue, then we can go back to lvalue */
     
    6701141            /* must save type because we must set it to int to get pointer */
    6711142            type1 = vtop->type;
    672             vtop->type.t = VT_INT;
     1143            vtop->type.t = VT_PTR;
    6731144            gaddrof();
    6741145            vpushi(0);
     
    6831154#endif
    6841155
     1156static void incr_bf_adr(int o)
     1157{
     1158    vtop->type = char_pointer_type;
     1159    gaddrof();
     1160    vpushi(o);
     1161    gen_op('+');
     1162    vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
     1163        | (VT_BYTE|VT_UNSIGNED);
     1164    vtop->r = (vtop->r & ~VT_LVAL_TYPE)
     1165        | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
     1166}
     1167
     1168/* single-byte load mode for packed or otherwise unaligned bitfields */
     1169static void load_packed_bf(CType *type, int bit_pos, int bit_size)
     1170{
     1171    int n, o, bits;
     1172    save_reg_upstack(vtop->r, 1);
     1173    vpush64(type->t & VT_BTYPE, 0); // B X
     1174    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
     1175    do {
     1176        vswap(); // X B
     1177        incr_bf_adr(o);
     1178        vdup(); // X B B
     1179        n = 8 - bit_pos;
     1180        if (n > bit_size)
     1181            n = bit_size;
     1182        if (bit_pos)
     1183            vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
     1184        if (n < 8)
     1185            vpushi((1 << n) - 1), gen_op('&');
     1186        gen_cast(type);
     1187        if (bits)
     1188            vpushi(bits), gen_op(TOK_SHL);
     1189        vrotb(3); // B Y X
     1190        gen_op('|'); // B X
     1191        bits += n, bit_size -= n, o = 1;
     1192    } while (bit_size);
     1193    vswap(), vpop();
     1194    if (!(type->t & VT_UNSIGNED)) {
     1195        n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
     1196        vpushi(n), gen_op(TOK_SHL);
     1197        vpushi(n), gen_op(TOK_SAR);
     1198    }
     1199}
     1200
     1201/* single-byte store mode for packed or otherwise unaligned bitfields */
     1202static void store_packed_bf(int bit_pos, int bit_size)
     1203{
     1204    int bits, n, o, m, c;
     1205
     1206    c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1207    vswap(); // X B
     1208    save_reg_upstack(vtop->r, 1);
     1209    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
     1210    do {
     1211        incr_bf_adr(o); // X B
     1212        vswap(); //B X
     1213        c ? vdup() : gv_dup(); // B V X
     1214        vrott(3); // X B V
     1215        if (bits)
     1216            vpushi(bits), gen_op(TOK_SHR);
     1217        if (bit_pos)
     1218            vpushi(bit_pos), gen_op(TOK_SHL);
     1219        n = 8 - bit_pos;
     1220        if (n > bit_size)
     1221            n = bit_size;
     1222        if (n < 8) {
     1223            m = ((1 << n) - 1) << bit_pos;
     1224            vpushi(m), gen_op('&'); // X B V1
     1225            vpushv(vtop-1); // X B V1 B
     1226            vpushi(m & 0x80 ? ~m & 0x7f : ~m);
     1227            gen_op('&'); // X B V1 B1
     1228            gen_op('|'); // X B V2
     1229        }
     1230        vdup(), vtop[-1] = vtop[-2]; // X B B V2
     1231        vstore(), vpop(); // X B
     1232        bits += n, bit_size -= n, bit_pos = 0, o = 1;
     1233    } while (bit_size);
     1234    vpop(), vpop();
     1235}
     1236
     1237static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
     1238{
     1239    int t;
     1240    if (0 == sv->type.ref)
     1241        return 0;
     1242    t = sv->type.ref->auxtype;
     1243    if (t != -1 && t != VT_STRUCT) {
     1244        sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
     1245        sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
     1246    }
     1247    return t;
     1248}
     1249
    6851250/* store vtop a register belonging to class 'rc'. lvalues are
    6861251   converted to values. Cannot be used if cannot be converted to
     
    6881253ST_FUNC int gv(int rc)
    6891254{
    690     int r, bit_pos, bit_size, size, align, i;
    691 #ifndef TCC_TARGET_X86_64
    692     int rc2;
    693 #endif
     1255    int r, bit_pos, bit_size, size, align, rc2;
    6941256
    6951257    /* NOTE: get_reg can modify vstack[] */
    6961258    if (vtop->type.t & VT_BITFIELD) {
    6971259        CType type;
    698         int bits = 32;
    699         bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    700         bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
     1260
     1261        bit_pos = BIT_POS(vtop->type.t);
     1262        bit_size = BIT_SIZE(vtop->type.t);
    7011263        /* remove bit field info to avoid loops */
    702         vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
    703         /* cast to int to propagate signedness in following ops */
    704         if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
    705             type.t = VT_LLONG;
    706             bits = 64;
    707         } else
    708             type.t = VT_INT;
    709         if((vtop->type.t & VT_UNSIGNED) ||
    710            (vtop->type.t & VT_BTYPE) == VT_BOOL)
     1264        vtop->type.t &= ~VT_STRUCT_MASK;
     1265
     1266        type.ref = NULL;
     1267        type.t = vtop->type.t & VT_UNSIGNED;
     1268        if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
    7111269            type.t |= VT_UNSIGNED;
    712         gen_cast(&type);
    713         /* generate shifts */
    714         vpushi(bits - (bit_pos + bit_size));
    715         gen_op(TOK_SHL);
    716         vpushi(bits - bit_size);
    717         /* NOTE: transformed to SHR if unsigned */
    718         gen_op(TOK_SAR);
     1270
     1271        r = adjust_bf(vtop, bit_pos, bit_size);
     1272
     1273        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
     1274            type.t |= VT_LLONG;
     1275        else
     1276            type.t |= VT_INT;
     1277
     1278        if (r == VT_STRUCT) {
     1279            load_packed_bf(&type, bit_pos, bit_size);
     1280        } else {
     1281            int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
     1282            /* cast to int to propagate signedness in following ops */
     1283            gen_cast(&type);
     1284            /* generate shifts */
     1285            vpushi(bits - (bit_pos + bit_size));
     1286            gen_op(TOK_SHL);
     1287            vpushi(bits - bit_size);
     1288            /* NOTE: transformed to SHR if unsigned */
     1289            gen_op(TOK_SAR);
     1290        }
    7191291        r = gv(rc);
    7201292    } else {
    7211293        if (is_float(vtop->type.t) &&
    7221294            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    723             Sym *sym;
    724             int *ptr;
    7251295            unsigned long offset;
    726 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
    727             CValue check;
    728 #endif
    729            
    730             /* XXX: unify with initializers handling ? */
    7311296            /* CPUs usually cannot use float constants, so we store them
    7321297               generically in data segment */
    7331298            size = type_size(&vtop->type, &align);
    734             offset = (data_section->data_offset + align - 1) & -align;
    735             data_section->data_offset = offset;
    736             /* XXX: not portable yet */
    737 #if defined(__i386__) || defined(__x86_64__)
    738             /* Zero pad x87 tenbyte long doubles */
    739             if (size == LDOUBLE_SIZE) {
    740                 vtop->c.tab[2] &= 0xffff;
    741 #if LDOUBLE_SIZE == 16
    742                 vtop->c.tab[3] = 0;
    743 #endif
    744             }
    745 #endif
    746             ptr = section_ptr_add(data_section, size);
    747             size = size >> 2;
    748 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
    749             check.d = 1;
    750             if(check.tab[0])
    751                 for(i=0;i<size;i++)
    752                     ptr[i] = vtop->c.tab[size-1-i];
    753             else
    754 #endif
    755             for(i=0;i<size;i++)
    756                 ptr[i] = vtop->c.tab[i];
    757             sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
    758             vtop->r |= VT_LVAL | VT_SYM;
    759             vtop->sym = sym;
    760             vtop->c.ul = 0;
     1299            if (NODATA_WANTED)
     1300                size = 0, align = 1;
     1301            offset = section_add(data_section, size, align);
     1302            vpush_ref(&vtop->type, data_section, offset, size);
     1303            vswap();
     1304            init_putv(&vtop->type, data_section, offset);
     1305            vtop->r |= VT_LVAL;
    7611306        }
    7621307#ifdef CONFIG_TCC_BCHECK
     
    7661311
    7671312        r = vtop->r & VT_VALMASK;
    768 #ifndef TCC_TARGET_X86_64
    769         rc2 = RC_INT;
     1313        rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
     1314#ifndef TCC_TARGET_ARM64
    7701315        if (rc == RC_IRET)
    7711316            rc2 = RC_LRET;
     1317#ifdef TCC_TARGET_X86_64
     1318        else if (rc == RC_FRET)
     1319            rc2 = RC_QRET;
     1320#endif
    7721321#endif
    7731322        /* need to reload if:
     
    7781327         || (vtop->r & VT_LVAL)
    7791328         || !(reg_classes[r] & rc)
    780 #ifndef TCC_TARGET_X86_64
     1329#if PTR_SIZE == 8
     1330         || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
     1331         || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
     1332#else
    7811333         || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
    7821334#endif
     
    7841336        {
    7851337            r = get_reg(rc);
    786 #ifndef TCC_TARGET_X86_64
     1338#if PTR_SIZE == 8
     1339            if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
     1340                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
     1341#else
    7871342            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
    788                 int r2;
     1343                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
    7891344                unsigned long long ll;
     1345#endif
     1346                int r2, original_type;
     1347                original_type = vtop->type.t;
    7901348                /* two register type load : expand to two words
    7911349                   temporarily */
     1350#if PTR_SIZE == 4
    7921351                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    7931352                    /* load constant */
    794                     ll = vtop->c.ull;
    795                     vtop->c.ui = ll; /* first word */
     1353                    ll = vtop->c.i;
     1354                    vtop->c.i = ll; /* first word */
    7961355                    load(r, vtop);
    7971356                    vtop->r = r; /* save register value */
    7981357                    vpushi(ll >> 32); /* second word */
    799                 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
    800                            (vtop->r & VT_LVAL)) {
     1358                } else
     1359#endif
     1360                if (vtop->r & VT_LVAL) {
    8011361                    /* We do not want to modifier the long long
    8021362                       pointer here, so the safest (and less
    8031363                       efficient) is to save all the other registers
    8041364                       in the stack. XXX: totally inefficient. */
     1365               #if 0
    8051366                    save_regs(1);
     1367               #else
     1368                    /* lvalue_save: save only if used further down the stack */
     1369                    save_reg_upstack(vtop->r, 1);
     1370               #endif
    8061371                    /* load from memory */
     1372                    vtop->type.t = load_type;
    8071373                    load(r, vtop);
    8081374                    vdup();
    8091375                    vtop[-1].r = r; /* save register value */
    8101376                    /* increment pointer to get second word */
    811                     vtop->type.t = VT_INT;
     1377                    vtop->type.t = addr_type;
    8121378                    gaddrof();
    813                     vpushi(4);
     1379                    vpushi(load_size);
    8141380                    gen_op('+');
    8151381                    vtop->r |= VT_LVAL;
     1382                    vtop->type.t = load_type;
    8161383                } else {
    8171384                    /* move registers */
     
    8281395                /* write second register */
    8291396                vtop->r2 = r2;
    830             } else
    831 #endif
    832             if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
     1397                vtop->type.t = original_type;
     1398            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
    8331399                int t1, t;
    8341400                /* lvalue of scalar type : need to use lvalue type
     
    8941460}
    8951461
     1462#ifndef TCC_TARGET_ARM64
    8961463/* wrapper around RC_FRET to return a register by type */
    8971464static int rc_fret(int t)
     
    9041471    return RC_FRET;
    9051472}
     1473#endif
    9061474
    9071475/* wrapper around REG_FRET to return a register by type */
     
    9161484}
    9171485
    918 /* expand long long on stack in two int registers */
     1486#if PTR_SIZE == 4
     1487/* expand 64bit on stack in two ints */
    9191488static void lexpand(void)
    9201489{
    921     int u;
    922 
    923     u = vtop->type.t & VT_UNSIGNED;
    924     gv(RC_INT);
    925     vdup();
    926     vtop[0].r = vtop[-1].r2;
    927     vtop[0].r2 = VT_CONST;
    928     vtop[-1].r2 = VT_CONST;
    929     vtop[0].type.t = VT_INT | u;
    930     vtop[-1].type.t = VT_INT | u;
    931 }
     1490    int u, v;
     1491    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
     1492    v = vtop->r & (VT_VALMASK | VT_LVAL);
     1493    if (v == VT_CONST) {
     1494        vdup();
     1495        vtop[0].c.i >>= 32;
     1496    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
     1497        vdup();
     1498        vtop[0].c.i += 4;
     1499    } else {
     1500        gv(RC_INT);
     1501        vdup();
     1502        vtop[0].r = vtop[-1].r2;
     1503        vtop[0].r2 = vtop[-1].r2 = VT_CONST;
     1504    }
     1505    vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
     1506}
     1507#endif
    9321508
    9331509#ifdef TCC_TARGET_ARM
     
    9371513    int u,v;
    9381514
    939     u = vtop->type.t & VT_UNSIGNED;
     1515    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
    9401516    vdup();
    9411517    vtop->r2 = VT_CONST;
     
    9431519    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
    9441520    if (v == VT_CONST) {
    945       vtop[-1].c.ui = vtop->c.ull;
    946       vtop->c.ui = vtop->c.ull >> 32;
     1521      vtop[-1].c.i = vtop->c.i;
     1522      vtop->c.i = vtop->c.i >> 32;
    9471523      vtop->r = VT_CONST;
    9481524    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
    949       vtop->c.ui += 4;
     1525      vtop->c.i += 4;
    9501526      vtop->r = vtop[-1].r;
    9511527    } else if (v > VT_CONST) {
     
    9591535#endif
    9601536
     1537#if PTR_SIZE == 4
    9611538/* build a long long from two ints */
    9621539static void lbuild(int t)
     
    9671544    vpop();
    9681545}
    969 
    970 /* rotate n first stack elements to the bottom
    971    I1 ... In -> I2 ... In I1 [top is right]
    972 */
    973 ST_FUNC void vrotb(int n)
    974 {
    975     int i;
    976     SValue tmp;
    977 
    978     tmp = vtop[-n + 1];
    979     for(i=-n+1;i!=0;i++)
    980         vtop[i] = vtop[i+1];
    981     vtop[0] = tmp;
    982 }
    983 
    984 /* rotate the n elements before entry e towards the top
    985    I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
    986  */
    987 ST_FUNC void vrote(SValue *e, int n)
    988 {
    989     int i;
    990     SValue tmp;
    991 
    992     tmp = *e;
    993     for(i = 0;i < n - 1; i++)
    994         e[-i] = e[-i - 1];
    995     e[-n + 1] = tmp;
    996 }
    997 
    998 /* rotate n first stack elements to the top
    999    I1 ... In -> In I1 ... I(n-1)  [top is right]
    1000  */
    1001 ST_FUNC void vrott(int n)
    1002 {
    1003     vrote(vtop, n);
    1004 }
    1005 
    1006 /* pop stack value */
    1007 ST_FUNC void vpop(void)
    1008 {
    1009     int v;
    1010     v = vtop->r & VT_VALMASK;
    1011 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
    1012     /* for x86, we need to pop the FP stack */
    1013     if (v == TREG_ST0 && !nocode_wanted) {
    1014         o(0xd8dd); /* fstp %st(0) */
    1015     } else
    1016 #endif
    1017     if (v == VT_JMP || v == VT_JMPI) {
    1018         /* need to put correct jump if && or || without test */
    1019         gsym(vtop->c.ul);
    1020     }
    1021     vtop--;
    1022 }
     1546#endif
    10231547
    10241548/* convert stack entry to register and duplicate its value in another
     
    10301554
    10311555    t = vtop->type.t;
     1556#if PTR_SIZE == 4
    10321557    if ((t & VT_BTYPE) == VT_LLONG) {
     1558        if (t & VT_BITFIELD) {
     1559            gv(RC_INT);
     1560            t = vtop->type.t;
     1561        }
    10331562        lexpand();
    10341563        gv_dup();
     
    10441573        lbuild(t);
    10451574        vswap();
    1046     } else {
     1575    } else
     1576#endif
     1577    {
    10471578        /* duplicate value */
    10481579        rc = RC_INT;
     
    10601591        r1 = get_reg(rc);
    10611592        sv.r = r;
    1062         sv.c.ul = 0;
     1593        sv.c.i = 0;
    10631594        load(r1, &sv); /* move r to r1 */
    10641595        vdup();
     
    10691600}
    10701601
    1071 #ifndef TCC_TARGET_X86_64
     1602/* Generate value test
     1603 *
     1604 * Generate a test for any value (jump, comparison and integers) */
     1605ST_FUNC int gvtst(int inv, int t)
     1606{
     1607    int v = vtop->r & VT_VALMASK;
     1608    if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
     1609        vpushi(0);
     1610        gen_op(TOK_NE);
     1611    }
     1612    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
     1613        /* constant jmp optimization */
     1614        if ((vtop->c.i != 0) != inv)
     1615            t = gjmp(t);
     1616        vtop--;
     1617        return t;
     1618    }
     1619    return gtst(inv, t);
     1620}
     1621
     1622#if PTR_SIZE == 4
    10721623/* generate CPU independent (unsigned) long long operations */
    10731624static void gen_opl(int op)
     
    11121663    case '+':
    11131664    case '-':
     1665        //pv("gen_opl A",0,2);
    11141666        t = vtop->type.t;
    11151667        vswap();
     
    11261678        vswap();
    11271679        /* stack: H1 H2 L1 L2 */
     1680        //pv("gen_opl B",0,4);
    11281681        if (op == '*') {
    11291682            vpushv(vtop - 1);
     
    11811734            /* constant: simpler */
    11821735            /* NOTE: all comments are for SHL. the other cases are
    1183                done by swaping words */
     1736               done by swapping words */
    11841737            vpop();
    11851738            if (op != TOK_SHL)
     
    12661819        b = 0;
    12671820        gen_op(op1);
    1268         if (op1 != TOK_NE) {
    1269             a = gtst(1, 0);
    1270         }
    1271         if (op != TOK_EQ) {
    1272             /* generate non equal test */
    1273             /* XXX: NOT PORTABLE yet */
    1274             if (a == 0) {
    1275                 b = gtst(0, 0);
    1276             } else {
    1277 #if defined(TCC_TARGET_I386)
    1278                 b = psym(0x850f, 0);
    1279 #elif defined(TCC_TARGET_ARM)
    1280                 b = ind;
    1281                 o(0x1A000000 | encbranch(ind, 0, 1));
    1282 #elif defined(TCC_TARGET_C67)
    1283                 tcc_error("not implemented");
    1284 #elif defined(TCC_TARGET_IL)
    1285                 tcc_error("not implemented");
    1286 #else
    1287 #error not supported
    1288 #endif
     1821        if (op == TOK_NE) {
     1822            b = gvtst(0, 0);
     1823        } else {
     1824            a = gvtst(1, 0);
     1825            if (op != TOK_EQ) {
     1826                /* generate non equal test */
     1827                vpushi(TOK_NE);
     1828                vtop->r = VT_CMP;
     1829                b = gvtst(0, 0);
    12891830            }
    12901831        }
     
    13001841            op1 = TOK_UGE;
    13011842        gen_op(op1);
    1302         a = gtst(1, a);
     1843        a = gvtst(1, a);
    13031844        gsym(b);
    13041845        vseti(VT_JMPI, a);
     
    13081849#endif
    13091850
     1851static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
     1852{
     1853    uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
     1854    return (a ^ b) >> 63 ? -x : x;
     1855}
     1856
     1857static int gen_opic_lt(uint64_t a, uint64_t b)
     1858{
     1859    return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
     1860}
     1861
    13101862/* handle integer constant optimizations and various machine
    13111863   independent opt */
    13121864static void gen_opic(int op)
    13131865{
    1314     int c1, c2, t1, t2, n;
    1315     SValue *v1, *v2;
    1316     long long l1, l2;
    1317     typedef unsigned long long U;
    1318 
    1319     v1 = vtop - 1;
    1320     v2 = vtop;
    1321     t1 = v1->type.t & VT_BTYPE;
    1322     t2 = v2->type.t & VT_BTYPE;
    1323 
    1324     if (t1 == VT_LLONG)
    1325         l1 = v1->c.ll;
    1326     else if (v1->type.t & VT_UNSIGNED)
    1327         l1 = v1->c.ui;
    1328     else
    1329         l1 = v1->c.i;
    1330 
    1331     if (t2 == VT_LLONG)
    1332         l2 = v2->c.ll;
    1333     else if (v2->type.t & VT_UNSIGNED)
    1334         l2 = v2->c.ui;
    1335     else
    1336         l2 = v2->c.i;
    1337 
    1338     /* currently, we cannot do computations with forward symbols */
    1339     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    1340     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1866    SValue *v1 = vtop - 1;
     1867    SValue *v2 = vtop;
     1868    int t1 = v1->type.t & VT_BTYPE;
     1869    int t2 = v2->type.t & VT_BTYPE;
     1870    int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1871    int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     1872    uint64_t l1 = c1 ? v1->c.i : 0;
     1873    uint64_t l2 = c2 ? v2->c.i : 0;
     1874    int shm = (t1 == VT_LLONG) ? 63 : 31;
     1875
     1876    if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
     1877        l1 = ((uint32_t)l1 |
     1878              (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
     1879    if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
     1880        l2 = ((uint32_t)l2 |
     1881              (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
     1882
    13411883    if (c1 && c2) {
    13421884        switch(op) {
     
    13601902            }
    13611903            switch(op) {
    1362             default: l1 /= l2; break;
    1363             case '%': l1 %= l2; break;
    1364             case TOK_UDIV: l1 = (U)l1 / l2; break;
    1365             case TOK_UMOD: l1 = (U)l1 % l2; break;
     1904            default: l1 = gen_opic_sdiv(l1, l2); break;
     1905            case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
     1906            case TOK_UDIV: l1 = l1 / l2; break;
     1907            case TOK_UMOD: l1 = l1 % l2; break;
    13661908            }
    13671909            break;
    1368         case TOK_SHL: l1 <<= l2; break;
    1369         case TOK_SHR: l1 = (U)l1 >> l2; break;
    1370         case TOK_SAR: l1 >>= l2; break;
     1910        case TOK_SHL: l1 <<= (l2 & shm); break;
     1911        case TOK_SHR: l1 >>= (l2 & shm); break;
     1912        case TOK_SAR:
     1913            l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
     1914            break;
    13711915            /* tests */
    1372         case TOK_ULT: l1 = (U)l1 < (U)l2; break;
    1373         case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
     1916        case TOK_ULT: l1 = l1 < l2; break;
     1917        case TOK_UGE: l1 = l1 >= l2; break;
    13741918        case TOK_EQ: l1 = l1 == l2; break;
    13751919        case TOK_NE: l1 = l1 != l2; break;
    1376         case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
    1377         case TOK_UGT: l1 = (U)l1 > (U)l2; break;
    1378         case TOK_LT: l1 = l1 < l2; break;
    1379         case TOK_GE: l1 = l1 >= l2; break;
    1380         case TOK_LE: l1 = l1 <= l2; break;
    1381         case TOK_GT: l1 = l1 > l2; break;
     1920        case TOK_ULE: l1 = l1 <= l2; break;
     1921        case TOK_UGT: l1 = l1 > l2; break;
     1922        case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
     1923        case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
     1924        case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
     1925        case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
    13821926            /* logical */
    13831927        case TOK_LAND: l1 = l1 && l2; break;
     
    13861930            goto general_case;
    13871931        }
    1388         v1->c.ll = l1;
     1932        if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
     1933            l1 = ((uint32_t)l1 |
     1934                (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
     1935        v1->c.i = l1;
    13891936        vtop--;
    13901937    } else {
     
    13961943            l2 = l1; //l = l1, l1 = l2, l2 = l;
    13971944        }
    1398         /* Filter out NOP operations like x*1, x-0, x&-1... */
    1399         if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
    1400                      op == TOK_PDIV) &&
    1401                     l2 == 1) ||
    1402                    ((op == '+' || op == '-' || op == '|' || op == '^' ||
    1403                      op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
    1404                     l2 == 0) ||
    1405                    (op == '&' &&
    1406                     l2 == -1))) {
    1407             /* nothing to do */
     1945        if (!const_wanted &&
     1946            c1 && ((l1 == 0 &&
     1947                    (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
     1948                   (l1 == -1 && op == TOK_SAR))) {
     1949            /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
     1950            vtop--;
     1951        } else if (!const_wanted &&
     1952                   c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
     1953                          (op == '|' &&
     1954                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
     1955                          (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
     1956            /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
     1957            if (l2 == 1)
     1958                vtop->c.i = 0;
     1959            vswap();
     1960            vtop--;
     1961        } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
     1962                          op == TOK_PDIV) &&
     1963                           l2 == 1) ||
     1964                          ((op == '+' || op == '-' || op == '|' || op == '^' ||
     1965                            op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
     1966                           l2 == 0) ||
     1967                          (op == '&' &&
     1968                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
     1969            /* filter out NOP operations like x*1, x-0, x&-1... */
    14081970            vtop--;
    14091971        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
    14101972            /* try to use shifts instead of muls or divs */
    14111973            if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
    1412                 n = -1;
     1974                int n = -1;
    14131975                while (l2) {
    14141976                    l2 >>= 1;
    14151977                    n++;
    14161978                }
    1417                 vtop->c.ll = n;
     1979                vtop->c.i = n;
    14181980                if (op == '*')
    14191981                    op = TOK_SHL;
     
    14301992            if (op == '-')
    14311993                l2 = -l2;
     1994            l2 += vtop[-1].c.i;
     1995            /* The backends can't always deal with addends to symbols
     1996               larger than +-1<<31.  Don't construct such.  */
     1997            if ((int)l2 != l2)
     1998                goto general_case;
    14321999            vtop--;
    1433             vtop->c.ll += l2;
     2000            vtop->c.i = l2;
    14342001        } else {
    14352002        general_case:
    1436             if (!nocode_wanted) {
    14372003                /* call low level op generator */
    1438                 if (t1 == VT_LLONG || t2 == VT_LLONG)
     2004                if (t1 == VT_LLONG || t2 == VT_LLONG ||
     2005                    (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
    14392006                    gen_opl(op);
    14402007                else
    14412008                    gen_opi(op);
    1442             } else {
    1443                 vtop--;
    1444             }
    14452009        }
    14462010    }
     
    14522016    int c1, c2;
    14532017    SValue *v1, *v2;
     2018#if defined _MSC_VER && defined _AMD64_
     2019    /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
     2020    volatile
     2021#endif
    14542022    long double f1, f2;
    14552023
     
    15032071    } else {
    15042072    general_case:
    1505         if (!nocode_wanted) {
    1506             gen_opf(op);
    1507         } else {
    1508             vtop--;
    1509         }
     2073        gen_opf(op);
    15102074    }
    15112075}
     
    15272091    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
    15282092        return 0;
    1529     return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
    1530         ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
    1531         ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
     2093    return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
     2094        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
     2095        ((p->type.t & VT_BTYPE) == VT_PTR &&
     2096         (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
    15322097}
    15332098
     
    15382103}
    15392104
    1540 /* check types for comparison or substraction of pointers */
     2105/* check types for comparison or subtraction of pointers */
    15412106static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
    15422107{
     
    15752140    tmp_type1 = *type1;
    15762141    tmp_type2 = *type2;
    1577     tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    1578     tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
     2142    tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
     2143    tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    15792144    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
    15802145        /* gcc-like error if '-' is used */
     
    15922157    CType type1;
    15932158
     2159redo:
    15942160    t1 = vtop[-1].type.t;
    15952161    t2 = vtop[0].type.t;
     
    15972163    bt2 = t2 & VT_BTYPE;
    15982164       
    1599     if (bt1 == VT_PTR || bt2 == VT_PTR) {
     2165    if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
     2166        tcc_error("operation on a struct");
     2167    } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
     2168        if (bt2 == VT_FUNC) {
     2169            mk_pointer(&vtop->type);
     2170            gaddrof();
     2171        }
     2172        if (bt1 == VT_FUNC) {
     2173            vswap();
     2174            mk_pointer(&vtop->type);
     2175            gaddrof();
     2176            vswap();
     2177        }
     2178        goto redo;
     2179    } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
    16002180        /* at least one operand is a pointer */
    1601         /* relationnal op: must be both pointers */
     2181        /* relational op: must be both pointers */
    16022182        if (op >= TOK_ULT && op <= TOK_LOR) {
    16032183            check_comparison_pointer_types(vtop - 1, vtop, op);
    16042184            /* pointers are handled are unsigned */
    1605 #ifdef TCC_TARGET_X86_64
     2185#if PTR_SIZE == 8
    16062186            t = VT_LLONG | VT_UNSIGNED;
    16072187#else
     
    16232203            vrott(3);
    16242204            gen_opic(op);
    1625             /* set to integer type */
    1626 #ifdef TCC_TARGET_X86_64
    1627             vtop->type.t = VT_LLONG;
    1628 #else
    1629             vtop->type.t = VT_INT;
    1630 #endif
     2205            vtop->type.t = ptrdiff_type.t;
    16312206            vswap();
    16322207            gen_op(TOK_PDIV);
     
    16382213            if (bt2 == VT_PTR) {
    16392214                vswap();
    1640                 swap(&t1, &t2);
    1641             }
     2215                t = t1, t1 = t2, t2 = t;
     2216            }
     2217#if PTR_SIZE == 4
     2218            if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
     2219                /* XXX: truncate here because gen_opl can't handle ptr + long long */
     2220                gen_cast_s(VT_INT);
     2221#endif
    16422222            type1 = vtop[-1].type;
    16432223            type1.t &= ~VT_ARRAY;
     
    16482228                if (u < 0)
    16492229                    tcc_error("unknown array element size");
    1650 #ifdef TCC_TARGET_X86_64
     2230#if PTR_SIZE == 8
    16512231                vpushll(u);
    16522232#else
     
    16562236            }
    16572237            gen_op('*');
    1658 #ifdef CONFIG_TCC_BCHECK
     2238#if 0
     2239/* #ifdef CONFIG_TCC_BCHECK
     2240    The main reason to removing this code:
     2241        #include <stdio.h>
     2242        int main ()
     2243        {
     2244            int v[10];
     2245            int i = 10;
     2246            int j = 9;
     2247            fprintf(stderr, "v+i-j  = %p\n", v+i-j);
     2248            fprintf(stderr, "v+(i-j)  = %p\n", v+(i-j));
     2249        }
     2250    When this code is on. then the output looks like
     2251        v+i-j = 0xfffffffe
     2252        v+(i-j) = 0xbff84000
     2253    */
    16592254            /* if evaluating constant expression, no code should be
    16602255               generated, so no bound check */
     
    16922287    } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
    16932288        t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
    1694         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
     2289        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
    16952290          t |= VT_UNSIGNED;
     2291        t |= (VT_LONG & t1);
    16962292        goto std_op;
    16972293    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
    16982294        /* cast to biggest op */
    1699         t = VT_LLONG;
     2295        t = VT_LLONG | VT_LONG;
     2296        if (bt1 == VT_LLONG)
     2297            t &= t1;
     2298        if (bt2 == VT_LLONG)
     2299            t &= t2;
    17002300        /* convert to unsigned if it does not fit in a long long */
    1701         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
    1702             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
     2301        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
     2302            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
    17032303            t |= VT_UNSIGNED;
    17042304        goto std_op;
    1705     } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
    1706         tcc_error("comparison of struct");
    17072305    } else {
    17082306        /* integer operations */
    1709         t = VT_INT;
     2307        t = VT_INT | (VT_LONG & (t1 | t2));
    17102308        /* convert to unsigned if it does not fit in an integer */
    1711         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
    1712             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
     2309        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
     2310            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
    17132311            t |= VT_UNSIGNED;
    17142312    std_op:
     
    17332331        vswap();
    17342332        type1.t = t;
     2333        type1.ref = NULL;
    17352334        gen_cast(&type1);
    17362335        vswap();
     
    17452344            gen_opic(op);
    17462345        if (op >= TOK_ULT && op <= TOK_GT) {
    1747             /* relationnal op: the result is an int */
     2346            /* relational op: the result is an int */
    17482347            vtop->type.t = VT_INT;
    17492348        } else {
     
    17512350        }
    17522351    }
     2352    // Make sure that we have converted to an rvalue:
     2353    if (vtop->r & VT_LVAL)
     2354        gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
    17532355}
    17542356
     
    17572359static void gen_cvt_itof1(int t)
    17582360{
     2361#ifdef TCC_TARGET_ARM64
     2362    gen_cvt_itof(t);
     2363#else
    17592364    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
    17602365        (VT_LLONG | VT_UNSIGNED)) {
     
    17752380        gen_cvt_itof(t);
    17762381    }
     2382#endif
    17772383}
    17782384#endif
     
    17812387static void gen_cvt_ftoi1(int t)
    17822388{
     2389#ifdef TCC_TARGET_ARM64
     2390    gen_cvt_ftoi(t);
     2391#else
    17832392    int st;
    17842393
     
    18022411        gen_cvt_ftoi(t);
    18032412    }
     2413#endif
    18042414}
    18052415
     
    18082418{
    18092419    int bits, dbt;
     2420
     2421    /* cannot cast static initializers */
     2422    if (STATIC_DATA_WANTED)
     2423        return;
     2424
    18102425    dbt = t & VT_BTYPE;
    18112426    /* XXX: add optimization if lvalue : just change type and offset */
     
    18182433        gen_op('&');
    18192434    } else {
    1820         bits = 32 - bits;
     2435        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
     2436            bits = 64 - bits;
     2437        else
     2438            bits = 32 - bits;
    18212439        vpushi(bits);
    18222440        gen_op(TOK_SHL);
     
    18312449
    18322450/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
     2451static void gen_cast_s(int t)
     2452{
     2453    CType type;
     2454    type.t = t;
     2455    type.ref = NULL;
     2456    gen_cast(&type);
     2457}
     2458
    18332459static void gen_cast(CType *type)
    18342460{
     
    18562482        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    18572483        p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
     2484#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
     2485        c &= dbt != VT_LDOUBLE;
     2486#endif
    18582487        if (c) {
    18592488            /* constant case: we can do it now */
     
    18662495            if (df) {
    18672496                if ((sbt & VT_BTYPE) == VT_LLONG) {
    1868                     if (sbt & VT_UNSIGNED)
    1869                         vtop->c.ld = vtop->c.ull;
     2497                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
     2498                        vtop->c.ld = vtop->c.i;
    18702499                    else
    1871                         vtop->c.ld = vtop->c.ll;
     2500                        vtop->c.ld = -(long double)-vtop->c.i;
    18722501                } else if(!sf) {
    1873                     if (sbt & VT_UNSIGNED)
    1874                         vtop->c.ld = vtop->c.ui;
     2502                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
     2503                        vtop->c.ld = (uint32_t)vtop->c.i;
    18752504                    else
    1876                         vtop->c.ld = vtop->c.i;
     2505                        vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
    18772506                }
    18782507
     
    18822511                    vtop->c.d = (double)vtop->c.ld;
    18832512            } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
    1884                 vtop->c.ull = (unsigned long long)vtop->c.ld;
     2513                vtop->c.i = vtop->c.ld;
    18852514            } else if (sf && dbt == VT_BOOL) {
    18862515                vtop->c.i = (vtop->c.ld != 0);
    18872516            } else {
    18882517                if(sf)
    1889                     vtop->c.ll = (long long)vtop->c.ld;
     2518                    vtop->c.i = vtop->c.ld;
    18902519                else if (sbt == (VT_LLONG|VT_UNSIGNED))
    1891                     vtop->c.ll = vtop->c.ull;
     2520                    ;
    18922521                else if (sbt & VT_UNSIGNED)
    1893                     vtop->c.ll = vtop->c.ui;
    1894 #ifdef TCC_TARGET_X86_64
     2522                    vtop->c.i = (uint32_t)vtop->c.i;
     2523#if PTR_SIZE == 8
    18952524                else if (sbt == VT_PTR)
    18962525                    ;
    18972526#endif
    18982527                else if (sbt != VT_LLONG)
    1899                     vtop->c.ll = vtop->c.i;
     2528                    vtop->c.i = ((uint32_t)vtop->c.i |
     2529                                  -(vtop->c.i & 0x80000000));
    19002530
    19012531                if (dbt == (VT_LLONG|VT_UNSIGNED))
    1902                     vtop->c.ull = vtop->c.ll;
     2532                    ;
    19032533                else if (dbt == VT_BOOL)
    1904                     vtop->c.i = (vtop->c.ll != 0);
     2534                    vtop->c.i = (vtop->c.i != 0);
     2535#if PTR_SIZE == 8
     2536                else if (dbt == VT_PTR)
     2537                    ;
     2538#endif
    19052539                else if (dbt != VT_LLONG) {
    1906                     int s = 0;
    1907                     if ((dbt & VT_BTYPE) == VT_BYTE)
    1908                         s = 24;
    1909                     else if ((dbt & VT_BTYPE) == VT_SHORT)
    1910                         s = 16;
    1911 
    1912                     if(dbt & VT_UNSIGNED)
    1913                         vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
    1914                     else
    1915                         vtop->c.i = ((int)vtop->c.ll << s) >> s;
     2540                    uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
     2541                                  (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
     2542                                  0xffffffff);
     2543                    vtop->c.i &= m;
     2544                    if (!(dbt & VT_UNSIGNED))
     2545                        vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
    19162546                }
    19172547            }
     
    19192549            vtop->r = VT_CONST;
    19202550            vtop->c.i = 1;
    1921         } else if (!nocode_wanted) {
     2551        } else {
    19222552            /* non constant case: generate code */
    19232553            if (sf && df) {
     
    19452575                    }
    19462576                }
    1947 #ifndef TCC_TARGET_X86_64
     2577#if PTR_SIZE == 4
    19482578            } else if ((dbt & VT_BTYPE) == VT_LLONG) {
    19492579                if ((sbt & VT_BTYPE) != VT_LLONG) {
     
    19592589                            /* cast from pointer to int before we apply
    19602590                               shift operation, which pointers don't support*/
    1961                             gen_cast(&int_type);
     2591                            gen_cast_s(VT_INT);
    19622592                        }
    19632593                        gv_dup();
     
    19772607                    (sbt & VT_BTYPE) != VT_FUNC) {
    19782608                    /* need to convert from 32bit to 64bit */
    1979                     int r = gv(RC_INT);
     2609                    gv(RC_INT);
    19802610                    if (sbt != (VT_INT | VT_UNSIGNED)) {
     2611#if defined(TCC_TARGET_ARM64)
     2612                        gen_cvt_sxtw();
     2613#elif defined(TCC_TARGET_X86_64)
     2614                        int r = gv(RC_INT);
    19812615                        /* x86_64 specific: movslq */
    19822616                        o(0x6348);
    19832617                        o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
     2618#else
     2619#error
     2620#endif
    19842621                    }
    19852622                }
     
    19962633                }
    19972634                force_charshort_cast(dbt);
     2635#if PTR_SIZE == 4
    19982636            } else if ((dbt & VT_BTYPE) == VT_INT) {
    19992637                /* scalar to int */
    2000                 if (sbt == VT_LLONG) {
     2638                if ((sbt & VT_BTYPE) == VT_LLONG) {
    20012639                    /* from long long: just take low order word */
    20022640                    lexpand();
     
    20062644                   the lvalue already contains the real type size (see
    20072645                   VT_LVAL_xxx constants) */
     2646#endif
    20082647            }
    20092648        }
     
    20442683            return PTR_SIZE;
    20452684        }
     2685    } else if (IS_ENUM(type->t) && type->ref->c == -1) {
     2686        return -1; /* incomplete enum */
    20462687    } else if (bt == VT_LDOUBLE) {
    20472688        *a = LDOUBLE_ALIGN;
     
    20642705#endif
    20652706        return 8;
    2066     } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
     2707    } else if (bt == VT_INT || bt == VT_FLOAT) {
    20672708        *a = 4;
    20682709        return 4;
     
    20702711        *a = 2;
    20712712        return 2;
     2713    } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
     2714        *a = 8;
     2715        return 16;
    20722716    } else {
    20732717        /* char, void, function, _Bool */
     
    20822726{
    20832727    if (type->t & VT_VLA) {
     2728        type_size(&type->ref->type, a);
    20842729        vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
    20852730    } else {
     
    20882733}
    20892734
     2735static void vla_sp_restore(void) {
     2736    if (vlas_in_scope) {
     2737        gen_vla_sp_restore(vla_sp_loc);
     2738    }
     2739}
     2740
     2741static void vla_sp_restore_root(void) {
     2742    if (vlas_in_scope) {
     2743        gen_vla_sp_restore(vla_sp_root_loc);
     2744    }
     2745}
     2746
    20902747/* return the pointed type of t */
    20912748static inline CType *pointed_type(CType *type)
     
    20992756    Sym *s;
    21002757    s = sym_push(SYM_FIELD, type, 0, -1);
    2101     type->t = VT_PTR | (type->t & ~VT_TYPE);
     2758    type->t = VT_PTR | (type->t & VT_STORAGE);
    21022759    type->ref = s;
    21032760}
     
    21132770        return 0;
    21142771    /* check func_call */
    2115     if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
     2772    if (s1->f.func_call != s2->f.func_call)
    21162773        return 0;
    21172774    /* XXX: not complete */
    2118     if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
     2775    if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
    21192776        return 1;
    2120     if (s1->c != s2->c)
     2777    if (s1->f.func_type != s2->f.func_type)
    21212778        return 0;
    21222779    while (s1 != NULL) {
    21232780        if (s2 == NULL)
    21242781            return 0;
    2125         if (!is_compatible_parameter_types(&s1->type, &s2->type))
     2782        if (!is_compatible_unqualified_types(&s1->type, &s2->type))
    21262783            return 0;
    21272784        s1 = s1->next;
     
    21482805        t1 &= ~(VT_CONSTANT | VT_VOLATILE);
    21492806        t2 &= ~(VT_CONSTANT | VT_VOLATILE);
     2807    }
     2808
     2809    /* Default Vs explicit signedness only matters for char */
     2810    if ((t1 & VT_BTYPE) != VT_BYTE) {
     2811        t1 &= ~VT_DEFSIGN;
     2812        t2 &= ~VT_DEFSIGN;
    21502813    }
    21512814    /* XXX: bitfields ? */
     
    21772840/* return true if type1 and type2 are the same (ignoring qualifiers).
    21782841*/
    2179 static int is_compatible_parameter_types(CType *type1, CType *type2)
     2842static int is_compatible_unqualified_types(CType *type1, CType *type2)
    21802843{
    21812844    return compare_types(type1,type2,1);
     
    21942857    const char *tstr;
    21952858
    2196     t = type->t & VT_TYPE;
     2859    t = type->t;
    21972860    bt = t & VT_BTYPE;
    21982861    buf[0] = '\0';
     2862
     2863    if (t & VT_EXTERN)
     2864        pstrcat(buf, buf_size, "extern ");
     2865    if (t & VT_STATIC)
     2866        pstrcat(buf, buf_size, "static ");
     2867    if (t & VT_TYPEDEF)
     2868        pstrcat(buf, buf_size, "typedef ");
     2869    if (t & VT_INLINE)
     2870        pstrcat(buf, buf_size, "inline ");
     2871    if (t & VT_VOLATILE)
     2872        pstrcat(buf, buf_size, "volatile ");
    21992873    if (t & VT_CONSTANT)
    22002874        pstrcat(buf, buf_size, "const ");
    2201     if (t & VT_VOLATILE)
    2202         pstrcat(buf, buf_size, "volatile ");
    2203     if (t & VT_UNSIGNED)
    2204         pstrcat(buf, buf_size, "unsigned ");
     2875
     2876    if (((t & VT_DEFSIGN) && bt == VT_BYTE)
     2877        || ((t & VT_UNSIGNED)
     2878            && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
     2879            && !IS_ENUM(t)
     2880            ))
     2881        pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
     2882
     2883    buf_size -= strlen(buf);
     2884    buf += strlen(buf);
     2885
    22052886    switch(bt) {
    22062887    case VT_VOID:
     
    22182899    case VT_INT:
    22192900        tstr = "int";
    2220         goto add_tstr;
    2221     case VT_LONG:
    2222         tstr = "long";
    2223         goto add_tstr;
     2901        goto maybe_long;
    22242902    case VT_LLONG:
    22252903        tstr = "long long";
    2226         goto add_tstr;
     2904    maybe_long:
     2905        if (t & VT_LONG)
     2906            tstr = "long";
     2907        if (!IS_ENUM(t))
     2908            goto add_tstr;
     2909        tstr = "enum ";
     2910        goto tstruct;
    22272911    case VT_FLOAT:
    22282912        tstr = "float";
     
    22362920        pstrcat(buf, buf_size, tstr);
    22372921        break;
    2238     case VT_ENUM:
    22392922    case VT_STRUCT:
    2240         if (bt == VT_STRUCT)
    2241             tstr = "struct ";
    2242         else
    2243             tstr = "enum ";
     2923        tstr = "struct ";
     2924        if (IS_UNION(t))
     2925            tstr = "union ";
     2926    tstruct:
    22442927        pstrcat(buf, buf_size, tstr);
    22452928        v = type->ref->v & ~SYM_STRUCT;
     
    22652948    case VT_PTR:
    22662949        s = type->ref;
     2950        if (t & VT_ARRAY) {
     2951            snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
     2952            type_to_str(buf, buf_size, &s->type, buf1);
     2953            goto no_var;
     2954        }
    22672955        pstrcpy(buf1, sizeof(buf1), "*");
     2956        if (t & VT_CONSTANT)
     2957            pstrcat(buf1, buf_size, "const ");
     2958        if (t & VT_VOLATILE)
     2959            pstrcat(buf1, buf_size, "volatile ");
    22682960        if (varstr)
    22692961            pstrcat(buf1, sizeof(buf1), varstr);
     
    22822974static void gen_assign_cast(CType *dt)
    22832975{
    2284     CType *st, *type1, *type2, tmp_type1, tmp_type2;
     2976    CType *st, *type1, *type2;
    22852977    char buf1[256], buf2[256];
    22862978    int dbt, sbt;
     
    22892981    dbt = dt->t & VT_BTYPE;
    22902982    sbt = st->t & VT_BTYPE;
    2291     if (sbt == VT_VOID)
    2292         tcc_error("Cannot assign void value");
     2983    if (sbt == VT_VOID || dbt == VT_VOID) {
     2984        if (sbt == VT_VOID && dbt == VT_VOID)
     2985            ; /*
     2986              It is Ok if both are void
     2987              A test program:
     2988                void func1() {}
     2989                void func2() {
     2990                  return func1();
     2991                }
     2992              gcc accepts this program
     2993              */
     2994        else
     2995            tcc_error("cannot cast from/to void");
     2996    }
    22932997    if (dt->t & VT_CONSTANT)
    22942998        tcc_warning("assignment of read-only location");
     
    23053009        }
    23063010        type1 = pointed_type(dt);
    2307         /* a function is implicitely a function pointer */
     3011        /* a function is implicitly a function pointer */
    23083012        if (sbt == VT_FUNC) {
    23093013            if ((type1->t & VT_BTYPE) != VT_VOID &&
     
    23193023            /* void * can match anything */
    23203024        } else {
    2321             /* exact type match, except for unsigned */
    2322             tmp_type1 = *type1;
    2323             tmp_type2 = *type2;
    2324             tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    2325             tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    2326             if (!is_compatible_types(&tmp_type1, &tmp_type2))
    2327                 tcc_warning("assignment from incompatible pointer type");
     3025            //printf("types %08x %08x\n", type1->t, type2->t);
     3026            /* exact type match, except for qualifiers */
     3027            if (!is_compatible_unqualified_types(type1, type2)) {
     3028                /* Like GCC don't warn by default for merely changes
     3029                   in pointer target signedness.  Do warn for different
     3030                   base types, though, in particular for unsigned enums
     3031                   and signed int targets.  */
     3032                if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
     3033                    || IS_ENUM(type1->t) || IS_ENUM(type2->t)
     3034                    )
     3035                    tcc_warning("assignment from incompatible pointer type");
     3036            }
    23283037        }
    23293038        /* check const and volatile */
     
    23383047        if (sbt == VT_PTR || sbt == VT_FUNC) {
    23393048            tcc_warning("assignment makes integer from pointer without a cast");
     3049        } else if (sbt == VT_STRUCT) {
     3050            goto case_VT_STRUCT;
    23403051        }
    23413052        /* XXX: more tests */
    23423053        break;
    23433054    case VT_STRUCT:
    2344         tmp_type1 = *dt;
    2345         tmp_type2 = *st;
    2346         tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
    2347         tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
    2348         if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
     3055    case_VT_STRUCT:
     3056        if (!is_compatible_unqualified_types(dt, st)) {
    23493057        error:
    23503058            type_to_str(buf1, sizeof(buf1), st, NULL);
     
    23713079        /* optimize char/short casts */
    23723080        delayed_cast = VT_MUSTCAST;
    2373         vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
     3081        vtop->type.t = ft & VT_TYPE;
    23743082        /* XXX: factorize */
    23753083        if (ft & VT_CONSTANT)
     
    23853093        /* structure assignment : generate memcpy */
    23863094        /* XXX: optimize if small size */
    2387         if (!nocode_wanted) {
    23883095            size = type_size(&vtop->type, &align);
    23893096
     
    24013108            else
    24023109#endif
    2403             vpush_global_sym(&func_old_type, TOK_memcpy);
     3110            /* Use memmove, rather than memcpy, as dest and src may be same: */
     3111            vpush_global_sym(&func_old_type, TOK_memmove);
    24043112
    24053113            vswap();
     
    24113119            vpushi(size);
    24123120            gfunc_call(3);
    2413         } else {
    2414             vswap();
    2415             vpop();
    2416         }
     3121
    24173122        /* leave source on stack */
    24183123    } else if (ft & VT_BITFIELD) {
    24193124        /* bitfield store handling */
    2420         bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
    2421         bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
     3125
     3126        /* save lvalue as expression result (example: s.b = s.a = n;) */
     3127        vdup(), vtop[-1] = vtop[-2];
     3128
     3129        bit_pos = BIT_POS(ft);
     3130        bit_size = BIT_SIZE(ft);
    24223131        /* remove bit field info to avoid loops */
    2423         vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
    2424 
    2425         /* duplicate source into other register */
    2426         gv_dup();
    2427         vswap();
    2428         vrott(3);
    2429 
    2430         if((ft & VT_BTYPE) == VT_BOOL) {
     3132        vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
     3133
     3134        if ((ft & VT_BTYPE) == VT_BOOL) {
    24313135            gen_cast(&vtop[-1].type);
    24323136            vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
    24333137        }
    24343138
    2435         /* duplicate destination */
    2436         vdup();
    2437         vtop[-1] = vtop[-2];
    2438 
    2439         /* mask and shift source */
    2440         if((ft & VT_BTYPE) != VT_BOOL) {
    2441             if((ft & VT_BTYPE) == VT_LLONG) {
    2442                 vpushll((1ULL << bit_size) - 1ULL);
    2443             } else {
    2444                 vpushi((1 << bit_size) - 1);
    2445             }
     3139        r = adjust_bf(vtop - 1, bit_pos, bit_size);
     3140        if (r == VT_STRUCT) {
     3141            gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
     3142            store_packed_bf(bit_pos, bit_size);
     3143        } else {
     3144            unsigned long long mask = (1ULL << bit_size) - 1;
     3145            if ((ft & VT_BTYPE) != VT_BOOL) {
     3146                /* mask source */
     3147                if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
     3148                    vpushll(mask);
     3149                else
     3150                    vpushi((unsigned)mask);
     3151                gen_op('&');
     3152            }
     3153            /* shift source */
     3154            vpushi(bit_pos);
     3155            gen_op(TOK_SHL);
     3156            vswap();
     3157            /* duplicate destination */
     3158            vdup();
     3159            vrott(3);
     3160            /* load destination, mask and or with source */
     3161            if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
     3162                vpushll(~(mask << bit_pos));
     3163            else
     3164                vpushi(~((unsigned)mask << bit_pos));
    24463165            gen_op('&');
    2447         }
    2448         vpushi(bit_pos);
    2449         gen_op(TOK_SHL);
    2450         /* load destination, mask and or with source */
    2451         vswap();
    2452         if((ft & VT_BTYPE) == VT_LLONG) {
    2453             vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
    2454         } else {
    2455             vpushi(~(((1 << bit_size) - 1) << bit_pos));
    2456         }
    2457         gen_op('&');
    2458         gen_op('|');
    2459         /* store result */
    2460         vstore();
    2461 
    2462         /* pop off shifted source from "duplicate source..." above */
    2463         vpop();
    2464 
     3166            gen_op('|');
     3167            /* store result */
     3168            vstore();
     3169            /* ... and discard */
     3170            vpop();
     3171        }
     3172    } else if (dbt == VT_VOID) {
     3173        --vtop;
    24653174    } else {
    24663175#ifdef CONFIG_TCC_BCHECK
    2467         /* bound check case */
    2468         if (vtop[-1].r & VT_MUSTBOUND) {
    2469             vswap();
    2470             gbound();
    2471             vswap();
    2472         }
    2473 #endif
    2474         if (!nocode_wanted) {
     3176            /* bound check case */
     3177            if (vtop[-1].r & VT_MUSTBOUND) {
     3178                vswap();
     3179                gbound();
     3180                vswap();
     3181            }
     3182#endif
    24753183            rc = RC_INT;
    24763184            if (is_float(ft)) {
     
    24793187                if ((ft & VT_BTYPE) == VT_LDOUBLE) {
    24803188                    rc = RC_ST0;
     3189                } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
     3190                    rc = RC_FRET;
    24813191                }
    24823192#endif
     
    24873197                SValue sv;
    24883198                t = get_reg(RC_INT);
    2489 #ifdef TCC_TARGET_X86_64
     3199#if PTR_SIZE == 8
    24903200                sv.type.t = VT_PTR;
    24913201#else
     
    24933203#endif
    24943204                sv.r = VT_LOCAL | VT_LVAL;
    2495                 sv.c.ul = vtop[-1].c.ul;
     3205                sv.c.i = vtop[-1].c.i;
    24963206                load(t, &sv);
    24973207                vtop[-1].r = t | VT_LVAL;
    24983208            }
    2499             store(r, vtop - 1);
    2500 #ifndef TCC_TARGET_X86_64
    2501             /* two word case handling : store second register at word + 4 */
     3209            /* two word case handling : store second register at word + 4 (or +8 for x86-64)  */
     3210#if PTR_SIZE == 8
     3211            if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
     3212                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
     3213#else
    25023214            if ((ft & VT_BTYPE) == VT_LLONG) {
     3215                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
     3216#endif
     3217                vtop[-1].type.t = load_type;
     3218                store(r, vtop - 1);
    25033219                vswap();
    25043220                /* convert to int to increment easily */
    2505                 vtop->type.t = VT_INT;
     3221                vtop->type.t = addr_type;
    25063222                gaddrof();
    2507                 vpushi(4);
     3223                vpushi(load_size);
    25083224                gen_op('+');
    25093225                vtop->r |= VT_LVAL;
    25103226                vswap();
     3227                vtop[-1].type.t = load_type;
    25113228                /* XXX: it works because r2 is spilled last ! */
    25123229                store(vtop->r2, vtop - 1);
    2513             }
    2514 #endif
    2515         }
     3230            } else {
     3231                store(r, vtop - 1);
     3232            }
     3233
    25163234        vswap();
    25173235        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
     
    25383256}
    25393257
    2540 /* Parse GNUC __attribute__ extension. Currently, the following
    2541    extensions are recognized:
    2542    - aligned(n) : set data/function alignment.
    2543    - packed : force data alignment to 1
    2544    - section(x) : generate data/code in this section.
    2545    - unused : currently ignored, but may be used someday.
    2546    - regparm(n) : pass function parameters in registers (i386 only)
    2547  */
     3258ST_FUNC void parse_mult_str (CString *astr, const char *msg)
     3259{
     3260    /* read the string */
     3261    if (tok != TOK_STR)
     3262        expect(msg);
     3263    cstr_new(astr);
     3264    while (tok == TOK_STR) {
     3265        /* XXX: add \0 handling too ? */
     3266        cstr_cat(astr, tokc.str.data, -1);
     3267        next();
     3268    }
     3269    cstr_ccat(astr, '\0');
     3270}
     3271
     3272/* If I is >= 1 and a power of two, returns log2(i)+1.
     3273   If I is 0 returns 0.  */
     3274static int exact_log2p1(int i)
     3275{
     3276  int ret;
     3277  if (!i)
     3278    return 0;
     3279  for (ret = 1; i >= 1 << 8; ret += 8)
     3280    i >>= 8;
     3281  if (i >= 1 << 4)
     3282    ret += 4, i >>= 4;
     3283  if (i >= 1 << 2)
     3284    ret += 2, i >>= 2;
     3285  if (i >= 1 << 1)
     3286    ret++;
     3287  return ret;
     3288}
     3289
     3290/* Parse __attribute__((...)) GNUC extension. */
    25483291static void parse_attribute(AttributeDef *ad)
    25493292{
    25503293    int t, n;
     3294    CString astr;
    25513295   
    2552     while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
     3296redo:
     3297    if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
     3298        return;
    25533299    next();
    25543300    skip('(');
     
    25633309        case TOK_SECTION2:
    25643310            skip('(');
    2565             if (tok != TOK_STR)
    2566                 expect("section name");
    2567             ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
    2568             next();
     3311            parse_mult_str(&astr, "section name");
     3312            ad->section = find_section(tcc_state, (char *)astr.data);
    25693313            skip(')');
     3314            cstr_free(&astr);
    25703315            break;
    25713316        case TOK_ALIAS1:
    25723317        case TOK_ALIAS2:
    25733318            skip('(');
    2574             if (tok != TOK_STR)
    2575                 expect("alias(\"target\")");
     3319            parse_mult_str(&astr, "alias(\"target\")");
    25763320            ad->alias_target = /* save string as token, for later */
    2577               tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
    2578             next();
     3321              tok_alloc((char*)astr.data, astr.size-1)->tok;
    25793322            skip(')');
     3323            cstr_free(&astr);
     3324            break;
     3325        case TOK_VISIBILITY1:
     3326        case TOK_VISIBILITY2:
     3327            skip('(');
     3328            parse_mult_str(&astr,
     3329                           "visibility(\"default|hidden|internal|protected\")");
     3330            if (!strcmp (astr.data, "default"))
     3331                ad->a.visibility = STV_DEFAULT;
     3332            else if (!strcmp (astr.data, "hidden"))
     3333                ad->a.visibility = STV_HIDDEN;
     3334            else if (!strcmp (astr.data, "internal"))
     3335                ad->a.visibility = STV_INTERNAL;
     3336            else if (!strcmp (astr.data, "protected"))
     3337                ad->a.visibility = STV_PROTECTED;
     3338            else
     3339                expect("visibility(\"default|hidden|internal|protected\")");
     3340            skip(')');
     3341            cstr_free(&astr);
    25803342            break;
    25813343        case TOK_ALIGNED1:
     
    25903352                n = MAX_ALIGN;
    25913353            }
    2592             ad->aligned = n;
     3354            ad->a.aligned = exact_log2p1(n);
     3355            if (n != 1 << (ad->a.aligned - 1))
     3356              tcc_error("alignment of %d is larger than implemented", n);
    25933357            break;
    25943358        case TOK_PACKED1:
    25953359        case TOK_PACKED2:
    2596             ad->packed = 1;
     3360            ad->a.packed = 1;
    25973361            break;
    25983362        case TOK_WEAK1:
    25993363        case TOK_WEAK2:
    2600             ad->weak = 1;
     3364            ad->a.weak = 1;
    26013365            break;
    26023366        case TOK_UNUSED1:
     
    26133377        case TOK_CDECL2:
    26143378        case TOK_CDECL3:
    2615             ad->func_call = FUNC_CDECL;
     3379            ad->f.func_call = FUNC_CDECL;
    26163380            break;
    26173381        case TOK_STDCALL1:
    26183382        case TOK_STDCALL2:
    26193383        case TOK_STDCALL3:
    2620             ad->func_call = FUNC_STDCALL;
     3384            ad->f.func_call = FUNC_STDCALL;
    26213385            break;
    26223386#ifdef TCC_TARGET_I386
     
    26303394                n = 0;
    26313395            if (n > 0)
    2632                 ad->func_call = FUNC_FASTCALL1 + n - 1;
     3396                ad->f.func_call = FUNC_FASTCALL1 + n - 1;
    26333397            skip(')');
    26343398            break;
     
    26363400        case TOK_FASTCALL2:
    26373401        case TOK_FASTCALL3:
    2638             ad->func_call = FUNC_FASTCALLW;
     3402            ad->f.func_call = FUNC_FASTCALLW;
    26393403            break;           
    26403404#endif
     
    26433407            switch(tok) {
    26443408                case TOK_MODE_DI:
    2645                     ad->mode = VT_LLONG + 1;
     3409                    ad->attr_mode = VT_LLONG + 1;
     3410                    break;
     3411                case TOK_MODE_QI:
     3412                    ad->attr_mode = VT_BYTE + 1;
    26463413                    break;
    26473414                case TOK_MODE_HI:
    2648                     ad->mode = VT_SHORT + 1;
     3415                    ad->attr_mode = VT_SHORT + 1;
    26493416                    break;
    26503417                case TOK_MODE_SI:
    2651                     ad->mode = VT_INT + 1;
     3418                case TOK_MODE_word:
     3419                    ad->attr_mode = VT_INT + 1;
    26523420                    break;
    26533421                default:
     
    26593427            break;
    26603428        case TOK_DLLEXPORT:
    2661             ad->func_export = 1;
     3429            ad->a.dllexport = 1;
    26623430            break;
    26633431        case TOK_DLLIMPORT:
    2664             ad->func_import = 1;
     3432            ad->a.dllimport = 1;
    26653433            break;
    26663434        default:
     
    26863454    skip(')');
    26873455    skip(')');
    2688     }
    2689 }
    2690 
    2691 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
     3456    goto redo;
     3457}
     3458
     3459static Sym * find_field (CType *type, int v)
     3460{
     3461    Sym *s = type->ref;
     3462    v |= SYM_FIELD;
     3463    while ((s = s->next) != NULL) {
     3464        if ((s->v & SYM_FIELD) &&
     3465            (s->type.t & VT_BTYPE) == VT_STRUCT &&
     3466            (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
     3467            Sym *ret = find_field (&s->type, v);
     3468            if (ret)
     3469                return ret;
     3470        }
     3471        if (s->v == v)
     3472          break;
     3473    }
     3474    return s;
     3475}
     3476
     3477static void struct_add_offset (Sym *s, int offset)
     3478{
     3479    while ((s = s->next) != NULL) {
     3480        if ((s->v & SYM_FIELD) &&
     3481            (s->type.t & VT_BTYPE) == VT_STRUCT &&
     3482            (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
     3483            struct_add_offset(s->type.ref, offset);
     3484        } else
     3485          s->c += offset;
     3486    }
     3487}
     3488
     3489static void struct_layout(CType *type, AttributeDef *ad)
     3490{
     3491    int size, align, maxalign, offset, c, bit_pos, bit_size;
     3492    int packed, a, bt, prevbt, prev_bit_size;
     3493    int pcc = !tcc_state->ms_bitfields;
     3494    int pragma_pack = *tcc_state->pack_stack_ptr;
     3495    Sym *f;
     3496
     3497    maxalign = 1;
     3498    offset = 0;
     3499    c = 0;
     3500    bit_pos = 0;
     3501    prevbt = VT_STRUCT; /* make it never match */
     3502    prev_bit_size = 0;
     3503
     3504//#define BF_DEBUG
     3505
     3506    for (f = type->ref->next; f; f = f->next) {
     3507        if (f->type.t & VT_BITFIELD)
     3508            bit_size = BIT_SIZE(f->type.t);
     3509        else
     3510            bit_size = -1;
     3511        size = type_size(&f->type, &align);
     3512        a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
     3513        packed = 0;
     3514
     3515        if (pcc && bit_size == 0) {
     3516            /* in pcc mode, packing does not affect zero-width bitfields */
     3517
     3518        } else {
     3519            /* in pcc mode, attribute packed overrides if set. */
     3520            if (pcc && (f->a.packed || ad->a.packed))
     3521                align = packed = 1;
     3522
     3523            /* pragma pack overrides align if lesser and packs bitfields always */
     3524            if (pragma_pack) {
     3525                packed = 1;
     3526                if (pragma_pack < align)
     3527                    align = pragma_pack;
     3528                /* in pcc mode pragma pack also overrides individual align */
     3529                if (pcc && pragma_pack < a)
     3530                    a = 0;
     3531            }
     3532        }
     3533        /* some individual align was specified */
     3534        if (a)
     3535            align = a;
     3536
     3537        if (type->ref->type.t == VT_UNION) {
     3538            if (pcc && bit_size >= 0)
     3539                size = (bit_size + 7) >> 3;
     3540            offset = 0;
     3541            if (size > c)
     3542                c = size;
     3543
     3544        } else if (bit_size < 0) {
     3545            if (pcc)
     3546                c += (bit_pos + 7) >> 3;
     3547            c = (c + align - 1) & -align;
     3548            offset = c;
     3549            if (size > 0)
     3550                c += size;
     3551            bit_pos = 0;
     3552            prevbt = VT_STRUCT;
     3553            prev_bit_size = 0;
     3554
     3555        } else {
     3556            /* A bit-field.  Layout is more complicated.  There are two
     3557               options: PCC (GCC) compatible and MS compatible */
     3558            if (pcc) {
     3559                /* In PCC layout a bit-field is placed adjacent to the
     3560                   preceding bit-fields, except if:
     3561                   - it has zero-width
     3562                   - an individual alignment was given
     3563                   - it would overflow its base type container and
     3564                     there is no packing */
     3565                if (bit_size == 0) {
     3566            new_field:
     3567                    c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
     3568                    bit_pos = 0;
     3569                } else if (f->a.aligned) {
     3570                    goto new_field;
     3571                } else if (!packed) {
     3572                    int a8 = align * 8;
     3573                    int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
     3574                    if (ofs > size / align)
     3575                        goto new_field;
     3576                }
     3577
     3578                /* in pcc mode, long long bitfields have type int if they fit */
     3579                if (size == 8 && bit_size <= 32)
     3580                    f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
     3581
     3582                while (bit_pos >= align * 8)
     3583                    c += align, bit_pos -= align * 8;
     3584                offset = c;
     3585
     3586                /* In PCC layout named bit-fields influence the alignment
     3587                   of the containing struct using the base types alignment,
     3588                   except for packed fields (which here have correct align).  */
     3589                if (f->v & SYM_FIRST_ANOM
     3590                    // && bit_size // ??? gcc on ARM/rpi does that
     3591                    )
     3592                    align = 1;
     3593
     3594            } else {
     3595                bt = f->type.t & VT_BTYPE;
     3596                if ((bit_pos + bit_size > size * 8)
     3597                    || (bit_size > 0) == (bt != prevbt)
     3598                    ) {
     3599                    c = (c + align - 1) & -align;
     3600                    offset = c;
     3601                    bit_pos = 0;
     3602                    /* In MS bitfield mode a bit-field run always uses
     3603                       at least as many bits as the underlying type.
     3604                       To start a new run it's also required that this
     3605                       or the last bit-field had non-zero width.  */
     3606                    if (bit_size || prev_bit_size)
     3607                        c += size;
     3608                }
     3609                /* In MS layout the records alignment is normally
     3610                   influenced by the field, except for a zero-width
     3611                   field at the start of a run (but by further zero-width
     3612                   fields it is again).  */
     3613                if (bit_size == 0 && prevbt != bt)
     3614                    align = 1;
     3615                prevbt = bt;
     3616                prev_bit_size = bit_size;
     3617            }
     3618
     3619            f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
     3620                        | (bit_pos << VT_STRUCT_SHIFT);
     3621            bit_pos += bit_size;
     3622        }
     3623        if (align > maxalign)
     3624            maxalign = align;
     3625
     3626#ifdef BF_DEBUG
     3627        printf("set field %s offset %-2d size %-2d align %-2d",
     3628               get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
     3629        if (f->type.t & VT_BITFIELD) {
     3630            printf(" pos %-2d bits %-2d",
     3631                    BIT_POS(f->type.t),
     3632                    BIT_SIZE(f->type.t)
     3633                    );
     3634        }
     3635        printf("\n");
     3636#endif
     3637
     3638        if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
     3639            Sym *ass;
     3640            /* An anonymous struct/union.  Adjust member offsets
     3641               to reflect the real offset of our containing struct.
     3642               Also set the offset of this anon member inside
     3643               the outer struct to be zero.  Via this it
     3644               works when accessing the field offset directly
     3645               (from base object), as well as when recursing
     3646               members in initializer handling.  */
     3647            int v2 = f->type.ref->v;
     3648            if (!(v2 & SYM_FIELD) &&
     3649                (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
     3650                Sym **pps;
     3651                /* This happens only with MS extensions.  The
     3652                   anon member has a named struct type, so it
     3653                   potentially is shared with other references.
     3654                   We need to unshare members so we can modify
     3655                   them.  */
     3656                ass = f->type.ref;
     3657                f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
     3658                                       &f->type.ref->type, 0,
     3659                                       f->type.ref->c);
     3660                pps = &f->type.ref->next;
     3661                while ((ass = ass->next) != NULL) {
     3662                    *pps = sym_push(ass->v, &ass->type, 0, ass->c);
     3663                    pps = &((*pps)->next);
     3664                }
     3665                *pps = NULL;
     3666            }
     3667            struct_add_offset(f->type.ref, offset);
     3668            f->c = 0;
     3669        } else {
     3670            f->c = offset;
     3671        }
     3672
     3673        f->r = 0;
     3674    }
     3675
     3676    if (pcc)
     3677        c += (bit_pos + 7) >> 3;
     3678
     3679    /* store size and alignment */
     3680    a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
     3681    if (a < maxalign)
     3682        a = maxalign;
     3683    type->ref->r = a;
     3684    if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
     3685        /* can happen if individual align for some member was given.  In
     3686           this case MSVC ignores maxalign when aligning the size */
     3687        a = pragma_pack;
     3688        if (a < bt)
     3689            a = bt;
     3690    }
     3691    c = (c + a - 1) & -a;
     3692    type->ref->c = c;
     3693
     3694#ifdef BF_DEBUG
     3695    printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
     3696#endif
     3697
     3698    /* check whether we can access bitfields by their type */
     3699    for (f = type->ref->next; f; f = f->next) {
     3700        int s, px, cx, c0;
     3701        CType t;
     3702
     3703        if (0 == (f->type.t & VT_BITFIELD))
     3704            continue;
     3705        f->type.ref = f;
     3706        f->auxtype = -1;
     3707        bit_size = BIT_SIZE(f->type.t);
     3708        if (bit_size == 0)
     3709            continue;
     3710        bit_pos = BIT_POS(f->type.t);
     3711        size = type_size(&f->type, &align);
     3712        if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
     3713            continue;
     3714
     3715        /* try to access the field using a different type */
     3716        c0 = -1, s = align = 1;
     3717        for (;;) {
     3718            px = f->c * 8 + bit_pos;
     3719            cx = (px >> 3) & -align;
     3720            px = px - (cx << 3);
     3721            if (c0 == cx)
     3722                break;
     3723            s = (px + bit_size + 7) >> 3;
     3724            if (s > 4) {
     3725                t.t = VT_LLONG;
     3726            } else if (s > 2) {
     3727                t.t = VT_INT;
     3728            } else if (s > 1) {
     3729                t.t = VT_SHORT;
     3730            } else {
     3731                t.t = VT_BYTE;
     3732            }
     3733            s = type_size(&t, &align);
     3734            c0 = cx;
     3735        }
     3736
     3737        if (px + bit_size <= s * 8 && cx + s <= c) {
     3738            /* update offset and bit position */
     3739            f->c = cx;
     3740            bit_pos = px;
     3741            f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
     3742                        | (bit_pos << VT_STRUCT_SHIFT);
     3743            if (s != size)
     3744                f->auxtype = t.t;
     3745#ifdef BF_DEBUG
     3746            printf("FIX field %s offset %-2d size %-2d align %-2d "
     3747                "pos %-2d bits %-2d\n",
     3748                get_tok_str(f->v & ~SYM_FIELD, NULL),
     3749                cx, s, align, px, bit_size);
     3750#endif
     3751        } else {
     3752            /* fall back to load/store single-byte wise */
     3753            f->auxtype = VT_STRUCT;
     3754#ifdef BF_DEBUG
     3755            printf("FIX field %s : load byte-wise\n",
     3756                 get_tok_str(f->v & ~SYM_FIELD, NULL));
     3757#endif
     3758        }
     3759    }
     3760}
     3761
     3762/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
    26923763static void struct_decl(CType *type, int u)
    26933764{
    2694     int a, v, size, align, maxalign, c, offset;
    2695     int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
    2696     Sym *s, *ss, *ass, **ps;
    2697     AttributeDef ad;
     3765    int v, c, size, align, flexible;
     3766    int bit_size, bsize, bt;
     3767    Sym *s, *ss, **ps;
     3768    AttributeDef ad, ad1;
    26983769    CType type1, btype;
    26993770
    2700     a = tok; /* save decl type */
     3771    memset(&ad, 0, sizeof ad);
    27013772    next();
     3773    parse_attribute(&ad);
    27023774    if (tok != '{') {
    27033775        v = tok;
     
    27073779            expect("struct/union/enum name");
    27083780        s = struct_find(v);
    2709         if (s) {
    2710             if (s->type.t != a)
    2711                 tcc_error("invalid type");
    2712             goto do_decl;
     3781        if (s && (s->sym_scope == local_scope || tok != '{')) {
     3782            if (u == s->type.t)
     3783                goto do_decl;
     3784            if (u == VT_ENUM && IS_ENUM(s->type.t))
     3785                goto do_decl;
     3786            tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
    27133787        }
    27143788    } else {
    27153789        v = anon_sym++;
    27163790    }
    2717     type1.t = a;
     3791    /* Record the original enum/struct/union token.  */
     3792    type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
     3793    type1.ref = NULL;
    27183794    /* we put an undefined size for struct/union */
    27193795    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
    27203796    s->r = 0; /* default alignment is zero as gcc */
    2721     /* put struct/union/enum name in type */
    2722  do_decl:
    2723     type->t = u;
     3797do_decl:
     3798    type->t = s->type.t;
    27243799    type->ref = s;
    2725    
     3800
    27263801    if (tok == '{') {
    27273802        next();
     
    27293804            tcc_error("struct/union/enum already defined");
    27303805        /* cannot be empty */
    2731         c = 0;
    27323806        /* non empty enums are not allowed */
    2733         if (a == TOK_ENUM) {
     3807        ps = &s->next;
     3808        if (u == VT_ENUM) {
     3809            long long ll = 0, pl = 0, nl = 0;
     3810            CType t;
     3811            t.ref = s;
     3812            /* enum symbols have static storage */
     3813            t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
    27343814            for(;;) {
    27353815                v = tok;
    27363816                if (v < TOK_UIDENT)
    27373817                    expect("identifier");
     3818                ss = sym_find(v);
     3819                if (ss && !local_stack)
     3820                    tcc_error("redefinition of enumerator '%s'",
     3821                              get_tok_str(v, NULL));
    27383822                next();
    27393823                if (tok == '=') {
    27403824                    next();
    2741                     c = expr_const();
     3825                    ll = expr_const64();
    27423826                }
    2743                 /* enum symbols have static storage */
    2744                 ss = sym_push(v, &int_type, VT_CONST, c);
    2745                 ss->type.t |= VT_STATIC;
     3827                ss = sym_push(v, &t, VT_CONST, 0);
     3828                ss->enum_val = ll;
     3829                *ps = ss, ps = &ss->next;
     3830                if (ll < nl)
     3831                    nl = ll;
     3832                if (ll > pl)
     3833                    pl = ll;
    27463834                if (tok != ',')
    27473835                    break;
    27483836                next();
    2749                 c++;
     3837                ll++;
    27503838                /* NOTE: we accept a trailing comma */
    27513839                if (tok == '}')
     
    27533841            }
    27543842            skip('}');
     3843            /* set integral type of the enum */
     3844            t.t = VT_INT;
     3845            if (nl >= 0) {
     3846                if (pl != (unsigned)pl)
     3847                    t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
     3848                t.t |= VT_UNSIGNED;
     3849            } else if (pl != (int)pl || nl != (int)nl)
     3850                t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
     3851            s->type.t = type->t = t.t | VT_ENUM;
     3852            s->c = 0;
     3853            /* set type for enum members */
     3854            for (ss = s->next; ss; ss = ss->next) {
     3855                ll = ss->enum_val;
     3856                if (ll == (int)ll) /* default is int if it fits */
     3857                    continue;
     3858                if (t.t & VT_UNSIGNED) {
     3859                    ss->type.t |= VT_UNSIGNED;
     3860                    if (ll == (unsigned)ll)
     3861                        continue;
     3862                }
     3863                ss->type.t = (ss->type.t & ~VT_BTYPE)
     3864                    | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
     3865            }
    27553866        } else {
    2756             maxalign = 1;
    2757             ps = &s->next;
    2758             prevbt = VT_INT;
    2759             bit_pos = 0;
    2760             offset = 0;
     3867            c = 0;
     3868            flexible = 0;
    27613869            while (tok != '}') {
    2762                 parse_btype(&btype, &ad);
     3870                if (!parse_btype(&btype, &ad1)) {
     3871                    skip(';');
     3872                    continue;
     3873                }
    27633874                while (1) {
     3875                    if (flexible)
     3876                        tcc_error("flexible array member '%s' not at the end of struct",
     3877                              get_tok_str(v, NULL));
    27643878                    bit_size = -1;
    27653879                    v = 0;
    27663880                    type1 = btype;
    27673881                    if (tok != ':') {
    2768                         type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
    2769                         if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
    2770                             expect("identifier");
     3882                        if (tok != ';')
     3883                            type_decl(&type1, &ad1, &v, TYPE_DIRECT);
     3884                        if (v == 0) {
     3885                            if ((type1.t & VT_BTYPE) != VT_STRUCT)
     3886                                expect("identifier");
     3887                            else {
     3888                                int v = btype.ref->v;
     3889                                if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
     3890                                    if (tcc_state->ms_extensions == 0)
     3891                                        expect("identifier");
     3892                                }
     3893                            }
     3894                        }
     3895                        if (type_size(&type1, &align) < 0) {
     3896                            if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
     3897                                flexible = 1;
     3898                            else
     3899                                tcc_error("field '%s' has incomplete type",
     3900                                      get_tok_str(v, NULL));
     3901                        }
    27713902                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
    2772                             (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
     3903                            (type1.t & VT_STORAGE))
    27733904                            tcc_error("invalid type for '%s'",
    27743905                                  get_tok_str(v, NULL));
     
    27843915                            tcc_error("zero width for bit-field '%s'",
    27853916                                  get_tok_str(v, NULL));
     3917                        parse_attribute(&ad1);
    27863918                    }
    27873919                    size = type_size(&type1, &align);
    2788                     if (ad.aligned) {
    2789                         if (align < ad.aligned)
    2790                             align = ad.aligned;
    2791                     } else if (ad.packed) {
    2792                         align = 1;
    2793                     } else if (*tcc_state->pack_stack_ptr) {
    2794                         if (align > *tcc_state->pack_stack_ptr)
    2795                             align = *tcc_state->pack_stack_ptr;
    2796                     }
    2797                     lbit_pos = 0;
    27983920                    if (bit_size >= 0) {
    27993921                        bt = type1.t & VT_BTYPE;
     
    28023924                            bt != VT_SHORT &&
    28033925                            bt != VT_BOOL &&
    2804                             bt != VT_ENUM &&
    28053926                            bt != VT_LLONG)
    28063927                            tcc_error("bitfields must have scalar type");
     
    28093930                            tcc_error("width of '%s' exceeds its type",
    28103931                                  get_tok_str(v, NULL));
    2811                         } else if (bit_size == bsize) {
     3932                        } else if (bit_size == bsize
     3933                                    && !ad.a.packed && !ad1.a.packed) {
    28123934                            /* no need for bit fields */
    2813                             bit_pos = 0;
    2814                         } else if (bit_size == 0) {
    2815                             /* XXX: what to do if only padding in a
    2816                                structure ? */
    2817                             /* zero size: means to pad */
    2818                             bit_pos = 0;
     3935                            ;
     3936                        } else if (bit_size == 64) {
     3937                            tcc_error("field width 64 not implemented");
    28193938                        } else {
    2820                             /* we do not have enough room ?
    2821                                did the type change?
    2822                                is it a union? */
    2823                             if ((bit_pos + bit_size) > bsize ||
    2824                                 bt != prevbt || a == TOK_UNION)
    2825                                 bit_pos = 0;
    2826                             lbit_pos = bit_pos;
    2827                             /* XXX: handle LSB first */
    2828                             type1.t |= VT_BITFIELD |
    2829                                 (bit_pos << VT_STRUCT_SHIFT) |
    2830                                 (bit_size << (VT_STRUCT_SHIFT + 6));
    2831                             bit_pos += bit_size;
     3939                            type1.t = (type1.t & ~VT_STRUCT_MASK)
     3940                                | VT_BITFIELD
     3941                                | (bit_size << (VT_STRUCT_SHIFT + 6));
    28323942                        }
    2833                         prevbt = bt;
    2834                     } else {
    2835                         bit_pos = 0;
    28363943                    }
    28373944                    if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
    2838                         /* add new memory data only if starting
    2839                            bit field */
    2840                         if (lbit_pos == 0) {
    2841                             if (a == TOK_STRUCT) {
    2842                                 c = (c + align - 1) & -align;
    2843                                 offset = c;
    2844                                 if (size > 0)
    2845                                     c += size;
    2846                             } else {
    2847                                 offset = 0;
    2848                                 if (size > c)
    2849                                     c = size;
    2850                             }
    2851                             if (align > maxalign)
    2852                                 maxalign = align;
    2853                         }
    2854 #if 0
    2855                         printf("add field %s offset=%d",
    2856                                get_tok_str(v, NULL), offset);
    2857                         if (type1.t & VT_BITFIELD) {
    2858                             printf(" pos=%d size=%d",
    2859                                    (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
    2860                                    (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
    2861                         }
    2862                         printf("\n");
    2863 #endif
     3945                        /* Remember we've seen a real field to check
     3946                           for placement of flexible array member. */
     3947                        c = 1;
    28643948                    }
    2865                     if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
    2866                         ass = type1.ref;
    2867                         while ((ass = ass->next) != NULL) {
    2868                            ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
    2869                            *ps = ss;
    2870                            ps = &ss->next;
    2871                         }
    2872                     } else if (v) {
    2873                         ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
     3949                    /* If member is a struct or bit-field, enforce
     3950                       placing into the struct (as anonymous).  */
     3951                    if (v == 0 &&
     3952                        ((type1.t & VT_BTYPE) == VT_STRUCT ||
     3953                         bit_size >= 0)) {
     3954                        v = anon_sym++;
     3955                    }
     3956                    if (v) {
     3957                        ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
     3958                        ss->a = ad1.a;
    28743959                        *ps = ss;
    28753960                        ps = &ss->next;
     
    28823967            }
    28833968            skip('}');
    2884             /* store size and alignment */
    2885             s->c = (c + maxalign - 1) & -maxalign;
    2886             s->r = maxalign;
    2887         }
    2888     }
     3969            parse_attribute(&ad);
     3970            struct_layout(type, &ad);
     3971        }
     3972    }
     3973}
     3974
     3975static void sym_to_attr(AttributeDef *ad, Sym *s)
     3976{
     3977    if (s->a.aligned && 0 == ad->a.aligned)
     3978        ad->a.aligned = s->a.aligned;
     3979    if (s->f.func_call && 0 == ad->f.func_call)
     3980        ad->f.func_call = s->f.func_call;
     3981    if (s->f.func_type && 0 == ad->f.func_type)
     3982        ad->f.func_type = s->f.func_type;
     3983    if (s->a.packed)
     3984        ad->a.packed = 1;
     3985}
     3986
     3987/* Add type qualifiers to a type. If the type is an array then the qualifiers
     3988   are added to the element type, copied because it could be a typedef. */
     3989static void parse_btype_qualify(CType *type, int qualifiers)
     3990{
     3991    while (type->t & VT_ARRAY) {
     3992        type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
     3993        type = &type->ref->type;
     3994    }
     3995    type->t |= qualifiers;
    28893996}
    28903997
     
    28944001static int parse_btype(CType *type, AttributeDef *ad)
    28954002{
    2896     int t, u, type_found, typespec_found, typedef_found;
     4003    int t, u, bt, st, type_found, typespec_found, g;
    28974004    Sym *s;
    28984005    CType type1;
     
    29014008    type_found = 0;
    29024009    typespec_found = 0;
    2903     typedef_found = 0;
    2904     t = 0;
     4010    t = VT_INT;
     4011    bt = st = -1;
     4012    type->ref = NULL;
     4013
    29054014    while(1) {
    29064015        switch(tok) {
     
    29164025            next();
    29174026        basic_type1:
    2918             if ((t & VT_BTYPE) != 0)
    2919                 tcc_error("too many basic types");
    2920             t |= u;
     4027            if (u == VT_SHORT || u == VT_LONG) {
     4028                if (st != -1 || (bt != -1 && bt != VT_INT))
     4029                    tmbt: tcc_error("too many basic types");
     4030                st = u;
     4031            } else {
     4032                if (bt != -1 || (st != -1 && u != VT_INT))
     4033                    goto tmbt;
     4034                bt = u;
     4035            }
     4036            if (u != VT_INT)
     4037                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
    29214038            typespec_found = 1;
    29224039            break;
     
    29284045            goto basic_type;
    29294046        case TOK_INT:
    2930             next();
    2931             typespec_found = 1;
    2932             break;
     4047            u = VT_INT;
     4048            goto basic_type;
    29334049        case TOK_LONG:
    2934             next();
    29354050            if ((t & VT_BTYPE) == VT_DOUBLE) {
    2936 #ifndef TCC_TARGET_PE
    2937                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
    2938 #endif
    2939             } else if ((t & VT_BTYPE) == VT_LONG) {
    2940                 t = (t & ~VT_BTYPE) | VT_LLONG;
     4051                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
     4052            } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
     4053                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
    29414054            } else {
    29424055                u = VT_LONG;
    2943                 goto basic_type1;
    2944             }
     4056                goto basic_type;
     4057            }
     4058            next();
    29454059            break;
     4060#ifdef TCC_TARGET_ARM64
     4061        case TOK_UINT128:
     4062            /* GCC's __uint128_t appears in some Linux header files. Make it a
     4063               synonym for long double to get the size and alignment right. */
     4064            u = VT_LDOUBLE;
     4065            goto basic_type;
     4066#endif
    29464067        case TOK_BOOL:
    29474068            u = VT_BOOL;
     
    29514072            goto basic_type;
    29524073        case TOK_DOUBLE:
    2953             next();
    2954             if ((t & VT_BTYPE) == VT_LONG) {
    2955 #ifdef TCC_TARGET_PE
    2956                 t = (t & ~VT_BTYPE) | VT_DOUBLE;
    2957 #else
    2958                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
    2959 #endif
     4074            if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
     4075                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
    29604076            } else {
    29614077                u = VT_DOUBLE;
    2962                 goto basic_type1;
    2963             }
     4078                goto basic_type;
     4079            }
     4080            next();
    29644081            break;
    29654082        case TOK_ENUM:
     
    29704087            goto basic_type1;
    29714088        case TOK_STRUCT:
     4089            struct_decl(&type1, VT_STRUCT);
     4090            goto basic_type2;
    29724091        case TOK_UNION:
    2973             struct_decl(&type1, VT_STRUCT);
     4092            struct_decl(&type1, VT_UNION);
    29744093            goto basic_type2;
    29754094
     
    29784097        case TOK_CONST2:
    29794098        case TOK_CONST3:
    2980             t |= VT_CONSTANT;
     4099            type->t = t;
     4100            parse_btype_qualify(type, VT_CONSTANT);
     4101            t = type->t;
    29814102            next();
    29824103            break;
     
    29844105        case TOK_VOLATILE2:
    29854106        case TOK_VOLATILE3:
    2986             t |= VT_VOLATILE;
     4107            type->t = t;
     4108            parse_btype_qualify(type, VT_VOLATILE);
     4109            t = type->t;
    29874110            next();
    29884111            break;
     
    29904113        case TOK_SIGNED2:
    29914114        case TOK_SIGNED3:
     4115            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
     4116                tcc_error("signed and unsigned modifier");
     4117            t |= VT_DEFSIGN;
     4118            next();
    29924119            typespec_found = 1;
    2993             t |= VT_SIGNED;
    2994             next();
    29954120            break;
    29964121        case TOK_REGISTER:
     
    30024127            break;
    30034128        case TOK_UNSIGNED:
    3004             t |= VT_UNSIGNED;
     4129            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
     4130                tcc_error("signed and unsigned modifier");
     4131            t |= VT_DEFSIGN | VT_UNSIGNED;
    30054132            next();
    30064133            typespec_found = 1;
     
    30094136            /* storage */
    30104137        case TOK_EXTERN:
    3011             t |= VT_EXTERN;
    3012             next();
    3013             break;
     4138            g = VT_EXTERN;
     4139            goto storage;
    30144140        case TOK_STATIC:
    3015             t |= VT_STATIC;
    3016             next();
    3017             break;
     4141            g = VT_STATIC;
     4142            goto storage;
    30184143        case TOK_TYPEDEF:
    3019             t |= VT_TYPEDEF;
     4144            g = VT_TYPEDEF;
     4145            goto storage;
     4146       storage:
     4147            if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
     4148                tcc_error("multiple storage classes");
     4149            t |= g;
    30204150            next();
    30214151            break;
     
    30314161        case TOK_ATTRIBUTE2:
    30324162            parse_attribute(ad);
    3033             if (ad->mode) {
    3034                 u = ad->mode -1;
    3035                 t = (t & ~VT_BTYPE) | u;
     4163            if (ad->attr_mode) {
     4164                u = ad->attr_mode -1;
     4165                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
    30364166            }
    30374167            break;
     
    30444174            /* remove all storage modifiers except typedef */
    30454175            type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
     4176            if (type1.ref)
     4177                sym_to_attr(ad, type1.ref);
    30464178            goto basic_type2;
    30474179        default:
    3048             if (typespec_found || typedef_found)
     4180            if (typespec_found)
    30494181                goto the_end;
    30504182            s = sym_find(tok);
    30514183            if (!s || !(s->type.t & VT_TYPEDEF))
    30524184                goto the_end;
    3053             typedef_found = 1;
    3054             t |= (s->type.t & ~VT_TYPEDEF);
     4185            t &= ~(VT_BTYPE|VT_LONG);
     4186            u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
     4187            type->t = (s->type.t & ~VT_TYPEDEF) | u;
    30554188            type->ref = s->type.ref;
    3056             if (s->r) {
    3057                 /* get attributes from typedef */
    3058                 if (0 == ad->aligned)
    3059                     ad->aligned = FUNC_ALIGN(s->r);
    3060                 if (0 == ad->func_call)
    3061                     ad->func_call = FUNC_CALL(s->r);
    3062                 ad->packed |= FUNC_PACKED(s->r);
    3063             }
     4189            if (t)
     4190                parse_btype_qualify(type, t);
     4191            t = type->t;
     4192            /* get attributes from typedef */
     4193            sym_to_attr(ad, s);
    30644194            next();
    30654195            typespec_found = 1;
     4196            st = bt = -2;
    30664197            break;
    30674198        }
     
    30694200    }
    30704201the_end:
    3071     if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
    3072         tcc_error("signed and unsigned modifier");
    30734202    if (tcc_state->char_is_unsigned) {
    3074         if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
     4203        if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
    30754204            t |= VT_UNSIGNED;
    30764205    }
    3077     t &= ~VT_SIGNED;
    3078 
    3079     /* long is never used as type */
    3080     if ((t & VT_BTYPE) == VT_LONG)
    3081 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
    3082         t = (t & ~VT_BTYPE) | VT_INT;
    3083 #else
    3084         t = (t & ~VT_BTYPE) | VT_LLONG;
     4206    /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
     4207    bt = t & (VT_BTYPE|VT_LONG);
     4208    if (bt == VT_LONG)
     4209        t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
     4210#ifdef TCC_TARGET_PE
     4211    if (bt == VT_LDOUBLE)
     4212        t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
    30854213#endif
    30864214    type->t = t;
     
    31054233{
    31064234    skip('(');
    3107     /* read the string */
    3108     if (tok != TOK_STR)
    3109         expect("string constant");
    3110     cstr_new(astr);
    3111     while (tok == TOK_STR) {
    3112         /* XXX: add \0 handling too ? */
    3113         cstr_cat(astr, tokc.cstr->data);
    3114         next();
    3115     }
    3116     cstr_ccat(astr, '\0');
    3117 }
    3118 
    3119 /* Parse an asm label and return the label
    3120  * Don't forget to free the CString in the caller! */
    3121 static void asm_label_instr(CString *astr)
    3122 {
     4235    parse_mult_str(astr, "string constant");
     4236}
     4237
     4238/* Parse an asm label and return the token */
     4239static int asm_label_instr(void)
     4240{
     4241    int v;
     4242    CString astr;
     4243
    31234244    next();
    3124     parse_asm_str(astr);
     4245    parse_asm_str(&astr);
    31254246    skip(')');
    31264247#ifdef ASM_DEBUG
    3127     printf("asm_alias: \"%s\"\n", (char *)astr->data);
    3128 #endif
    3129 }
    3130 
    3131 static void post_type(CType *type, AttributeDef *ad)
     4248    printf("asm_alias: \"%s\"\n", (char *)astr.data);
     4249#endif
     4250    v = tok_alloc(astr.data, astr.size - 1)->tok;
     4251    cstr_free(&astr);
     4252    return v;
     4253}
     4254
     4255static int post_type(CType *type, AttributeDef *ad, int storage, int td)
    31324256{
    31334257    int n, l, t1, arg_size, align;
     
    31374261
    31384262    if (tok == '(') {
    3139         /* function declaration */
     4263        /* function type, or recursive declarator (return if so) */
    31404264        next();
    3141         l = 0;
     4265        if (td && !(td & TYPE_ABSTRACT))
     4266          return 0;
     4267        if (tok == ')')
     4268          l = 0;
     4269        else if (parse_btype(&pt, &ad1))
     4270          l = FUNC_NEW;
     4271        else if (td)
     4272          return 0;
     4273        else
     4274          l = FUNC_OLD;
    31424275        first = NULL;
    31434276        plast = &first;
    31444277        arg_size = 0;
    3145         if (tok != ')') {
     4278        if (l) {
    31464279            for(;;) {
    31474280                /* read param name and compute offset */
    31484281                if (l != FUNC_OLD) {
    3149                     if (!parse_btype(&pt, &ad1)) {
    3150                         if (l) {
    3151                             tcc_error("invalid type");
    3152                         } else {
    3153                             l = FUNC_OLD;
    3154                             goto old_proto;
    3155                         }
    3156                     }
    3157                     l = FUNC_NEW;
    31584282                    if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
    31594283                        break;
     
    31634287                    arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
    31644288                } else {
    3165                 old_proto:
    31664289                    n = tok;
    31674290                    if (n < TOK_UIDENT)
    31684291                        expect("identifier");
    3169                     pt.t = VT_INT;
     4292                    pt.t = VT_VOID; /* invalid type */
    31704293                    next();
    31714294                }
     
    31824305                    break;
    31834306                }
    3184             }
    3185         }
    3186         /* if no parameters, then old type prototype */
    3187         if (l == 0)
     4307                if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
     4308                    tcc_error("invalid type");
     4309            }
     4310        } else
     4311            /* if no parameters, then old type prototype */
    31884312            l = FUNC_OLD;
    31894313        skip(')');
     
    31974321            next();
    31984322            skip(']'); /* only handle simple "[]" */
    3199             type->t |= VT_PTR;
     4323            mk_pointer(type);
    32004324        }
    32014325        /* we push a anonymous symbol which will contain the function prototype */
    3202         ad->func_args = arg_size;
    3203         s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
     4326        ad->f.func_args = arg_size;
     4327        ad->f.func_type = l;
     4328        s = sym_push(SYM_FIELD, type, 0, 0);
     4329        s->a = ad->a;
     4330        s->f = ad->f;
    32044331        s->next = first;
    32054332        type->t = VT_FUNC;
    32064333        type->ref = s;
    32074334    } else if (tok == '[') {
     4335        int saved_nocode_wanted = nocode_wanted;
    32084336        /* array definition */
    32094337        next();
     
    32134341        t1 = 0;
    32144342        if (tok != ']') {
    3215             if (!local_stack || nocode_wanted)
    3216                  vpushi(expr_const());
    3217             else gexpr();
     4343            if (!local_stack || (storage & VT_STATIC))
     4344                vpushi(expr_const());
     4345            else {
     4346                /* VLAs (which can only happen with local_stack && !VT_STATIC)
     4347                   length must always be evaluated, even under nocode_wanted,
     4348                   so that its size slot is initialized (e.g. under sizeof
     4349                   or typeof).  */
     4350                nocode_wanted = 0;
     4351                gexpr();
     4352            }
    32184353            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    32194354                n = vtop->c.i;
     
    32284363        skip(']');
    32294364        /* parse next post type */
    3230         post_type(type, ad);
     4365        post_type(type, ad, storage, 0);
     4366        if (type->t == VT_FUNC)
     4367            tcc_error("declaration of an array of functions");
    32314368        t1 |= type->t & VT_VLA;
    32324369       
     
    32384375            vla_runtime_type_size(type, &align);
    32394376            gen_op('*');
    3240             vset(&int_type, VT_LOCAL|VT_LVAL, loc);
     4377            vset(&int_type, VT_LOCAL|VT_LVAL, n);
    32414378            vswap();
    32424379            vstore();
     
    32444381        if (n != -1)
    32454382            vpop();
     4383        nocode_wanted = saved_nocode_wanted;
    32464384               
    32474385        /* we push an anonymous symbol which will contain the array
     
    32514389        type->ref = s;
    32524390    }
    3253 }
    3254 
    3255 /* Parse a type declaration (except basic type), and return the type
     4391    return 1;
     4392}
     4393
     4394/* Parse a type declarator (except basic type), and return the type
    32564395   in 'type'. 'td' is a bitmask indicating which kind of type decl is
    32574396   expected. 'type' should contain the basic type. 'ad' is the
    32584397   attribute definition of the basic type. It can be modified by
    3259    type_decl().
    3260  */
    3261 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
    3262 {
    3263     Sym *s;
    3264     CType type1, *type2;
     4398   type_decl().  If this (possibly abstract) declarator is a pointer chain
     4399   it returns the innermost pointed to type (equals *type, but is a different
     4400   pointer), otherwise returns type itself, that's used for recursive calls.  */
     4401static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
     4402{
     4403    CType *post, *ret;
    32654404    int qualifiers, storage;
     4405
     4406    /* recursive type, remove storage bits first, apply them later again */
     4407    storage = type->t & VT_STORAGE;
     4408    type->t &= ~VT_STORAGE;
     4409    post = ret = type;
    32664410
    32674411    while (tok == '*') {
     
    32844428        case TOK_RESTRICT3:
    32854429            goto redo;
     4430        /* XXX: clarify attribute handling */
     4431        case TOK_ATTRIBUTE1:
     4432        case TOK_ATTRIBUTE2:
     4433            parse_attribute(ad);
     4434            break;
    32864435        }
    32874436        mk_pointer(type);
    32884437        type->t |= qualifiers;
    3289     }
    3290    
    3291     /* XXX: clarify attribute handling */
    3292     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
    3293         parse_attribute(ad);
    3294 
    3295     /* recursive type */
    3296     /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
    3297     type1.t = 0; /* XXX: same as int */
     4438        if (ret == type)
     4439            /* innermost pointed to type is the one for the first derivation */
     4440            ret = pointed_type(type);
     4441    }
     4442
    32984443    if (tok == '(') {
    3299         next();
    3300         /* XXX: this is not correct to modify 'ad' at this point, but
    3301            the syntax is not clear */
    3302         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
    3303             parse_attribute(ad);
    3304         type_decl(&type1, ad, v, td);
    3305         skip(')');
     4444        /* This is possibly a parameter type list for abstract declarators
     4445           ('int ()'), use post_type for testing this.  */
     4446        if (!post_type(type, ad, 0, td)) {
     4447            /* It's not, so it's a nested declarator, and the post operations
     4448               apply to the innermost pointed to type (if any).  */
     4449            /* XXX: this is not correct to modify 'ad' at this point, but
     4450               the syntax is not clear */
     4451            parse_attribute(ad);
     4452            post = type_decl(type, ad, v, td);
     4453            skip(')');
     4454        }
     4455    } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
     4456        /* type identifier */
     4457        *v = tok;
     4458        next();
    33064459    } else {
    3307         /* type identifier */
    3308         if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
    3309             *v = tok;
    3310             next();
    3311         } else {
    3312             if (!(td & TYPE_ABSTRACT))
    3313                 expect("identifier");
    3314             *v = 0;
    3315         }
    3316     }
    3317     storage = type->t & VT_STORAGE;
    3318     type->t &= ~VT_STORAGE;
    3319     if (storage & VT_STATIC) {
    3320         int saved_nocode_wanted = nocode_wanted;
    3321         nocode_wanted = 1;
    3322         post_type(type, ad);
    3323         nocode_wanted = saved_nocode_wanted;
    3324     } else
    3325         post_type(type, ad);
     4460        if (!(td & TYPE_ABSTRACT))
     4461          expect("identifier");
     4462        *v = 0;
     4463    }
     4464    post_type(post, ad, storage, 0);
     4465    parse_attribute(ad);
    33264466    type->t |= storage;
    3327     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
    3328         parse_attribute(ad);
    3329    
    3330     if (!type1.t)
    3331         return;
    3332     /* append type at the end of type1 */
    3333     type2 = &type1;
    3334     for(;;) {
    3335         s = type2->ref;
    3336         type2 = &s->type;
    3337         if (!type2->t) {
    3338             *type2 = *type;
    3339             break;
    3340         }
    3341     }
    3342     *type = type1;
     4467    return ret;
    33434468}
    33444469
     
    33684493        expect("pointer");
    33694494    }
    3370     if ((vtop->r & VT_LVAL) && !nocode_wanted)
     4495    if (vtop->r & VT_LVAL)
    33714496        gv(RC_INT);
    33724497    vtop->type = *pointed_type(&vtop->type);
     
    33894514    CType type;
    33904515
    3391     func_type = func->c;
     4516    func_type = func->f.func_type;
    33924517    if (func_type == FUNC_OLD ||
    33934518        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
    33944519        /* default casting : only need to convert float to double */
    33954520        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
    3396             type.t = VT_DOUBLE;
     4521            gen_cast_s(VT_DOUBLE);
     4522        } else if (vtop->type.t & VT_BITFIELD) {
     4523            type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
     4524            type.ref = vtop->type.ref;
    33974525            gen_cast(&type);
    33984526        }
     
    34064534}
    34074535
     4536/* parse an expression and return its type without any side effect. */
     4537static void expr_type(CType *type, void (*expr_fn)(void))
     4538{
     4539    nocode_wanted++;
     4540    expr_fn();
     4541    *type = vtop->type;
     4542    vpop();
     4543    nocode_wanted--;
     4544}
     4545
    34084546/* parse an expression of the form '(type)' or '(expr)' and return its
    34094547   type */
     
    34174555        type_decl(type, &ad, &n, TYPE_ABSTRACT);
    34184556    } else {
    3419         expr_type(type);
     4557        expr_type(type, gexpr);
    34204558    }
    34214559    skip(')');
     
    34334571}
    34344572
    3435 static void vpush_tokc(int t)
    3436 {
    3437     CType type;
    3438     type.t = t;
    3439     type.ref = 0;
    3440     vsetc(&type, VT_CONST, &tokc);
     4573static void parse_builtin_params(int nc, const char *args)
     4574{
     4575    char c, sep = '(';
     4576    CType t;
     4577    if (nc)
     4578        nocode_wanted++;
     4579    next();
     4580    while ((c = *args++)) {
     4581        skip(sep);
     4582        sep = ',';
     4583        switch (c) {
     4584            case 'e': expr_eq(); continue;
     4585            case 't': parse_type(&t); vpush(&t); continue;
     4586            default: tcc_error("internal error"); break;
     4587        }
     4588    }
     4589    skip(')');
     4590    if (nc)
     4591        nocode_wanted--;
    34414592}
    34424593
     
    34474598    Sym *s;
    34484599    AttributeDef ad;
    3449     static int in_sizeof = 0;
    34504600
    34514601    sizeof_caller = in_sizeof;
    34524602    in_sizeof = 0;
     4603    type.ref = NULL;
    34534604    /* XXX: GCC 2.95.3 does not generate a table although it should be
    34544605       better here */
     
    34584609        next();
    34594610        goto tok_next;
     4611    case TOK_LCHAR:
     4612#ifdef TCC_TARGET_PE
     4613        t = VT_SHORT|VT_UNSIGNED;
     4614        goto push_tokc;
     4615#endif
    34604616    case TOK_CINT:
    34614617    case TOK_CCHAR:
    3462     case TOK_LCHAR:
    3463         vpushi(tokc.i);
     4618        t = VT_INT;
     4619 push_tokc:
     4620        type.t = t;
     4621        vsetc(&type, VT_CONST, &tokc);
    34644622        next();
    34654623        break;
    34664624    case TOK_CUINT:
    3467         vpush_tokc(VT_INT | VT_UNSIGNED);
    3468         next();
    3469         break;
     4625        t = VT_INT | VT_UNSIGNED;
     4626        goto push_tokc;
    34704627    case TOK_CLLONG:
    3471         vpush_tokc(VT_LLONG);
    3472         next();
    3473         break;
     4628        t = VT_LLONG;
     4629        goto push_tokc;
    34744630    case TOK_CULLONG:
    3475         vpush_tokc(VT_LLONG | VT_UNSIGNED);
    3476         next();
    3477         break;
     4631        t = VT_LLONG | VT_UNSIGNED;
     4632        goto push_tokc;
    34784633    case TOK_CFLOAT:
    3479         vpush_tokc(VT_FLOAT);
    3480         next();
    3481         break;
     4634        t = VT_FLOAT;
     4635        goto push_tokc;
    34824636    case TOK_CDOUBLE:
    3483         vpush_tokc(VT_DOUBLE);
    3484         next();
    3485         break;
     4637        t = VT_DOUBLE;
     4638        goto push_tokc;
    34864639    case TOK_CLDOUBLE:
    3487         vpush_tokc(VT_LDOUBLE);
    3488         next();
    3489         break;
     4640        t = VT_LDOUBLE;
     4641        goto push_tokc;
     4642    case TOK_CLONG:
     4643        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
     4644        goto push_tokc;
     4645    case TOK_CULONG:
     4646        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
     4647        goto push_tokc;
    34904648    case TOK___FUNCTION__:
    34914649        if (!gnu_ext)
     
    35044662            type.ref->c = len;
    35054663            vpush_ref(&type, data_section, data_section->data_offset, len);
    3506             ptr = section_ptr_add(data_section, len);
    3507             memcpy(ptr, funcname, len);
     4664            if (!NODATA_WANTED) {
     4665                ptr = section_ptr_add(data_section, len);
     4666                memcpy(ptr, funcname, len);
     4667            }
    35084668            next();
    35094669        }
     
    35194679        /* string parsing */
    35204680        t = VT_BYTE;
     4681        if (tcc_state->char_is_unsigned)
     4682            t = VT_BYTE | VT_UNSIGNED;
    35214683    str_init:
    35224684        if (tcc_state->warn_write_strings)
     
    35264688        type.t |= VT_ARRAY;
    35274689        memset(&ad, 0, sizeof(AttributeDef));
    3528         decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
     4690        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
    35294691        break;
    35304692    case '(':
     
    35454707                    r |= lvalue_type(type.t);
    35464708                memset(&ad, 0, sizeof(AttributeDef));
    3547                 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
     4709                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
    35484710            } else {
    35494711                if (sizeof_caller) {
     
    35554717            }
    35564718        } else if (tok == '{') {
     4719            int saved_nocode_wanted = nocode_wanted;
     4720            if (const_wanted)
     4721                tcc_error("expected constant");
    35574722            /* save all registers */
    3558             save_regs(0); 
     4723            save_regs(0);
    35594724            /* statement expression : we do not accept break/continue
    3560                inside as GCC does */
    3561             block(NULL, NULL, NULL, NULL, 0, 1);
     4725               inside as GCC does.  We do retain the nocode_wanted state,
     4726               as statement expressions can't ever be entered from the
     4727               outside, so any reactivation of code emission (from labels
     4728               or loop heads) can be disabled again after the end of it. */
     4729            block(NULL, NULL, 1);
     4730            nocode_wanted = saved_nocode_wanted;
    35624731            skip(')');
    35634732        } else {
     
    35804749        /* arrays can also be used although they are not lvalues */
    35814750        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
    3582             !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
     4751            !(vtop->type.t & VT_ARRAY))
    35834752            test_lvalue();
    35844753        mk_pointer(&vtop->type);
     
    35894758        unary();
    35904759        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    3591             CType boolean;
    3592             boolean.t = VT_BOOL;
    3593             gen_cast(&boolean);
     4760            gen_cast_s(VT_BOOL);
    35944761            vtop->c.i = !vtop->c.i;
    35954762        } else if ((vtop->r & VT_VALMASK) == VT_CMP)
    3596             vtop->c.i = vtop->c.i ^ 1;
     4763            vtop->c.i ^= 1;
    35974764        else {
    35984765            save_regs(1);
    3599             vseti(VT_JMP, gtst(1, 0));
     4766            vseti(VT_JMP, gvtst(1, 0));
    36004767        }
    36014768        break;
     
    36084775    case '+':
    36094776        next();
    3610         /* in order to force cast, we add zero */
    36114777        unary();
    36124778        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
    36134779            tcc_error("pointer not accepted for unary plus");
    3614         vpushi(0);
    3615         gen_op('+');
     4780        /* In order to force cast, we add zero, except for floating point
     4781           where we really need an noop (otherwise -0.0 will be transformed
     4782           into +0.0).  */
     4783        if (!is_float(vtop->type.t)) {
     4784            vpushi(0);
     4785            gen_op('+');
     4786        }
    36164787        break;
    36174788    case TOK_SIZEOF:
     
    36214792        next();
    36224793        in_sizeof++;
    3623         unary_type(&type); // Perform a in_sizeof = 0;
     4794        expr_type(&type, unary); /* Perform a in_sizeof = 0; */
     4795        s = vtop[1].sym; /* hack: accessing previous vtop */
    36244796        size = type_size(&type, &align);
     4797        if (s && s->a.aligned)
     4798            align = 1 << (s->a.aligned - 1);
    36254799        if (t == TOK_SIZEOF) {
    36264800            if (!(type.t & VT_VLA)) {
     
    36374811        break;
    36384812
     4813    case TOK_builtin_expect:
     4814        /* __builtin_expect is a no-op for now */
     4815        parse_builtin_params(0, "ee");
     4816        vpop();
     4817        break;
    36394818    case TOK_builtin_types_compatible_p:
     4819        parse_builtin_params(0, "tt");
     4820        vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
     4821        vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
     4822        n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
     4823        vtop -= 2;
     4824        vpushi(n);
     4825        break;
     4826    case TOK_builtin_choose_expr:
     4827        {
     4828            int64_t c;
     4829            next();
     4830            skip('(');
     4831            c = expr_const64();
     4832            skip(',');
     4833            if (!c) {
     4834                nocode_wanted++;
     4835            }
     4836            expr_eq();
     4837            if (!c) {
     4838                vpop();
     4839                nocode_wanted--;
     4840            }
     4841            skip(',');
     4842            if (c) {
     4843                nocode_wanted++;
     4844            }
     4845            expr_eq();
     4846            if (c) {
     4847                vpop();
     4848                nocode_wanted--;
     4849            }
     4850            skip(')');
     4851        }
     4852        break;
     4853    case TOK_builtin_constant_p:
     4854        parse_builtin_params(1, "e");
     4855        n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
     4856        vtop--;
     4857        vpushi(n);
     4858        break;
     4859    case TOK_builtin_frame_address:
     4860    case TOK_builtin_return_address:
    36404861        {
    3641             CType type1, type2;
     4862            int tok1 = tok;
     4863            int level;
    36424864            next();
    36434865            skip('(');
    3644             parse_type(&type1);
    3645             skip(',');
    3646             parse_type(&type2);
    3647             skip(')');
    3648             type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
    3649             type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
    3650             vpushi(is_compatible_types(&type1, &type2));
    3651         }
    3652         break;
    3653     case TOK_builtin_constant_p:
    3654         {
    3655             int saved_nocode_wanted, res;
    3656             next();
    3657             skip('(');
    3658             saved_nocode_wanted = nocode_wanted;
    3659             nocode_wanted = 1;
    3660             gexpr();
    3661             res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    3662             vpop();
    3663             nocode_wanted = saved_nocode_wanted;
    3664             skip(')');
    3665             vpushi(res);
    3666         }
    3667         break;
    3668     case TOK_builtin_frame_address:
    3669         {
    3670             int level;
    3671             CType type;
    3672             next();
    3673             skip('(');
    3674             if (tok != TOK_CINT || tokc.i < 0) {
    3675                 tcc_error("__builtin_frame_address only takes positive integers");
    3676             }
    3677             level = tokc.i;
     4866            if (tok != TOK_CINT) {
     4867                tcc_error("%s only takes positive integers",
     4868                          tok1 == TOK_builtin_return_address ?
     4869                          "__builtin_return_address" :
     4870                          "__builtin_frame_address");
     4871            }
     4872            level = (uint32_t)tokc.i;
    36784873            next();
    36794874            skip(')');
     
    36854880                indir();                    /* -> parent frame */
    36864881            }
     4882            if (tok1 == TOK_builtin_return_address) {
     4883                // assume return address is just above frame pointer on stack
     4884                vpushi(PTR_SIZE);
     4885                gen_op('+');
     4886                mk_pointer(&vtop->type);
     4887                indir();
     4888            }
    36874889        }
    36884890        break;
    36894891#ifdef TCC_TARGET_X86_64
     4892#ifdef TCC_TARGET_PE
     4893    case TOK_builtin_va_start:
     4894        parse_builtin_params(0, "ee");
     4895        r = vtop->r & VT_VALMASK;
     4896        if (r == VT_LLOCAL)
     4897            r = VT_LOCAL;
     4898        if (r != VT_LOCAL)
     4899            tcc_error("__builtin_va_start expects a local variable");
     4900        vtop->r = r;
     4901        vtop->type = char_pointer_type;
     4902        vtop->c.i += 8;
     4903        vstore();
     4904        break;
     4905#else
    36904906    case TOK_builtin_va_arg_types:
    3691         {
    3692             /* This definition must be synced with stdarg.h */
    3693             enum __va_arg_type {
    3694                 __va_gen_reg, __va_float_reg, __va_stack
    3695             };
    3696             CType type;
    3697             int bt;
    3698             next();
    3699             skip('(');
    3700             parse_type(&type);
    3701             skip(')');
    3702             bt = type.t & VT_BTYPE;
    3703             if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
    3704                 vpushi(__va_stack);
    3705             } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
    3706                 vpushi(__va_float_reg);
    3707             } else {
    3708                 vpushi(__va_gen_reg);
    3709             }
    3710         }
     4907        parse_builtin_params(0, "t");
     4908        vpushi(classify_x86_64_va_arg(&vtop->type));
     4909        vswap();
     4910        vpop();
    37114911        break;
    37124912#endif
     4913#endif
     4914
     4915#ifdef TCC_TARGET_ARM64
     4916    case TOK___va_start: {
     4917        parse_builtin_params(0, "ee");
     4918        //xx check types
     4919        gen_va_start();
     4920        vpushi(0);
     4921        vtop->type.t = VT_VOID;
     4922        break;
     4923    }
     4924    case TOK___va_arg: {
     4925        parse_builtin_params(0, "et");
     4926        type = vtop->type;
     4927        vpop();
     4928        //xx check types
     4929        gen_va_arg(&type);
     4930        vtop->type = type;
     4931        break;
     4932    }
     4933    case TOK___arm64_clear_cache: {
     4934        parse_builtin_params(0, "ee");
     4935        gen_clear_cache();
     4936        vpushi(0);
     4937        vtop->type.t = VT_VOID;
     4938        break;
     4939    }
     4940#endif
     4941    /* pre operations */
    37134942    case TOK_INC:
    37144943    case TOK_DEC:
     
    37204949    case '-':
    37214950        next();
    3722         vpushi(0);
    37234951        unary();
    3724         gen_op('-');
     4952        t = vtop->type.t & VT_BTYPE;
     4953        if (is_float(t)) {
     4954            /* In IEEE negate(x) isn't subtract(0,x), but rather
     4955               subtract(-0, x).  */
     4956            vpush(&vtop->type);
     4957            if (t == VT_FLOAT)
     4958                vtop->c.f = -1.0 * 0.0;
     4959            else if (t == VT_DOUBLE)
     4960                vtop->c.d = -1.0 * 0.0;
     4961            else
     4962                vtop->c.ld = -1.0 * 0.0;
     4963        } else
     4964            vpushi(0);
     4965        vswap();
     4966        gen_op('-');
    37254967        break;
    37264968    case TOK_LAND:
     
    37434985            s->type.t |= VT_STATIC;
    37444986        }
    3745         vset(&s->type, VT_CONST | VT_SYM, 0);
    3746         vtop->sym = s;
     4987        vpushsym(&s->type, s);
    37474988        next();
    37484989        break;
    3749    
     4990
     4991    case TOK_GENERIC:
     4992    {
     4993        CType controlling_type;
     4994        int has_default = 0;
     4995        int has_match = 0;
     4996        int learn = 0;
     4997        TokenString *str = NULL;
     4998
     4999        next();
     5000        skip('(');
     5001        expr_type(&controlling_type, expr_eq);
     5002        controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
     5003        for (;;) {
     5004            learn = 0;
     5005            skip(',');
     5006            if (tok == TOK_DEFAULT) {
     5007                if (has_default)
     5008                    tcc_error("too many 'default'");
     5009                has_default = 1;
     5010                if (!has_match)
     5011                    learn = 1;
     5012                next();
     5013            } else {
     5014                AttributeDef ad_tmp;
     5015                int itmp;
     5016                CType cur_type;
     5017                parse_btype(&cur_type, &ad_tmp);
     5018                type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
     5019                if (compare_types(&controlling_type, &cur_type, 0)) {
     5020                    if (has_match) {
     5021                      tcc_error("type match twice");
     5022                    }
     5023                    has_match = 1;
     5024                    learn = 1;
     5025                }
     5026            }
     5027            skip(':');
     5028            if (learn) {
     5029                if (str)
     5030                    tok_str_free(str);
     5031                skip_or_save_block(&str);
     5032            } else {
     5033                skip_or_save_block(NULL);
     5034            }
     5035            if (tok == ')')
     5036                break;
     5037        }
     5038        if (!str) {
     5039            char buf[60];
     5040            type_to_str(buf, sizeof buf, &controlling_type, NULL);
     5041            tcc_error("type '%s' does not match any association", buf);
     5042        }
     5043        begin_macro(str, 1);
     5044        next();
     5045        expr_eq();
     5046        if (tok != TOK_EOF)
     5047            expect(",");
     5048        end_macro();
     5049        next();
     5050        break;
     5051    }
    37505052    // special qnan , snan and infinity values
    37515053    case TOK___NAN__:
     
    37695071            expect("identifier");
    37705072        s = sym_find(t);
    3771         if (!s) {
     5073        if (!s || IS_ASM_SYM(s)) {
     5074            const char *name = get_tok_str(t, NULL);
    37725075            if (tok != '(')
    3773                 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
     5076                tcc_error("'%s' undeclared", name);
    37745077            /* for simple function calls, we tolerate undeclared
    37755078               external reference to int() function */
    3776             if (tcc_state->warn_implicit_function_declaration)
    3777                 tcc_warning("implicit declaration of function '%s'",
    3778                         get_tok_str(t, NULL));
     5079            if (tcc_state->warn_implicit_function_declaration
     5080#ifdef TCC_TARGET_PE
     5081                /* people must be warned about using undeclared WINAPI functions
     5082                   (which usually start with uppercase letter) */
     5083                || (name[0] >= 'A' && name[0] <= 'Z')
     5084#endif
     5085            )
     5086                tcc_warning("implicit declaration of function '%s'", name);
    37795087            s = external_global_sym(t, &func_old_type, 0);
    37805088        }
    3781         if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
    3782             (VT_STATIC | VT_INLINE | VT_FUNC)) {
    3783             /* if referencing an inline function, then we generate a
    3784                symbol to it if not already done. It will have the
    3785                effect to generate code for it at the end of the
    3786                compilation unit. Inline function as always
    3787                generated in the text section. */
    3788             if (!s->c)
    3789                 put_extern_sym(s, text_section, 0, 0);
    3790             r = VT_SYM | VT_CONST;
    3791         } else {
    3792             r = s->r;
    3793         }
     5089
     5090        r = s->r;
     5091        /* A symbol that has a register is a local register variable,
     5092           which starts out as VT_LOCAL value.  */
     5093        if ((r & VT_VALMASK) < VT_CONST)
     5094            r = (r & ~VT_VALMASK) | VT_LOCAL;
     5095
    37945096        vset(&s->type, r, s->c);
    3795         /* if forward reference, we must point to s */
    3796         if (vtop->r & VT_SYM) {
    3797             vtop->sym = s;
    3798             vtop->c.ul = 0;
     5097        /* Point to s as backpointer (even without r&VT_SYM).
     5098           Will be used by at least the x86 inline asm parser for
     5099           regvars.  */
     5100        vtop->sym = s;
     5101
     5102        if (r & VT_SYM) {
     5103            vtop->c.i = 0;
     5104        } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
     5105            vtop->c.i = s->enum_val;
    37995106        }
    38005107        break;
     
    38065113            inc(1, tok);
    38075114            next();
    3808         } else if (tok == '.' || tok == TOK_ARROW) {
     5115        } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
    38095116            int qualifiers;
    38105117            /* field */
     
    38145121            test_lvalue();
    38155122            gaddrof();
    3816             next();
    38175123            /* expect pointer on structure */
    38185124            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
    38195125                expect("struct or union");
    3820             s = vtop->type.ref;
    3821             /* find field */
    3822             tok |= SYM_FIELD;
    3823             while ((s = s->next) != NULL) {
    3824                 if (s->v == tok)
    3825                     break;
    3826             }
     5126            if (tok == TOK_CDOUBLE)
     5127                expect("field name");
     5128            next();
     5129            if (tok == TOK_CINT || tok == TOK_CUINT)
     5130                expect("field name");
     5131            s = find_field(&vtop->type, tok);
    38275132            if (!s)
    3828                 tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, NULL));
     5133                tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, &tokc));
    38295134            /* add field offset to pointer */
    38305135            vtop->type = char_pointer_type; /* change type to 'char *' */
     
    38395144#ifdef CONFIG_TCC_BCHECK
    38405145                /* if bound checking, the referenced pointer must be checked */
    3841                 if (tcc_state->do_bounds_check)
     5146                if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
    38425147                    vtop->r |= VT_MUSTBOUND;
    38435148#endif
     
    38535158            SValue ret;
    38545159            Sym *sa;
    3855             int nb_args;
     5160            int nb_args, ret_nregs, ret_align, regsize, variadic;
    38565161
    38575162            /* function call  */
     
    38735178            next();
    38745179            sa = s->next; /* first parameter */
    3875             nb_args = 0;
     5180            nb_args = regsize = 0;
    38765181            ret.r2 = VT_CONST;
    38775182            /* compute first implicit argument if a structure is returned */
    38785183            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
    3879                 /* get some space for the returned structure */
    3880                 size = type_size(&s->type, &align);
    3881                 loc = (loc - size) & -align;
     5184                variadic = (s->f.func_type == FUNC_ELLIPSIS);
     5185                ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
     5186                                       &ret_align, &regsize);
     5187                if (!ret_nregs) {
     5188                    /* get some space for the returned structure */
     5189                    size = type_size(&s->type, &align);
     5190#ifdef TCC_TARGET_ARM64
     5191                /* On arm64, a small struct is return in registers.
     5192                   It is much easier to write it to memory if we know
     5193                   that we are allowed to write some extra bytes, so
     5194                   round the allocated space up to a power of 2: */
     5195                if (size < 16)
     5196                    while (size & (size - 1))
     5197                        size = (size | (size - 1)) + 1;
     5198#endif
     5199                    loc = (loc - size) & -align;
     5200                    ret.type = s->type;
     5201                    ret.r = VT_LOCAL | VT_LVAL;
     5202                    /* pass it as 'int' to avoid structure arg passing
     5203                       problems */
     5204                    vseti(VT_LOCAL, loc);
     5205                    ret.c = vtop->c;
     5206                    nb_args++;
     5207                }
     5208            } else {
     5209                ret_nregs = 1;
    38825210                ret.type = s->type;
    3883                 ret.r = VT_LOCAL | VT_LVAL;
    3884                 /* pass it as 'int' to avoid structure arg passing
    3885                    problems */
    3886                 vseti(VT_LOCAL, loc);
    3887                 ret.c = vtop->c;
    3888                 nb_args++;
    3889             } else {
    3890                 ret.type = s->type;
     5211            }
     5212
     5213            if (ret_nregs) {
    38915214                /* return in register */
    38925215                if (is_float(ret.type.t)) {
    38935216                    ret.r = reg_fret(ret.type.t);
     5217#ifdef TCC_TARGET_X86_64
     5218                    if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
     5219                      ret.r2 = REG_QRET;
     5220#endif
    38945221                } else {
     5222#ifndef TCC_TARGET_ARM64
     5223#ifdef TCC_TARGET_X86_64
     5224                    if ((ret.type.t & VT_BTYPE) == VT_QLONG)
     5225#else
    38955226                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
     5227#endif
    38965228                        ret.r2 = REG_LRET;
     5229#endif
    38975230                    ret.r = REG_IRET;
    38985231                }
     
    39145247                tcc_error("too few arguments to function");
    39155248            skip(')');
    3916             if (!nocode_wanted) {
    3917                 gfunc_call(nb_args);
    3918             } else {
    3919                 vtop -= (nb_args + 1);
    3920             }
     5249            gfunc_call(nb_args);
     5250
    39215251            /* return value */
    3922             vsetc(&ret.type, ret.r, &ret.c);
    3923             vtop->r2 = ret.r2;
     5252            for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
     5253                vsetc(&ret.type, r, &ret.c);
     5254                vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
     5255            }
     5256
     5257            /* handle packed struct return */
     5258            if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
     5259                int addr, offset;
     5260
     5261                size = type_size(&s->type, &align);
     5262                /* We're writing whole regs often, make sure there's enough
     5263                   space.  Assume register size is power of 2.  */
     5264                if (regsize > align)
     5265                  align = regsize;
     5266                loc = (loc - size) & -align;
     5267                addr = loc;
     5268                offset = 0;
     5269                for (;;) {
     5270                    vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
     5271                    vswap();
     5272                    vstore();
     5273                    vtop--;
     5274                    if (--ret_nregs == 0)
     5275                        break;
     5276                    offset += regsize;
     5277                }
     5278                vset(&s->type, VT_LOCAL | VT_LVAL, addr);
     5279            }
    39245280        } else {
    39255281            break;
     
    40245380}
    40255381
    4026 /* XXX: fix this mess */
    4027 static void expr_land_const(void)
    4028 {
    4029     expr_or();
    4030     while (tok == TOK_LAND) {
    4031         next();
    4032         expr_or();
    4033         gen_op(TOK_LAND);
    4034     }
    4035 }
    4036 
    4037 /* XXX: fix this mess */
    4038 static void expr_lor_const(void)
    4039 {
    4040     expr_land_const();
    4041     while (tok == TOK_LOR) {
    4042         next();
    4043         expr_land_const();
    4044         gen_op(TOK_LOR);
    4045     }
    4046 }
    4047 
    4048 /* only used if non constant */
    40495382static void expr_land(void)
    40505383{
    4051     int t;
    4052 
    40535384    expr_or();
    40545385    if (tok == TOK_LAND) {
    4055         t = 0;
    4056         save_regs(1);
    4057         for(;;) {
    4058             t = gtst(1, t);
    4059             if (tok != TOK_LAND) {
    4060                 vseti(VT_JMPI, t);
    4061                 break;
    4062             }
    4063             next();
    4064             expr_or();
    4065         }
     5386        int t = 0;
     5387        for(;;) {
     5388            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
     5389                gen_cast_s(VT_BOOL);
     5390                if (vtop->c.i) {
     5391                    vpop();
     5392                } else {
     5393                    nocode_wanted++;
     5394                    while (tok == TOK_LAND) {
     5395                        next();
     5396                        expr_or();
     5397                        vpop();
     5398                    }
     5399                    nocode_wanted--;
     5400                    if (t)
     5401                      gsym(t);
     5402                    gen_cast_s(VT_INT);
     5403                    break;
     5404                }
     5405            } else {
     5406                if (!t)
     5407                  save_regs(1);
     5408                t = gvtst(1, t);
     5409            }
     5410            if (tok != TOK_LAND) {
     5411                if (t)
     5412                  vseti(VT_JMPI, t);
     5413                else
     5414                  vpushi(1);
     5415                break;
     5416            }
     5417            next();
     5418            expr_or();
     5419        }
    40665420    }
    40675421}
     
    40695423static void expr_lor(void)
    40705424{
    4071     int t;
    4072 
    40735425    expr_land();
    40745426    if (tok == TOK_LOR) {
    4075         t = 0;
    4076         save_regs(1);
    4077         for(;;) {
    4078             t = gtst(0, t);
    4079             if (tok != TOK_LOR) {
    4080                 vseti(VT_JMP, t);
    4081                 break;
    4082             }
    4083             next();
    4084             expr_land();
    4085         }
    4086     }
    4087 }
    4088 
    4089 /* XXX: better constant handling */
     5427        int t = 0;
     5428        for(;;) {
     5429            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
     5430                gen_cast_s(VT_BOOL);
     5431                if (!vtop->c.i) {
     5432                    vpop();
     5433                } else {
     5434                    nocode_wanted++;
     5435                    while (tok == TOK_LOR) {
     5436                        next();
     5437                        expr_land();
     5438                        vpop();
     5439                    }
     5440                    nocode_wanted--;
     5441                    if (t)
     5442                      gsym(t);
     5443                    gen_cast_s(VT_INT);
     5444                    break;
     5445                }
     5446            } else {
     5447                if (!t)
     5448                  save_regs(1);
     5449                t = gvtst(0, t);
     5450            }
     5451            if (tok != TOK_LOR) {
     5452                if (t)
     5453                  vseti(VT_JMP, t);
     5454                else
     5455                  vpushi(0);
     5456                break;
     5457            }
     5458            next();
     5459            expr_land();
     5460        }
     5461    }
     5462}
     5463
     5464/* Assuming vtop is a value used in a conditional context
     5465   (i.e. compared with zero) return 0 if it's false, 1 if
     5466   true and -1 if it can't be statically determined.  */
     5467static int condition_3way(void)
     5468{
     5469    int c = -1;
     5470    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
     5471        (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
     5472        vdup();
     5473        gen_cast_s(VT_BOOL);
     5474        c = vtop->c.i;
     5475        vpop();
     5476    }
     5477    return c;
     5478}
     5479
    40905480static void expr_cond(void)
    40915481{
    4092     int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
     5482    int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
    40935483    SValue sv;
    40945484    CType type, type1, type2;
    40955485
    4096     if (const_wanted) {
    4097         expr_lor_const();
    4098         if (tok == '?') {
    4099             CType boolean;
    4100             int c;
    4101             boolean.t = VT_BOOL;
    4102             vdup();
    4103             gen_cast(&boolean);
    4104             c = vtop->c.i;
    4105             vpop();
    4106             next();
    4107             if (tok != ':' || !gnu_ext) {
     5486    expr_lor();
     5487    if (tok == '?') {
     5488        next();
     5489        c = condition_3way();
     5490        g = (tok == ':' && gnu_ext);
     5491        if (c < 0) {
     5492            /* needed to avoid having different registers saved in
     5493               each branch */
     5494            if (is_float(vtop->type.t)) {
     5495                rc = RC_FLOAT;
     5496#ifdef TCC_TARGET_X86_64
     5497                if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
     5498                    rc = RC_ST0;
     5499                }
     5500#endif
     5501            } else
     5502                rc = RC_INT;
     5503            gv(rc);
     5504            save_regs(1);
     5505            if (g)
     5506                gv_dup();
     5507            tt = gvtst(1, 0);
     5508
     5509        } else {
     5510            if (!g)
    41085511                vpop();
     5512            tt = 0;
     5513        }
     5514
     5515        if (1) {
     5516            if (c == 0)
     5517                nocode_wanted++;
     5518            if (!g)
    41095519                gexpr();
    4110             }
    4111             if (!c)
    4112                 vpop();
    4113             skip(':');
    4114             expr_cond();
    4115             if (c)
    4116                 vpop();
    4117         }
    4118     } else {
    4119         expr_lor();
    4120         if (tok == '?') {
    4121             next();
    4122             if (vtop != vstack) {
    4123                 /* needed to avoid having different registers saved in
    4124                    each branch */
    4125                 if (is_float(vtop->type.t)) {
    4126                     rc = RC_FLOAT;
    4127 #ifdef TCC_TARGET_X86_64
    4128                     if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
    4129                         rc = RC_ST0;
    4130                     }
    4131 #endif
    4132                 }
    4133                 else
    4134                     rc = RC_INT;
    4135                     gv(rc);
    4136                     save_regs(1);
    4137             }
    4138             if (tok == ':' && gnu_ext) {
    4139                 gv_dup();
    4140                 tt = gtst(1, 0);
    4141             } else {
    4142                 tt = gtst(1, 0);
    4143                 gexpr();
    4144             }
     5520
    41455521            type1 = vtop->type;
    41465522            sv = *vtop; /* save value to handle it later */
    41475523            vtop--; /* no vpop so that FP stack is not flushed */
    41485524            skip(':');
    4149             u = gjmp(0);
     5525
     5526            u = 0;
     5527            if (c < 0)
     5528                u = gjmp(0);
    41505529            gsym(tt);
     5530
     5531            if (c == 0)
     5532                nocode_wanted--;
     5533            if (c == 1)
     5534                nocode_wanted++;
    41515535            expr_cond();
     5536            if (c == 1)
     5537                nocode_wanted--;
     5538
    41525539            type2 = vtop->type;
    4153 
    41545540            t1 = type1.t;
    41555541            bt1 = t1 & VT_BTYPE;
    41565542            t2 = type2.t;
    41575543            bt2 = t2 & VT_BTYPE;
     5544            type.ref = NULL;
     5545
    41585546            /* cast operands to correct type according to ISOC rules */
    41595547            if (is_float(bt1) || is_float(bt2)) {
    41605548                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
    41615549                    type.t = VT_LDOUBLE;
     5550
    41625551                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
    41635552                    type.t = VT_DOUBLE;
     
    41675556            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
    41685557                /* cast to biggest op */
    4169                 type.t = VT_LLONG;
     5558                type.t = VT_LLONG | VT_LONG;
     5559                if (bt1 == VT_LLONG)
     5560                    type.t &= t1;
     5561                if (bt2 == VT_LLONG)
     5562                    type.t &= t2;
    41705563                /* convert to unsigned if it does not fit in a long long */
    4171                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
    4172                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
     5564                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
     5565                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
    41735566                    type.t |= VT_UNSIGNED;
    41745567            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
     
    41945587            } else {
    41955588                /* integer operations */
    4196                 type.t = VT_INT;
     5589                type.t = VT_INT | (VT_LONG & (t1 | t2));
    41975590                /* convert to unsigned if it does not fit in an integer */
    4198                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
    4199                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
     5591                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
     5592                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
    42005593                    type.t |= VT_UNSIGNED;
    42015594            }
    4202                
     5595            /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
     5596               that `(expr ? a : b).mem` does not error  with "lvalue expected" */
     5597            islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
     5598            islv &= c < 0;
     5599
    42035600            /* now we convert second operand */
    4204             gen_cast(&type);
    4205             if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
    4206                 gaddrof();
     5601            if (c != 1) {
     5602                gen_cast(&type);
     5603                if (islv) {
     5604                    mk_pointer(&vtop->type);
     5605                    gaddrof();
     5606                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
     5607                    gaddrof();
     5608            }
     5609
    42075610            rc = RC_INT;
    42085611            if (is_float(type.t)) {
     
    42165619                /* for long longs, we use fixed registers to avoid having
    42175620                   to handle a complicated move */
    4218                 rc = RC_IRET;
    4219             }
    4220            
    4221             r2 = gv(rc);
     5621                rc = RC_IRET;
     5622            }
     5623
     5624            tt = r2 = 0;
     5625            if (c < 0) {
     5626                r2 = gv(rc);
     5627                tt = gjmp(0);
     5628            }
     5629            gsym(u);
     5630
    42225631            /* this is horrible, but we must also convert first
    42235632               operand */
    4224             tt = gjmp(0);
    4225             gsym(u);
    4226             /* put again first value and cast it */
    4227             *vtop = sv;
    4228             gen_cast(&type);
    4229             if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
    4230                 gaddrof();
    4231             r1 = gv(rc);
    4232             move_reg(r2, r1);
    4233             vtop->r = r2;
    4234             gsym(tt);
     5633            if (c != 0) {
     5634                *vtop = sv;
     5635                gen_cast(&type);
     5636                if (islv) {
     5637                    mk_pointer(&vtop->type);
     5638                    gaddrof();
     5639                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
     5640                    gaddrof();
     5641            }
     5642
     5643            if (c < 0) {
     5644                r1 = gv(rc);
     5645                move_reg(r2, r1, type.t);
     5646                vtop->r = r2;
     5647                gsym(tt);
     5648                if (islv)
     5649                    indir();
     5650            }
    42355651        }
    42365652    }
     
    42715687}
    42725688
    4273 /* parse an expression and return its type without any side effect. */
    4274 static void expr_type(CType *type)
    4275 {
    4276     int saved_nocode_wanted;
    4277 
    4278     saved_nocode_wanted = nocode_wanted;
    4279     nocode_wanted = 1;
    4280     gexpr();
    4281     *type = vtop->type;
    4282     vpop();
    4283     nocode_wanted = saved_nocode_wanted;
    4284 }
    4285 
    4286 /* parse a unary expression and return its type without any side
    4287    effect. */
    4288 static void unary_type(CType *type)
    4289 {
    4290     int a;
    4291 
    4292     a = nocode_wanted;
    4293     nocode_wanted = 1;
    4294     unary();
    4295     *type = vtop->type;
    4296     vpop();
    4297     nocode_wanted = a;
    4298 }
    4299 
    43005689/* parse a constant expression and return value in vtop.  */
    43015690static void expr_const1(void)
    43025691{
    4303     int a;
    4304     a = const_wanted;
    4305     const_wanted = 1;
     5692    const_wanted++;
     5693    nocode_wanted++;
    43065694    expr_cond();
    4307     const_wanted = a;
     5695    nocode_wanted--;
     5696    const_wanted--;
    43085697}
    43095698
    43105699/* parse an integer constant and return its value. */
    4311 ST_FUNC int expr_const(void)
    4312 {
    4313     int c;
     5700static inline int64_t expr_const64(void)
     5701{
     5702    int64_t c;
    43145703    expr_const1();
    43155704    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
     
    43175706    c = vtop->c.i;
    43185707    vpop();
     5708    return c;
     5709}
     5710
     5711/* parse an integer constant and return its value.
     5712   Complain if it doesn't fit 32bit (signed or unsigned).  */
     5713ST_FUNC int expr_const(void)
     5714{
     5715    int c;
     5716    int64_t wc = expr_const64();
     5717    c = wc;
     5718    if (c != wc && (unsigned)c != wc)
     5719        tcc_error("constant exceeds 32 bit");
    43195720    return c;
    43205721}
     
    43335734    next();
    43345735    if (tok == ':') {
    4335         next();
    43365736        return last_tok;
    43375737    } else {
     
    43415741}
    43425742
    4343 static void label_or_decl(int l)
    4344 {
    4345     int last_tok;
    4346 
    4347     /* fast test first */
    4348     if (tok >= TOK_UIDENT)
    4349       {
    4350         /* no need to save tokc because tok is an identifier */
    4351         last_tok = tok;
    4352         next();
    4353         if (tok == ':') {
    4354             unget_tok(last_tok);
    4355             return;
    4356         }
    4357         unget_tok(last_tok);
    4358       }
    4359     decl(l);
    4360 }
    4361 
    4362 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
    4363                   int case_reg, int is_expr)
    4364 {
    4365     int a, b, c, d;
    4366     Sym *s, *frame_bottom;
     5743#ifndef TCC_TARGET_ARM64
     5744static void gfunc_return(CType *func_type)
     5745{
     5746    if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
     5747        CType type, ret_type;
     5748        int ret_align, ret_nregs, regsize;
     5749        ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
     5750                               &ret_align, &regsize);
     5751        if (0 == ret_nregs) {
     5752            /* if returning structure, must copy it to implicit
     5753               first pointer arg location */
     5754            type = *func_type;
     5755            mk_pointer(&type);
     5756            vset(&type, VT_LOCAL | VT_LVAL, func_vc);
     5757            indir();
     5758            vswap();
     5759            /* copy structure value to pointer */
     5760            vstore();
     5761        } else {
     5762            /* returning structure packed into registers */
     5763            int r, size, addr, align;
     5764            size = type_size(func_type,&align);
     5765            if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
     5766                 (vtop->c.i & (ret_align-1)))
     5767                && (align & (ret_align-1))) {
     5768                loc = (loc - size) & -ret_align;
     5769                addr = loc;
     5770                type = *func_type;
     5771                vset(&type, VT_LOCAL | VT_LVAL, addr);
     5772                vswap();
     5773                vstore();
     5774                vpop();
     5775                vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
     5776            }
     5777            vtop->type = ret_type;
     5778            if (is_float(ret_type.t))
     5779                r = rc_fret(ret_type.t);
     5780            else
     5781                r = RC_IRET;
     5782
     5783            if (ret_nregs == 1)
     5784                gv(r);
     5785            else {
     5786                for (;;) {
     5787                    vdup();
     5788                    gv(r);
     5789                    vpop();
     5790                    if (--ret_nregs == 0)
     5791                      break;
     5792                    /* We assume that when a structure is returned in multiple
     5793                       registers, their classes are consecutive values of the
     5794                       suite s(n) = 2^n */
     5795                    r <<= 1;
     5796                    vtop->c.i += regsize;
     5797                }
     5798            }
     5799        }
     5800    } else if (is_float(func_type->t)) {
     5801        gv(rc_fret(func_type->t));
     5802    } else {
     5803        gv(RC_IRET);
     5804    }
     5805    vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
     5806}
     5807#endif
     5808
     5809static int case_cmp(const void *pa, const void *pb)
     5810{
     5811    int64_t a = (*(struct case_t**) pa)->v1;
     5812    int64_t b = (*(struct case_t**) pb)->v1;
     5813    return a < b ? -1 : a > b;
     5814}
     5815
     5816static void gcase(struct case_t **base, int len, int *bsym)
     5817{
     5818    struct case_t *p;
     5819    int e;
     5820    int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
     5821    gv(RC_INT);
     5822    while (len > 4) {
     5823        /* binary search */
     5824        p = base[len/2];
     5825        vdup();
     5826        if (ll)
     5827            vpushll(p->v2);
     5828        else
     5829            vpushi(p->v2);
     5830        gen_op(TOK_LE);
     5831        e = gtst(1, 0);
     5832        vdup();
     5833        if (ll)
     5834            vpushll(p->v1);
     5835        else
     5836            vpushi(p->v1);
     5837        gen_op(TOK_GE);
     5838        gtst_addr(0, p->sym); /* v1 <= x <= v2 */
     5839        /* x < v1 */
     5840        gcase(base, len/2, bsym);
     5841        if (cur_switch->def_sym)
     5842            gjmp_addr(cur_switch->def_sym);
     5843        else
     5844            *bsym = gjmp(*bsym);
     5845        /* x > v2 */
     5846        gsym(e);
     5847        e = len/2 + 1;
     5848        base += e; len -= e;
     5849    }
     5850    /* linear scan */
     5851    while (len--) {
     5852        p = *base++;
     5853        vdup();
     5854        if (ll)
     5855            vpushll(p->v2);
     5856        else
     5857            vpushi(p->v2);
     5858        if (p->v1 == p->v2) {
     5859            gen_op(TOK_EQ);
     5860            gtst_addr(0, p->sym);
     5861        } else {
     5862            gen_op(TOK_LE);
     5863            e = gtst(1, 0);
     5864            vdup();
     5865            if (ll)
     5866                vpushll(p->v1);
     5867            else
     5868                vpushi(p->v1);
     5869            gen_op(TOK_GE);
     5870            gtst_addr(0, p->sym);
     5871            gsym(e);
     5872        }
     5873    }
     5874}
     5875
     5876static void block(int *bsym, int *csym, int is_expr)
     5877{
     5878    int a, b, c, d, cond;
     5879    Sym *s;
    43675880
    43685881    /* generate line number info */
    4369     if (tcc_state->do_debug &&
    4370         (last_line_num != file->line_num || last_ind != ind)) {
    4371         put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
    4372         last_ind = ind;
    4373         last_line_num = file->line_num;
    4374     }
     5882    if (tcc_state->do_debug)
     5883        tcc_debug_line(tcc_state);
    43755884
    43765885    if (is_expr) {
     
    43825891    if (tok == TOK_IF) {
    43835892        /* if test */
     5893        int saved_nocode_wanted = nocode_wanted;
    43845894        next();
    43855895        skip('(');
    43865896        gexpr();
    43875897        skip(')');
    4388         a = gtst(1, 0);
    4389         block(bsym, csym, case_sym, def_sym, case_reg, 0);
     5898        cond = condition_3way();
     5899        if (cond == 1)
     5900            a = 0, vpop();
     5901        else
     5902            a = gvtst(1, 0);
     5903        if (cond == 0)
     5904            nocode_wanted |= 0x20000000;
     5905        block(bsym, csym, 0);
     5906        if (cond != 1)
     5907            nocode_wanted = saved_nocode_wanted;
    43905908        c = tok;
    43915909        if (c == TOK_ELSE) {
     
    43935911            d = gjmp(0);
    43945912            gsym(a);
    4395             block(bsym, csym, case_sym, def_sym, case_reg, 0);
     5913            if (cond == 1)
     5914                nocode_wanted |= 0x20000000;
     5915            block(bsym, csym, 0);
    43965916            gsym(d); /* patch else jmp */
     5917            if (cond != 0)
     5918                nocode_wanted = saved_nocode_wanted;
    43975919        } else
    43985920            gsym(a);
    43995921    } else if (tok == TOK_WHILE) {
     5922        int saved_nocode_wanted;
     5923        nocode_wanted &= ~0x20000000;
    44005924        next();
    44015925        d = ind;
     5926        vla_sp_restore();
    44025927        skip('(');
    44035928        gexpr();
    44045929        skip(')');
    4405         a = gtst(1, 0);
     5930        a = gvtst(1, 0);
    44065931        b = 0;
    4407         block(&a, &b, case_sym, def_sym, case_reg, 0);
     5932        ++local_scope;
     5933        saved_nocode_wanted = nocode_wanted;
     5934        block(&a, &b, 0);
     5935        nocode_wanted = saved_nocode_wanted;
     5936        --local_scope;
    44085937        gjmp_addr(d);
    44095938        gsym(a);
     
    44115940    } else if (tok == '{') {
    44125941        Sym *llabel;
    4413        
     5942        int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
     5943
    44145944        next();
    44155945        /* record local declaration stack position */
    44165946        s = local_stack;
    4417         frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
    4418         frame_bottom->next = scope_stack_bottom;
    4419         scope_stack_bottom = frame_bottom;
    44205947        llabel = local_label_stack;
     5948        ++local_scope;
     5949       
    44215950        /* handle local labels declarations */
    44225951        if (tok == TOK_LABEL) {
     
    44365965        }
    44375966        while (tok != '}') {
    4438             label_or_decl(VT_LOCAL);
     5967            if ((a = is_label()))
     5968                unget_tok(a);
     5969            else
     5970                decl(VT_LOCAL);
    44395971            if (tok != '}') {
    44405972                if (is_expr)
    44415973                    vpop();
    4442                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
     5974                block(bsym, csym, is_expr);
    44435975            }
    44445976        }
    44455977        /* pop locally defined labels */
    4446         label_pop(&local_label_stack, llabel);
    4447         if(is_expr) {
    4448             /* XXX: this solution makes only valgrind happy...
    4449                triggered by gcc.c-torture/execute/20000917-1.c */
    4450             Sym *p;
    4451             switch(vtop->type.t & VT_BTYPE) {
    4452             case VT_PTR:
    4453             case VT_STRUCT:
    4454             case VT_ENUM:
    4455             case VT_FUNC:
    4456                 for(p=vtop->type.ref;p;p=p->prev)
    4457                     if(p->prev==s)
    4458                         tcc_error("unsupported expression type");
    4459             }
    4460         }
     5978        label_pop(&local_label_stack, llabel, is_expr);
    44615979        /* pop locally defined symbols */
    4462         scope_stack_bottom = scope_stack_bottom->next;
    4463         sym_pop(&local_stack, s);
     5980        --local_scope;
     5981        /* In the is_expr case (a statement expression is finished here),
     5982           vtop might refer to symbols on the local_stack.  Either via the
     5983           type or via vtop->sym.  We can't pop those nor any that in turn
     5984           might be referred to.  To make it easier we don't roll back
     5985           any symbols in that case; some upper level call to block() will
     5986           do that.  We do have to remove such symbols from the lookup
     5987           tables, though.  sym_pop will do that.  */
     5988        sym_pop(&local_stack, s, is_expr);
     5989
     5990        /* Pop VLA frames and restore stack pointer if required */
     5991        if (vlas_in_scope > saved_vlas_in_scope) {
     5992            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
     5993            vla_sp_restore();
     5994        }
     5995        vlas_in_scope = saved_vlas_in_scope;
     5996       
    44645997        next();
    44655998    } else if (tok == TOK_RETURN) {
     
    44686001            gexpr();
    44696002            gen_assign_cast(&func_vt);
    4470             if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
    4471                 CType type;
    4472                 /* if returning structure, must copy it to implicit
    4473                    first pointer arg location */
    4474 #ifdef TCC_ARM_EABI
    4475                 int align, size;
    4476                 size = type_size(&func_vt,&align);
    4477                 if(size <= 4)
    4478                 {
    4479                     if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
    4480                        && (align & 3))
    4481                     {
    4482                         int addr;
    4483                         loc = (loc - size) & -4;
    4484                         addr = loc;
    4485                         type = func_vt;
    4486                         vset(&type, VT_LOCAL | VT_LVAL, addr);
    4487                         vswap();
    4488                         vstore();
    4489                         vset(&int_type, VT_LOCAL | VT_LVAL, addr);
    4490                     }
    4491                     vtop->type = int_type;
    4492                     gv(RC_IRET);
    4493                 } else {
    4494 #endif
    4495                 type = func_vt;
    4496                 mk_pointer(&type);
    4497                 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
    4498                 indir();
    4499                 vswap();
    4500                 /* copy structure value to pointer */
    4501                 vstore();
    4502 #ifdef TCC_ARM_EABI
    4503                 }
    4504 #endif
    4505             } else if (is_float(func_vt.t)) {
    4506                 gv(rc_fret(func_vt.t));
    4507             } else {
    4508                 gv(RC_IRET);
    4509             }
    4510             vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
     6003            if ((func_vt.t & VT_BTYPE) == VT_VOID)
     6004                vtop--;
     6005            else
     6006                gfunc_return(&func_vt);
    45116007        }
    45126008        skip(';');
    4513         rsym = gjmp(rsym); /* jmp */
     6009        /* jump unless last stmt in top-level block */
     6010        if (tok != '}' || local_scope != 1)
     6011            rsym = gjmp(rsym);
     6012        nocode_wanted |= 0x20000000;
    45146013    } else if (tok == TOK_BREAK) {
    45156014        /* compute jump */
     
    45196018        next();
    45206019        skip(';');
     6020        nocode_wanted |= 0x20000000;
    45216021    } else if (tok == TOK_CONTINUE) {
    45226022        /* compute jump */
    45236023        if (!csym)
    45246024            tcc_error("cannot continue");
     6025        vla_sp_restore_root();
    45256026        *csym = gjmp(*csym);
    45266027        next();
     
    45286029    } else if (tok == TOK_FOR) {
    45296030        int e;
     6031        int saved_nocode_wanted;
     6032        nocode_wanted &= ~0x20000000;
    45306033        next();
    45316034        skip('(');
    45326035        s = local_stack;
    4533         frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
    4534         frame_bottom->next = scope_stack_bottom;
    4535         scope_stack_bottom = frame_bottom;
     6036        ++local_scope;
    45366037        if (tok != ';') {
    45376038            /* c99 for-loop init decl? */
    4538             if (!decl0(VT_LOCAL, 1)) {
     6039            if (!decl0(VT_LOCAL, 1, NULL)) {
    45396040                /* no, regular for-loop init expr */
    45406041                gexpr();
     
    45456046        d = ind;
    45466047        c = ind;
     6048        vla_sp_restore();
    45476049        a = 0;
    45486050        b = 0;
    45496051        if (tok != ';') {
    45506052            gexpr();
    4551             a = gtst(1, 0);
     6053            a = gvtst(1, 0);
    45526054        }
    45536055        skip(';');
     
    45556057            e = gjmp(0);
    45566058            c = ind;
     6059            vla_sp_restore();
    45576060            gexpr();
    45586061            vpop();
     
    45616064        }
    45626065        skip(')');
    4563         block(&a, &b, case_sym, def_sym, case_reg, 0);
     6066        saved_nocode_wanted = nocode_wanted;
     6067        block(&a, &b, 0);
     6068        nocode_wanted = saved_nocode_wanted;
    45646069        gjmp_addr(c);
    45656070        gsym(a);
    45666071        gsym_addr(b, c);
    4567         scope_stack_bottom = scope_stack_bottom->next;
    4568         sym_pop(&local_stack, s);
     6072        --local_scope;
     6073        sym_pop(&local_stack, s, 0);
     6074
    45696075    } else
    45706076    if (tok == TOK_DO) {
     6077        int saved_nocode_wanted;
     6078        nocode_wanted &= ~0x20000000;
    45716079        next();
    45726080        a = 0;
    45736081        b = 0;
    45746082        d = ind;
    4575         block(&a, &b, case_sym, def_sym, case_reg, 0);
     6083        vla_sp_restore();
     6084        saved_nocode_wanted = nocode_wanted;
     6085        block(&a, &b, 0);
    45766086        skip(TOK_WHILE);
    45776087        skip('(');
    45786088        gsym(b);
    4579         gexpr();
    4580         c = gtst(0, 0);
    4581         gsym_addr(c, d);
     6089        gexpr();
     6090        c = gvtst(0, 0);
     6091        gsym_addr(c, d);
     6092        nocode_wanted = saved_nocode_wanted;
    45826093        skip(')');
    45836094        gsym(a);
     
    45856096    } else
    45866097    if (tok == TOK_SWITCH) {
     6098        struct switch_t *saved, sw;
     6099        int saved_nocode_wanted = nocode_wanted;
     6100        SValue switchval;
    45876101        next();
    45886102        skip('(');
    45896103        gexpr();
    4590         /* XXX: other types than integer */
    4591         case_reg = gv(RC_INT);
    4592         vpop();
    45936104        skip(')');
     6105        switchval = *vtop--;
    45946106        a = 0;
    45956107        b = gjmp(0); /* jump to first case */
    4596         c = 0;
    4597         block(&a, csym, &b, &c, case_reg, 0);
    4598         /* if no default, jmp after switch */
    4599         if (c == 0)
    4600             c = ind;
    4601         /* default label */
    4602         gsym_addr(b, c);
     6108        sw.p = NULL; sw.n = 0; sw.def_sym = 0;
     6109        saved = cur_switch;
     6110        cur_switch = &sw;
     6111        block(&a, csym, 0);
     6112        nocode_wanted = saved_nocode_wanted;
     6113        a = gjmp(a); /* add implicit break */
     6114        /* case lookup */
     6115        gsym(b);
     6116        qsort(sw.p, sw.n, sizeof(void*), case_cmp);
     6117        for (b = 1; b < sw.n; b++)
     6118            if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
     6119                tcc_error("duplicate case value");
     6120        /* Our switch table sorting is signed, so the compared
     6121           value needs to be as well when it's 64bit.  */
     6122        if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
     6123            switchval.type.t &= ~VT_UNSIGNED;
     6124        vpushv(&switchval);
     6125        gcase(sw.p, sw.n, &a);
     6126        vpop();
     6127        if (sw.def_sym)
     6128          gjmp_addr(sw.def_sym);
     6129        dynarray_reset(&sw.p, &sw.n);
     6130        cur_switch = saved;
    46036131        /* break label */
    46046132        gsym(a);
    46056133    } else
    46066134    if (tok == TOK_CASE) {
    4607         int v1, v2;
    4608         if (!case_sym)
     6135        struct case_t *cr = tcc_malloc(sizeof(struct case_t));
     6136        if (!cur_switch)
    46096137            expect("switch");
     6138        nocode_wanted &= ~0x20000000;
    46106139        next();
    4611         v1 = expr_const();
    4612         v2 = v1;
     6140        cr->v1 = cr->v2 = expr_const64();
    46136141        if (gnu_ext && tok == TOK_DOTS) {
    46146142            next();
    4615             v2 = expr_const();
    4616             if (v2 < v1)
     6143            cr->v2 = expr_const64();
     6144            if (cr->v2 < cr->v1)
    46176145                tcc_warning("empty case range");
    46186146        }
    4619         /* since a case is like a label, we must skip it with a jmp */
    4620         b = gjmp(0);
    4621         gsym(*case_sym);
    4622         vseti(case_reg, 0);
    4623         vpushi(v1);
    4624         if (v1 == v2) {
    4625             gen_op(TOK_EQ);
    4626             *case_sym = gtst(1, 0);
    4627         } else {
    4628             gen_op(TOK_GE);
    4629             *case_sym = gtst(1, 0);
    4630             vseti(case_reg, 0);
    4631             vpushi(v2);
    4632             gen_op(TOK_LE);
    4633             *case_sym = gtst(1, *case_sym);
    4634         }
    4635         gsym(b);
     6147        cr->sym = ind;
     6148        dynarray_add(&cur_switch->p, &cur_switch->n, cr);
    46366149        skip(':');
    46376150        is_expr = 0;
     
    46416154        next();
    46426155        skip(':');
    4643         if (!def_sym)
     6156        if (!cur_switch)
    46446157            expect("switch");
    4645         if (*def_sym)
     6158        if (cur_switch->def_sym)
    46466159            tcc_error("too many 'default'");
    4647         *def_sym = ind;
     6160        cur_switch->def_sym = ind;
    46486161        is_expr = 0;
    46496162        goto block_after_label;
     
    46676180                    s->r = LABEL_FORWARD;
    46686181            }
    4669             /* label already defined */
    4670             if (s->r & LABEL_FORWARD)
     6182            vla_sp_restore_root();
     6183            if (s->r & LABEL_FORWARD)
    46716184                s->jnext = gjmp(s->jnext);
    46726185            else
     
    46836196        if (b) {
    46846197            /* label case */
     6198            next();
    46856199            s = label_find(b);
    46866200            if (s) {
     
    46936207            }
    46946208            s->jnext = ind;
     6209            vla_sp_restore();
    46956210            /* we accept this, but it is a mistake */
    46966211        block_after_label:
     6212            nocode_wanted &= ~0x20000000;
    46976213            if (tok == '}') {
    46986214                tcc_warning("deprecated use of label at end of compound statement");
     
    47006216                if (is_expr)
    47016217                    vpop();
    4702                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
     6218                block(bsym, csym, is_expr);
    47036219            }
    47046220        } else {
     
    47186234}
    47196235
    4720 /* t is the array or struct type. c is the array or struct
    4721    address. cur_index/cur_field is the pointer to the current
    4722    value. 'size_only' is true if only size info is needed (only used
    4723    in arrays) */
    4724 static void decl_designator(CType *type, Section *sec, unsigned long c,
    4725                             int *cur_index, Sym **cur_field,
    4726                             int size_only)
    4727 {
    4728     Sym *s, *f;
    4729     int notfirst, index, index_last, align, l, nb_elems, elem_size;
    4730     CType type1;
    4731 
    4732     notfirst = 0;
    4733     elem_size = 0;
    4734     nb_elems = 1;
    4735     if (gnu_ext && (l = is_label()) != 0)
    4736         goto struct_field;
    4737     while (tok == '[' || tok == '.') {
    4738         if (tok == '[') {
    4739             if (!(type->t & VT_ARRAY))
    4740                 expect("array type");
    4741             s = type->ref;
    4742             next();
    4743             index = expr_const();
    4744             if (index < 0 || (s->c >= 0 && index >= s->c))
    4745                 expect("invalid index");
    4746             if (tok == TOK_DOTS && gnu_ext) {
    4747                 next();
    4748                 index_last = expr_const();
    4749                 if (index_last < 0 ||
    4750                     (s->c >= 0 && index_last >= s->c) ||
    4751                     index_last < index)
    4752                     expect("invalid index");
    4753             } else {
    4754                 index_last = index;
    4755             }
    4756             skip(']');
    4757             if (!notfirst)
    4758                 *cur_index = index_last;
    4759             type = pointed_type(type);
    4760             elem_size = type_size(type, &align);
    4761             c += index * elem_size;
    4762             /* NOTE: we only support ranges for last designator */
    4763             nb_elems = index_last - index + 1;
    4764             if (nb_elems != 1) {
    4765                 notfirst = 1;
    4766                 break;
    4767             }
    4768         } else {
    4769             next();
    4770             l = tok;
    4771             next();
    4772         struct_field:
    4773             if ((type->t & VT_BTYPE) != VT_STRUCT)
    4774                 expect("struct/union type");
    4775             s = type->ref;
    4776             l |= SYM_FIELD;
    4777             f = s->next;
    4778             while (f) {
    4779                 if (f->v == l)
    4780                     break;
    4781                 f = f->next;
    4782             }
    4783             if (!f)
    4784                 expect("field");
    4785             if (!notfirst)
    4786                 *cur_field = f;
    4787             /* XXX: fix this mess by using explicit storage field */
    4788             type1 = f->type;
    4789             type1.t |= (type->t & ~VT_TYPE);
    4790             type = &type1;
    4791             c += f->c;
    4792         }
    4793         notfirst = 1;
    4794     }
    4795     if (notfirst) {
    4796         if (tok == '=') {
    4797             next();
    4798         } else {
    4799             if (!gnu_ext)
    4800                 expect("=");
    4801         }
    4802     } else {
    4803         if (type->t & VT_ARRAY) {
    4804             index = *cur_index;
    4805             type = pointed_type(type);
    4806             c += index * type_size(type, &align);
    4807         } else {
    4808             f = *cur_field;
    4809             if (!f)
    4810                 tcc_error("too many field init");
    4811             /* XXX: fix this mess by using explicit storage field */
    4812             type1 = f->type;
    4813             type1.t |= (type->t & ~VT_TYPE);
    4814             type = &type1;
    4815             c += f->c;
    4816         }
    4817     }
    4818     decl_initializer(type, sec, c, 0, size_only);
    4819 
    4820     /* XXX: make it more general */
    4821     if (!size_only && nb_elems > 1) {
    4822         unsigned long c_end;
    4823         uint8_t *src, *dst;
    4824         int i;
    4825 
    4826         if (!sec)
    4827             tcc_error("range init not supported yet for dynamic storage");
    4828         c_end = c + nb_elems * elem_size;
    4829         if (c_end > sec->data_allocated)
    4830             section_realloc(sec, c_end);
    4831         src = sec->data + c;
    4832         dst = src;
    4833         for(i = 1; i < nb_elems; i++) {
    4834             dst += elem_size;
    4835             memcpy(dst, src, elem_size);
    4836         }
    4837     }
    4838 }
    4839 
    4840 #define EXPR_VAL   0
     6236/* This skips over a stream of tokens containing balanced {} and ()
     6237   pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
     6238   with a '{').  If STR then allocates and stores the skipped tokens
     6239   in *STR.  This doesn't check if () and {} are nested correctly,
     6240   i.e. "({)}" is accepted.  */
     6241static void skip_or_save_block(TokenString **str)
     6242{
     6243    int braces = tok == '{';
     6244    int level = 0;
     6245    if (str)
     6246      *str = tok_str_alloc();
     6247
     6248    while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
     6249        int t;
     6250        if (tok == TOK_EOF) {
     6251             if (str || level > 0)
     6252               tcc_error("unexpected end of file");
     6253             else
     6254               break;
     6255        }
     6256        if (str)
     6257          tok_str_add_tok(*str);
     6258        t = tok;
     6259        next();
     6260        if (t == '{' || t == '(') {
     6261            level++;
     6262        } else if (t == '}' || t == ')') {
     6263            level--;
     6264            if (level == 0 && braces && t == '}')
     6265              break;
     6266        }
     6267    }
     6268    if (str) {
     6269        tok_str_add(*str, -1);
     6270        tok_str_add(*str, 0);
     6271    }
     6272}
     6273
    48416274#define EXPR_CONST 1
    48426275#define EXPR_ANY   2
    48436276
    4844 /* store a value or an expression directly in global data or in local array */
    4845 static void init_putv(CType *type, Section *sec, unsigned long c,
    4846                       int v, int expr_type)
    4847 {
    4848     int saved_global_expr, bt, bit_pos, bit_size;
    4849     void *ptr;
    4850     unsigned long long bit_mask;
    4851     CType dtype;
    4852 
     6277static void parse_init_elem(int expr_type)
     6278{
     6279    int saved_global_expr;
    48536280    switch(expr_type) {
    4854     case EXPR_VAL:
    4855         vpushi(v);
    4856         break;
    48576281    case EXPR_CONST:
    48586282        /* compound literals must be allocated globally in this case */
     
    48616285        expr_const1();
    48626286        global_expr = saved_global_expr;
    4863         /* NOTE: symbols are accepted */
    4864         if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
     6287        /* NOTE: symbols are accepted, as well as lvalue for anon symbols
     6288           (compound literals).  */
     6289        if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
     6290             && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
     6291                 || vtop->sym->v < SYM_FIRST_ANOM))
     6292#ifdef TCC_TARGET_PE
     6293                 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
     6294#endif
     6295            )
    48656296            tcc_error("initializer element is not constant");
    48666297        break;
     
    48696300        break;
    48706301    }
    4871    
     6302}
     6303
     6304/* put zeros for variable based init */
     6305static void init_putz(Section *sec, unsigned long c, int size)
     6306{
     6307    if (sec) {
     6308        /* nothing to do because globals are already set to zero */
     6309    } else {
     6310        vpush_global_sym(&func_old_type, TOK_memset);
     6311        vseti(VT_LOCAL, c);
     6312#ifdef TCC_TARGET_ARM
     6313        vpushs(size);
     6314        vpushi(0);
     6315#else
     6316        vpushi(0);
     6317        vpushs(size);
     6318#endif
     6319        gfunc_call(3);
     6320    }
     6321}
     6322
     6323/* t is the array or struct type. c is the array or struct
     6324   address. cur_field is the pointer to the current
     6325   field, for arrays the 'c' member contains the current start
     6326   index.  'size_only' is true if only size info is needed (only used
     6327   in arrays).  al contains the already initialized length of the
     6328   current container (starting at c).  This returns the new length of that.  */
     6329static int decl_designator(CType *type, Section *sec, unsigned long c,
     6330                           Sym **cur_field, int size_only, int al)
     6331{
     6332    Sym *s, *f;
     6333    int index, index_last, align, l, nb_elems, elem_size;
     6334    unsigned long corig = c;
     6335
     6336    elem_size = 0;
     6337    nb_elems = 1;
     6338    if (gnu_ext && (l = is_label()) != 0)
     6339        goto struct_field;
     6340    /* NOTE: we only support ranges for last designator */
     6341    while (nb_elems == 1 && (tok == '[' || tok == '.')) {
     6342        if (tok == '[') {
     6343            if (!(type->t & VT_ARRAY))
     6344                expect("array type");
     6345            next();
     6346            index = index_last = expr_const();
     6347            if (tok == TOK_DOTS && gnu_ext) {
     6348                next();
     6349                index_last = expr_const();
     6350            }
     6351            skip(']');
     6352            s = type->ref;
     6353            if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
     6354                index_last < index)
     6355                tcc_error("invalid index");
     6356            if (cur_field)
     6357                (*cur_field)->c = index_last;
     6358            type = pointed_type(type);
     6359            elem_size = type_size(type, &align);
     6360            c += index * elem_size;
     6361            nb_elems = index_last - index + 1;
     6362        } else {
     6363            next();
     6364            l = tok;
     6365        struct_field:
     6366            next();
     6367            if ((type->t & VT_BTYPE) != VT_STRUCT)
     6368                expect("struct/union type");
     6369            f = find_field(type, l);
     6370            if (!f)
     6371                expect("field");
     6372            if (cur_field)
     6373                *cur_field = f;
     6374            type = &f->type;
     6375            c += f->c;
     6376        }
     6377        cur_field = NULL;
     6378    }
     6379    if (!cur_field) {
     6380        if (tok == '=') {
     6381            next();
     6382        } else if (!gnu_ext) {
     6383            expect("=");
     6384        }
     6385    } else {
     6386        if (type->t & VT_ARRAY) {
     6387            index = (*cur_field)->c;
     6388            if (type->ref->c >= 0 && index >= type->ref->c)
     6389                tcc_error("index too large");
     6390            type = pointed_type(type);
     6391            c += index * type_size(type, &align);
     6392        } else {
     6393            f = *cur_field;
     6394            while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
     6395                *cur_field = f = f->next;
     6396            if (!f)
     6397                tcc_error("too many field init");
     6398            type = &f->type;
     6399            c += f->c;
     6400        }
     6401    }
     6402    /* must put zero in holes (note that doing it that way
     6403       ensures that it even works with designators) */
     6404    if (!size_only && c - corig > al)
     6405        init_putz(sec, corig + al, c - corig - al);
     6406    decl_initializer(type, sec, c, 0, size_only);
     6407
     6408    /* XXX: make it more general */
     6409    if (!size_only && nb_elems > 1) {
     6410        unsigned long c_end;
     6411        uint8_t *src, *dst;
     6412        int i;
     6413
     6414        if (!sec) {
     6415            vset(type, VT_LOCAL|VT_LVAL, c);
     6416            for (i = 1; i < nb_elems; i++) {
     6417                vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
     6418                vswap();
     6419                vstore();
     6420            }
     6421            vpop();
     6422        } else if (!NODATA_WANTED) {
     6423            c_end = c + nb_elems * elem_size;
     6424            if (c_end > sec->data_allocated)
     6425                section_realloc(sec, c_end);
     6426            src = sec->data + c;
     6427            dst = src;
     6428            for(i = 1; i < nb_elems; i++) {
     6429                dst += elem_size;
     6430                memcpy(dst, src, elem_size);
     6431            }
     6432        }
     6433    }
     6434    c += nb_elems * type_size(type, &align);
     6435    if (c - corig > al)
     6436      al = c - corig;
     6437    return al;
     6438}
     6439
     6440/* store a value or an expression directly in global data or in local array */
     6441static void init_putv(CType *type, Section *sec, unsigned long c)
     6442{
     6443    int bt;
     6444    void *ptr;
     6445    CType dtype;
     6446
    48726447    dtype = *type;
    48736448    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
    48746449
    48756450    if (sec) {
     6451        int size, align;
    48766452        /* XXX: not portable */
    48776453        /* XXX: generate error if incorrect relocation */
    48786454        gen_assign_cast(&dtype);
    48796455        bt = type->t & VT_BTYPE;
    4880         /* we'll write at most 12 bytes */
    4881         if (c + 12 > sec->data_allocated) {
    4882             section_realloc(sec, c + 12);
    4883         }
     6456
     6457        if ((vtop->r & VT_SYM)
     6458            && bt != VT_PTR
     6459            && bt != VT_FUNC
     6460            && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
     6461                || (type->t & VT_BITFIELD))
     6462            && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
     6463            )
     6464            tcc_error("initializer element is not computable at load time");
     6465
     6466        if (NODATA_WANTED) {
     6467            vtop--;
     6468            return;
     6469        }
     6470
     6471        size = type_size(type, &align);
     6472        section_reserve(sec, c + size);
    48846473        ptr = sec->data + c;
     6474
    48856475        /* XXX: make code faster ? */
    4886         if (!(type->t & VT_BITFIELD)) {
    4887             bit_pos = 0;
    4888             bit_size = 32;
    4889             bit_mask = -1LL;
    4890         } else {
    4891             bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    4892             bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
    4893             bit_mask = (1LL << bit_size) - 1;
    4894         }
    4895         if ((vtop->r & VT_SYM) &&
    4896             (bt == VT_BYTE ||
    4897              bt == VT_SHORT ||
    4898              bt == VT_DOUBLE ||
    4899              bt == VT_LDOUBLE ||
    4900              bt == VT_LLONG ||
    4901              (bt == VT_INT && bit_size != 32)))
    4902             tcc_error("initializer element is not computable at load time");
    4903         switch(bt) {
    4904         case VT_BOOL:
    4905             vtop->c.i = (vtop->c.i != 0);
    4906         case VT_BYTE:
    4907             *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
    4908             break;
    4909         case VT_SHORT:
    4910             *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
    4911             break;
    4912         case VT_DOUBLE:
    4913             *(double *)ptr = vtop->c.d;
    4914             break;
    4915         case VT_LDOUBLE:
    4916             *(long double *)ptr = vtop->c.ld;
    4917             break;
    4918         case VT_LLONG:
    4919             *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
    4920             break;
    4921         default:
    4922             if (vtop->r & VT_SYM) {
    4923                 greloc(sec, vtop->sym, c, R_DATA_PTR);
    4924             }
    4925             *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
    4926             break;
    4927         }
     6476        if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
     6477            vtop->sym->v >= SYM_FIRST_ANOM &&
     6478            /* XXX This rejects compound literals like
     6479               '(void *){ptr}'.  The problem is that '&sym' is
     6480               represented the same way, which would be ruled out
     6481               by the SYM_FIRST_ANOM check above, but also '"string"'
     6482               in 'char *p = "string"' is represented the same
     6483               with the type being VT_PTR and the symbol being an
     6484               anonymous one.  That is, there's no difference in vtop
     6485               between '(void *){x}' and '&(void *){x}'.  Ignore
     6486               pointer typed entities here.  Hopefully no real code
     6487               will every use compound literals with scalar type.  */
     6488            (vtop->type.t & VT_BTYPE) != VT_PTR) {
     6489            /* These come from compound literals, memcpy stuff over.  */
     6490            Section *ssec;
     6491            ElfSym *esym;
     6492            ElfW_Rel *rel;
     6493            esym = elfsym(vtop->sym);
     6494            ssec = tcc_state->sections[esym->st_shndx];
     6495            memmove (ptr, ssec->data + esym->st_value, size);
     6496            if (ssec->reloc) {
     6497                /* We need to copy over all memory contents, and that
     6498                   includes relocations.  Use the fact that relocs are
     6499                   created it order, so look from the end of relocs
     6500                   until we hit one before the copied region.  */
     6501                int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
     6502                rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
     6503                while (num_relocs--) {
     6504                    rel--;
     6505                    if (rel->r_offset >= esym->st_value + size)
     6506                      continue;
     6507                    if (rel->r_offset < esym->st_value)
     6508                      break;
     6509                    /* Note: if the same fields are initialized multiple
     6510                       times (possible with designators) then we possibly
     6511                       add multiple relocations for the same offset here.
     6512                       That would lead to wrong code, the last reloc needs
     6513                       to win.  We clean this up later after the whole
     6514                       initializer is parsed.  */
     6515                    put_elf_reloca(symtab_section, sec,
     6516                                   c + rel->r_offset - esym->st_value,
     6517                                   ELFW(R_TYPE)(rel->r_info),
     6518                                   ELFW(R_SYM)(rel->r_info),
     6519#if PTR_SIZE == 8
     6520                                   rel->r_addend
     6521#else
     6522                                   0
     6523#endif
     6524                                  );
     6525                }
     6526            }
     6527        } else {
     6528            if (type->t & VT_BITFIELD) {
     6529                int bit_pos, bit_size, bits, n;
     6530                unsigned char *p, v, m;
     6531                bit_pos = BIT_POS(vtop->type.t);
     6532                bit_size = BIT_SIZE(vtop->type.t);
     6533                p = (unsigned char*)ptr + (bit_pos >> 3);
     6534                bit_pos &= 7, bits = 0;
     6535                while (bit_size) {
     6536                    n = 8 - bit_pos;
     6537                    if (n > bit_size)
     6538                        n = bit_size;
     6539                    v = vtop->c.i >> bits << bit_pos;
     6540                    m = ((1 << n) - 1) << bit_pos;
     6541                    *p = (*p & ~m) | (v & m);
     6542                    bits += n, bit_size -= n, bit_pos = 0, ++p;
     6543                }
     6544            } else
     6545            switch(bt) {
     6546                /* XXX: when cross-compiling we assume that each type has the
     6547                   same representation on host and target, which is likely to
     6548                   be wrong in the case of long double */
     6549            case VT_BOOL:
     6550                vtop->c.i = vtop->c.i != 0;
     6551            case VT_BYTE:
     6552                *(char *)ptr |= vtop->c.i;
     6553                break;
     6554            case VT_SHORT:
     6555                *(short *)ptr |= vtop->c.i;
     6556                break;
     6557            case VT_FLOAT:
     6558                *(float*)ptr = vtop->c.f;
     6559                break;
     6560            case VT_DOUBLE:
     6561                *(double *)ptr = vtop->c.d;
     6562                break;
     6563            case VT_LDOUBLE:
     6564#if defined TCC_IS_NATIVE_387
     6565                if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
     6566                    memcpy(ptr, &vtop->c.ld, 10);
     6567#ifdef __TINYC__
     6568                else if (sizeof (long double) == sizeof (double))
     6569                    __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
     6570#endif
     6571                else if (vtop->c.ld == 0.0)
     6572                    ;
     6573                else
     6574#endif
     6575                if (sizeof(long double) == LDOUBLE_SIZE)
     6576                    *(long double*)ptr = vtop->c.ld;
     6577                else if (sizeof(double) == LDOUBLE_SIZE)
     6578                    *(double *)ptr = (double)vtop->c.ld;
     6579                else
     6580                    tcc_error("can't cross compile long double constants");
     6581                break;
     6582#if PTR_SIZE != 8
     6583            case VT_LLONG:
     6584                *(long long *)ptr |= vtop->c.i;
     6585                break;
     6586#else
     6587            case VT_LLONG:
     6588#endif
     6589            case VT_PTR:
     6590                {
     6591                    addr_t val = vtop->c.i;
     6592#if PTR_SIZE == 8
     6593                    if (vtop->r & VT_SYM)
     6594                      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
     6595                    else
     6596                      *(addr_t *)ptr |= val;
     6597#else
     6598                    if (vtop->r & VT_SYM)
     6599                      greloc(sec, vtop->sym, c, R_DATA_PTR);
     6600                    *(addr_t *)ptr |= val;
     6601#endif
     6602                    break;
     6603                }
     6604            default:
     6605                {
     6606                    int val = vtop->c.i;
     6607#if PTR_SIZE == 8
     6608                    if (vtop->r & VT_SYM)
     6609                      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
     6610                    else
     6611                      *(int *)ptr |= val;
     6612#else
     6613                    if (vtop->r & VT_SYM)
     6614                      greloc(sec, vtop->sym, c, R_DATA_PTR);
     6615                    *(int *)ptr |= val;
     6616#endif
     6617                    break;
     6618                }
     6619            }
     6620        }
    49286621        vtop--;
    49296622    } else {
     
    49326625        vstore();
    49336626        vpop();
    4934     }
    4935 }
    4936 
    4937 /* put zeros for variable based init */
    4938 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
    4939 {
    4940     if (sec) {
    4941         /* nothing to do because globals are already set to zero */
    4942     } else {
    4943         vpush_global_sym(&func_old_type, TOK_memset);
    4944         vseti(VT_LOCAL, c);
    4945         vpushi(0);
    4946         vpushi(size);
    4947         gfunc_call(3);
    49486627    }
    49496628}
     
    49576636                             int first, int size_only)
    49586637{
    4959     int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
    4960     int size1, align1, expr_type;
     6638    int len, n, no_oblock, nb, i;
     6639    int size1, align1;
     6640    int have_elem;
    49616641    Sym *s, *f;
     6642    Sym indexsym;
    49626643    CType *t1;
    49636644
    4964     if (type->t & VT_VLA) {
    4965 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    4966         int a;
    4967         CValue retcval;
    4968 
    4969         vpush_global_sym(&func_old_type, TOK_alloca);
    4970         vla_runtime_type_size(type, &a);
    4971         gfunc_call(1);
    4972 
    4973         /* return value */
    4974         retcval.i = 0;
    4975         vsetc(type, REG_IRET, &retcval);
    4976         vset(type, VT_LOCAL|VT_LVAL, c);
    4977         vswap();
    4978         vstore();
    4979         vpop();
    4980 #else
    4981         tcc_error("variable length arrays unsupported for this target");
    4982 #endif
     6645    /* If we currently are at an '}' or ',' we have read an initializer
     6646       element in one of our callers, and not yet consumed it.  */
     6647    have_elem = tok == '}' || tok == ',';
     6648    if (!have_elem && tok != '{' &&
     6649        /* In case of strings we have special handling for arrays, so
     6650           don't consume them as initializer value (which would commit them
     6651           to some anonymous symbol).  */
     6652        tok != TOK_LSTR && tok != TOK_STR &&
     6653        !size_only) {
     6654        parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
     6655        have_elem = 1;
     6656    }
     6657
     6658    if (have_elem &&
     6659        !(type->t & VT_ARRAY) &&
     6660        /* Use i_c_parameter_t, to strip toplevel qualifiers.
     6661           The source type might have VT_CONSTANT set, which is
     6662           of course assignable to non-const elements.  */
     6663        is_compatible_unqualified_types(type, &vtop->type)) {
     6664        init_putv(type, sec, c);
    49836665    } else if (type->t & VT_ARRAY) {
    49846666        s = type->ref;
    49856667        n = s->c;
    4986         array_length = 0;
    49876668        t1 = pointed_type(type);
    49886669        size1 = type_size(t1, &align1);
     
    50076688#endif
    50086689            ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
     6690            len = 0;
    50096691            while (tok == TOK_STR || tok == TOK_LSTR) {
    50106692                int cstr_len, ch;
    5011                 CString *cstr;
    5012 
    5013                 cstr = tokc.cstr;
     6693
    50146694                /* compute maximum number of chars wanted */
    50156695                if (tok == TOK_STR)
    5016                     cstr_len = cstr->size;
     6696                    cstr_len = tokc.str.size;
    50176697                else
    5018                     cstr_len = cstr->size / sizeof(nwchar_t);
     6698                    cstr_len = tokc.str.size / sizeof(nwchar_t);
    50196699                cstr_len--;
    50206700                nb = cstr_len;
    5021                 if (n >= 0 && nb > (n - array_length))
    5022                     nb = n - array_length;
     6701                if (n >= 0 && nb > (n - len))
     6702                    nb = n - len;
    50236703                if (!size_only) {
    50246704                    if (cstr_len > nb)
     
    50286708                       specifically */
    50296709                    if (sec && tok == TOK_STR && size1 == 1) {
    5030                         memcpy(sec->data + c + array_length, cstr->data, nb);
     6710                        if (!NODATA_WANTED)
     6711                            memcpy(sec->data + c + len, tokc.str.data, nb);
    50316712                    } else {
    50326713                        for(i=0;i<nb;i++) {
    50336714                            if (tok == TOK_STR)
    5034                                 ch = ((unsigned char *)cstr->data)[i];
     6715                                ch = ((unsigned char *)tokc.str.data)[i];
    50356716                            else
    5036                                 ch = ((nwchar_t *)cstr->data)[i];
    5037                             init_putv(t1, sec, c + (array_length + i) * size1,
    5038                                       ch, EXPR_VAL);
     6717                                ch = ((nwchar_t *)tokc.str.data)[i];
     6718                            vpushi(ch);
     6719                            init_putv(t1, sec, c + (len + i) * size1);
    50396720                        }
    50406721                    }
    50416722                }
    5042                 array_length += nb;
     6723                len += nb;
    50436724                next();
    50446725            }
    50456726            /* only add trailing zero if enough storage (no
    50466727               warning in this case since it is standard) */
    5047             if (n < 0 || array_length < n) {
     6728            if (n < 0 || len < n) {
    50486729                if (!size_only) {
    5049                     init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
     6730                    vpushi(0);
     6731                    init_putv(t1, sec, c + (len * size1));
    50506732                }
    5051                 array_length++;
    5052             }
     6733                len++;
     6734            }
     6735            len *= size1;
    50536736        } else {
    5054             index = 0;
    5055             while (tok != '}') {
    5056                 decl_designator(type, sec, c, &index, NULL, size_only);
    5057                 if (n >= 0 && index >= n)
    5058                     tcc_error("index too large");
    5059                 /* must put zero in holes (note that doing it that way
    5060                    ensures that it even works with designators) */
    5061                 if (!size_only && array_length < index) {
    5062                     init_putz(t1, sec, c + array_length * size1,
    5063                               (index - array_length) * size1);
    5064                 }
    5065                 index++;
    5066                 if (index > array_length)
    5067                     array_length = index;
    5068                 /* special test for multi dimensional arrays (may not
    5069                    be strictly correct if designators are used at the
    5070                    same time) */
    5071                 if (index >= n && no_oblock)
    5072                     break;
    5073                 if (tok == '}')
    5074                     break;
    5075                 skip(',');
    5076             }
    5077         }
     6737            indexsym.c = 0;
     6738            f = &indexsym;
     6739
     6740          do_init_list:
     6741            len = 0;
     6742            while (tok != '}' || have_elem) {
     6743                len = decl_designator(type, sec, c, &f, size_only, len);
     6744                have_elem = 0;
     6745                if (type->t & VT_ARRAY) {
     6746                    ++indexsym.c;
     6747                    /* special test for multi dimensional arrays (may not
     6748                       be strictly correct if designators are used at the
     6749                       same time) */
     6750                    if (no_oblock && len >= n*size1)
     6751                        break;
     6752                } else {
     6753                    if (s->type.t == VT_UNION)
     6754                        f = NULL;
     6755                    else
     6756                        f = f->next;
     6757                    if (no_oblock && f == NULL)
     6758                        break;
     6759                }
     6760
     6761                if (tok == '}')
     6762                    break;
     6763                skip(',');
     6764            }
     6765        }
     6766        /* put zeros at the end */
     6767        if (!size_only && len < n*size1)
     6768            init_putz(sec, c + len, n*size1 - len);
    50786769        if (!no_oblock)
    50796770            skip('}');
    5080         /* put zeros at the end */
    5081         if (!size_only && n >= 0 && array_length < n) {
    5082             init_putz(t1, sec, c + array_length * size1,
    5083                       (n - array_length) * size1);
    5084         }
    5085         /* patch type size if needed */
     6771        /* patch type size if needed, which happens only for array types */
    50866772        if (n < 0)
    5087             s->c = array_length;
    5088     } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
    5089                (sec || !first || tok == '{')) {
    5090         int par_count;
    5091 
    5092         /* NOTE: the previous test is a specific case for automatic
    5093            struct/union init */
    5094         /* XXX: union needs only one init */
    5095 
    5096         /* XXX: this test is incorrect for local initializers
    5097            beginning with ( without {. It would be much more difficult
    5098            to do it correctly (ideally, the expression parser should
    5099            be used in all cases) */
    5100         par_count = 0;
    5101         if (tok == '(') {
    5102             AttributeDef ad1;
    5103             CType type1;
    5104             next();
    5105             while (tok == '(') {
    5106                 par_count++;
    5107                 next();
    5108             }
    5109             if (!parse_btype(&type1, &ad1))
    5110                 expect("cast");
    5111             type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
    5112 #if 0
    5113             if (!is_assignable_types(type, &type1))
    5114                 tcc_error("invalid type for cast");
    5115 #endif
    5116             skip(')');
    5117         }
     6773            s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
     6774    } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
     6775        size1 = 1;
    51186776        no_oblock = 1;
    51196777        if (first || tok == '{') {
     
    51236781        s = type->ref;
    51246782        f = s->next;
    5125         array_length = 0;
    5126         index = 0;
    51276783        n = s->c;
    5128         while (tok != '}') {
    5129             decl_designator(type, sec, c, NULL, &f, size_only);
    5130             index = f->c;
    5131             if (!size_only && array_length < index) {
    5132                 init_putz(type, sec, c + array_length,
    5133                           index - array_length);
    5134             }
    5135             index = index + type_size(&f->type, &align1);
    5136             if (index > array_length)
    5137                 array_length = index;
    5138 
    5139             /* gr: skip fields from same union - ugly. */
    5140             while (f->next) {
    5141                 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
    5142                 /* test for same offset */
    5143                 if (f->next->c != f->c)
    5144                     break;
    5145                 /* if yes, test for bitfield shift */
    5146                 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
    5147                     int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    5148                     int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
    5149                     //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
    5150                     if (bit_pos_1 != bit_pos_2)
    5151                         break;
    5152                 }
    5153                 f = f->next;
    5154             }
    5155 
    5156             f = f->next;
    5157             if (no_oblock && f == NULL)
    5158                 break;
    5159             if (tok == '}')
    5160                 break;
    5161             skip(',');
    5162         }
    5163         /* put zeros at the end */
    5164         if (!size_only && array_length < n) {
    5165             init_putz(type, sec, c + array_length,
    5166                       n - array_length);
    5167         }
    5168         if (!no_oblock)
    5169             skip('}');
    5170         while (par_count) {
    5171             skip(')');
    5172             par_count--;
    5173         }
     6784        goto do_init_list;
    51746785    } else if (tok == '{') {
    51756786        next();
     
    51776788        skip('}');
    51786789    } else if (size_only) {
     6790        /* If we supported only ISO C we wouldn't have to accept calling
     6791           this on anything than an array size_only==1 (and even then
     6792           only on the outermost level, so no recursion would be needed),
     6793           because initializing a flex array member isn't supported.
     6794           But GNU C supports it, so we need to recurse even into
     6795           subfields of structs and arrays when size_only is set.  */
    51796796        /* just skip expression */
    5180         parlevel = parlevel1 = 0;
    5181         while ((parlevel > 0 || parlevel1 > 0 ||
    5182                 (tok != '}' && tok != ',')) &&  tok != -1) {
    5183             if (tok == '(')
    5184                 parlevel++;
    5185             else if (tok == ')')
    5186                 parlevel--;
    5187             else if (tok == '{')
    5188                 parlevel1++;
    5189             else if (tok == '}')
    5190                 parlevel1--;
    5191             next();
    5192         }
     6797        skip_or_save_block(NULL);
    51936798    } else {
    5194         /* currently, we always use constant expression for globals
    5195            (may change for scripting case) */
    5196         expr_type = EXPR_CONST;
    5197         if (!sec)
    5198             expr_type = EXPR_ANY;
    5199         init_putv(type, sec, c, 0, expr_type);
     6799        if (!have_elem) {
     6800            /* This should happen only when we haven't parsed
     6801               the init element above for fear of committing a
     6802               string constant to memory too early.  */
     6803            if (tok != TOK_STR && tok != TOK_LSTR)
     6804              expect("string constant");
     6805            parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
     6806        }
     6807        init_putv(type, sec, c);
    52006808    }
    52016809}
     
    52046812   allocate space in local or global data space ('r' is either
    52056813   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
    5206    variable 'v' with an associated name represented by 'asm_label' of
    5207    scope 'scope' is declared before initializers are parsed. If 'v' is
    5208    zero, then a reference to the new object is put in the value stack.
    5209    If 'has_init' is 2, a special parsing is done to handle string
    5210    constants. */
     6814   variable 'v' of scope 'scope' is declared before initializers
     6815   are parsed. If 'v' is zero, then a reference to the new object
     6816   is put in the value stack. If 'has_init' is 2, a special parsing
     6817   is done to handle string constants. */
    52116818static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
    5212                                    int has_init, int v, char *asm_label,
    5213                                    int scope)
    5214 {
    5215     int size, align, addr, data_offset;
    5216     int level;
    5217     ParseState saved_parse_state = {0};
    5218     TokenString init_str;
     6819                                   int has_init, int v, int scope)
     6820{
     6821    int size, align, addr;
     6822    TokenString *init_str = NULL;
     6823
    52196824    Section *sec;
    52206825    Sym *flexible_array;
     6826    Sym *sym = NULL;
     6827    int saved_nocode_wanted = nocode_wanted;
     6828#ifdef CONFIG_TCC_BCHECK
     6829    int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
     6830#endif
     6831
     6832    if (type->t & VT_STATIC)
     6833        nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000;
    52216834
    52226835    flexible_array = NULL;
    52236836    if ((type->t & VT_BTYPE) == VT_STRUCT) {
    5224         Sym *field;
    5225         field = type->ref;
    5226         while (field && field->next)
    5227             field = field->next;
    5228         if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
    5229             flexible_array = field;
     6837        Sym *field = type->ref->next;
     6838        if (field) {
     6839            while (field->next)
     6840                field = field->next;
     6841            if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
     6842                flexible_array = field;
     6843        }
    52306844    }
    52316845
     
    52376851       literals). It also simplifies local
    52386852       initializers handling */
    5239     tok_str_new(&init_str);
    52406853    if (size < 0 || (flexible_array && has_init)) {
    52416854        if (!has_init)
     
    52436856        /* get all init string */
    52446857        if (has_init == 2) {
     6858            init_str = tok_str_alloc();
    52456859            /* only get strings */
    52466860            while (tok == TOK_STR || tok == TOK_LSTR) {
    5247                 tok_str_add_tok(&init_str);
     6861                tok_str_add_tok(init_str);
    52486862                next();
    52496863            }
     6864            tok_str_add(init_str, -1);
     6865            tok_str_add(init_str, 0);
    52506866        } else {
    5251             level = 0;
    5252             while (level > 0 || (tok != ',' && tok != ';')) {
    5253                 if (tok < 0)
    5254                     tcc_error("unexpected end of file in initializer");
    5255                 tok_str_add_tok(&init_str);
    5256                 if (tok == '{')
    5257                     level++;
    5258                 else if (tok == '}') {
    5259                     level--;
    5260                     if (level <= 0) {
    5261                         next();
    5262                         break;
    5263                     }
    5264                 }
    5265                 next();
    5266             }
    5267         }
    5268         tok_str_add(&init_str, -1);
    5269         tok_str_add(&init_str, 0);
    5270        
     6867            skip_or_save_block(&init_str);
     6868        }
     6869        unget_tok(0);
     6870
    52716871        /* compute size */
    5272         save_parse_state(&saved_parse_state);
    5273 
    5274         macro_ptr = init_str.str;
     6872        begin_macro(init_str, 1);
    52756873        next();
    52766874        decl_initializer(type, NULL, 0, 1, 1);
    52776875        /* prepare second initializer parsing */
    5278         macro_ptr = init_str.str;
     6876        macro_ptr = init_str->str;
    52796877        next();
    52806878       
     
    52846882            tcc_error("unknown type size");
    52856883    }
    5286     if (flexible_array)
    5287         size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
     6884    /* If there's a flex member and it was used in the initializer
     6885       adjust size.  */
     6886    if (flexible_array &&
     6887        flexible_array->type.ref->c > 0)
     6888        size += flexible_array->type.ref->c
     6889                * pointed_size(&flexible_array->type);
    52886890    /* take into account specified alignment if bigger */
    5289     if (ad->aligned) {
    5290         if (ad->aligned > align)
    5291             align = ad->aligned;
    5292     } else if (ad->packed) {
     6891    if (ad->a.aligned) {
     6892        int speca = 1 << (ad->a.aligned - 1);
     6893        if (speca > align)
     6894            align = speca;
     6895    } else if (ad->a.packed) {
    52936896        align = 1;
    52946897    }
     6898
     6899    if (NODATA_WANTED)
     6900        size = 0, align = 1;
     6901
    52956902    if ((r & VT_VALMASK) == VT_LOCAL) {
    52966903        sec = NULL;
    52976904#ifdef CONFIG_TCC_BCHECK
    5298         if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
     6905        if (bcheck && (type->t & VT_ARRAY)) {
    52996906            loc--;
    53006907        }
     
    53066913        /* XXX: currently, since we do only one pass, we cannot track
    53076914           '&' operators, so we add only arrays */
    5308         if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
    5309             unsigned long *bounds_ptr;
     6915        if (bcheck && (type->t & VT_ARRAY)) {
     6916            addr_t *bounds_ptr;
    53106917            /* add padding between regions */
    53116918            loc--;
    53126919            /* then add local bound info */
    5313             bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
     6920            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
    53146921            bounds_ptr[0] = addr;
    53156922            bounds_ptr[1] = size;
     
    53186925        if (v) {
    53196926            /* local variable */
    5320             sym_push(v, type, r, addr);
     6927#ifdef CONFIG_TCC_ASM
     6928            if (ad->asm_label) {
     6929                int reg = asm_parse_regvar(ad->asm_label);
     6930                if (reg >= 0)
     6931                    r = (r & ~VT_VALMASK) | reg;
     6932            }
     6933#endif
     6934            sym = sym_push(v, type, r, addr);
     6935            sym->a = ad->a;
    53216936        } else {
    53226937            /* push local reference */
     
    53246939        }
    53256940    } else {
    5326         Sym *sym;
    5327 
    5328         sym = NULL;
    53296941        if (v && scope == VT_CONST) {
    53306942            /* see if the symbol was already defined */
    53316943            sym = sym_find(v);
    53326944            if (sym) {
    5333                 if (!is_compatible_types(&sym->type, type))
    5334                     tcc_error("incompatible types for redefinition of '%s'",
    5335                           get_tok_str(v, NULL));
    5336                 if (sym->type.t & VT_EXTERN) {
    5337                     /* if the variable is extern, it was not allocated */
    5338                     sym->type.t &= ~VT_EXTERN;
    5339                     /* set array size if it was ommited in extern
    5340                        declaration */
    5341                     if ((sym->type.t & VT_ARRAY) &&
    5342                         sym->type.ref->c < 0 &&
    5343                         type->ref->c >= 0)
    5344                         sym->type.ref->c = type->ref->c;
    5345                 } else {
    5346                     /* we accept several definitions of the same
    5347                        global variable. this is tricky, because we
    5348                        must play with the SHN_COMMON type of the symbol */
    5349                     /* XXX: should check if the variable was already
    5350                        initialized. It is incorrect to initialized it
    5351                        twice */
    5352                     /* no init data, we won't add more to the symbol */
    5353                     if (!has_init)
    5354                         goto no_alloc;
    5355                 }
     6945                patch_storage(sym, ad, type);
     6946                /* we accept several definitions of the same global variable. */
     6947                if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
     6948                    goto no_alloc;
    53566949            }
    53576950        }
     
    53656958                sec = bss_section;
    53666959        }
     6960
    53676961        if (sec) {
    5368             data_offset = sec->data_offset;
    5369             data_offset = (data_offset + align - 1) & -align;
    5370             addr = data_offset;
    5371             /* very important to increment global pointer at this time
    5372                because initializers themselves can create new initializers */
    5373             data_offset += size;
     6962            addr = section_add(sec, size, align);
    53746963#ifdef CONFIG_TCC_BCHECK
    53756964            /* add padding if bound check */
    5376             if (tcc_state->do_bounds_check)
    5377                 data_offset++;
    5378 #endif
    5379             sec->data_offset = data_offset;
    5380             /* allocate section space to put the data */
    5381             if (sec->sh_type != SHT_NOBITS &&
    5382                 data_offset > sec->data_allocated)
    5383                 section_realloc(sec, data_offset);
    5384             /* align section if needed */
    5385             if (align > sec->sh_addralign)
    5386                 sec->sh_addralign = align;
     6965            if (bcheck)
     6966                section_add(sec, 1, 1);
     6967#endif
    53876968        } else {
    5388             addr = 0; /* avoid warning */
     6969            addr = align; /* SHN_COMMON is special, symbol value is align */
     6970            sec = common_section;
    53896971        }
    53906972
    53916973        if (v) {
    5392             if (scope != VT_CONST || !sym) {
     6974            if (!sym) {
    53936975                sym = sym_push(v, type, r | VT_SYM, 0);
    5394                 sym->asm_label = asm_label;
    5395             }
     6976                patch_storage(sym, ad, NULL);
     6977            }
     6978            /* Local statics have a scope until now (for
     6979               warnings), remove it here.  */
     6980            sym->sym_scope = 0;
    53966981            /* update symbol definition */
    5397             if (sec) {
    5398                 put_extern_sym(sym, sec, addr, size);
    5399             } else {
    5400                 ElfW(Sym) *esym;
    5401                 /* put a common area */
    5402                 put_extern_sym(sym, NULL, align, size);
    5403                 /* XXX: find a nicer way */
    5404                 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    5405                 esym->st_shndx = SHN_COMMON;
    5406             }
     6982            put_extern_sym(sym, sec, addr, size);
    54076983        } else {
    5408             CValue cval;
    5409 
    54106984            /* push global reference */
    54116985            sym = get_sym_ref(type, sec, addr, size);
    5412             cval.ul = 0;
    5413             vsetc(type, VT_CONST | VT_SYM, &cval);
    5414             vtop->sym = sym;
    5415         }
    5416         /* patch symbol weakness */
    5417         if (type->t & VT_WEAK)
    5418             weaken_symbol(sym);
     6986            vpushsym(type, sym);
     6987            vtop->r |= r;
     6988        }
     6989
    54196990#ifdef CONFIG_TCC_BCHECK
    54206991        /* handles bounds now because the symbol must be defined
    54216992           before for the relocation */
    5422         if (tcc_state->do_bounds_check) {
    5423             unsigned long *bounds_ptr;
    5424 
    5425             greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
     6993        if (bcheck) {
     6994            addr_t *bounds_ptr;
     6995
     6996            greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
    54266997            /* then add global bound info */
    5427             bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
     6998            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
    54286999            bounds_ptr[0] = 0; /* relocated */
    54297000            bounds_ptr[1] = size;
     
    54317002#endif
    54327003    }
    5433     if (has_init || (type->t & VT_VLA)) {
     7004
     7005    if (type->t & VT_VLA) {
     7006        int a;
     7007
     7008        if (NODATA_WANTED)
     7009            goto no_alloc;
     7010
     7011        /* save current stack pointer */
     7012        if (vlas_in_scope == 0) {
     7013            if (vla_sp_root_loc == -1)
     7014                vla_sp_root_loc = (loc -= PTR_SIZE);
     7015            gen_vla_sp_save(vla_sp_root_loc);
     7016        }
     7017
     7018        vla_runtime_type_size(type, &a);
     7019        gen_vla_alloc(type, a);
     7020#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
     7021        /* on _WIN64, because of the function args scratch area, the
     7022           result of alloca differs from RSP and is returned in RAX.  */
     7023        gen_vla_result(addr), addr = (loc -= PTR_SIZE);
     7024#endif
     7025        gen_vla_sp_save(addr);
     7026        vla_sp_loc = addr;
     7027        vlas_in_scope++;
     7028
     7029    } else if (has_init) {
     7030        size_t oldreloc_offset = 0;
     7031        if (sec && sec->reloc)
     7032          oldreloc_offset = sec->reloc->data_offset;
    54347033        decl_initializer(type, sec, addr, 1, 0);
    5435         /* restore parse state if needed */
    5436         if (init_str.str) {
    5437             tok_str_free(init_str.str);
    5438             restore_parse_state(&saved_parse_state);
    5439         }
     7034        if (sec && sec->reloc)
     7035          squeeze_multi_relocs(sec, oldreloc_offset);
    54407036        /* patch flexible array member size back to -1, */
    54417037        /* for possible subsequent similar declarations */
     
    54437039            flexible_array->type.ref->c = -1;
    54447040    }
    5445  no_alloc: ;
    5446 }
    5447 
    5448 static void put_func_debug(Sym *sym)
    5449 {
    5450     char buf[512];
    5451 
    5452     /* stabs info */
    5453     /* XXX: we put here a dummy type */
    5454     snprintf(buf, sizeof(buf), "%s:%c1",
    5455              funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
    5456     put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
    5457                 cur_text_section, sym->c);
    5458     /* //gr gdb wants a line at the function */
    5459     put_stabn(N_SLINE, 0, file->line_num, 0);
    5460     last_ind = 0;
    5461     last_line_num = 0;
    5462 }
    5463 
    5464 /* parse an old style function declaration list */
    5465 /* XXX: check multiple parameter */
    5466 static void func_decl_list(Sym *func_sym)
    5467 {
    5468     AttributeDef ad;
    5469     int v;
    5470     Sym *s;
    5471     CType btype, type;
    5472 
    5473     /* parse each declaration */
    5474     while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
    5475            tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
    5476         if (!parse_btype(&btype, &ad))
    5477             expect("declaration list");
    5478         if (((btype.t & VT_BTYPE) == VT_ENUM ||
    5479              (btype.t & VT_BTYPE) == VT_STRUCT) &&
    5480             tok == ';') {
    5481             /* we accept no variable after */
    5482         } else {
    5483             for(;;) {
    5484                 type = btype;
    5485                 type_decl(&type, &ad, &v, TYPE_DIRECT);
    5486                 /* find parameter in function parameter list */
    5487                 s = func_sym->next;
    5488                 while (s != NULL) {
    5489                     if ((s->v & ~SYM_FIELD) == v)
    5490                         goto found;
    5491                     s = s->next;
    5492                 }
    5493                 tcc_error("declaration for parameter '%s' but no such parameter",
    5494                       get_tok_str(v, NULL));
    5495             found:
    5496                 /* check that no storage specifier except 'register' was given */
    5497                 if (type.t & VT_STORAGE)
    5498                     tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
    5499                 convert_parameter_type(&type);
    5500                 /* we can add the type (NOTE: it could be local to the function) */
    5501                 s->type = type;
    5502                 /* accept other parameters */
    5503                 if (tok == ',')
    5504                     next();
    5505                 else
    5506                     break;
    5507             }
    5508         }
    5509         skip(';');
    5510     }
     7041
     7042 no_alloc:
     7043    /* restore parse state if needed */
     7044    if (init_str) {
     7045        end_macro();
     7046        next();
     7047    }
     7048
     7049    nocode_wanted = saved_nocode_wanted;
    55117050}
    55127051
     
    55157054static void gen_function(Sym *sym)
    55167055{
    5517     int saved_nocode_wanted = nocode_wanted;
    55187056    nocode_wanted = 0;
    55197057    ind = cur_text_section->data_offset;
     
    55227060    funcname = get_tok_str(sym->v, NULL);
    55237061    func_ind = ind;
     7062    /* Initialize VLA state */
     7063    vla_sp_loc = -1;
     7064    vla_sp_root_loc = -1;
    55247065    /* put debug symbol */
    5525     if (tcc_state->do_debug)
    5526         put_func_debug(sym);
     7066    tcc_debug_funcstart(tcc_state, sym);
    55277067    /* push a dummy symbol to enable local sym storage */
    55287068    sym_push2(&local_stack, SYM_FIELD, 0, 0);
     7069    local_scope = 1; /* for function parameters */
    55297070    gfunc_prolog(&sym->type);
     7071    local_scope = 0;
    55307072    rsym = 0;
    5531     block(NULL, NULL, NULL, NULL, 0, 0);
     7073    block(NULL, NULL, 0);
     7074    nocode_wanted = 0;
    55327075    gsym(rsym);
    55337076    gfunc_epilog();
    55347077    cur_text_section->data_offset = ind;
    5535     label_pop(&global_label_stack, NULL);
     7078    label_pop(&global_label_stack, NULL, 0);
    55367079    /* reset local stack */
    5537     scope_stack_bottom = NULL;
    5538     sym_pop(&local_stack, NULL);
     7080    local_scope = 0;
     7081    sym_pop(&local_stack, NULL, 0);
    55397082    /* end of function */
    55407083    /* patch symbol size */
    5541     ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
    5542         ind - func_ind;
    5543     /* patch symbol weakness (this definition overrules any prototype) */
    5544     if (sym->type.t & VT_WEAK)
    5545         weaken_symbol(sym);
    5546     if (tcc_state->do_debug) {
    5547         put_stabn(N_FUN, 0, 0, ind - func_ind);
    5548     }
     7084    elfsym(sym)->st_size = ind - func_ind;
     7085    tcc_debug_funcend(tcc_state, ind - func_ind);
    55497086    /* It's better to crash than to generate wrong code */
    55507087    cur_text_section = NULL;
    55517088    funcname = ""; /* for safety */
    55527089    func_vt.t = VT_VOID; /* for safety */
     7090    func_var = 0; /* for safety */
    55537091    ind = 0; /* for safety */
    5554     nocode_wanted = saved_nocode_wanted;
    5555 }
    5556 
    5557 ST_FUNC void gen_inline_functions(void)
     7092    nocode_wanted = 0x80000000;
     7093    check_vstack();
     7094}
     7095
     7096static void gen_inline_functions(TCCState *s)
    55587097{
    55597098    Sym *sym;
    5560     int *str, inline_generated, i;
     7099    int inline_generated, i, ln;
    55617100    struct InlineFunc *fn;
    55627101
     7102    ln = file->line_num;
    55637103    /* iterate while inline function are referenced */
    5564     for(;;) {
     7104    do {
    55657105        inline_generated = 0;
    5566         for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
    5567             fn = tcc_state->inline_fns[i];
     7106        for (i = 0; i < s->nb_inline_fns; ++i) {
     7107            fn = s->inline_fns[i];
    55687108            sym = fn->sym;
    55697109            if (sym && sym->c) {
    55707110                /* the function was used: generate its code and
    55717111                   convert it to a normal function */
    5572                 str = fn->token_str;
    55737112                fn->sym = NULL;
    55747113                if (file)
    55757114                    pstrcpy(file->filename, sizeof file->filename, fn->filename);
    5576                 sym->r = VT_SYM | VT_CONST;
    55777115                sym->type.t &= ~VT_INLINE;
    55787116
    5579                 macro_ptr = str;
     7117                begin_macro(fn->func_str, 1);
    55807118                next();
    55817119                cur_text_section = text_section;
    55827120                gen_function(sym);
    5583                 macro_ptr = NULL; /* fail safe */
     7121                end_macro();
    55847122
    55857123                inline_generated = 1;
    55867124            }
    55877125        }
    5588         if (!inline_generated)
    5589             break;
    5590     }
    5591     for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
    5592         fn = tcc_state->inline_fns[i];
    5593         str = fn->token_str;
    5594         tok_str_free(str);
    5595     }
    5596     dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
    5597 }
    5598 
    5599 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
    5600 static int decl0(int l, int is_for_loop_init)
     7126    } while (inline_generated);
     7127    file->line_num = ln;
     7128}
     7129
     7130ST_FUNC void free_inline_functions(TCCState *s)
     7131{
     7132    int i;
     7133    /* free tokens of unused inline functions */
     7134    for (i = 0; i < s->nb_inline_fns; ++i) {
     7135        struct InlineFunc *fn = s->inline_fns[i];
     7136        if (fn->sym)
     7137            tok_str_free(fn->func_str);
     7138    }
     7139    dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
     7140}
     7141
     7142/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
     7143   if parsing old style parameter decl list (and FUNC_SYM is set then) */
     7144static int decl0(int l, int is_for_loop_init, Sym *func_sym)
    56017145{
    56027146    int v, has_init, r;
     
    56097153            if (is_for_loop_init)
    56107154                return 0;
    5611             /* skip redundant ';' */
    5612             /* XXX: find more elegant solution */
    5613             if (tok == ';') {
     7155            /* skip redundant ';' if not in old parameter decl scope */
     7156            if (tok == ';' && l != VT_CMP) {
    56147157                next();
    56157158                continue;
    56167159            }
    5617             if (l == VT_CONST &&
    5618                 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
     7160            if (l != VT_CONST)
     7161                break;
     7162            if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
    56197163                /* global asm block */
    56207164                asm_global_instr();
    56217165                continue;
    56227166            }
    5623             /* special test for old K&R protos without explicit int
    5624                type. Only accepted when defining global data */
    5625             if (l == VT_LOCAL || tok < TOK_DEFINE)
     7167            if (tok >= TOK_UIDENT) {
     7168               /* special test for old K&R protos without explicit int
     7169                  type. Only accepted when defining global data */
     7170                btype.t = VT_INT;
     7171            } else {
     7172                if (tok != TOK_EOF)
     7173                    expect("declaration");
    56267174                break;
    5627             btype.t = VT_INT;
    5628         }
    5629         if (((btype.t & VT_BTYPE) == VT_ENUM ||
    5630              (btype.t & VT_BTYPE) == VT_STRUCT) &&
    5631             tok == ';') {
    5632             /* we accept no variable after */
    5633             next();
    5634             continue;
     7175            }
     7176        }
     7177        if (tok == ';') {
     7178            if ((btype.t & VT_BTYPE) == VT_STRUCT) {
     7179                int v = btype.ref->v;
     7180                if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
     7181                    tcc_warning("unnamed struct/union that defines no instances");
     7182                next();
     7183                continue;
     7184            }
     7185            if (IS_ENUM(btype.t)) {
     7186                next();
     7187                continue;
     7188            }
    56357189        }
    56367190        while (1) { /* iterate thru each declaration */
    5637             char *asm_label; // associated asm label
    56387191            type = btype;
     7192            /* If the base type itself was an array type of unspecified
     7193               size (like in 'typedef int arr[]; arr x = {1};') then
     7194               we will overwrite the unknown size by the real one for
     7195               this decl.  We need to unshare the ref symbol holding
     7196               that size.  */
     7197            if ((type.t & VT_ARRAY) && type.ref->c < 0) {
     7198                type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
     7199            }
    56397200            type_decl(&type, &ad, &v, TYPE_DIRECT);
    56407201#if 0
    56417202            {
    56427203                char buf[500];
    5643                 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
     7204                type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
    56447205                printf("type = '%s'\n", buf);
    56457206            }
     
    56527213                   declaration list */
    56537214                sym = type.ref;
    5654                 if (sym->c == FUNC_OLD)
    5655                     func_decl_list(sym);
    5656             }
    5657 
    5658             asm_label = NULL;
     7215                if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
     7216                    decl0(VT_CMP, 0, sym);
     7217            }
     7218
    56597219            if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
    5660                 CString astr;
    5661 
    5662                 asm_label_instr(&astr);
    5663                 asm_label = tcc_strdup(astr.data);
    5664                 cstr_free(&astr);
    5665                
     7220                ad.asm_label = asm_label_instr();
    56667221                /* parse one last attribute list, after asm label */
    56677222                parse_attribute(&ad);
    5668             }
    5669 
    5670             if (ad.weak)
    5671                 type.t |= VT_WEAK;
     7223                if (tok == '{')
     7224                    expect(";");
     7225            }
     7226
    56727227#ifdef TCC_TARGET_PE
    5673             if (ad.func_import)
    5674                 type.t |= VT_IMPORT;
    5675             if (ad.func_export)
    5676                 type.t |= VT_EXPORT;
     7228            if (ad.a.dllimport || ad.a.dllexport) {
     7229                if (type.t & (VT_STATIC|VT_TYPEDEF))
     7230                    tcc_error("cannot have dll linkage with static or typedef");
     7231                if (ad.a.dllimport) {
     7232                    if ((type.t & VT_BTYPE) == VT_FUNC)
     7233                        ad.a.dllimport = 0;
     7234                    else
     7235                        type.t |= VT_EXTERN;
     7236                }
     7237            }
    56777238#endif
    56787239            if (tok == '{') {
    5679                 if (l == VT_LOCAL)
     7240                if (l != VT_CONST)
    56807241                    tcc_error("cannot use local functions");
    56817242                if ((type.t & VT_BTYPE) != VT_FUNC)
    56827243                    expect("function definition");
    56837244
    5684                 /* reject abstract declarators in function definition */
     7245                /* reject abstract declarators in function definition
     7246                   make old style params without decl have int type */
    56857247                sym = type.ref;
    5686                 while ((sym = sym->next) != NULL)
     7248                while ((sym = sym->next) != NULL) {
    56877249                    if (!(sym->v & ~SYM_FIELD))
    5688                        expect("identifier");
     7250                        expect("identifier");
     7251                    if (sym->type.t == VT_VOID)
     7252                        sym->type = int_type;
     7253                }
    56897254               
    56907255                /* XXX: cannot do better now: convert extern line to static inline */
    56917256                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
    56927257                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
    5693                
    5694                 sym = sym_find(v);
    5695                 if (sym) {
    5696                     if ((sym->type.t & VT_BTYPE) != VT_FUNC)
    5697                         goto func_error1;
    5698 
    5699                     r = sym->type.ref->r;
    5700                     /* use func_call from prototype if not defined */
    5701                     if (FUNC_CALL(r) != FUNC_CDECL
    5702                      && FUNC_CALL(type.ref->r) == FUNC_CDECL)
    5703                         FUNC_CALL(type.ref->r) = FUNC_CALL(r);
    5704 
    5705                     /* use export from prototype */
    5706                     if (FUNC_EXPORT(r))
    5707                         FUNC_EXPORT(type.ref->r) = 1;
    5708 
    5709                     /* use static from prototype */
    5710                     if (sym->type.t & VT_STATIC)
    5711                         type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
    5712 
    5713                     if (!is_compatible_types(&sym->type, &type)) {
    5714                     func_error1:
    5715                         tcc_error("incompatible types for redefinition of '%s'",
    5716                               get_tok_str(v, NULL));
    5717                     }
    5718                     /* if symbol is already defined, then put complete type */
    5719                     sym->type = type;
    5720                 } else {
    5721                     /* put function symbol */
    5722                     sym = global_identifier_push(v, type.t, 0);
    5723                     sym->type.ref = type.ref;
    5724                 }
     7258
     7259                /* put function symbol */
     7260                sym = external_global_sym(v, &type, 0);
     7261                type.t &= ~VT_EXTERN;
     7262                patch_storage(sym, &ad, &type);
    57257263
    57267264                /* static inline functions are just recorded as a kind
     
    57297267                if ((type.t & (VT_INLINE | VT_STATIC)) ==
    57307268                    (VT_INLINE | VT_STATIC)) {
    5731                     TokenString func_str;
    5732                     int block_level;
    57337269                    struct InlineFunc *fn;
    57347270                    const char *filename;
    57357271                           
    5736                     tok_str_new(&func_str);
    5737                    
    5738                     block_level = 0;
    5739                     for(;;) {
    5740                         int t;
    5741                         if (tok == TOK_EOF)
    5742                             tcc_error("unexpected end of file");
    5743                         tok_str_add_tok(&func_str);
    5744                         t = tok;
    5745                         next();
    5746                         if (t == '{') {
    5747                             block_level++;
    5748                         } else if (t == '}') {
    5749                             block_level--;
    5750                             if (block_level == 0)
    5751                                 break;
    5752                         }
    5753                     }
    5754                     tok_str_add(&func_str, -1);
    5755                     tok_str_add(&func_str, 0);
    57567272                    filename = file ? file->filename : "";
    57577273                    fn = tcc_malloc(sizeof *fn + strlen(filename));
    57587274                    strcpy(fn->filename, filename);
    57597275                    fn->sym = sym;
    5760                     fn->token_str = func_str.str;
    5761                     dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
    5762 
     7276                    skip_or_save_block(&fn->func_str);
     7277                    dynarray_add(&tcc_state->inline_fns,
     7278                                 &tcc_state->nb_inline_fns, fn);
    57637279                } else {
    57647280                    /* compute text section */
     
    57667282                    if (!cur_text_section)
    57677283                        cur_text_section = text_section;
    5768                     sym->r = VT_SYM | VT_CONST;
    57697284                    gen_function(sym);
    57707285                }
    57717286                break;
    57727287            } else {
    5773                 if (btype.t & VT_TYPEDEF) {
     7288                if (l == VT_CMP) {
     7289                    /* find parameter in function parameter list */
     7290                    for (sym = func_sym->next; sym; sym = sym->next)
     7291                        if ((sym->v & ~SYM_FIELD) == v)
     7292                            goto found;
     7293                    tcc_error("declaration for parameter '%s' but no such parameter",
     7294                              get_tok_str(v, NULL));
     7295found:
     7296                    if (type.t & VT_STORAGE) /* 'register' is okay */
     7297                        tcc_error("storage class specified for '%s'",
     7298                                  get_tok_str(v, NULL));
     7299                    if (sym->type.t != VT_VOID)
     7300                        tcc_error("redefinition of parameter '%s'",
     7301                                  get_tok_str(v, NULL));
     7302                    convert_parameter_type(&type);
     7303                    sym->type = type;
     7304                } else if (type.t & VT_TYPEDEF) {
    57747305                    /* save typedefed type  */
    57757306                    /* XXX: test storage specifiers ? */
    5776                     sym = sym_push(v, &type, INT_ATTR(&ad), 0);
    5777                     sym->type.t |= VT_TYPEDEF;
     7307                    sym = sym_find(v);
     7308                    if (sym && sym->sym_scope == local_scope) {
     7309                        if (!is_compatible_types(&sym->type, &type)
     7310                            || !(sym->type.t & VT_TYPEDEF))
     7311                            tcc_error("incompatible redefinition of '%s'",
     7312                                get_tok_str(v, NULL));
     7313                        sym->type = type;
     7314                    } else {
     7315                        sym = sym_push(v, &type, 0, 0);
     7316                    }
     7317                    sym->a = ad.a;
     7318                    sym->f = ad.f;
    57787319                } else {
    57797320                    r = 0;
     
    57817322                        /* external function definition */
    57827323                        /* specific case for func_call attribute */
    5783                         type.ref->r = INT_ATTR(&ad);
     7324                        type.ref->f = ad.f;
    57847325                    } else if (!(type.t & VT_ARRAY)) {
    57857326                        /* not lvalue if array */
     
    57887329                    has_init = (tok == '=');
    57897330                    if (has_init && (type.t & VT_VLA))
    5790                         tcc_error("Variable length array cannot be initialized");
    5791                     if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
     7331                        tcc_error("variable length array cannot be initialized");
     7332                    if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
     7333                        ((type.t & VT_BTYPE) == VT_FUNC) ||
    57927334                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
    57937335                         !has_init && l == VT_CONST && type.ref->c < 0)) {
     
    57967338                           arrays of null size are considered as
    57977339                           extern */
    5798                         sym = external_sym(v, &type, r, asm_label);
    5799 
    5800                         if (type.t & VT_WEAK)
    5801                             weaken_symbol(sym);
    5802 
     7340                        type.t |= VT_EXTERN;
     7341                        sym = external_sym(v, &type, r, &ad);
    58037342                        if (ad.alias_target) {
    5804                             Section tsec;
    5805                             Elf32_Sym *esym;
     7343                            ElfSym *esym;
    58067344                            Sym *alias_target;
    5807 
    58087345                            alias_target = sym_find(ad.alias_target);
    5809                             if (!alias_target || !alias_target->c)
     7346                            esym = elfsym(alias_target);
     7347                            if (!esym)
    58107348                                tcc_error("unsupported forward __alias__ attribute");
    5811                             esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
    5812                             tsec.sh_num = esym->st_shndx;
    5813                             put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
     7349                            /* Local statics have a scope until now (for
     7350                               warnings), remove it here.  */
     7351                            sym->sym_scope = 0;
     7352                            put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
    58147353                        }
    58157354                    } else {
    5816                         type.t |= (btype.t & VT_STATIC); /* Retain "static". */
    58177355                        if (type.t & VT_STATIC)
    58187356                            r |= VT_CONST;
     
    58217359                        if (has_init)
    58227360                            next();
    5823                         decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
     7361                        else if (l == VT_CONST)
     7362                            /* uninitialized global variables may be overridden */
     7363                            type.t |= VT_EXTERN;
     7364                        decl_initializer_alloc(&type, &ad, r, has_init, v, l);
    58247365                    }
    58257366                }
     
    58327373                next();
    58337374            }
    5834             ad.aligned = 0;
     7375            ad.a.aligned = 0;
    58357376        }
    58367377    }
     
    58387379}
    58397380
    5840 ST_FUNC void decl(int l)
    5841 {
    5842     decl0(l, 0);
    5843 }
     7381static void decl(int l)
     7382{
     7383    decl0(l, 0, NULL);
     7384}
     7385
     7386/* ------------------------------------------------------------------------- */
  • EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c

    r321 r331  
    2121#include "tcc.h"
    2222
     23#define PE_MERGE_DATA
     24/* #define PE_PRINT_SECTIONS */
     25
    2326#ifndef _WIN32
    2427#define stricmp strcasecmp
    2528#define strnicmp strncasecmp
    26 #endif
    27 
    28 #ifndef MAX_PATH
    29 #define MAX_PATH 260
    30 #endif
    31 
    32 #define PE_MERGE_DATA
    33 // #define PE_PRINT_SECTIONS
     29#include <sys/stat.h> /* chmod() */
     30#endif
    3431
    3532#ifdef TCC_TARGET_X86_64
    3633# define ADDR3264 ULONGLONG
    37 #else
     34# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
     35# define REL_TYPE_DIRECT R_X86_64_64
     36# define R_XXX_THUNKFIX R_X86_64_PC32
     37# define R_XXX_RELATIVE R_X86_64_RELATIVE
     38# define IMAGE_FILE_MACHINE 0x8664
     39# define RSRC_RELTYPE 3
     40
     41#elif defined TCC_TARGET_ARM
    3842# define ADDR3264 DWORD
    39 #endif
    40 
    41 #ifdef _WIN32
    42 void dbg_printf (const char *fmt, ...)
    43 {
    44     char buffer[4000];
    45     va_list arg;
    46     int x;
    47     va_start(arg, fmt);
    48     x = vsprintf (buffer, fmt, arg);
    49     strcpy(buffer+x, "\n");
    50     OutputDebugString(buffer);
    51 }
    52 #endif
    53 
    54 /* ----------------------------------------------------------- */
     43# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
     44# define REL_TYPE_DIRECT R_ARM_ABS32
     45# define R_XXX_THUNKFIX R_ARM_ABS32
     46# define R_XXX_RELATIVE R_ARM_RELATIVE
     47# define IMAGE_FILE_MACHINE 0x01C0
     48# define RSRC_RELTYPE 7 /* ??? (not tested) */
     49
     50#elif defined TCC_TARGET_I386
     51# define ADDR3264 DWORD
     52# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
     53# define REL_TYPE_DIRECT R_386_32
     54# define R_XXX_THUNKFIX R_386_32
     55# define R_XXX_RELATIVE R_386_RELATIVE
     56# define IMAGE_FILE_MACHINE 0x014C
     57# define RSRC_RELTYPE 7 /* DIR32NB */
     58
     59#endif
     60
    5561#ifndef IMAGE_NT_SIGNATURE
    5662/* ----------------------------------------------------------- */
     
    224230#define IMAGE_REL_BASED_SECTION          6
    225231#define IMAGE_REL_BASED_REL32            7
     232#define IMAGE_REL_BASED_DIR64           10
    226233
    227234#pragma pack(pop)
     
    230237#endif /* ndef IMAGE_NT_SIGNATURE */
    231238/* ----------------------------------------------------------- */
     239
     240#ifndef IMAGE_REL_BASED_DIR64
     241# define IMAGE_REL_BASED_DIR64 10
     242#endif
     243
    232244#pragma pack(push, 1)
    233 
    234245struct pe_header
    235246{
     
    264275    WORD type;
    265276};
    266 
    267277#pragma pack(pop)
    268278
     
    337347    DWORD sizeofheaders;
    338348    ADDR3264 imagebase;
     349    const char *start_symbol;
    339350    DWORD start_addr;
    340351    DWORD imp_offs;
     
    363374static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
    364375{
    365     const char *name = symtab_section->link->data + sym->st_name;
    366     if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2))
     376    const char *name = (char*)symtab_section->link->data + sym->st_name;
     377    if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL))
    367378        return name + 1;
    368379    return name;
     
    374385    const char *s, *p;
    375386    int sym_index = 0, n = 0;
     387    int a, err = 0;
    376388
    377389    do {
    378390        s = pe_export_name(s1, sym);
     391        a = 0;
    379392        if (n) {
    380393            /* second try: */
    381             if (sym->st_other & 2) {
     394            if (sym->st_other & ST_PE_STDCALL) {
    382395                /* try w/0 stdcall deco (windows API convention) */
    383396                p = strrchr(s, '@');
     
    387400            } else if (s[0] != '_') { /* try non-ansi function */
    388401                buffer[0] = '_', strcpy(buffer + 1, s);
    389             } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
    390                 strcpy(buffer, s + 6);
    391             } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
    392                 strcpy(buffer, s + 6);
     402            } else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */
     403                strcpy(buffer, s + 6), a = 1;
     404            } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */
     405                strcpy(buffer, s + 6), a = 1;
    393406            } else {
    394                 break;
     407                continue;
    395408            }
    396409            s = buffer;
     
    398411        sym_index = find_elf_sym(s1->dynsymtab_section, s);
    399412        // printf("find (%d) %d %s\n", n, sym_index, s);
     413        if (sym_index
     414            && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT
     415            && 0 == (sym->st_other & ST_PE_IMPORT)
     416            && 0 == a
     417            ) err = -1, sym_index = 0;
    400418    } while (0 == sym_index && ++n < 2);
    401     return sym_index;
     419    return n == 2 ? err : sym_index;
    402420}
    403421
     
    508526    {
    509527    /* IMAGE_FILE_HEADER filehdr */
    510 #if defined(TCC_TARGET_I386)
    511     0x014C,   /*WORD    Machine; */
    512 #elif defined(TCC_TARGET_X86_64)
    513     0x8664,   /*WORD    Machine; */
    514 #elif defined(TCC_TARGET_ARM)
    515     0x01C0,   /*WORD    Machine; */
    516 #endif
     528    IMAGE_FILE_MACHINE, /*WORD    Machine; */
    517529    0x0003, /*WORD    NumberOfSections; */
    518530    0x00000000, /*DWORD   TimeDateStamp; */
     
    623635            case sec_text:
    624636                pe_header.opthdr.BaseOfCode = addr;
    625                 pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
    626637                break;
    627638
     
    664675        }
    665676
    666         pstrcpy((char*)psh->Name, sizeof psh->Name, sh_name);
     677        strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
    667678
    668679        psh->Characteristics = pe_sec_flags[si->cls];
     
    676687            file_offset = pe_file_align(pe, file_offset + si->data_size);
    677688            psh->SizeOfRawData = file_offset - psh->PointerToRawData;
     689            if (si->cls == sec_text)
     690                pe_header.opthdr.SizeOfCode += psh->SizeOfRawData;
     691            else
     692                pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData;
    678693        }
    679694    }
     
    681696    //pe_header.filehdr.TimeDateStamp = time(NULL);
    682697    pe_header.filehdr.NumberOfSections = pe->sec_count;
     698    pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
    683699    pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
    684700    pe_header.opthdr.ImageBase = pe->imagebase;
     
    688704    if (PE_DLL == pe->type)
    689705        pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
     706    pe_header.filehdr.Characteristics |= pe->s1->pe_characteristics;
    690707
    691708    sum = 0;
     
    708725    pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
    709726    fclose (op);
     727#ifndef _WIN32
     728    chmod(pe->filename, 0777);
     729#endif
    710730
    711731    if (2 == pe->s1->verbose)
     
    717737}
    718738
    719 /*----------------------------------------------------------------------------*/
    720 
    721 #if defined(TCC_TARGET_X86_64)
    722 #define REL_TYPE_DIRECT R_X86_64_64
    723 #define R_XXX_THUNKFIX R_X86_64_PC32
    724 #define R_XXX_RELATIVE R_X86_64_RELATIVE
    725 
    726 #elif defined(TCC_TARGET_I386)
    727 #define REL_TYPE_DIRECT R_386_32
    728 #define R_XXX_THUNKFIX R_386_32
    729 #define R_XXX_RELATIVE R_386_RELATIVE
    730 
    731 #elif defined(TCC_TARGET_ARM)
    732 #define REL_TYPE_DIRECT R_ARM_ABS32
    733 #define R_XXX_THUNKFIX R_ARM_ABS32
    734 #define R_XXX_RELATIVE R_ARM_RELATIVE
    735 
    736 #endif
    737739/*----------------------------------------------------------------------------*/
    738740
     
    755757    p = tcc_mallocz(sizeof *p);
    756758    p->dll_index = dll_index;
    757     dynarray_add((void***)&pe->imp_info, &pe->imp_count, p);
     759    dynarray_add(&pe->imp_info, &pe->imp_count, p);
    758760
    759761found_dll:
     
    763765
    764766    s = tcc_mallocz(sizeof *s);
    765     dynarray_add((void***)&p->symbols, &p->sym_count, s);
     767    dynarray_add(&p->symbols, &p->sym_count, s);
    766768    s->sym_index = sym_index;
    767769    return s;
     770}
     771
     772void pe_free_imports(struct pe_info *pe)
     773{
     774    int i;
     775    for (i = 0; i < pe->imp_count; ++i) {
     776        struct pe_import_info *p = pe->imp_info[i];
     777        dynarray_reset(&p->symbols, &p->sym_count);
     778    }
     779    dynarray_reset(&pe->imp_info, &pe->imp_count);
    768780}
    769781
     
    819831                ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
    820832                ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
    821                 const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
     833                const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
     834                int ordinal;
    822835
    823836                org_sym->st_value = thk_ptr;
    824837                org_sym->st_shndx = pe->thunk->sh_num;
    825                 v = pe->thunk->data_offset + rva_base;
    826                 section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
    827                 put_elf_str(pe->thunk, name);
     838
     839                if (dllref)
     840                    v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */
     841                else
     842                    ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */
     843
    828844#ifdef TCC_IS_NATIVE
    829845                if (pe->type == PE_RUN) {
    830                     v = imp_sym->st_value;
    831846                    if (dllref) {
    832847                        if ( !dllref->handle )
    833848                            dllref->handle = LoadLibrary(dllref->name);
    834                         v = (ADDR3264)GetProcAddress(dllref->handle, name);
     849                        v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name);
    835850                    }
    836851                    if (!v)
    837                         tcc_error_noabort("undefined symbol '%s'", name);
     852                        tcc_error_noabort("can't build symbol '%s'", name);
     853                } else
     854#endif
     855                if (ordinal) {
     856                    v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1);
     857                } else {
     858                    v = pe->thunk->data_offset + rva_base;
     859                    section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
     860                    put_elf_str(pe->thunk, name);
    838861                }
    839 #endif
     862
    840863            } else {
    841864                v = 0; /* last entry is zero */
    842865            }
     866
    843867            *(ADDR3264*)(pe->thunk->data+thk_ptr) =
    844868            *(ADDR3264*)(pe->thunk->data+ent_ptr) = v;
     
    847871        }
    848872        dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
    849         dynarray_reset(&p->symbols, &p->sym_count);
    850     }
    851     dynarray_reset(&pe->imp_info, &pe->imp_count);
     873    }
    852874}
    853875
     
    877899
    878900    FILE *op;
    879     char buf[MAX_PATH];
     901    char buf[260];
    880902    const char *dllname;
    881903    const char *name;
     
    888910        sym = (ElfW(Sym)*)symtab_section->data + sym_index;
    889911        name = pe_export_name(pe->s1, sym);
    890         if ((sym->st_other & 1)
     912        if ((sym->st_other & ST_PE_EXPORT)
    891913            /* export only symbols from actually written sections */
    892914            && pe->s1->sections[sym->st_shndx]->sh_addr) {
     
    894916            p->index = sym_index;
    895917            p->name = name;
    896             dynarray_add((void***)&sorted, &sym_count, p);
     918            dynarray_add(&sorted, &sym_count, p);
    897919        }
    898920#if 0
    899         if (sym->st_other & 1)
     921        if (sym->st_other & ST_PE_EXPORT)
    900922            printf("export: %s\n", name);
    901         if (sym->st_other & 2)
     923        if (sym->st_other & ST_PE_STDCALL)
    902924            printf("stdcall: %s\n", name);
    903925#endif
     
    933955    pstrcpy(buf, sizeof buf, pe->filename);
    934956    strcpy(tcc_fileextension(buf), ".def");
    935     op = fopen(buf, "w");
     957    op = fopen(buf, "wb");
    936958    if (NULL == op) {
    937959        tcc_error_noabort("could not create '%s': %s", buf, strerror(errno));
     
    939961        fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
    940962        if (pe->s1->verbose)
    941             printf("<- %s (%d symbols)\n", buf, sym_count);
     963            printf("<- %s (%d symbol%s)\n", buf, sym_count, &"s"[sym_count < 2]);
    942964    }
    943965#endif
     
    946968    {
    947969        p = sorted[ord], sym_index = p->index, name = p->name;
    948         /* insert actual address later in pe_relocate_rva */
     970        /* insert actual address later in relocate_section() */
    949971        put_elf_reloc(symtab_section, pe->thunk,
    950972            func_o, R_XXX_RELATIVE, sym_index);
     
    9911013            if ((addr -= offset)  < (1<<12)) { /* one block spans 4k addresses */
    9921014                WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
    993                 *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12;
     1015                *wp = addr | PE_IMAGE_REL<<12;
    9941016                ++count;
    9951017                continue;
     
    10651087    Section *s;
    10661088
     1089    if (PE_DLL == pe->type)
     1090        pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0);
     1091
    10671092    // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
    10681093
     
    11571182}
    11581183
    1159 /* ------------------------------------------------------------- */
    1160 static void pe_relocate_rva (struct pe_info *pe, Section *s)
    1161 {
    1162     Section *sr = s->reloc;
    1163     ElfW_Rel *rel, *rel_end;
    1164     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    1165     for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
    1166         if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) {
    1167             int sym_index = ELFW(R_SYM)(rel->r_info);
    1168             DWORD addr = s->sh_addr;
    1169             if (sym_index) {
    1170                 ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
    1171                 addr = sym->st_value;
    1172             }
    1173             // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, s->name);
    1174             *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase;
    1175         }
    1176     }
    1177 }
    1178 
    11791184/*----------------------------------------------------------------------------*/
    11801185
     
    12081213        if (sym->st_shndx == SHN_UNDEF) {
    12091214
    1210             const char *name = symtab_section->link->data + sym->st_name;
     1215            const char *name = (char*)symtab_section->link->data + sym->st_name;
    12111216            unsigned type = ELFW(ST_TYPE)(sym->st_info);
    12121217            int imp_sym = pe_find_import(pe->s1, sym);
    12131218            struct import_symbol *is;
    12141219
    1215             if (0 == imp_sym)
     1220            if (imp_sym <= 0)
    12161221                goto not_found;
    12171222
     
    12711276                sym->st_value = offset;
    12721277                sym->st_shndx = text_section->sh_num;
    1273                 sym->st_other &= ~1; /* do not export */
     1278                sym->st_other &= ~ST_PE_EXPORT; /* do not export */
    12741279                continue;
    12751280            }
     
    12841289
    12851290        not_found:
    1286             tcc_error_noabort("undefined symbol '%s'", name);
     1291            if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
     1292                /* STB_WEAK undefined symbols are accepted */
     1293                continue;
     1294            tcc_error_noabort("undefined symbol '%s'%s", name,
     1295                imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
    12871296            ret = -1;
    12881297
     
    12901299                   && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    12911300            /* if -rdynamic option, then export all non local symbols */
    1292             sym->st_other |= 1;
     1301            sym->st_other |= ST_PE_EXPORT;
    12931302        }
    12941303    }
     
    13001309static void pe_print_section(FILE * f, Section * s)
    13011310{
    1302     /* just if you'r curious */
     1311    /* just if you're curious */
    13031312    BYTE *p, *e, b;
    13041313    int i, n, l, m;
     
    14381447/* helper function for load/store to insert one more indirection */
    14391448
     1449#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    14401450ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
    14411451{
    1442     Sym *sym;
    1443     ElfW(Sym) *esym;
    14441452    int r2;
    1445 
    14461453    if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
    14471454        return sv;
    1448     sym = sv->sym;
    1449     if ((sym->type.t & (VT_EXTERN|VT_STATIC)) != VT_EXTERN)
     1455    if (!sv->sym->a.dllimport)
    14501456        return sv;
    1451     if (!sym->c)
    1452         put_extern_sym(sym, NULL, 0, 0);
    1453     esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    1454     if (!(esym->st_other & 4))
    1455         return sv;
    1456 
    1457     // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
    1458 
     1457    // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
    14591458    memset(v2, 0, sizeof *v2);
    14601459    v2->type.t = VT_PTR;
     
    14651464    load(r2, v2);
    14661465    v2->r = r2;
    1467 
    1468     if (sv->c.ui) {
     1466    if ((uint32_t)sv->c.i) {
    14691467        vpushv(v2);
    1470         vpushi(sv->c.ui);
     1468        vpushi(sv->c.i);
    14711469        gen_opi('+');
    14721470        *v2 = *vtop--;
    14731471    }
    1474 
    14751472    v2->type.t = sv->type.t;
    14761473    v2->r |= sv->r & VT_LVAL;
    14771474    return v2;
    14781475}
     1476#endif
    14791477
    14801478ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
    14811479{
    1482     return add_elf_sym(
     1480    return set_elf_sym(
    14831481        s1->dynsymtab_section,
    14841482        value,
     
    15001498    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
    15011499    strcpy(dllref->name, dllname);
    1502     dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
     1500    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
    15031501    return s1->nb_loaded_dlls;
    15041502}
     
    15101508    lseek(fd, offset, SEEK_SET);
    15111509    return len == read(fd, buffer, len);
     1510}
     1511
     1512/* ------------------------------------------------------------- */
     1513
     1514PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
     1515{
     1516    int l, i, n, n0, ret;
     1517    char *p;
     1518    int fd;
     1519
     1520    IMAGE_SECTION_HEADER ish;
     1521    IMAGE_EXPORT_DIRECTORY ied;
     1522    IMAGE_DOS_HEADER dh;
     1523    IMAGE_FILE_HEADER ih;
     1524    DWORD sig, ref, addr, ptr, namep;
     1525
     1526    int pef_hdroffset, opt_hdroffset, sec_hdroffset;
     1527
     1528    n = n0 = 0;
     1529    p = NULL;
     1530    ret = -1;
     1531
     1532    fd = open(filename, O_RDONLY | O_BINARY);
     1533    if (fd < 0)
     1534        goto the_end_1;
     1535    ret = 1;
     1536    if (!read_mem(fd, 0, &dh, sizeof dh))
     1537        goto the_end;
     1538    if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
     1539        goto the_end;
     1540    if (sig != 0x00004550)
     1541        goto the_end;
     1542    pef_hdroffset = dh.e_lfanew + sizeof sig;
     1543    if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
     1544        goto the_end;
     1545    opt_hdroffset = pef_hdroffset + sizeof ih;
     1546    if (ih.Machine == 0x014C) {
     1547        IMAGE_OPTIONAL_HEADER32 oh;
     1548        sec_hdroffset = opt_hdroffset + sizeof oh;
     1549        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
     1550            goto the_end;
     1551        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
     1552            goto the_end_0;
     1553        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
     1554    } else if (ih.Machine == 0x8664) {
     1555        IMAGE_OPTIONAL_HEADER64 oh;
     1556        sec_hdroffset = opt_hdroffset + sizeof oh;
     1557        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
     1558            goto the_end;
     1559        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
     1560            goto the_end_0;
     1561        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
     1562    } else
     1563        goto the_end;
     1564
     1565    //printf("addr: %08x\n", addr);
     1566    for (i = 0; i < ih.NumberOfSections; ++i) {
     1567        if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
     1568            goto the_end;
     1569        //printf("vaddr: %08x\n", ish.VirtualAddress);
     1570        if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
     1571            goto found;
     1572    }
     1573    goto the_end_0;
     1574
     1575found:
     1576    ref = ish.VirtualAddress - ish.PointerToRawData;
     1577    if (!read_mem(fd, addr - ref, &ied, sizeof ied))
     1578        goto the_end;
     1579
     1580    namep = ied.AddressOfNames - ref;
     1581    for (i = 0; i < ied.NumberOfNames; ++i) {
     1582        if (!read_mem(fd, namep, &ptr, sizeof ptr))
     1583            goto the_end;
     1584        namep += sizeof ptr;
     1585        for (l = 0;;) {
     1586            if (n+1 >= n0)
     1587                p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
     1588            if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
     1589                tcc_free(p), p = NULL;
     1590                goto the_end;
     1591            }
     1592            if (p[n++] == 0)
     1593                break;
     1594        }
     1595    }
     1596    if (p)
     1597        p[n] = 0;
     1598the_end_0:
     1599    ret = 0;
     1600the_end:
     1601    close(fd);
     1602the_end_1:
     1603    *pp = p;
     1604    return ret;
    15121605}
    15131606
     
    15211614    struct pe_rsrc_header hdr;
    15221615    Section *rsrc_section;
    1523     int i, ret = -1;
     1616    int i, ret = -1, sym_index;
    15241617    BYTE *ptr;
    15251618    unsigned offs;
     
    15281621        goto quit;
    15291622
    1530     if (hdr.filehdr.Machine != 0x014C
     1623    if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE
    15311624        || hdr.filehdr.NumberOfSections != 1
    1532         || strcmp(hdr.sectionhdr.Name, ".rsrc") != 0)
     1625        || strcmp((char*)hdr.sectionhdr.Name, ".rsrc") != 0)
    15331626        goto quit;
    15341627
     
    15391632        goto quit;
    15401633    offs = hdr.sectionhdr.PointerToRelocations;
    1541     for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
    1542     {
     1634    sym_index = put_elf_sym(symtab_section, 0, 0, 0, 0, rsrc_section->sh_num, ".rsrc");
     1635    for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) {
    15431636        struct pe_rsrc_reloc rel;
    15441637        if (!read_mem(fd, offs, &rel, sizeof rel))
    15451638            goto quit;
    15461639        // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
    1547         if (rel.type != 7) /* DIR32NB */
     1640        if (rel.type != RSRC_RELTYPE)
    15481641            goto quit;
    15491642        put_elf_reloc(symtab_section, rsrc_section,
    1550             rel.offset, R_XXX_RELATIVE, 0);
     1643            rel.offset, R_XXX_RELATIVE, sym_index);
    15511644        offs += sizeof rel;
    15521645    }
     
    15571650
    15581651/* ------------------------------------------------------------- */
     1652
    15591653static char *trimfront(char *p)
    15601654{
    15611655    while (*p && (unsigned char)*p <= ' ')
    1562         ++p;
     1656        ++p;
    15631657    return p;
    15641658}
     
    15671661{
    15681662    while (e > a && (unsigned char)e[-1] <= ' ')
    1569         --e;
     1663        --e;
    15701664    *e = 0;;
    15711665    return a;
    15721666}
    15731667
    1574 static char *get_line(char *line, int size, int fd)
    1575 {
    1576     int n;
    1577     for (n = 0; n < size - 1; )
    1578         if (read(fd, line + n, 1) < 1 || line[n++] == '\n')
    1579             break;
    1580     if (0 == n)
    1581         return NULL;
    1582     trimback(line, line + n);
    1583     return trimfront(line);
    1584 }
    1585 
    15861668/* ------------------------------------------------------------- */
    15871669static int pe_load_def(TCCState *s1, int fd)
    15881670{
    1589     int state = 0, ret = -1, dllindex = 0;
    1590     char line[400], dllname[80], *p;
    1591 
    1592     for (;;) {
    1593         p = get_line(line, sizeof line, fd);
    1594         if (NULL == p)
    1595             break;
     1671    int state = 0, ret = -1, dllindex = 0, ord;
     1672    char line[400], dllname[80], *p, *x;
     1673    FILE *fp;
     1674
     1675    fp = fdopen(dup(fd), "rb");
     1676    while (fgets(line, sizeof line, fp))
     1677    {
     1678        p = trimfront(trimback(line, strchr(line, 0)));
    15961679        if (0 == *p || ';' == *p)
    15971680            continue;
     1681
    15981682        switch (state) {
    15991683        case 0:
     
    16131697            dllindex = add_dllref(s1, dllname);
    16141698            ++state;
    1615 
     1699            /* fall through */
    16161700        default:
    1617             pe_putimport(s1, dllindex, p, 0);
     1701            /* get ordinal and will store in sym->st_value */
     1702            ord = 0;
     1703            x = strchr(p, ' ');
     1704            if (x) {
     1705                *x = 0, x = strrchr(x + 1, '@');
     1706                if (x) {
     1707                    char *d;
     1708                    ord = (int)strtol(x + 1, &d, 10);
     1709                    if (*d)
     1710                        ord = 0;
     1711                }
     1712            }
     1713            pe_putimport(s1, dllindex, p, ord);
    16181714            continue;
    16191715        }
     
    16211717    ret = 0;
    16221718quit:
     1719    fclose(fp);
    16231720    return ret;
    16241721}
    16251722
    16261723/* ------------------------------------------------------------- */
    1627 #define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
    1628 #include "win32/tools/tiny_impdef.c"
    1629 
    1630 static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
     1724static int pe_load_dll(TCCState *s1, const char *filename)
    16311725{
    16321726    char *p, *q;
    1633     int index;
    1634     p = get_export_names(fd);
    1635     if (!p)
     1727    int index, ret;
     1728
     1729    ret = tcc_get_dllexports(filename, &p);
     1730    if (ret) {
    16361731        return -1;
    1637     index = add_dllref(s1, dllname);
    1638     for (q = p; *q; q += 1 + strlen(q))
    1639         pe_putimport(s1, index, q, 0);
    1640     tcc_free(p);
     1732    } else if (p) {
     1733        index = add_dllref(s1, tcc_basename(filename));
     1734        for (q = p; *q; q += 1 + strlen(q))
     1735            pe_putimport(s1, index, q, 0);
     1736        tcc_free(p);
     1737    }
    16411738    return 0;
    16421739}
     
    16511748    else if (pe_load_res(s1, fd) == 0)
    16521749        ret = 0;
    1653     else if (read_mem(fd, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2))
    1654         ret = pe_load_dll(s1, tcc_basename(filename), fd);
     1750    else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
     1751        ret = pe_load_dll(s1, filename);
    16551752    return ret;
    16561753}
     
    16631760        s1->uw_pdata = find_section(tcc_state, ".pdata");
    16641761        s1->uw_pdata->sh_addralign = 4;
    1665         s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL);
    1666     }
    1667 
     1762    }
     1763    if (0 == s1->uw_sym)
     1764        s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, ".uw_base");
    16681765    if (0 == s1->uw_offs) {
    16691766        /* As our functions all have the same stackframe, we use one entry for all */
     
    17141811    /* put relocations on it */
    17151812    for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
    1716         put_elf_reloc(symtab_section, pd, o,  R_X86_64_RELATIVE, s1->uw_sym);
     1813        put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
    17171814}
    17181815#endif
     
    17271824{
    17281825    const char *start_symbol;
    1729     ADDR3264 addr = 0;
    17301826    int pe_type = 0;
     1827    int unicode_entry = 0;
    17311828
    17321829    if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
    17331830        pe_type = PE_GUI;
     1831    else
     1832    if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
     1833        pe_type = PE_GUI;
     1834        unicode_entry = PE_GUI;
     1835    }
    17341836    else
    17351837    if (TCC_OUTPUT_DLL == s1->output_type) {
     
    17381840        s1->output_type = TCC_OUTPUT_EXE;
    17391841    }
    1740     else
     1842    else {
    17411843        pe_type = PE_EXE;
     1844        if (find_elf_sym(symtab_section, "wmain"))
     1845            unicode_entry = PE_EXE;
     1846    }
    17421847
    17431848    start_symbol =
    17441849        TCC_OUTPUT_MEMORY == s1->output_type
    1745         ? PE_GUI == pe_type ? "__runwinmain" : "_main"
     1850        ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain")
     1851            : (unicode_entry ? "__runwmain" : "__runmain")
    17461852        : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
    1747         : PE_GUI == pe_type ? "__winstart" : "__start"
     1853            : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart")
     1854                : (unicode_entry ? "__wstart" : "__start")
    17481855        ;
    17491856
    1750     if (!s1->leading_underscore || strchr(start_symbol, '@')) {
     1857    if (!s1->leading_underscore || strchr(start_symbol, '@'))
    17511858        ++start_symbol;
    1752         if (start_symbol[0] != '_')
    1753             start_symbol = NULL;
    1754     }
    17551859
    17561860    /* grab the startup code from libtcc1 */
    1757     if (start_symbol)
    1758         add_elf_sym(symtab_section,
    1759             0, 0,
    1760             ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    1761             SHN_UNDEF, start_symbol);
     1861#ifdef TCC_IS_NATIVE
     1862    if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
     1863#endif
     1864    set_elf_sym(symtab_section,
     1865        0, 0,
     1866        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     1867        SHN_UNDEF, start_symbol);
     1868
     1869    tcc_add_pragma_libs(s1);
    17621870
    17631871    if (0 == s1->nostdlib) {
    17641872        static const char *libs[] = {
    1765             "libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
     1873            TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL
    17661874        };
    17671875        const char **pp, *p;
     
    17701878                if (PE_DLL != pe_type && PE_GUI != pe_type)
    17711879                    break;
    1772             } else if (pp == libs ? tcc_add_dll(s1, p, 0) : tcc_add_library(s1, p)) {
    1773                 tcc_error_noabort("cannot find library: %s", p);
    1774                 break;
     1880            } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) {
     1881                continue;
     1882            } else {
     1883                tcc_add_library_err(s1, p);
    17751884            }
    17761885        }
     
    17791888    if (TCC_OUTPUT_MEMORY == s1->output_type)
    17801889        pe_type = PE_RUN;
    1781 
    1782     if (start_symbol) {
    1783         addr = get_elf_sym_addr(s1, start_symbol, 1);
    1784         if (PE_RUN == pe_type && addr)
    1785             /* for -run GUI's, put '_runwinmain' instead of 'main' */
    1786             add_elf_sym(symtab_section,
    1787                     addr, 0,
    1788                     ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    1789                     text_section->sh_num, "main");
    1790     }
    1791 
    17921890    pe->type = pe_type;
    1793     pe->start_addr = addr;
    1794 }
    1795 
    1796 ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
     1891    pe->start_symbol = start_symbol;
     1892}
     1893
     1894static void pe_set_options(TCCState * s1, struct pe_info *pe)
     1895{
     1896    if (PE_DLL == pe->type) {
     1897        /* XXX: check if is correct for arm-pe target */
     1898        pe->imagebase = 0x10000000;
     1899    } else {
     1900#if defined(TCC_TARGET_ARM)
     1901        pe->imagebase = 0x00010000;
     1902#else
     1903        pe->imagebase = 0x00400000;
     1904#endif
     1905    }
     1906
     1907#if defined(TCC_TARGET_ARM)
     1908    /* we use "console" subsystem by default */
     1909    pe->subsystem = 9;
     1910#else
     1911    if (PE_DLL == pe->type || PE_GUI == pe->type)
     1912        pe->subsystem = 2;
     1913    else
     1914        pe->subsystem = 3;
     1915#endif
     1916    /* Allow override via -Wl,-subsystem=... option */
     1917    if (s1->pe_subsystem != 0)
     1918        pe->subsystem = s1->pe_subsystem;
     1919
     1920    /* set default file/section alignment */
     1921    if (pe->subsystem == 1) {
     1922        pe->section_align = 0x20;
     1923        pe->file_align = 0x20;
     1924    } else {
     1925        pe->section_align = 0x1000;
     1926        pe->file_align = 0x200;
     1927    }
     1928
     1929    if (s1->section_align != 0)
     1930        pe->section_align = s1->section_align;
     1931    if (s1->pe_file_align != 0)
     1932        pe->file_align = s1->pe_file_align;
     1933
     1934    if ((pe->subsystem >= 10) && (pe->subsystem <= 12))
     1935        pe->imagebase = 0;
     1936
     1937    if (s1->has_text_addr)
     1938        pe->imagebase = s1->text_addr;
     1939}
     1940
     1941ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
    17971942{
    17981943    int ret;
     
    18061951    tcc_add_bcheck(s1);
    18071952    pe_add_runtime(s1, &pe);
    1808     relocate_common_syms(); /* assign bss adresses */
    1809     tcc_add_linker_symbols(s1);
     1953    resolve_common_syms(s1);
     1954    pe_set_options(s1, &pe);
    18101955
    18111956    ret = pe_check_symbols(&pe);
     
    18131958        ;
    18141959    else if (filename) {
    1815         if (PE_DLL == pe.type) {
    1816             pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0);
    1817             /* XXX: check if is correct for arm-pe target */
    1818             pe.imagebase = 0x10000000;
    1819         } else {
    1820 #if defined(TCC_TARGET_ARM)
    1821             pe.imagebase = 0x00010000;
    1822 #else
    1823             pe.imagebase = 0x00400000;
    1824 #endif
    1825         }
    1826 
    1827 #if defined(TCC_TARGET_ARM)
    1828         /* we use "console" subsystem by default */
    1829         pe.subsystem = 9;
    1830 #else
    1831         if (PE_DLL == pe.type || PE_GUI == pe.type)
    1832             pe.subsystem = 2;
    1833         else
    1834             pe.subsystem = 3;
    1835 #endif
    1836         /* Allow override via -Wl,-subsystem=... option */
    1837         if (s1->pe_subsystem != 0)
    1838             pe.subsystem = s1->pe_subsystem;
    1839 
    1840         /* set default file/section alignment */
    1841         if (pe.subsystem == 1) {
    1842             pe.section_align = 0x20;
    1843             pe.file_align = 0x20;
    1844         } else {
    1845             pe.section_align = 0x1000;
    1846             pe.file_align = 0x200;
    1847         }
    1848 
    1849         if (s1->section_align != 0)
    1850             pe.section_align = s1->section_align;
    1851         if (s1->pe_file_align != 0)
    1852             pe.file_align = s1->pe_file_align;
    1853 
    1854         if ((pe.subsystem >= 10) && (pe.subsystem <= 12))
    1855             pe.imagebase = 0;
    1856 
    1857         if (s1->has_text_addr)
    1858             pe.imagebase = s1->text_addr;
    1859 
    18601960        pe_assign_addresses(&pe);
    1861         relocate_syms(s1, 0);
     1961        relocate_syms(s1, s1->symtab, 0);
     1962        s1->pe_imagebase = pe.imagebase;
    18621963        for (i = 1; i < s1->nb_sections; ++i) {
    18631964            Section *s = s1->sections[i];
    18641965            if (s->reloc) {
    18651966                relocate_section(s1, s);
    1866                 pe_relocate_rva(&pe, s);
    18671967            }
    18681968        }
     1969        pe.start_addr = (DWORD)
     1970            ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
     1971                - pe.imagebase);
    18691972        if (s1->nb_errors)
    18701973            ret = -1;
     
    18761979        pe.thunk = data_section;
    18771980        pe_build_imports(&pe);
    1878 #endif
    1879     }
     1981        s1->runtime_main = pe.start_symbol;
     1982#ifdef TCC_TARGET_X86_64
     1983        s1->uw_pdata = find_section(s1, ".pdata");
     1984#endif
     1985#endif
     1986    }
     1987
     1988    pe_free_imports(&pe);
    18801989
    18811990#ifdef PE_PRINT_SECTIONS
  • EcnlProtoTool/trunk/tcc-0.9.27/tccpp.c

    r321 r331  
    2525
    2626ST_DATA int tok_flags;
    27 /* additional informations about token */
    28 #define TOK_FLAG_BOL   0x0001 /* beginning of line before */
    29 #define TOK_FLAG_BOF   0x0002 /* beginning of file before */
    30 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
    31 #define TOK_FLAG_EOF   0x0008 /* end of file */
    32 
    3327ST_DATA int parse_flags;
    34 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
    35 #define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
    36 #define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
    37                                         token. line feed is also
    38                                         returned at eof */
    39 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
    40 #define PARSE_FLAG_SPACES     0x0010 /* next() returns space tokens (for -E) */
    4128
    4229ST_DATA struct BufferedFile *file;
     
    5441/* ------------------------------------------------------------------------- */
    5542
    56 static int *macro_ptr_allocated;
    57 static const int *unget_saved_macro_ptr;
    58 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
    59 static int unget_buffer_enabled;
    6043static TokenSym *hash_ident[TOK_HASH_SIZE];
    6144static char token_buf[STRING_MAX_SIZE + 1];
    62 /* true if isid(c) || isnum(c) */
    63 static unsigned char isidnum_table[256-CH_EOF];
     45static CString cstr_buf;
     46static CString macro_equal_buf;
     47static TokenString tokstr_buf;
     48static unsigned char isidnum_table[256 - CH_EOF];
     49static int pp_debug_tok, pp_debug_symv;
     50static int pp_once;
     51static int pp_expr;
     52static int pp_counter;
     53static void tok_print(const char *msg, const int *str);
     54
     55static struct TinyAlloc *toksym_alloc;
     56static struct TinyAlloc *tokstr_alloc;
     57static struct TinyAlloc *cstr_alloc;
     58
     59static TokenString *macro_stack;
    6460
    6561static const char tcc_keywords[] =
     
    7167/* WARNING: the content of this string encodes token numbers */
    7268static const unsigned char tok_two_chars[] =
     69/* outdated -- gr
    7370    "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
    7471    "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
    75 
    76 struct macro_level {
    77     struct macro_level *prev;
    78     const int *p;
     72*/{
     73    '<','=', TOK_LE,
     74    '>','=', TOK_GE,
     75    '!','=', TOK_NE,
     76    '&','&', TOK_LAND,
     77    '|','|', TOK_LOR,
     78    '+','+', TOK_INC,
     79    '-','-', TOK_DEC,
     80    '=','=', TOK_EQ,
     81    '<','<', TOK_SHL,
     82    '>','>', TOK_SAR,
     83    '+','=', TOK_A_ADD,
     84    '-','=', TOK_A_SUB,
     85    '*','=', TOK_A_MUL,
     86    '/','=', TOK_A_DIV,
     87    '%','=', TOK_A_MOD,
     88    '&','=', TOK_A_AND,
     89    '^','=', TOK_A_XOR,
     90    '|','=', TOK_A_OR,
     91    '-','>', TOK_ARROW,
     92    '.','.', TOK_TWODOTS,
     93    '#','#', TOK_TWOSHARPS,
     94    0
    7995};
    8096
    81 ST_FUNC void next_nomacro(void);
    8297static void next_nomacro_spc(void);
    83 static void macro_subst(
    84     TokenString *tok_str,
    85     Sym **nested_list,
    86     const int *macro_str,
    87     struct macro_level **can_read_stream
    88     );
    8998
    9099ST_FUNC void skip(int c)
     
    101110
    102111/* ------------------------------------------------------------------------- */
     112/* Custom allocator for tiny objects */
     113
     114//#define USE_TAL
     115
     116#ifndef USE_TAL
     117#define tal_free(al, p) tcc_free(p)
     118#define tal_realloc(al, p, size) tcc_realloc(p, size)
     119#define tal_new(a,b,c)
     120#define tal_delete(a)
     121#else
     122#if !defined(MEM_DEBUG)
     123#define tal_free(al, p) tal_free_impl(al, p)
     124#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
     125#define TAL_DEBUG_PARAMS
     126#else
     127#define TAL_DEBUG 1
     128//#define TAL_INFO 1 /* collect and dump allocators stats */
     129#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
     130#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
     131#define TAL_DEBUG_PARAMS , const char *file, int line
     132#define TAL_DEBUG_FILE_LEN 40
     133#endif
     134
     135#define TOKSYM_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenSym in table_ident */
     136#define TOKSTR_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenString instances */
     137#define CSTR_TAL_SIZE       (256 * 1024) /* allocator for tiny CString instances */
     138#define TOKSYM_TAL_LIMIT    256 /* prefer unique limits to distinguish allocators debug msgs */
     139#define TOKSTR_TAL_LIMIT    128 /* 32 * sizeof(int) */
     140#define CSTR_TAL_LIMIT      1024
     141
     142typedef struct TinyAlloc {
     143    unsigned  limit;
     144    unsigned  size;
     145    uint8_t *buffer;
     146    uint8_t *p;
     147    unsigned  nb_allocs;
     148    struct TinyAlloc *next, *top;
     149#ifdef TAL_INFO
     150    unsigned  nb_peak;
     151    unsigned  nb_total;
     152    unsigned  nb_missed;
     153    uint8_t *peak_p;
     154#endif
     155} TinyAlloc;
     156
     157typedef struct tal_header_t {
     158    unsigned  size;
     159#ifdef TAL_DEBUG
     160    int     line_num; /* negative line_num used for double free check */
     161    char    file_name[TAL_DEBUG_FILE_LEN + 1];
     162#endif
     163} tal_header_t;
     164
     165/* ------------------------------------------------------------------------- */
     166
     167static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
     168{
     169    TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
     170    al->p = al->buffer = tcc_malloc(size);
     171    al->limit = limit;
     172    al->size = size;
     173    if (pal) *pal = al;
     174    return al;
     175}
     176
     177static void tal_delete(TinyAlloc *al)
     178{
     179    TinyAlloc *next;
     180
     181tail_call:
     182    if (!al)
     183        return;
     184#ifdef TAL_INFO
     185    fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",
     186            al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,
     187            (al->peak_p - al->buffer) * 100.0 / al->size);
     188#endif
     189#ifdef TAL_DEBUG
     190    if (al->nb_allocs > 0) {
     191        uint8_t *p;
     192        fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n",
     193                al->nb_allocs, al->limit);
     194        p = al->buffer;
     195        while (p < al->p) {
     196            tal_header_t *header = (tal_header_t *)p;
     197            if (header->line_num > 0) {
     198                fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
     199                        header->file_name, header->line_num, header->size);
     200            }
     201            p += header->size + sizeof(tal_header_t);
     202        }
     203#if MEM_DEBUG-0 == 2
     204        exit(2);
     205#endif
     206    }
     207#endif
     208    next = al->next;
     209    tcc_free(al->buffer);
     210    tcc_free(al);
     211    al = next;
     212    goto tail_call;
     213}
     214
     215static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
     216{
     217    if (!p)
     218        return;
     219tail_call:
     220    if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) {
     221#ifdef TAL_DEBUG
     222        tal_header_t *header = (((tal_header_t *)p) - 1);
     223        if (header->line_num < 0) {
     224            fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
     225                    file, line);
     226            fprintf(stderr, "%s:%d: %d bytes\n",
     227                    header->file_name, (int)-header->line_num, (int)header->size);
     228        } else
     229            header->line_num = -header->line_num;
     230#endif
     231        al->nb_allocs--;
     232        if (!al->nb_allocs)
     233            al->p = al->buffer;
     234    } else if (al->next) {
     235        al = al->next;
     236        goto tail_call;
     237    }
     238    else
     239        tcc_free(p);
     240}
     241
     242static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
     243{
     244    tal_header_t *header;
     245    void *ret;
     246    int is_own;
     247    unsigned adj_size = (size + 3) & -4;
     248    TinyAlloc *al = *pal;
     249
     250tail_call:
     251    is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size);
     252    if ((!p || is_own) && size <= al->limit) {
     253        if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) {
     254            header = (tal_header_t *)al->p;
     255            header->size = adj_size;
     256#ifdef TAL_DEBUG
     257            { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
     258            strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
     259            header->file_name[TAL_DEBUG_FILE_LEN] = 0;
     260            header->line_num = line; }
     261#endif
     262            ret = al->p + sizeof(tal_header_t);
     263            al->p += adj_size + sizeof(tal_header_t);
     264            if (is_own) {
     265                header = (((tal_header_t *)p) - 1);
     266                memcpy(ret, p, header->size);
     267#ifdef TAL_DEBUG
     268                header->line_num = -header->line_num;
     269#endif
     270            } else {
     271                al->nb_allocs++;
     272            }
     273#ifdef TAL_INFO
     274            if (al->nb_peak < al->nb_allocs)
     275                al->nb_peak = al->nb_allocs;
     276            if (al->peak_p < al->p)
     277                al->peak_p = al->p;
     278            al->nb_total++;
     279#endif
     280            return ret;
     281        } else if (is_own) {
     282            al->nb_allocs--;
     283            ret = tal_realloc(*pal, 0, size);
     284            header = (((tal_header_t *)p) - 1);
     285            memcpy(ret, p, header->size);
     286#ifdef TAL_DEBUG
     287            header->line_num = -header->line_num;
     288#endif
     289            return ret;
     290        }
     291        if (al->next) {
     292            al = al->next;
     293        } else {
     294            TinyAlloc *bottom = al, *next = al->top ? al->top : al;
     295
     296            al = tal_new(pal, next->limit, next->size * 2);
     297            al->next = next;
     298            bottom->top = al;
     299        }
     300        goto tail_call;
     301    }
     302    if (is_own) {
     303        al->nb_allocs--;
     304        ret = tcc_malloc(size);
     305        header = (((tal_header_t *)p) - 1);
     306        memcpy(ret, p, header->size);
     307#ifdef TAL_DEBUG
     308        header->line_num = -header->line_num;
     309#endif
     310    } else if (al->next) {
     311        al = al->next;
     312        goto tail_call;
     313    } else
     314        ret = tcc_realloc(p, size);
     315#ifdef TAL_INFO
     316    al->nb_missed++;
     317#endif
     318    return ret;
     319}
     320
     321#endif /* USE_TAL */
     322
     323/* ------------------------------------------------------------------------- */
    103324/* CString handling */
    104325static void cstr_realloc(CString *cstr, int new_size)
    105326{
    106327    int size;
    107     void *data;
    108328
    109329    size = cstr->size_allocated;
    110     if (size == 0)
     330    if (size < 8)
    111331        size = 8; /* no need to allocate a too small first string */
    112332    while (size < new_size)
    113333        size = size * 2;
    114     data = tcc_realloc(cstr->data_allocated, size);
    115     cstr->data_allocated = data;
     334    cstr->data = tal_realloc(cstr_alloc, cstr->data, size);
    116335    cstr->size_allocated = size;
    117     cstr->data = data;
    118336}
    119337
    120338/* add a byte */
    121 ST_FUNC void cstr_ccat(CString *cstr, int ch)
     339ST_INLN void cstr_ccat(CString *cstr, int ch)
    122340{
    123341    int size;
     
    129347}
    130348
    131 ST_FUNC void cstr_cat(CString *cstr, const char *str)
    132 {
    133     int c;
    134     for(;;) {
    135         c = *str;
    136         if (c == '\0')
    137             break;
    138         cstr_ccat(cstr, c);
    139         str++;
    140     }
     349ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
     350{
     351    int size;
     352    if (len <= 0)
     353        len = strlen(str) + 1 + len;
     354    size = cstr->size + len;
     355    if (size > cstr->size_allocated)
     356        cstr_realloc(cstr, size);
     357    memmove(((unsigned char *)cstr->data) + cstr->size, str, len);
     358    cstr->size = size;
    141359}
    142360
     
    160378ST_FUNC void cstr_free(CString *cstr)
    161379{
    162     tcc_free(cstr->data_allocated);
     380    tal_free(cstr_alloc, cstr->data);
    163381    cstr_new(cstr);
    164382}
     
    199417
    200418    if (tok_ident >= SYM_FIRST_ANOM)
    201         tcc_error("memory full");
     419        tcc_error("memory full (symbols)");
    202420
    203421    /* expand token table if needed */
     
    208426    }
    209427
    210     ts = tcc_malloc(sizeof(TokenSym) + len);
     428    ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len);
    211429    table_ident[i] = ts;
    212430    ts->tok = tok_ident++;
     
    224442
    225443#define TOK_HASH_INIT 1
    226 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
     444#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c))
     445
    227446
    228447/* find a token and add it if not found */
     
    252471/* XXX: buffer overflow */
    253472/* XXX: float tokens */
    254 ST_FUNC char *get_tok_str(int v, CValue *cv)
    255 {
    256     static char buf[STRING_MAX_SIZE + 1];
    257     static CString cstr_buf;
    258     CString *cstr;
     473ST_FUNC const char *get_tok_str(int v, CValue *cv)
     474{
    259475    char *p;
    260476    int i, len;
    261477
    262     /* NOTE: to go faster, we give a fixed buffer for small strings */
    263478    cstr_reset(&cstr_buf);
    264     cstr_buf.data = buf;
    265     cstr_buf.size_allocated = sizeof(buf);
    266     p = buf;
     479    p = cstr_buf.data;
    267480
    268481    switch(v) {
    269482    case TOK_CINT:
    270483    case TOK_CUINT:
    271         /* XXX: not quite exact, but only useful for testing */
    272         sprintf(p, "%u", cv->ui);
    273         break;
     484    case TOK_CLONG:
     485    case TOK_CULONG:
    274486    case TOK_CLLONG:
    275487    case TOK_CULLONG:
    276488        /* XXX: not quite exact, but only useful for testing  */
    277489#ifdef _WIN32
    278         sprintf(p, "%u", (unsigned)cv->ull);
     490        sprintf(p, "%u", (unsigned)cv->i);
    279491#else
    280         sprintf(p, "%Lu", cv->ull);
     492        sprintf(p, "%llu", (unsigned long long)cv->i);
    281493#endif
    282494        break;
     
    290502        break;
    291503    case TOK_PPNUM:
    292         cstr = cv->cstr;
    293         len = cstr->size - 1;
    294         for(i=0;i<len;i++)
    295             add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
    296         cstr_ccat(&cstr_buf, '\0');
    297         break;
     504    case TOK_PPSTR:
     505        return (char*)cv->str.data;
    298506    case TOK_LSTR:
    299507        cstr_ccat(&cstr_buf, 'L');
    300508    case TOK_STR:
    301         cstr = cv->cstr;
    302509        cstr_ccat(&cstr_buf, '\"');
    303510        if (v == TOK_STR) {
    304             len = cstr->size - 1;
     511            len = cv->str.size - 1;
    305512            for(i=0;i<len;i++)
    306                 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
     513                add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]);
    307514        } else {
    308             len = (cstr->size / sizeof(nwchar_t)) - 1;
     515            len = (cv->str.size / sizeof(nwchar_t)) - 1;
    309516            for(i=0;i<len;i++)
    310                 add_char(&cstr_buf, ((nwchar_t *)cstr->data)[i]);
     517                add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]);
    311518        }
    312519        cstr_ccat(&cstr_buf, '\"');
    313520        cstr_ccat(&cstr_buf, '\0');
    314521        break;
     522
     523    case TOK_CFLOAT:
     524        cstr_cat(&cstr_buf, "<float>", 0);
     525        break;
     526    case TOK_CDOUBLE:
     527        cstr_cat(&cstr_buf, "<double>", 0);
     528        break;
     529    case TOK_CLDOUBLE:
     530        cstr_cat(&cstr_buf, "<long double>", 0);
     531        break;
     532    case TOK_LINENUM:
     533        cstr_cat(&cstr_buf, "<linenumber>", 0);
     534        break;
     535
     536    /* above tokens have value, the ones below don't */
    315537    case TOK_LT:
    316538        v = '<';
     
    325547    case TOK_A_SAR:
    326548        return strcpy(p, ">>=");
     549    case TOK_EOF:
     550        return strcpy(p, "<eof>");
    327551    default:
    328552        if (v < TOK_IDENT) {
     
    334558                    *p++ = q[1];
    335559                    *p = '\0';
    336                     return buf;
     560                    return cstr_buf.data;
    337561                }
    338562                q += 3;
    339563            }
     564        if (v >= 127) {
     565            sprintf(cstr_buf.data, "<%02x>", v);
     566            return cstr_buf.data;
     567        }
    340568        addv:
    341569            *p++ = v;
     
    355583}
    356584
    357 /* fill input buffer and peek next char */
    358 static int tcc_peekc_slow(BufferedFile *bf)
    359 {
     585/* return the current character, handling end of block if necessary
     586   (but not stray) */
     587ST_FUNC int handle_eob(void)
     588{
     589    BufferedFile *bf = file;
    360590    int len;
     591
    361592    /* only tries to read if really end of buffer */
    362593    if (bf->buf_ptr >= bf->buf_end) {
    363         if (bf->fd != -1) {
     594        if (bf->fd >= 0) {
    364595#if defined(PARSE_DEBUG)
    365             len = 8;
     596            len = 1;
    366597#else
    367598            len = IO_BUF_SIZE;
     
    384615        return CH_EOF;
    385616    }
    386 }
    387 
    388 /* return the current character, handling end of block if necessary
    389    (but not stray) */
    390 ST_FUNC int handle_eob(void)
    391 {
    392     return tcc_peekc_slow(file);
    393617}
    394618
     
    436660    int c;
    437661
     662    file->buf_ptr = p;
    438663    if (p >= file->buf_end) {
    439         file->buf_ptr = p;
    440664        c = handle_eob();
     665        if (c != '\\')
     666            return c;
    441667        p = file->buf_ptr;
    442         if (c == '\\')
    443             goto parse_stray;
    444     } else {
    445     parse_stray:
    446         file->buf_ptr = p;
    447         ch = *p;
    448         handle_stray();
    449         p = file->buf_ptr;
    450         c = *p;
    451     }
     668    }
     669    ch = *p;
     670    if (handle_stray_noerror()) {
     671        if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
     672            tcc_error("stray '\\' in program");
     673        *--file->buf_ptr = '\\';
     674    }
     675    p = file->buf_ptr;
     676    c = *p;
    452677    return c;
    453678}
     
    485710        handle_stray();
    486711}
    487 
    488712
    489713/* single line C++ comments */
     
    528752{
    529753    int c;
    530    
     754
    531755    p++;
    532756    for(;;) {
     
    558782                    c = handle_eob();
    559783                    p = file->buf_ptr;
     784                    if (c == CH_EOF)
     785                        tcc_error("unexpected end of file in comment");
    560786                    if (c == '\\') {
    561787                        /* skip '\[\r]\n', otherwise just skip the stray */
     
    598824}
    599825
     826ST_FUNC int set_idnum(int c, int val)
     827{
     828    int prev = isidnum_table[c - CH_EOF];
     829    isidnum_table[c - CH_EOF] = val;
     830    return prev;
     831}
     832
    600833#define cinp minp
    601834
    602835static inline void skip_spaces(void)
    603836{
    604     while (is_space(ch))
     837    while (isidnum_table[ch - CH_EOF] & IS_SPC)
    605838        cinp();
    606839}
     
    608841static inline int check_space(int t, int *spc)
    609842{
    610     if (is_space(t)) {
     843    if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
    611844        if (*spc)
    612845            return 1;
     
    756989                else if (tok == TOK_LINEFEED)
    757990                    goto redo_start;
    758             }
     991                else if (parse_flags & PARSE_FLAG_ASM_FILE)
     992                    p = parse_line_comment(p - 1);
     993            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
     994                p = parse_line_comment(p - 1);
    759995            break;
    760996_default:
     
    7691005}
    7701006
    771 /* ParseState handling */
    772 
    773 /* XXX: currently, no include file info is stored. Thus, we cannot display
    774    accurate messages if the function or data definition spans multiple
    775    files */
    776 
    777 /* save current parse state in 's' */
    778 ST_FUNC void save_parse_state(ParseState *s)
    779 {
    780     s->line_num = file->line_num;
    781     s->macro_ptr = macro_ptr;
    782     s->tok = tok;
    783     s->tokc = tokc;
    784 }
    785 
    786 /* restore parse state from 's' */
    787 ST_FUNC void restore_parse_state(ParseState *s)
    788 {
    789     file->line_num = s->line_num;
    790     macro_ptr = s->macro_ptr;
    791     tok = s->tok;
    792     tokc = s->tokc;
    793 }
    794 
     1007#if 0
    7951008/* return the number of additional 'ints' necessary to store the
    7961009   token */
    797 static inline int tok_ext_size(int t)
    798 {
    799     switch(t) {
     1010static inline int tok_size(const int *p)
     1011{
     1012    switch(*p) {
    8001013        /* 4 bytes */
    8011014    case TOK_CINT:
     
    8051018    case TOK_CFLOAT:
    8061019    case TOK_LINENUM:
    807         return 1;
     1020        return 1 + 1;
    8081021    case TOK_STR:
    8091022    case TOK_LSTR:
    8101023    case TOK_PPNUM:
    811         tcc_error("unsupported token");
    812         return 1;
     1024    case TOK_PPSTR:
     1025        return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
     1026    case TOK_CLONG:
     1027    case TOK_CULONG:
     1028        return 1 + LONG_SIZE / 4;
    8131029    case TOK_CDOUBLE:
    8141030    case TOK_CLLONG:
    8151031    case TOK_CULLONG:
    816         return 2;
     1032        return 1 + 2;
    8171033    case TOK_CLDOUBLE:
    818         return LDOUBLE_SIZE / 4;
     1034        return 1 + LDOUBLE_SIZE / 4;
    8191035    default:
    820         return 0;
    821     }
    822 }
     1036        return 1 + 0;
     1037    }
     1038}
     1039#endif
    8231040
    8241041/* token string handling */
    825 
    8261042ST_INLN void tok_str_new(TokenString *s)
    8271043{
    8281044    s->str = NULL;
    829     s->len = 0;
     1045    s->len = s->lastlen = 0;
    8301046    s->allocated_len = 0;
    8311047    s->last_line_num = -1;
    8321048}
    8331049
    834 ST_FUNC void tok_str_free(int *str)
    835 {
    836     tcc_free(str);
    837 }
    838 
    839 static int *tok_str_realloc(TokenString *s)
    840 {
    841     int *str, len;
    842 
    843     if (s->allocated_len == 0) {
    844         len = 8;
    845     } else {
    846         len = s->allocated_len * 2;
    847     }
    848     str = tcc_realloc(s->str, len * sizeof(int));
    849     s->allocated_len = len;
    850     s->str = str;
     1050ST_FUNC TokenString *tok_str_alloc(void)
     1051{
     1052    TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str);
     1053    tok_str_new(str);
    8511054    return str;
     1055}
     1056
     1057ST_FUNC int *tok_str_dup(TokenString *s)
     1058{
     1059    int *str;
     1060
     1061    str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int));
     1062    memcpy(str, s->str, s->len * sizeof(int));
     1063    return str;
     1064}
     1065
     1066ST_FUNC void tok_str_free_str(int *str)
     1067{
     1068    tal_free(tokstr_alloc, str);
     1069}
     1070
     1071ST_FUNC void tok_str_free(TokenString *str)
     1072{
     1073    tok_str_free_str(str->str);
     1074    tal_free(tokstr_alloc, str);
     1075}
     1076
     1077ST_FUNC int *tok_str_realloc(TokenString *s, int new_size)
     1078{
     1079    int *str, size;
     1080
     1081    size = s->allocated_len;
     1082    if (size < 16)
     1083        size = 16;
     1084    while (size < new_size)
     1085        size = size * 2;
     1086    if (size > s->allocated_len) {
     1087        str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int));
     1088        s->allocated_len = size;
     1089        s->str = str;
     1090    }
     1091    return s->str;
    8521092}
    8531093
     
    8591099    str = s->str;
    8601100    if (len >= s->allocated_len)
    861         str = tok_str_realloc(s);
     1101        str = tok_str_realloc(s, len + 1);
    8621102    str[len++] = t;
    8631103    s->len = len;
    8641104}
    8651105
     1106ST_FUNC void begin_macro(TokenString *str, int alloc)
     1107{
     1108    str->alloc = alloc;
     1109    str->prev = macro_stack;
     1110    str->prev_ptr = macro_ptr;
     1111    str->save_line_num = file->line_num;
     1112    macro_ptr = str->str;
     1113    macro_stack = str;
     1114}
     1115
     1116ST_FUNC void end_macro(void)
     1117{
     1118    TokenString *str = macro_stack;
     1119    macro_stack = str->prev;
     1120    macro_ptr = str->prev_ptr;
     1121    file->line_num = str->save_line_num;
     1122    if (str->alloc == 2) {
     1123        str->alloc = 3; /* just mark as finished */
     1124    } else {
     1125        tok_str_free(str);
     1126    }
     1127}
     1128
    8661129static void tok_str_add2(TokenString *s, int t, CValue *cv)
    8671130{
    8681131    int len, *str;
    8691132
    870     len = s->len;
     1133    len = s->lastlen = s->len;
    8711134    str = s->str;
    8721135
    8731136    /* allocate space for worst case */
    874     if (len + TOK_MAX_SIZE > s->allocated_len)
    875         str = tok_str_realloc(s);
     1137    if (len + TOK_MAX_SIZE >= s->allocated_len)
     1138        str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1);
    8761139    str[len++] = t;
    8771140    switch(t) {
     
    8821145    case TOK_CFLOAT:
    8831146    case TOK_LINENUM:
     1147#if LONG_SIZE == 4
     1148    case TOK_CLONG:
     1149    case TOK_CULONG:
     1150#endif
    8841151        str[len++] = cv->tab[0];
    8851152        break;
    8861153    case TOK_PPNUM:
     1154    case TOK_PPSTR:
    8871155    case TOK_STR:
    8881156    case TOK_LSTR:
    8891157        {
    890             int nb_words;
    891             CString *cstr;
    892 
    893             nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
    894             while ((len + nb_words) > s->allocated_len)
    895                 str = tok_str_realloc(s);
    896             cstr = (CString *)(str + len);
    897             cstr->data = NULL;
    898             cstr->size = cv->cstr->size;
    899             cstr->data_allocated = NULL;
    900             cstr->size_allocated = cstr->size;
    901             memcpy((char *)cstr + sizeof(CString),
    902                    cv->cstr->data, cstr->size);
     1158            /* Insert the string into the int array. */
     1159            size_t nb_words =
     1160                1 + (cv->str.size + sizeof(int) - 1) / sizeof(int);
     1161            if (len + nb_words >= s->allocated_len)
     1162                str = tok_str_realloc(s, len + nb_words + 1);
     1163            str[len] = cv->str.size;
     1164            memcpy(&str[len + 1], cv->str.data, cv->str.size);
    9031165            len += nb_words;
    9041166        }
     
    9071169    case TOK_CLLONG:
    9081170    case TOK_CULLONG:
     1171#if LONG_SIZE == 8
     1172    case TOK_CLONG:
     1173    case TOK_CULONG:
     1174#endif
    9091175#if LDOUBLE_SIZE == 8
    9101176    case TOK_CLDOUBLE:
     
    9571223    tab = cv->tab;
    9581224    switch(*t = *p++) {
     1225#if LONG_SIZE == 4
     1226    case TOK_CLONG:
     1227#endif
    9591228    case TOK_CINT:
    960     case TOK_CUINT:
    9611229    case TOK_CCHAR:
    9621230    case TOK_LCHAR:
     1231    case TOK_LINENUM:
     1232        cv->i = *p++;
     1233        break;
     1234#if LONG_SIZE == 4
     1235    case TOK_CULONG:
     1236#endif
     1237    case TOK_CUINT:
     1238        cv->i = (unsigned)*p++;
     1239        break;
    9631240    case TOK_CFLOAT:
    964     case TOK_LINENUM:
    965         tab[0] = *p++;
    966         break;
     1241        tab[0] = *p++;
     1242        break;
    9671243    case TOK_STR:
    9681244    case TOK_LSTR:
    9691245    case TOK_PPNUM:
    970         cv->cstr = (CString *)p;
    971         cv->cstr->data = (char *)p + sizeof(CString);
    972         p += (sizeof(CString) + cv->cstr->size + 3) >> 2;
     1246    case TOK_PPSTR:
     1247        cv->str.size = *p++;
     1248        cv->str.data = p;
     1249        p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
    9731250        break;
    9741251    case TOK_CDOUBLE:
    9751252    case TOK_CLLONG:
    9761253    case TOK_CULLONG:
     1254#if LONG_SIZE == 8
     1255    case TOK_CLONG:
     1256    case TOK_CULONG:
     1257#endif
    9771258        n = 2;
    9781259        goto copy;
     
    10001281static int macro_is_equal(const int *a, const int *b)
    10011282{
    1002     char buf[STRING_MAX_SIZE + 1];
    10031283    CValue cv;
    10041284    int t;
     1285
     1286    if (!a || !b)
     1287        return 1;
     1288
    10051289    while (*a && *b) {
     1290        /* first time preallocate macro_equal_buf, next time only reset position to start */
     1291        cstr_reset(&macro_equal_buf);
    10061292        TOK_GET(&t, &a, &cv);
    1007         pstrcpy(buf, sizeof buf, get_tok_str(t, &cv));
     1293        cstr_cat(&macro_equal_buf, get_tok_str(t, &cv), 0);
    10081294        TOK_GET(&t, &b, &cv);
    1009         if (strcmp(buf, get_tok_str(t, &cv)))
     1295        if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv)))
    10101296            return 0;
    10111297    }
     
    10161302ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
    10171303{
    1018     Sym *s;
    1019 
    1020     s = define_find(v);
    1021     if (s && !macro_is_equal(s->d, str))
    1022         tcc_warning("%s redefined", get_tok_str(v, NULL));
    1023 
     1304    Sym *s, *o;
     1305
     1306    o = define_find(v);
    10241307    s = sym_push2(&define_stack, v, macro_type, 0);
    10251308    s->d = str;
    10261309    s->next = first_arg;
    10271310    table_ident[v - TOK_IDENT]->sym_define = s;
     1311
     1312    if (o && !macro_is_equal(o->d, s->d))
     1313        tcc_warning("%s redefined", get_tok_str(v, NULL));
    10281314}
    10291315
     
    10311317ST_FUNC void define_undef(Sym *s)
    10321318{
    1033     int v;
    1034     v = s->v;
     1319    int v = s->v;
    10351320    if (v >= TOK_IDENT && v < tok_ident)
    10361321        table_ident[v - TOK_IDENT]->sym_define = NULL;
    1037     s->v = 0;
    10381322}
    10391323
     
    10491333ST_FUNC void free_defines(Sym *b)
    10501334{
    1051     Sym *top, *top1;
    1052     int v;
    1053 
    1054     top = define_stack;
    1055     while (top != b) {
    1056         top1 = top->prev;
    1057         /* do not free args or predefined defines */
    1058         if (top->d)
    1059             tok_str_free(top->d);
    1060         v = top->v;
    1061         if (v >= TOK_IDENT && v < tok_ident)
    1062             table_ident[v - TOK_IDENT]->sym_define = NULL;
     1335    while (define_stack != b) {
     1336        Sym *top = define_stack;
     1337        define_stack = top->prev;
     1338        tok_str_free_str(top->d);
     1339        define_undef(top);
    10631340        sym_free(top);
    1064         top = top1;
    1065     }
    1066     define_stack = b;
     1341    }
     1342
     1343    /* restore remaining (-D or predefined) symbols if they were
     1344       #undef'd in the file */
     1345    while (b) {
     1346        int v = b->v;
     1347        if (v >= TOK_IDENT && v < tok_ident) {
     1348            Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
     1349            if (!*d)
     1350                *d = b;
     1351        }
     1352        b = b->prev;
     1353    }
    10671354}
    10681355
     
    10951382/* pop labels until element last is reached. Look if any labels are
    10961383   undefined. Define symbols if '&&label' was used. */
    1097 ST_FUNC void label_pop(Sym **ptop, Sym *slast)
     1384ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
    10981385{
    10991386    Sym *s, *s1;
     
    11141401        /* remove label */
    11151402        table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
    1116         sym_free(s);
    1117     }
    1118     *ptop = slast;
     1403        if (!keep)
     1404            sym_free(s);
     1405    }
     1406    if (!keep)
     1407        *ptop = slast;
     1408}
     1409
     1410/* fake the nth "#if defined test_..." for tcc -dt -run */
     1411static void maybe_run_test(TCCState *s)
     1412{
     1413    const char *p;
     1414    if (s->include_stack_ptr != s->include_stack)
     1415        return;
     1416    p = get_tok_str(tok, NULL);
     1417    if (0 != memcmp(p, "test_", 5))
     1418        return;
     1419    if (0 != --s->run_test)
     1420        return;
     1421    fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp);
     1422    define_push(tok, MACRO_OBJ, NULL, NULL);
    11191423}
    11201424
     
    11231427{
    11241428    int c, t;
    1125     TokenString str;
     1429    TokenString *str;
    11261430   
    1127     tok_str_new(&str);
     1431    str = tok_str_alloc();
     1432    pp_expr = 1;
    11281433    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
    11291434        next(); /* do macro subst */
     
    11331438            if (t == '(')
    11341439                next_nomacro();
     1440            if (tok < TOK_IDENT)
     1441                expect("identifier");
     1442            if (tcc_state->run_test)
     1443                maybe_run_test(tcc_state);
    11351444            c = define_find(tok) != 0;
    1136             if (t == '(')
     1445            if (t == '(') {
    11371446                next_nomacro();
     1447                if (tok != ')')
     1448                    expect("')'");
     1449            }
    11381450            tok = TOK_CINT;
    11391451            tokc.i = c;
     
    11431455            tokc.i = 0;
    11441456        }
    1145         tok_str_add_tok(&str);
    1146     }
    1147     tok_str_add(&str, -1); /* simulate end of file */
    1148     tok_str_add(&str, 0);
     1457        tok_str_add_tok(str);
     1458    }
     1459    pp_expr = 0;
     1460    tok_str_add(str, -1); /* simulate end of file */
     1461    tok_str_add(str, 0);
    11491462    /* now evaluate C constant expression */
    1150     macro_ptr = str.str;
     1463    begin_macro(str, 1);
    11511464    next();
    11521465    c = expr_const();
    1153     macro_ptr = NULL;
    1154     tok_str_free(str.str);
     1466    end_macro();
    11551467    return c != 0;
    11561468}
    11571469
    1158 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
    1159 static void tok_print(int *str)
    1160 {
    1161     int t;
    1162     CValue cval;
    1163 
    1164     printf("<");
    1165     while (1) {
    1166         TOK_GET(&t, &str, &cval);
    1167         if (!t)
    1168             break;
    1169         printf("%s", get_tok_str(t, &cval));
    1170     }
    1171     printf(">\n");
    1172 }
    1173 #endif
    11741470
    11751471/* parse after #define */
     
    11781474    Sym *s, *first, **ps;
    11791475    int v, t, varg, is_vaargs, spc;
    1180     TokenString str;
    1181    
     1476    int saved_parse_flags = parse_flags;
     1477
    11821478    v = tok;
    1183     if (v < TOK_IDENT)
     1479    if (v < TOK_IDENT || v == TOK_DEFINED)
    11841480        tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc));
    11851481    /* XXX: should check if same macro (ANSI) */
    11861482    first = NULL;
    11871483    t = MACRO_OBJ;
     1484    /* We have to parse the whole define as if not in asm mode, in particular
     1485       no line comment with '#' must be ignored.  Also for function
     1486       macros the argument list must be parsed without '.' being an ID
     1487       character.  */
     1488    parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
    11881489    /* '(' must be just after macro definition for MACRO_FUNC */
    11891490    next_nomacro_spc();
    11901491    if (tok == '(') {
     1492        int dotid = set_idnum('.', 0);
    11911493        next_nomacro();
    11921494        ps = &first;
    1193         while (tok != ')') {
     1495        if (tok != ')') for (;;) {
    11941496            varg = tok;
    11951497            next_nomacro();
     
    12031505            }
    12041506            if (varg < TOK_IDENT)
    1205                 tcc_error("badly punctuated parameter list");
     1507        bad_list:
     1508                tcc_error("bad macro parameter list");
    12061509            s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
    12071510            *ps = s;
    12081511            ps = &s->next;
    1209             if (tok != ',')
     1512            if (tok == ')')
    12101513                break;
     1514            if (tok != ',' || is_vaargs)
     1515                goto bad_list;
    12111516            next_nomacro();
    12121517        }
    1213         if (tok == ')')
    1214             next_nomacro_spc();
     1518        next_nomacro_spc();
    12151519        t = MACRO_FUNC;
    1216     }
    1217     tok_str_new(&str);
     1520        set_idnum('.', dotid);
     1521    }
     1522
     1523    tokstr_buf.len = 0;
    12181524    spc = 2;
    1219     /* EOF testing necessary for '-D' handling */
     1525    parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
     1526    /* The body of a macro definition should be parsed such that identifiers
     1527       are parsed like the file mode determines (i.e. with '.' being an
     1528       ID character in asm mode).  But '#' should be retained instead of
     1529       regarded as line comment leader, so still don't set ASM_FILE
     1530       in parse_flags. */
    12201531    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
    1221         /* remove spaces around ## and after '#' */       
     1532        /* remove spaces around ## and after '#' */
    12221533        if (TOK_TWOSHARPS == tok) {
     1534            if (2 == spc)
     1535                goto bad_twosharp;
    12231536            if (1 == spc)
    1224                 --str.len;
    1225             spc = 2;
     1537                --tokstr_buf.len;
     1538            spc = 3;
     1539            tok = TOK_PPJOIN;
    12261540        } else if ('#' == tok) {
    1227             spc = 2;
     1541            spc = 4;
    12281542        } else if (check_space(tok, &spc)) {
    12291543            goto skip;
    12301544        }
    1231         tok_str_add2(&str, tok, &tokc);
     1545        tok_str_add2(&tokstr_buf, tok, &tokc);
    12321546    skip:
    12331547        next_nomacro_spc();
    12341548    }
     1549
     1550    parse_flags = saved_parse_flags;
    12351551    if (spc == 1)
    1236         --str.len; /* remove trailing space */
    1237     tok_str_add(&str, 0);
    1238 #ifdef PP_DEBUG
    1239     printf("define %s %d: ", get_tok_str(v, NULL), t);
    1240     tok_print(str.str);
    1241 #endif
    1242     define_push(v, t, str.str, first);
    1243 }
    1244 
    1245 static inline int hash_cached_include(const char *filename)
     1552        --tokstr_buf.len; /* remove trailing space */
     1553    tok_str_add(&tokstr_buf, 0);
     1554    if (3 == spc)
     1555bad_twosharp:
     1556        tcc_error("'##' cannot appear at either end of macro");
     1557    define_push(v, t, tok_str_dup(&tokstr_buf), first);
     1558}
     1559
     1560static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
    12461561{
    12471562    const unsigned char *s;
    12481563    unsigned int h;
     1564    CachedInclude *e;
     1565    int i;
    12491566
    12501567    h = TOK_HASH_INIT;
    1251     s = filename;
     1568    s = (unsigned char *) filename;
    12521569    while (*s) {
     1570#ifdef _WIN32
     1571        h = TOK_HASH_FUNC(h, toup(*s));
     1572#else
    12531573        h = TOK_HASH_FUNC(h, *s);
     1574#endif
    12541575        s++;
    12551576    }
    12561577    h &= (CACHED_INCLUDES_HASH_SIZE - 1);
    1257     return h;
    1258 }
    1259 
    1260 static CachedInclude *search_cached_include(TCCState *s1, const char *filename)
    1261 {
    1262     CachedInclude *e;
    1263     int i, h;
    1264     h = hash_cached_include(filename);
     1578
    12651579    i = s1->cached_includes_hash[h];
    12661580    for(;;) {
     
    12721586        i = e->hash_next;
    12731587    }
    1274     return NULL;
    1275 }
    1276 
    1277 static inline void add_cached_include(TCCState *s1, const char *filename, int ifndef_macro)
    1278 {
    1279     CachedInclude *e;
    1280     int h;
    1281 
    1282     if (search_cached_include(s1, filename))
    1283         return;
    1284 #ifdef INC_DEBUG
    1285     printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
    1286 #endif
     1588    if (!add)
     1589        return NULL;
     1590
    12871591    e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
    12881592    strcpy(e->filename, filename);
    1289     e->ifndef_macro = ifndef_macro;
    1290     dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
     1593    e->ifndef_macro = e->once = 0;
     1594    dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
    12911595    /* add in hash table */
    1292     h = hash_cached_include(filename);
    12931596    e->hash_next = s1->cached_includes_hash[h];
    12941597    s1->cached_includes_hash[h] = s1->nb_cached_includes;
     1598#ifdef INC_DEBUG
     1599    printf("adding cached '%s'\n", filename);
     1600#endif
     1601    return e;
    12951602}
    12961603
    12971604static void pragma_parse(TCCState *s1)
    12981605{
    1299     int val;
    1300 
    1301     next();
    1302     if (tok == TOK_pack) {
    1303         /*
    1304           This may be:
    1305           #pragma pack(1) // set
    1306           #pragma pack() // reset to default
    1307           #pragma pack(push,1) // push & set
    1308           #pragma pack(pop) // restore previous
    1309         */
     1606    next_nomacro();
     1607    if (tok == TOK_push_macro || tok == TOK_pop_macro) {
     1608        int t = tok, v;
     1609        Sym *s;
     1610
     1611        if (next(), tok != '(')
     1612            goto pragma_err;
     1613        if (next(), tok != TOK_STR)
     1614            goto pragma_err;
     1615        v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok;
     1616        if (next(), tok != ')')
     1617            goto pragma_err;
     1618        if (t == TOK_push_macro) {
     1619            while (NULL == (s = define_find(v)))
     1620                define_push(v, 0, NULL, NULL);
     1621            s->type.ref = s; /* set push boundary */
     1622        } else {
     1623            for (s = define_stack; s; s = s->prev)
     1624                if (s->v == v && s->type.ref == s) {
     1625                    s->type.ref = NULL;
     1626                    break;
     1627                }
     1628        }
     1629        if (s)
     1630            table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
     1631        else
     1632            tcc_warning("unbalanced #pragma pop_macro");
     1633        pp_debug_tok = t, pp_debug_symv = v;
     1634
     1635    } else if (tok == TOK_once) {
     1636        search_cached_include(s1, file->filename, 1)->once = pp_once;
     1637
     1638    } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
     1639        /* tcc -E: keep pragmas below unchanged */
     1640        unget_tok(' ');
     1641        unget_tok(TOK_PRAGMA);
     1642        unget_tok('#');
     1643        unget_tok(TOK_LINEFEED);
     1644
     1645    } else if (tok == TOK_pack) {
     1646        /* This may be:
     1647           #pragma pack(1) // set
     1648           #pragma pack() // reset to default
     1649           #pragma pack(push,1) // push & set
     1650           #pragma pack(pop) // restore previous */
    13101651        next();
    13111652        skip('(');
     
    13181659            s1->pack_stack_ptr--;
    13191660        } else {
    1320             val = 0;
     1661            int val = 0;
    13211662            if (tok != ')') {
    13221663                if (tok == TOK_ASM_push) {
     
    13271668                    skip(',');
    13281669                }
    1329                 if (tok != TOK_CINT) {
    1330                 pack_error:
    1331                     tcc_error("invalid pack pragma");
    1332                 }
     1670                if (tok != TOK_CINT)
     1671                    goto pragma_err;
    13331672                val = tokc.i;
    13341673                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
    1335                     goto pack_error;
     1674                    goto pragma_err;
    13361675                next();
    13371676            }
    13381677            *s1->pack_stack_ptr = val;
    1339             skip(')');
    1340         }
    1341     }
     1678        }
     1679        if (tok != ')')
     1680            goto pragma_err;
     1681
     1682    } else if (tok == TOK_comment) {
     1683        char *p; int t;
     1684        next();
     1685        skip('(');
     1686        t = tok;
     1687        next();
     1688        skip(',');
     1689        if (tok != TOK_STR)
     1690            goto pragma_err;
     1691        p = tcc_strdup((char *)tokc.str.data);
     1692        next();
     1693        if (tok != ')')
     1694            goto pragma_err;
     1695        if (t == TOK_lib) {
     1696            dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
     1697        } else {
     1698            if (t == TOK_option)
     1699                tcc_set_options(s1, p);
     1700            tcc_free(p);
     1701        }
     1702
     1703    } else if (s1->warn_unsupported) {
     1704        tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
     1705    }
     1706    return;
     1707
     1708pragma_err:
     1709    tcc_error("malformed #pragma directive");
     1710    return;
    13421711}
    13431712
     
    13511720
    13521721    saved_parse_flags = parse_flags;
    1353     parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
    1354         PARSE_FLAG_LINEFEED;
     1722    parse_flags = PARSE_FLAG_PREPROCESS
     1723        | PARSE_FLAG_TOK_NUM
     1724        | PARSE_FLAG_TOK_STR
     1725        | PARSE_FLAG_LINEFEED
     1726        | (parse_flags & PARSE_FLAG_ASM_FILE)
     1727        ;
     1728
    13551729    next_nomacro();
    13561730 redo:
    13571731    switch(tok) {
    13581732    case TOK_DEFINE:
     1733        pp_debug_tok = tok;
    13591734        next_nomacro();
     1735        pp_debug_symv = tok;
    13601736        parse_define();
    13611737        break;
    13621738    case TOK_UNDEF:
     1739        pp_debug_tok = tok;
    13631740        next_nomacro();
     1741        pp_debug_symv = tok;
    13641742        s = define_find(tok);
    13651743        /* undefine symbol by putting an invalid name */
     
    13981776#endif
    13991777        } else {
    1400             /* computed #include : either we have only strings or
    1401                we have anything enclosed in '<>' */
     1778            int len;
     1779            /* computed #include : concatenate everything up to linefeed,
     1780               the result must be one of the two accepted forms.
     1781               Don't convert pp-tokens to tokens here.  */
     1782            parse_flags = (PARSE_FLAG_PREPROCESS
     1783                           | PARSE_FLAG_LINEFEED
     1784                           | (parse_flags & PARSE_FLAG_ASM_FILE));
    14021785            next();
    14031786            buf[0] = '\0';
    1404             if (tok == TOK_STR) {
    1405                 while (tok != TOK_LINEFEED) {
    1406                     if (tok != TOK_STR) {
    1407                     include_syntax:
    1408                         tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
    1409                     }
    1410                     pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
    1411                     next();
    1412                 }
    1413                 c = '\"';
    1414             } else {
    1415                 int len;
    1416                 while (tok != TOK_LINEFEED) {
    1417                     pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
    1418                     next();
    1419                 }
    1420                 len = strlen(buf);
    1421                 /* check syntax and remove '<>' */
    1422                 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
    1423                     goto include_syntax;
    1424                 memmove(buf, buf + 1, len - 2);
    1425                 buf[len - 2] = '\0';
    1426                 c = '>';
    1427             }
     1787            while (tok != TOK_LINEFEED) {
     1788                pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
     1789                next();
     1790            }
     1791            len = strlen(buf);
     1792            /* check syntax and remove '<>|""' */
     1793            if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') &&
     1794                             (buf[0] != '<' || buf[len-1] != '>'))))
     1795                tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
     1796            c = buf[len-1];
     1797            memmove(buf, buf + 1, len - 2);
     1798            buf[len - 2] = '\0';
    14281799        }
    14291800
     
    14321803        /* store current file in stack, but increment stack later below */
    14331804        *s1->include_stack_ptr = file;
    1434 
    1435         n = s1->nb_include_paths + s1->nb_sysinclude_paths;
    1436         for (i = -2; i < n; ++i) {
     1805        i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
     1806        n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
     1807        for (; i < n; ++i) {
    14371808            char buf1[sizeof file->filename];
    14381809            CachedInclude *e;
    1439             BufferedFile **f;
    14401810            const char *path;
    14411811
    1442             if (i == -2) {
     1812            if (i == 0) {
    14431813                /* check absolute include path */
    14441814                if (!IS_ABSPATH(buf))
    14451815                    continue;
    14461816                buf1[0] = 0;
    1447                 i = n; /* force end loop */
    1448 
    1449             } else if (i == -1) {
    1450                 /* search in current dir if "header.h" */
     1817
     1818            } else if (i == 1) {
     1819                /* search in file's dir if "header.h" */
    14511820                if (c != '\"')
    14521821                    continue;
    1453                 path = file->filename;
     1822                /* https://savannah.nongnu.org/bugs/index.php?50847 */
     1823                path = file->true_filename;
    14541824                pstrncpy(buf1, path, tcc_basename(path) - path);
    14551825
    14561826            } else {
    14571827                /* search in all the include paths */
    1458                 if (i < s1->nb_include_paths)
    1459                     path = s1->include_paths[i];
    1460                 else
    1461                     path = s1->sysinclude_paths[i - s1->nb_include_paths];
     1828                int j = i - 2, k = j - s1->nb_include_paths;
     1829                path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k];
    14621830                pstrcpy(buf1, sizeof(buf1), path);
    14631831                pstrcat(buf1, sizeof(buf1), "/");
     
    14651833
    14661834            pstrcat(buf1, sizeof(buf1), buf);
    1467 
    1468             if (tok == TOK_INCLUDE_NEXT)
    1469                 for (f = s1->include_stack_ptr; f >= s1->include_stack; --f)
    1470                     if (0 == PATHCMP((*f)->filename, buf1)) {
    1471 #ifdef INC_DEBUG
    1472                         printf("%s: #include_next skipping %s\n", file->filename, buf1);
    1473 #endif
    1474                         goto include_trynext;
    1475                     }
    1476 
    1477             e = search_cached_include(s1, buf1);
    1478             if (e && define_find(e->ifndef_macro)) {
     1835            e = search_cached_include(s1, buf1, 0);
     1836            if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
    14791837                /* no need to parse the include because the 'ifndef macro'
    1480                    is defined */
     1838                   is defined (or had #pragma once) */
    14811839#ifdef INC_DEBUG
    14821840                printf("%s: skipping cached %s\n", file->filename, buf1);
     
    14861844
    14871845            if (tcc_open(s1, buf1) < 0)
    1488 include_trynext:
    14891846                continue;
    14901847
     1848            file->include_next_index = i + 1;
    14911849#ifdef INC_DEBUG
    14921850            printf("%s: including %s\n", file->prev->filename, file->filename);
    14931851#endif
    14941852            /* update target deps */
    1495             dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
     1853            dynarray_add(&s1->target_deps, &s1->nb_target_deps,
    14961854                    tcc_strdup(buf1));
    14971855            /* push current file in stack */
     
    15301888    do_if:
    15311889        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
    1532             tcc_error("memory full");
     1890            tcc_error("memory full (ifdef)");
    15331891        *s1->ifdef_stack_ptr++ = c;
    15341892        goto test_skip;
     
    15471905            tcc_error("#elif after #else");
    15481906        /* last #if/#elif expression was true: we skip */
    1549         if (c == 1)
    1550             goto skip;
    1551         c = expr_preprocess();
    1552         s1->ifdef_stack_ptr[-1] = c;
     1907        if (c == 1) {
     1908            c = 0;
     1909        } else {
     1910            c = expr_preprocess();
     1911            s1->ifdef_stack_ptr[-1] = c;
     1912        }
    15531913    test_else:
    15541914        if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
     
    15561916    test_skip:
    15571917        if (!(c & 1)) {
    1558         skip:
    15591918            preprocess_skip();
    15601919            is_bof = 0;
     
    15801939        }
    15811940        break;
     1941    case TOK_PPNUM:
     1942        n = strtoul((char*)tokc.str.data, &q, 10);
     1943        goto _line_num;
    15821944    case TOK_LINE:
    15831945        next();
    15841946        if (tok != TOK_CINT)
    1585             tcc_error("#line");
    1586         file->line_num = tokc.i - 1; /* the line number will be incremented after */
     1947    _line_err:
     1948            tcc_error("wrong #line format");
     1949        n = tokc.i;
     1950    _line_num:
    15871951        next();
    15881952        if (tok != TOK_LINEFEED) {
    1589             if (tok != TOK_STR)
    1590                 tcc_error("#line");
    1591             pstrcpy(file->filename, sizeof(file->filename),
    1592                     (char *)tokc.cstr->data);
    1593         }
     1953            if (tok == TOK_STR) {
     1954                if (file->true_filename == file->filename)
     1955                    file->true_filename = tcc_strdup(file->filename);
     1956                pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
     1957            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
     1958                break;
     1959            else
     1960                goto _line_err;
     1961            --n;
     1962        }
     1963        if (file->fd > 0)
     1964            total_lines += file->line_num - n;
     1965        file->line_num = n;
     1966        if (s1->do_debug)
     1967            put_stabs(file->filename, N_BINCL, 0, 0, 0);
    15941968        break;
    15951969    case TOK_ERROR:
     
    16171991        pragma_parse(s1);
    16181992        break;
     1993    case TOK_LINEFEED:
     1994        goto the_end;
    16191995    default:
    1620         if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
    1621             /* '!' is ignored to allow C scripts. numbers are ignored
    1622                to emulate cpp behaviour */
    1623         } else {
    1624             if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
    1625                 tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
    1626             else {
    1627                 /* this is a gas line comment in an 'S' file. */
    1628                 file->buf_ptr = parse_line_comment(file->buf_ptr);
    1629                 goto the_end;
    1630             }
    1631         }
    1632         break;
     1996        /* ignore gas line comment in an 'S' file. */
     1997        if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
     1998            goto ignore;
     1999        if (tok == '!' && is_bof)
     2000            /* '!' is ignored at beginning to allow C scripts. */
     2001            goto ignore;
     2002        tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
     2003    ignore:
     2004        file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
     2005        goto the_end;
    16332006    }
    16342007    /* ignore other preprocess commands or #! for C scripts */
     
    17312104                break;
    17322105            }
     2106        } else if (is_long && c >= 0x80) {
     2107            /* assume we are processing UTF-8 sequence */
     2108            /* reference: The Unicode Standard, Version 10.0, ch3.9 */
     2109
     2110            int cont; /* count of continuation bytes */
     2111            int skip; /* how many bytes should skip when error occurred */
     2112            int i;
     2113
     2114            /* decode leading byte */
     2115            if (c < 0xC2) {
     2116                    skip = 1; goto invalid_utf8_sequence;
     2117            } else if (c <= 0xDF) {
     2118                    cont = 1; n = c & 0x1f;
     2119            } else if (c <= 0xEF) {
     2120                    cont = 2; n = c & 0xf;
     2121            } else if (c <= 0xF4) {
     2122                    cont = 3; n = c & 0x7;
     2123            } else {
     2124                    skip = 1; goto invalid_utf8_sequence;
     2125            }
     2126
     2127            /* decode continuation bytes */
     2128            for (i = 1; i <= cont; i++) {
     2129                int l = 0x80, h = 0xBF;
     2130
     2131                /* adjust limit for second byte */
     2132                if (i == 1) {
     2133                    switch (c) {
     2134                    case 0xE0: l = 0xA0; break;
     2135                    case 0xED: h = 0x9F; break;
     2136                    case 0xF0: l = 0x90; break;
     2137                    case 0xF4: h = 0x8F; break;
     2138                    }
     2139                }
     2140
     2141                if (p[i] < l || p[i] > h) {
     2142                    skip = i; goto invalid_utf8_sequence;
     2143                }
     2144
     2145                n = (n << 6) | (p[i] & 0x3f);
     2146            }
     2147
     2148            /* advance pointer */
     2149            p += 1 + cont;
     2150            c = n;
     2151            goto add_char_nonext;
     2152
     2153            /* error handling */
     2154        invalid_utf8_sequence:
     2155            tcc_warning("ill-formed UTF-8 subsequence starting with: \'\\x%x\'", c);
     2156            c = 0xFFFD;
     2157            p += skip;
     2158            goto add_char_nonext;
     2159
    17332160        }
    17342161        p++;
     
    17362163        if (!is_long)
    17372164            cstr_ccat(outstr, c);
    1738         else
     2165        else {
     2166#ifdef TCC_TARGET_PE
     2167            /* store as UTF-16 */
     2168            if (c < 0x10000) {
     2169                cstr_wccat(outstr, c);
     2170            } else {
     2171                c -= 0x10000;
     2172                cstr_wccat(outstr, (c >> 10) + 0xD800);
     2173                cstr_wccat(outstr, (c & 0x3FF) + 0xDC00);
     2174            }
     2175#else
    17392176            cstr_wccat(outstr, c);
     2177#endif
     2178        }
    17402179    }
    17412180    /* add a trailing '\0' */
     
    17442183    else
    17452184        cstr_wccat(outstr, '\0');
     2185}
     2186
     2187static void parse_string(const char *s, int len)
     2188{
     2189    uint8_t buf[1000], *p = buf;
     2190    int is_long, sep;
     2191
     2192    if ((is_long = *s == 'L'))
     2193        ++s, --len;
     2194    sep = *s++;
     2195    len -= 2;
     2196    if (len >= sizeof buf)
     2197        p = tcc_malloc(len + 1);
     2198    memcpy(p, s, len);
     2199    p[len] = 0;
     2200
     2201    cstr_reset(&tokcstr);
     2202    parse_escape_string(&tokcstr, p, is_long);
     2203    if (p != buf)
     2204        tcc_free(p);
     2205
     2206    if (sep == '\'') {
     2207        int char_size, i, n, c;
     2208        /* XXX: make it portable */
     2209        if (!is_long)
     2210            tok = TOK_CCHAR, char_size = 1;
     2211        else
     2212            tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
     2213        n = tokcstr.size / char_size - 1;
     2214        if (n < 1)
     2215            tcc_error("empty character constant");
     2216        if (n > 1)
     2217            tcc_warning("multi-character character constant");
     2218        for (c = i = 0; i < n; ++i) {
     2219            if (is_long)
     2220                c = ((nwchar_t *)tokcstr.data)[i];
     2221            else
     2222                c = (c << 8) | ((char *)tokcstr.data)[i];
     2223        }
     2224        tokc.i = c;
     2225    } else {
     2226        tokc.str.size = tokcstr.size;
     2227        tokc.str.data = tokcstr.data;
     2228        if (!is_long)
     2229            tok = TOK_STR;
     2230        else
     2231            tok = TOK_LSTR;
     2232    }
    17462233}
    17472234
     
    18312318                shift = 4;
    18322319            else
    1833                 shift = 2;
     2320                shift = 1;
    18342321            bn_zero(bn);
    18352322            q = token_buf;
     
    19692456    } else {
    19702457        unsigned long long n, n1;
    1971         int lcount, ucount;
     2458        int lcount, ucount, ov = 0;
     2459        const char *p1;
    19722460
    19732461        /* integer number */
     
    19822470            t = *q++;
    19832471            /* no need for checks except for base 10 / 8 errors */
    1984             if (t == '\0') {
     2472            if (t == '\0')
    19852473                break;
    1986             } else if (t >= 'a') {
     2474            else if (t >= 'a')
    19872475                t = t - 'a' + 10;
    1988             } else if (t >= 'A') {
     2476            else if (t >= 'A')
    19892477                t = t - 'A' + 10;
    1990             } else {
     2478            else
    19912479                t = t - '0';
    1992                 if (t >= b)
    1993                     tcc_error("invalid digit");
    1994             }
     2480            if (t >= b)
     2481                tcc_error("invalid digit");
    19952482            n1 = n;
    19962483            n = n * b + t;
    19972484            /* detect overflow */
    1998             /* XXX: this test is not reliable */
    1999             if (n < n1)
    2000                 tcc_error("integer constant overflow");
    2001         }
    2002        
    2003         /* XXX: not exactly ANSI compliant */
    2004         if ((n & 0xffffffff00000000LL) != 0) {
    2005             if ((n >> 63) != 0)
    2006                 tok = TOK_CULLONG;
    2007             else
    2008                 tok = TOK_CLLONG;
    2009         } else if (n > 0x7fffffff) {
    2010             tok = TOK_CUINT;
    2011         } else {
    2012             tok = TOK_CINT;
    2013         }
    2014         lcount = 0;
    2015         ucount = 0;
     2485            if (n1 >= 0x1000000000000000ULL && n / b != n1)
     2486                ov = 1;
     2487        }
     2488
     2489        /* Determine the characteristics (unsigned and/or 64bit) the type of
     2490           the constant must have according to the constant suffix(es) */
     2491        lcount = ucount = 0;
     2492        p1 = p;
    20162493        for(;;) {
    20172494            t = toup(ch);
     
    20192496                if (lcount >= 2)
    20202497                    tcc_error("three 'l's in integer constant");
     2498                if (lcount && *(p - 1) != ch)
     2499                    tcc_error("incorrect integer suffix: %s", p1);
    20212500                lcount++;
    2022 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
    2023                 if (lcount == 2) {
    2024 #endif
    2025                     if (tok == TOK_CINT)
    2026                         tok = TOK_CLLONG;
    2027                     else if (tok == TOK_CUINT)
    2028                         tok = TOK_CULLONG;
    2029 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
    2030                 }
    2031 #endif
    20322501                ch = *p++;
    20332502            } else if (t == 'U') {
     
    20352504                    tcc_error("two 'u's in integer constant");
    20362505                ucount++;
    2037                 if (tok == TOK_CINT)
    2038                     tok = TOK_CUINT;
    2039                 else if (tok == TOK_CLLONG)
    2040                     tok = TOK_CULLONG;
    20412506                ch = *p++;
    20422507            } else {
     
    20442509            }
    20452510        }
    2046         if (tok == TOK_CINT || tok == TOK_CUINT)
    2047             tokc.ui = n;
    2048         else
    2049             tokc.ull = n;
     2511
     2512        /* Determine if it needs 64 bits and/or unsigned in order to fit */
     2513        if (ucount == 0 && b == 10) {
     2514            if (lcount <= (LONG_SIZE == 4)) {
     2515                if (n >= 0x80000000U)
     2516                    lcount = (LONG_SIZE == 4) + 1;
     2517            }
     2518            if (n >= 0x8000000000000000ULL)
     2519                ov = 1, ucount = 1;
     2520        } else {
     2521            if (lcount <= (LONG_SIZE == 4)) {
     2522                if (n >= 0x100000000ULL)
     2523                    lcount = (LONG_SIZE == 4) + 1;
     2524                else if (n >= 0x80000000U)
     2525                    ucount = 1;
     2526            }
     2527            if (n >= 0x8000000000000000ULL)
     2528                ucount = 1;
     2529        }
     2530
     2531        if (ov)
     2532            tcc_warning("integer constant overflow");
     2533
     2534        tok = TOK_CINT;
     2535        if (lcount) {
     2536            tok = TOK_CLONG;
     2537            if (lcount == 2)
     2538                tok = TOK_CLLONG;
     2539        }
     2540        if (ucount)
     2541            ++tok; /* TOK_CU... */
     2542        tokc.i = n;
    20502543    }
    20512544    if (ch)
     
    20682561static inline void next_nomacro1(void)
    20692562{
    2070     int t, c, is_long;
     2563    int t, c, is_long, len;
    20712564    TokenSym *ts;
    20722565    uint8_t *p, *p1;
     
    20812574        tok = c;
    20822575        p++;
    2083         goto keep_tok_flags;
     2576        if (parse_flags & PARSE_FLAG_SPACES)
     2577            goto keep_tok_flags;
     2578        while (isidnum_table[*p - CH_EOF] & IS_SPC)
     2579            ++p;
     2580        goto redo_no_start;
    20842581    case '\f':
    20852582    case '\v':
     
    20892586    case '\\':
    20902587        /* first look if it is in fact an end of buffer */
    2091         if (p >= file->buf_end) {
    2092             file->buf_ptr = p;
    2093             handle_eob();
    2094             p = file->buf_ptr;
    2095             if (p >= file->buf_end)
    2096                 goto parse_eof;
    2097             else
    2098                 goto redo_no_start;
    2099         } else {
    2100             file->buf_ptr = p;
    2101             ch = *p;
    2102             handle_stray();
    2103             p = file->buf_ptr;
     2588        c = handle_stray1(p);
     2589        p = file->buf_ptr;
     2590        if (c == '\\')
     2591            goto parse_simple;
     2592        if (c != CH_EOF)
    21042593            goto redo_no_start;
    2105         }
    2106     parse_eof:
    21072594        {
    21082595            TCCState *s1 = tcc_state;
     
    21292616                    printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
    21302617#endif
    2131                     add_cached_include(s1, file->filename, file->ifndef_macro_saved);
     2618                    search_cached_include(s1, file->filename, 1)
     2619                        ->ifndef_macro = file->ifndef_macro_saved;
    21322620                    tok_flags &= ~TOK_FLAG_ENDIF;
    21332621                }
     
    21412629                s1->include_stack_ptr--;
    21422630                p = file->buf_ptr;
     2631                if (p == file->buffer)
     2632                    tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
    21432633                goto redo_no_start;
    21442634            }
     
    21702660                tok = TOK_TWOSHARPS;
    21712661            } else {
    2172                 if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
     2662                if (parse_flags & PARSE_FLAG_ASM_FILE) {
    21732663                    p = parse_line_comment(p - 1);
    21742664                    goto redo_no_start;
     
    21792669        }
    21802670        break;
     2671   
     2672    /* dollar is allowed to start identifiers when not parsing asm */
     2673    case '$':
     2674        if (!(isidnum_table[c - CH_EOF] & IS_ID)
     2675         || (parse_flags & PARSE_FLAG_ASM_FILE))
     2676            goto parse_simple;
    21812677
    21822678    case 'a': case 'b': case 'c': case 'd':
     
    21992695        h = TOK_HASH_INIT;
    22002696        h = TOK_HASH_FUNC(h, c);
    2201         p++;
    2202         for(;;) {
    2203             c = *p;
    2204             if (!isidnum_table[c-CH_EOF])
    2205                 break;
     2697        while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
    22062698            h = TOK_HASH_FUNC(h, c);
    2207             p++;
    2208         }
     2699        len = p - p1;
    22092700        if (c != '\\') {
    22102701            TokenSym **pts;
    2211             int len;
    22122702
    22132703            /* fast case : no stray found, so we have the full token
    22142704               and we have already hashed it */
    2215             len = p - p1;
    22162705            h &= (TOK_HASH_SIZE - 1);
    22172706            pts = &hash_ident[h];
     
    22242713                pts = &(ts->hash_next);
    22252714            }
    2226             ts = tok_alloc_new(pts, p1, len);
     2715            ts = tok_alloc_new(pts, (char *) p1, len);
    22272716        token_found: ;
    22282717        } else {
    22292718            /* slower case */
    22302719            cstr_reset(&tokcstr);
    2231 
    2232             while (p1 < p) {
    2233                 cstr_ccat(&tokcstr, *p1);
    2234                 p1++;
    2235             }
     2720            cstr_cat(&tokcstr, (char *) p1, len);
    22362721            p--;
    22372722            PEEKC(c, p);
    22382723        parse_ident_slow:
    2239             while (isidnum_table[c-CH_EOF]) {
     2724            while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
     2725            {
    22402726                cstr_ccat(&tokcstr, c);
    22412727                PEEKC(c, p);
     
    22622748        }
    22632749        break;
     2750
    22642751    case '0': case '1': case '2': case '3':
    22652752    case '4': case '5': case '6': case '7':
    22662753    case '8': case '9':
    2267 
    2268         cstr_reset(&tokcstr);
     2754        t = c;
     2755        PEEKC(c, p);
    22692756        /* after the first digit, accept digits, alpha, '.' or sign if
    22702757           prefixed by 'eEpP' */
    22712758    parse_num:
     2759        cstr_reset(&tokcstr);
    22722760        for(;;) {
     2761            cstr_ccat(&tokcstr, t);
     2762            if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
     2763                  || c == '.'
     2764                  || ((c == '+' || c == '-')
     2765                      && (((t == 'e' || t == 'E')
     2766                            && !(parse_flags & PARSE_FLAG_ASM_FILE
     2767                                /* 0xe+1 is 3 tokens in asm */
     2768                                && ((char*)tokcstr.data)[0] == '0'
     2769                                && toup(((char*)tokcstr.data)[1]) == 'X'))
     2770                          || t == 'p' || t == 'P'))))
     2771                break;
    22732772            t = c;
    2274             cstr_ccat(&tokcstr, c);
    22752773            PEEKC(c, p);
    2276             if (!(isnum(c) || isid(c) || c == '.' ||
    2277                   ((c == '+' || c == '-') &&
    2278                    (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
    2279                 break;
    22802774        }
    22812775        /* We add a trailing '\0' to ease parsing */
    22822776        cstr_ccat(&tokcstr, '\0');
    2283         tokc.cstr = &tokcstr;
     2777        tokc.str.size = tokcstr.size;
     2778        tokc.str.data = tokcstr.data;
    22842779        tok = TOK_PPNUM;
    22852780        break;
     2781
    22862782    case '.':
    22872783        /* special dot handling because it can also start a number */
    22882784        PEEKC(c, p);
    22892785        if (isnum(c)) {
    2290             cstr_reset(&tokcstr);
    2291             cstr_ccat(&tokcstr, '.');
     2786            t = '.';
    22922787            goto parse_num;
     2788        } else if ((isidnum_table['.' - CH_EOF] & IS_ID)
     2789                   && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
     2790            *--p = c = '.';
     2791            goto parse_ident_fast;
    22932792        } else if (c == '.') {
    22942793            PEEKC(c, p);
    2295             if (c != '.')
    2296                 expect("'.'");
    2297             PEEKC(c, p);
    2298             tok = TOK_DOTS;
     2794            if (c == '.') {
     2795                p++;
     2796                tok = TOK_DOTS;
     2797            } else {
     2798                *--p = '.'; /* may underflow into file->unget[] */
     2799                tok = '.';
     2800            }
    22992801        } else {
    23002802            tok = '.';
     
    23052807        is_long = 0;
    23062808    str_const:
    2307         {
    2308             CString str;
    2309             int sep;
    2310 
    2311             sep = c;
    2312 
    2313             /* parse the string */
    2314             cstr_new(&str);
    2315             p = parse_pp_string(p, sep, &str);
    2316             cstr_ccat(&str, '\0');
    2317            
    2318             /* eval the escape (should be done as TOK_PPNUM) */
    2319             cstr_reset(&tokcstr);
    2320             parse_escape_string(&tokcstr, str.data, is_long);
    2321             cstr_free(&str);
    2322 
    2323             if (sep == '\'') {
    2324                 int char_size;
    2325                 /* XXX: make it portable */
    2326                 if (!is_long)
    2327                     char_size = 1;
    2328                 else
    2329                     char_size = sizeof(nwchar_t);
    2330                 if (tokcstr.size <= char_size)
    2331                     tcc_error("empty character constant");
    2332                 if (tokcstr.size > 2 * char_size)
    2333                     tcc_warning("multi-character character constant");
    2334                 if (!is_long) {
    2335                     tokc.i = *(int8_t *)tokcstr.data;
    2336                     tok = TOK_CCHAR;
    2337                 } else {
    2338                     tokc.i = *(nwchar_t *)tokcstr.data;
    2339                     tok = TOK_LCHAR;
    2340                 }
    2341             } else {
    2342                 tokc.cstr = &tokcstr;
    2343                 if (!is_long)
    2344                     tok = TOK_STR;
    2345                 else
    2346                     tok = TOK_LSTR;
    2347             }
    2348         }
     2809        cstr_reset(&tokcstr);
     2810        if (is_long)
     2811            cstr_ccat(&tokcstr, 'L');
     2812        cstr_ccat(&tokcstr, c);
     2813        p = parse_pp_string(p, c, &tokcstr);
     2814        cstr_ccat(&tokcstr, c);
     2815        cstr_ccat(&tokcstr, '\0');
     2816        tokc.str.size = tokcstr.size;
     2817        tokc.str.data = tokcstr.data;
     2818        tok = TOK_PPSTR;
    23492819        break;
    23502820
     
    23662836        }
    23672837        break;
    2368        
    23692838    case '>':
    23702839        PEEKC(c, p);
     
    24782947    case '?':
    24792948    case '~':
    2480     case '$': /* only used in assembler */
    2481     case '@': /* dito */
     2949    case '@': /* only used in assembler */
     2950    parse_simple:
    24822951        tok = c;
    24832952        p++;
    24842953        break;
    24852954    default:
     2955        if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
     2956            goto parse_ident_fast;
     2957        if (parse_flags & PARSE_FLAG_ASM_FILE)
     2958            goto parse_simple;
    24862959        tcc_error("unrecognized character \\x%02x", c);
    24872960        break;
     
    24912964    file->buf_ptr = p;
    24922965#if defined(PARSE_DEBUG)
    2493     printf("token = %s\n", get_tok_str(tok, &tokc));
     2966    printf("token = %d %s\n", tok, get_tok_str(tok, &tokc));
    24942967#endif
    24952968}
     
    25122985        next_nomacro1();
    25132986    }
     2987    //printf("token = %s\n", get_tok_str(tok, &tokc));
    25142988}
    25152989
     
    25182992    do {
    25192993        next_nomacro_spc();
    2520     } while (is_space(tok));
     2994    } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
    25212995}
    25222996 
    2523 /* substitute args in macro_str and return allocated string */
     2997
     2998static void macro_subst(
     2999    TokenString *tok_str,
     3000    Sym **nested_list,
     3001    const int *macro_str
     3002    );
     3003
     3004/* substitute arguments in replacement lists in macro_str by the values in
     3005   args (field d) and return allocated string */
    25243006static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
    25253007{
    2526     int last_tok, t, spc;
     3008    int t, t0, t1, spc;
    25273009    const int *st;
    25283010    Sym *s;
     
    25323014
    25333015    tok_str_new(&str);
    2534     last_tok = 0;
     3016    t0 = t1 = 0;
    25353017    while(1) {
    25363018        TOK_GET(&t, &macro_str, &cval);
     
    25413023            TOK_GET(&t, &macro_str, &cval);
    25423024            if (!t)
    2543                 break;
     3025                goto bad_stringy;
    25443026            s = sym_find2(args, t);
    25453027            if (s) {
    25463028                cstr_new(&cstr);
     3029                cstr_ccat(&cstr, '\"');
    25473030                st = s->d;
    25483031                spc = 0;
    2549                 while (*st) {
     3032                while (*st >= 0) {
    25503033                    TOK_GET(&t, &st, &cval);
    2551                     if (!check_space(t, &spc))
    2552                         cstr_cat(&cstr, get_tok_str(t, &cval));
     3034                    if (t != TOK_PLCHLDR
     3035                     && t != TOK_NOSUBST
     3036                     && 0 == check_space(t, &spc)) {
     3037                        const char *s = get_tok_str(t, &cval);
     3038                        while (*s) {
     3039                            if (t == TOK_PPSTR && *s != '\'')
     3040                                add_char(&cstr, *s);
     3041                            else
     3042                                cstr_ccat(&cstr, *s);
     3043                            ++s;
     3044                        }
     3045                    }
    25533046                }
    25543047                cstr.size -= spc;
     3048                cstr_ccat(&cstr, '\"');
    25553049                cstr_ccat(&cstr, '\0');
    25563050#ifdef PP_DEBUG
    2557                 printf("stringize: %s\n", (char *)cstr.data);
     3051                printf("\nstringize: <%s>\n", (char *)cstr.data);
    25583052#endif
    25593053                /* add string */
    2560                 cval.cstr = &cstr;
    2561                 tok_str_add2(&str, TOK_STR, &cval);
     3054                cval.str.size = cstr.size;
     3055                cval.str.data = cstr.data;
     3056                tok_str_add2(&str, TOK_PPSTR, &cval);
    25623057                cstr_free(&cstr);
    25633058            } else {
    2564                 tok_str_add2(&str, t, &cval);
     3059        bad_stringy:
     3060                expect("macro parameter after '#'");
    25653061            }
    25663062        } else if (t >= TOK_IDENT) {
    25673063            s = sym_find2(args, t);
    25683064            if (s) {
     3065                int l0 = str.len;
    25693066                st = s->d;
    25703067                /* if '##' is present before or after, no arg substitution */
    2571                 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
    2572                     /* special case for var arg macros : ## eats the
    2573                        ',' if empty VA_ARGS variable. */
    2574                     /* XXX: test of the ',' is not 100%
    2575                        reliable. should fix it to avoid security
    2576                        problems */
    2577                     if (gnu_ext && s->type.t &&
    2578                         last_tok == TOK_TWOSHARPS &&
    2579                         str.len >= 2 && str.str[str.len - 2] == ',') {
    2580                         if (*st == 0) {
     3068                if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
     3069                    /* special case for var arg macros : ## eats the ','
     3070                       if empty VA_ARGS variable. */
     3071                    if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
     3072                        if (*st <= 0) {
    25813073                            /* suppress ',' '##' */
    25823074                            str.len -= 2;
     
    25863078                            goto add_var;
    25873079                        }
    2588                     } else {
    2589                         int t1;
    2590                     add_var:
    2591                         for(;;) {
    2592                             TOK_GET(&t1, &st, &cval);
    2593                             if (!t1)
    2594                                 break;
    2595                             tok_str_add2(&str, t1, &cval);
    2596                         }
    25973080                    }
    25983081                } else {
    2599                     /* NOTE: the stream cannot be read when macro
    2600                        substituing an argument */
    2601                     macro_subst(&str, nested_list, st, NULL);
     3082            add_var:
     3083                    if (!s->next) {
     3084                        /* Expand arguments tokens and store them.  In most
     3085                           cases we could also re-expand each argument if
     3086                           used multiple times, but not if the argument
     3087                           contains the __COUNTER__ macro.  */
     3088                        TokenString str2;
     3089                        sym_push2(&s->next, s->v, s->type.t, 0);
     3090                        tok_str_new(&str2);
     3091                        macro_subst(&str2, nested_list, st);
     3092                        tok_str_add(&str2, 0);
     3093                        s->next->d = str2.str;
     3094                    }
     3095                    st = s->next->d;
    26023096                }
     3097                for(;;) {
     3098                    int t2;
     3099                    TOK_GET(&t2, &st, &cval);
     3100                    if (t2 <= 0)
     3101                        break;
     3102                    tok_str_add2(&str, t2, &cval);
     3103                }
     3104                if (str.len == l0) /* expanded to empty string */
     3105                    tok_str_add(&str, TOK_PLCHLDR);
    26033106            } else {
    26043107                tok_str_add(&str, t);
     
    26073110            tok_str_add2(&str, t, &cval);
    26083111        }
    2609         last_tok = t;
     3112        t0 = t1, t1 = t;
    26103113    }
    26113114    tok_str_add(&str, 0);
     
    26183121    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    26193122};
     3123
     3124static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
     3125{
     3126    CString cstr;
     3127    int n, ret = 1;
     3128
     3129    cstr_new(&cstr);
     3130    if (t1 != TOK_PLCHLDR)
     3131        cstr_cat(&cstr, get_tok_str(t1, v1), -1);
     3132    n = cstr.size;
     3133    if (t2 != TOK_PLCHLDR)
     3134        cstr_cat(&cstr, get_tok_str(t2, v2), -1);
     3135    cstr_ccat(&cstr, '\0');
     3136
     3137    tcc_open_bf(tcc_state, ":paste:", cstr.size);
     3138    memcpy(file->buffer, cstr.data, cstr.size);
     3139    tok_flags = 0;
     3140    for (;;) {
     3141        next_nomacro1();
     3142        if (0 == *file->buf_ptr)
     3143            break;
     3144        if (is_space(tok))
     3145            continue;
     3146        tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
     3147            " preprocessing token", n, cstr.data, (char*)cstr.data + n);
     3148        ret = 0;
     3149        break;
     3150    }
     3151    tcc_close();
     3152    //printf("paste <%s>\n", (char*)cstr.data);
     3153    cstr_free(&cstr);
     3154    return ret;
     3155}
     3156
     3157/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
     3158   return the resulting string (which must be freed). */
     3159static inline int *macro_twosharps(const int *ptr0)
     3160{
     3161    int t;
     3162    CValue cval;
     3163    TokenString macro_str1;
     3164    int start_of_nosubsts = -1;
     3165    const int *ptr;
     3166
     3167    /* we search the first '##' */
     3168    for (ptr = ptr0;;) {
     3169        TOK_GET(&t, &ptr, &cval);
     3170        if (t == TOK_PPJOIN)
     3171            break;
     3172        if (t == 0)
     3173            return NULL;
     3174    }
     3175
     3176    tok_str_new(&macro_str1);
     3177
     3178    //tok_print(" $$$", ptr0);
     3179    for (ptr = ptr0;;) {
     3180        TOK_GET(&t, &ptr, &cval);
     3181        if (t == 0)
     3182            break;
     3183        if (t == TOK_PPJOIN)
     3184            continue;
     3185        while (*ptr == TOK_PPJOIN) {
     3186            int t1; CValue cv1;
     3187            /* given 'a##b', remove nosubsts preceding 'a' */
     3188            if (start_of_nosubsts >= 0)
     3189                macro_str1.len = start_of_nosubsts;
     3190            /* given 'a##b', remove nosubsts preceding 'b' */
     3191            while ((t1 = *++ptr) == TOK_NOSUBST)
     3192                ;
     3193            if (t1 && t1 != TOK_PPJOIN) {
     3194                TOK_GET(&t1, &ptr, &cv1);
     3195                if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
     3196                    if (paste_tokens(t, &cval, t1, &cv1)) {
     3197                        t = tok, cval = tokc;
     3198                    } else {
     3199                        tok_str_add2(&macro_str1, t, &cval);
     3200                        t = t1, cval = cv1;
     3201                    }
     3202                }
     3203            }
     3204        }
     3205        if (t == TOK_NOSUBST) {
     3206            if (start_of_nosubsts < 0)
     3207                start_of_nosubsts = macro_str1.len;
     3208        } else {
     3209            start_of_nosubsts = -1;
     3210        }
     3211        tok_str_add2(&macro_str1, t, &cval);
     3212    }
     3213    tok_str_add(&macro_str1, 0);
     3214    //tok_print(" ###", macro_str1.str);
     3215    return macro_str1.str;
     3216}
     3217
     3218/* peek or read [ws_str == NULL] next token from function macro call,
     3219   walking up macro levels up to the file if necessary */
     3220static int next_argstream(Sym **nested_list, TokenString *ws_str)
     3221{
     3222    int t;
     3223    const int *p;
     3224    Sym *sa;
     3225
     3226    for (;;) {
     3227        if (macro_ptr) {
     3228            p = macro_ptr, t = *p;
     3229            if (ws_str) {
     3230                while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t)
     3231                    tok_str_add(ws_str, t), t = *++p;
     3232            }
     3233            if (t == 0) {
     3234                end_macro();
     3235                /* also, end of scope for nested defined symbol */
     3236                sa = *nested_list;
     3237                while (sa && sa->v == 0)
     3238                    sa = sa->prev;
     3239                if (sa)
     3240                    sa->v = 0;
     3241                continue;
     3242            }
     3243        } else {
     3244            ch = handle_eob();
     3245            if (ws_str) {
     3246                while (is_space(ch) || ch == '\n' || ch == '/') {
     3247                    if (ch == '/') {
     3248                        int c;
     3249                        uint8_t *p = file->buf_ptr;
     3250                        PEEKC(c, p);
     3251                        if (c == '*') {
     3252                            p = parse_comment(p);
     3253                            file->buf_ptr = p - 1;
     3254                        } else if (c == '/') {
     3255                            p = parse_line_comment(p);
     3256                            file->buf_ptr = p - 1;
     3257                        } else
     3258                            break;
     3259                        ch = ' ';
     3260                    }
     3261                    if (ch == '\n')
     3262                        file->line_num++;
     3263                    if (!(ch == '\f' || ch == '\v' || ch == '\r'))
     3264                        tok_str_add(ws_str, ch);
     3265                    cinp();
     3266                }
     3267            }
     3268            t = ch;
     3269        }
     3270
     3271        if (ws_str)
     3272            return t;
     3273        next_nomacro_spc();
     3274        return tok;
     3275    }
     3276}
    26203277
    26213278/* do macro substitution of current token with macro 's' and add
     
    26233280   macros we got inside to avoid recursing. Return non zero if no
    26243281   substitution needs to be done */
    2625 static int macro_subst_tok(TokenString *tok_str,
    2626                            Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
     3282static int macro_subst_tok(
     3283    TokenString *tok_str,
     3284    Sym **nested_list,
     3285    Sym *s)
    26273286{
    26283287    Sym *args, *sa, *sa1;
    2629     int mstr_allocated, parlevel, *mstr, t, t1, spc;
    2630     const int *p;
     3288    int parlevel, t, t1, spc;
    26313289    TokenString str;
    26323290    char *cstrval;
     
    26343292    CString cstr;
    26353293    char buf[32];
    2636    
     3294
    26373295    /* if symbol is a macro, prepare substitution */
    26383296    /* special macros */
    2639     if (tok == TOK___LINE__) {
    2640         snprintf(buf, sizeof(buf), "%d", file->line_num);
     3297    if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
     3298        t = tok == TOK___LINE__ ? file->line_num : pp_counter++;
     3299        snprintf(buf, sizeof(buf), "%d", t);
    26413300        cstrval = buf;
    26423301        t1 = TOK_PPNUM;
     
    26633322    add_cstr1:
    26643323        cstr_new(&cstr);
    2665         cstr_cat(&cstr, cstrval);
    2666         cstr_ccat(&cstr, '\0');
    2667         cval.cstr = &cstr;
     3324        cstr_cat(&cstr, cstrval, 0);
     3325        cval.str.size = cstr.size;
     3326        cval.str.data = cstr.data;
    26683327        tok_str_add2(tok_str, t1, &cval);
    26693328        cstr_free(&cstr);
    2670     } else {
    2671         mstr = s->d;
    2672         mstr_allocated = 0;
     3329    } else if (s->d) {
     3330        int saved_parse_flags = parse_flags;
     3331        int *joined_str = NULL;
     3332        int *mstr = s->d;
     3333
    26733334        if (s->type.t == MACRO_FUNC) {
    2674             /* NOTE: we do not use next_nomacro to avoid eating the
    2675                next token. XXX: find better solution */
    2676         redo:
    2677             if (macro_ptr) {
    2678                 p = macro_ptr;
    2679                 while (is_space(t = *p) || TOK_LINEFEED == t)
    2680                     ++p;
    2681                 if (t == 0 && can_read_stream) {
    2682                     /* end of macro stream: we must look at the token
    2683                        after in the file */
    2684                     struct macro_level *ml = *can_read_stream;
    2685                     macro_ptr = NULL;
    2686                     if (ml)
    2687                     {
    2688                         macro_ptr = ml->p;
    2689                         ml->p = NULL;
    2690                         *can_read_stream = ml -> prev;
    2691                     }
    2692                     /* also, end of scope for nested defined symbol */
    2693                     (*nested_list)->v = -1;
    2694                     goto redo;
     3335            /* whitespace between macro name and argument list */
     3336            TokenString ws_str;
     3337            tok_str_new(&ws_str);
     3338
     3339            spc = 0;
     3340            parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED
     3341                | PARSE_FLAG_ACCEPT_STRAYS;
     3342
     3343            /* get next token from argument stream */
     3344            t = next_argstream(nested_list, &ws_str);
     3345            if (t != '(') {
     3346                /* not a macro substitution after all, restore the
     3347                 * macro token plus all whitespace we've read.
     3348                 * whitespace is intentionally not merged to preserve
     3349                 * newlines. */
     3350                parse_flags = saved_parse_flags;
     3351                tok_str_add(tok_str, tok);
     3352                if (parse_flags & PARSE_FLAG_SPACES) {
     3353                    int i;
     3354                    for (i = 0; i < ws_str.len; i++)
     3355                        tok_str_add(tok_str, ws_str.str[i]);
    26953356                }
     3357                tok_str_free_str(ws_str.str);
     3358                return 0;
    26963359            } else {
    2697                 ch = file->buf_ptr[0];
    2698                 while (is_space(ch) || ch == '\n' || ch == '/')
    2699                   {
    2700                     if (ch == '/')
    2701                       {
    2702                         int c;
    2703                         uint8_t *p = file->buf_ptr;
    2704                         PEEKC(c, p);
    2705                         if (c == '*') {
    2706                             p = parse_comment(p);
    2707                             file->buf_ptr = p - 1;
    2708                         } else if (c == '/') {
    2709                             p = parse_line_comment(p);
    2710                             file->buf_ptr = p - 1;
    2711                         } else
    2712                           break;
    2713                       }
    2714                     cinp();
    2715                   }
    2716                 t = ch;
    2717             }
    2718             if (t != '(') /* no macro subst */
    2719                 return -1;
    2720                    
     3360                tok_str_free_str(ws_str.str);
     3361            }
     3362            do {
     3363                next_nomacro(); /* eat '(' */
     3364            } while (tok == TOK_PLCHLDR);
     3365
    27213366            /* argument macro */
    2722             next_nomacro();
    2723             next_nomacro();
    27243367            args = NULL;
    27253368            sa = s->next;
    27263369            /* NOTE: empty args are allowed, except if no args */
    27273370            for(;;) {
     3371                do {
     3372                    next_argstream(nested_list, NULL);
     3373                } while (is_space(tok) || TOK_LINEFEED == tok);
     3374    empty_arg:
    27283375                /* handle '()' case */
    27293376                if (!args && !sa && tok == ')')
     
    27373384                while ((parlevel > 0 ||
    27383385                        (tok != ')' &&
    2739                          (tok != ',' || sa->type.t))) &&
    2740                        tok != -1) {
     3386                         (tok != ',' || sa->type.t)))) {
     3387                    if (tok == TOK_EOF || tok == 0)
     3388                        break;
    27413389                    if (tok == '(')
    27423390                        parlevel++;
     
    27473395                    if (!check_space(tok, &spc))
    27483396                        tok_str_add2(&str, tok, &tokc);
    2749                     next_nomacro_spc();
     3397                    next_argstream(nested_list, NULL);
    27503398                }
     3399                if (parlevel)
     3400                    expect(")");
    27513401                str.len -= spc;
     3402                tok_str_add(&str, -1);
    27523403                tok_str_add(&str, 0);
    27533404                sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
     
    27583409                       var arg argument if it is omitted */
    27593410                    if (sa && sa->type.t && gnu_ext)
    2760                         continue;
    2761                     else
    2762                         break;
     3411                        goto empty_arg;
     3412                    break;
    27633413                }
    27643414                if (tok != ',')
    27653415                    expect(",");
    2766                 next_nomacro();
    27673416            }
    27683417            if (sa) {
     
    27703419                      get_tok_str(s->v, 0));
    27713420            }
     3421
     3422            parse_flags = saved_parse_flags;
    27723423
    27733424            /* now subst each arg */
     
    27773428            while (sa) {
    27783429                sa1 = sa->prev;
    2779                 tok_str_free(sa->d);
     3430                tok_str_free_str(sa->d);
     3431                if (sa->next) {
     3432                    tok_str_free_str(sa->next->d);
     3433                    sym_free(sa->next);
     3434                }
    27803435                sym_free(sa);
    27813436                sa = sa1;
    27823437            }
    2783             mstr_allocated = 1;
    2784         }
     3438        }
     3439
    27853440        sym_push2(nested_list, s->v, 0, 0);
    2786         macro_subst(tok_str, nested_list, mstr, can_read_stream);
     3441        parse_flags = saved_parse_flags;
     3442        joined_str = macro_twosharps(mstr);
     3443        macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr);
     3444
    27873445        /* pop nested defined symbol */
    27883446        sa1 = *nested_list;
    27893447        *nested_list = sa1->prev;
    27903448        sym_free(sa1);
    2791         if (mstr_allocated)
    2792             tok_str_free(mstr);
     3449        if (joined_str)
     3450            tok_str_free_str(joined_str);
     3451        if (mstr != s->d)
     3452            tok_str_free_str(mstr);
    27933453    }
    27943454    return 0;
    27953455}
    2796 
    2797 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
    2798    return the resulting string (which must be freed). */
    2799 static inline int *macro_twosharps(const int *macro_str)
    2800 {
    2801     const int *ptr;
    2802     int t;
    2803     TokenString macro_str1;
    2804     CString cstr;
    2805     int n, start_of_nosubsts;
    2806 
    2807     /* we search the first '##' */
    2808     for(ptr = macro_str;;) {
    2809         CValue cval;
    2810         TOK_GET(&t, &ptr, &cval);
    2811         if (t == TOK_TWOSHARPS)
    2812             break;
    2813         /* nothing more to do if end of string */
    2814         if (t == 0)
    2815             return NULL;
    2816     }
    2817 
    2818     /* we saw '##', so we need more processing to handle it */
    2819     start_of_nosubsts = -1;
    2820     tok_str_new(&macro_str1);
    2821     for(ptr = macro_str;;) {
    2822         TOK_GET(&tok, &ptr, &tokc);
    2823         if (tok == 0)
    2824             break;
    2825         if (tok == TOK_TWOSHARPS)
    2826             continue;
    2827         if (tok == TOK_NOSUBST && start_of_nosubsts < 0)
    2828             start_of_nosubsts = macro_str1.len;
    2829         while (*ptr == TOK_TWOSHARPS) {
    2830             /* given 'a##b', remove nosubsts preceding 'a' */
    2831             if (start_of_nosubsts >= 0)
    2832                 macro_str1.len = start_of_nosubsts;
    2833             /* given 'a##b', skip '##' */
    2834             t = *++ptr;
    2835             /* given 'a##b', remove nosubsts preceding 'b' */
    2836             while (t == TOK_NOSUBST)
    2837                 t = *++ptr;
    2838             if (t && t != TOK_TWOSHARPS) {
    2839                 CValue cval;
    2840                 TOK_GET(&t, &ptr, &cval);
    2841                 /* We concatenate the two tokens */
    2842                 cstr_new(&cstr);
    2843                 cstr_cat(&cstr, get_tok_str(tok, &tokc));
    2844                 n = cstr.size;
    2845                 cstr_cat(&cstr, get_tok_str(t, &cval));
    2846                 cstr_ccat(&cstr, '\0');
    2847 
    2848                 tcc_open_bf(tcc_state, ":paste:", cstr.size);
    2849                 memcpy(file->buffer, cstr.data, cstr.size);
    2850                 for (;;) {
    2851                     next_nomacro1();
    2852                     if (0 == *file->buf_ptr)
    2853                         break;
    2854                     tok_str_add2(&macro_str1, tok, &tokc);
    2855                     tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid preprocessing token",
    2856                         n, cstr.data, (char*)cstr.data + n);
    2857                 }
    2858                 tcc_close();
    2859                 cstr_free(&cstr);
    2860             }
    2861         }
    2862         if (tok != TOK_NOSUBST)
    2863             start_of_nosubsts = -1;
    2864         tok_str_add2(&macro_str1, tok, &tokc);
    2865     }
    2866     tok_str_add(&macro_str1, 0);
    2867     return macro_str1.str;
    2868 }
    2869 
    28703456
    28713457/* do macro substitution of macro_str and add result to
    28723458   (tok_str,tok_len). 'nested_list' is the list of all macros we got
    28733459   inside to avoid recursing. */
    2874 static void macro_subst(TokenString *tok_str, Sym **nested_list,
    2875                         const int *macro_str, struct macro_level ** can_read_stream)
     3460static void macro_subst(
     3461    TokenString *tok_str,
     3462    Sym **nested_list,
     3463    const int *macro_str
     3464    )
    28763465{
    28773466    Sym *s;
    2878     int *macro_str1;
    2879     const int *ptr;
    2880     int t, ret, spc;
     3467    int t, spc, nosubst;
    28813468    CValue cval;
    2882     struct macro_level ml;
    2883     int force_blank;
    28843469   
    2885     /* first scan for '##' operator handling */
    2886     ptr = macro_str;
    2887     macro_str1 = macro_twosharps(ptr);
    2888 
    2889     if (macro_str1)
    2890         ptr = macro_str1;
    2891     spc = 0;
    2892     force_blank = 0;
     3470    spc = nosubst = 0;
    28933471
    28943472    while (1) {
    2895         /* NOTE: ptr == NULL can only happen if tokens are read from
    2896            file stream due to a macro function call */
    2897         if (ptr == NULL)
     3473        TOK_GET(&t, &macro_str, &cval);
     3474        if (t <= 0)
    28983475            break;
    2899         TOK_GET(&t, &ptr, &cval);
    2900         if (t == 0)
    2901             break;
    2902         if (t == TOK_NOSUBST) {
    2903             /* following token has already been subst'd. just copy it on */
    2904             tok_str_add2(tok_str, TOK_NOSUBST, NULL);
    2905             TOK_GET(&t, &ptr, &cval);
    2906             goto no_subst;
    2907         }
    2908         s = define_find(t);
    2909         if (s != NULL) {
     3476
     3477        if (t >= TOK_IDENT && 0 == nosubst) {
     3478            s = define_find(t);
     3479            if (s == NULL)
     3480                goto no_subst;
     3481
    29103482            /* if nested substitution, do nothing */
    29113483            if (sym_find2(*nested_list, t)) {
     
    29143486                goto no_subst;
    29153487            }
    2916             ml.p = macro_ptr;
    2917             if (can_read_stream)
    2918                 ml.prev = *can_read_stream, *can_read_stream = &ml;
    2919             macro_ptr = (int *)ptr;
    2920             tok = t;
    2921             ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
    2922             ptr = (int *)macro_ptr;
    2923             macro_ptr = ml.p;
    2924             if (can_read_stream && *can_read_stream == &ml)
    2925                 *can_read_stream = ml.prev;
    2926             if (ret != 0)
    2927                 goto no_subst;
    2928             if (parse_flags & PARSE_FLAG_SPACES)
    2929                 force_blank = 1;
     3488
     3489            {
     3490                TokenString str;
     3491                str.str = (int*)macro_str;
     3492                begin_macro(&str, 2);
     3493
     3494                tok = t;
     3495                macro_subst_tok(tok_str, nested_list, s);
     3496
     3497                if (str.alloc == 3) {
     3498                    /* already finished by reading function macro arguments */
     3499                    break;
     3500                }
     3501
     3502                macro_str = macro_ptr;
     3503                end_macro ();
     3504            }
     3505            if (tok_str->len)
     3506                spc = is_space(t = tok_str->str[tok_str->lastlen]);
    29303507        } else {
    2931         no_subst:
    2932             if (force_blank) {
    2933                 tok_str_add(tok_str, ' ');
    2934                 spc = 1;
    2935                 force_blank = 0;
    2936             }
    2937             if (!check_space(t, &spc))
     3508            if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
     3509                tcc_error("stray '\\' in program");
     3510no_subst:
     3511            if (!check_space(t, &spc))
    29383512                tok_str_add2(tok_str, t, &cval);
    2939         }
    2940     }
    2941     if (macro_str1)
    2942         tok_str_free(macro_str1);
     3513
     3514            if (nosubst) {
     3515                if (nosubst > 1 && (spc || (++nosubst == 3 && t == '(')))
     3516                    continue;
     3517                nosubst = 0;
     3518            }
     3519            if (t == TOK_NOSUBST)
     3520                nosubst = 1;
     3521        }
     3522        /* GCC supports 'defined' as result of a macro substitution */
     3523        if (t == TOK_DEFINED && pp_expr)
     3524            nosubst = 2;
     3525    }
    29433526}
    29443527
     
    29463529ST_FUNC void next(void)
    29473530{
    2948     Sym *nested_list, *s;
    2949     TokenString str;
    2950     struct macro_level *ml;
    2951 
    29523531 redo:
    29533532    if (parse_flags & PARSE_FLAG_SPACES)
     
    29553534    else
    29563535        next_nomacro();
    2957     if (!macro_ptr) {
    2958         /* if not reading from macro substituted string, then try
    2959            to substitute macros */
    2960         if (tok >= TOK_IDENT &&
    2961             (parse_flags & PARSE_FLAG_PREPROCESS)) {
    2962             s = define_find(tok);
    2963             if (s) {
    2964                 /* we have a macro: we try to substitute */
    2965                 tok_str_new(&str);
    2966                 nested_list = NULL;
    2967                 ml = NULL;
    2968                 if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
    2969                     /* substitution done, NOTE: maybe empty */
    2970                     tok_str_add(&str, 0);
    2971                     macro_ptr = str.str;
    2972                     macro_ptr_allocated = str.str;
    2973                     goto redo;
    2974                 }
    2975             }
    2976         }
    2977     } else {
    2978         if (tok == 0) {
    2979             /* end of macro or end of unget buffer */
    2980             if (unget_buffer_enabled) {
    2981                 macro_ptr = unget_saved_macro_ptr;
    2982                 unget_buffer_enabled = 0;
    2983             } else {
    2984                 /* end of macro string: free it */
    2985                 tok_str_free(macro_ptr_allocated);
    2986                 macro_ptr_allocated = NULL;
    2987                 macro_ptr = NULL;
    2988             }
     3536
     3537    if (macro_ptr) {
     3538        if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) {
     3539        /* discard preprocessor markers */
    29893540            goto redo;
    2990         } else if (tok == TOK_NOSUBST) {
    2991             /* discard preprocessor's nosubst markers */
     3541        } else if (tok == 0) {
     3542            /* end of macro or unget token string */
     3543            end_macro();
    29923544            goto redo;
    29933545        }
    2994     }
    2995    
     3546    } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
     3547        Sym *s;
     3548        /* if reading from file, try to substitute macros */
     3549        s = define_find(tok);
     3550        if (s) {
     3551            Sym *nested_list = NULL;
     3552            tokstr_buf.len = 0;
     3553            macro_subst_tok(&tokstr_buf, &nested_list, s);
     3554            tok_str_add(&tokstr_buf, 0);
     3555            begin_macro(&tokstr_buf, 2);
     3556            goto redo;
     3557        }
     3558    }
    29963559    /* convert preprocessor tokens into C tokens */
    2997     if (tok == TOK_PPNUM &&
    2998         (parse_flags & PARSE_FLAG_TOK_NUM)) {
    2999         parse_number((char *)tokc.cstr->data);
     3560    if (tok == TOK_PPNUM) {
     3561        if  (parse_flags & PARSE_FLAG_TOK_NUM)
     3562            parse_number((char *)tokc.str.data);
     3563    } else if (tok == TOK_PPSTR) {
     3564        if (parse_flags & PARSE_FLAG_TOK_STR)
     3565            parse_string((char *)tokc.str.data, tokc.str.size - 1);
    30003566    }
    30013567}
     
    30053571ST_INLN void unget_tok(int last_tok)
    30063572{
    3007     int i, n;
    3008     int *q;
    3009     if (unget_buffer_enabled)
    3010       {
    3011         /* assert(macro_ptr == unget_saved_buffer + 1);
    3012            assert(*macro_ptr == 0);  */
    3013       }
    3014     else
    3015       {
    3016         unget_saved_macro_ptr = macro_ptr;
    3017         unget_buffer_enabled = 1;
    3018       }
    3019     q = unget_saved_buffer;
    3020     macro_ptr = q;
    3021     *q++ = tok;
    3022     n = tok_ext_size(tok) - 1;
    3023     for(i=0;i<n;i++)
    3024         *q++ = tokc.tab[i];
    3025     *q = 0; /* end of token string */
     3573
     3574    TokenString *str = tok_str_alloc();
     3575    tok_str_add2(str, tok, &tokc);
     3576    tok_str_add(str, 0);
     3577    begin_macro(str, 1);
    30263578    tok = last_tok;
    30273579}
    30283580
    3029 
    3030 /* better than nothing, but needs extension to handle '-E' option
    3031    correctly too */
    3032 ST_FUNC void preprocess_init(TCCState *s1)
    3033 {
     3581ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
     3582{
     3583    CString cstr;
     3584    int i;
     3585
    30343586    s1->include_stack_ptr = s1->include_stack;
    3035     /* XXX: move that before to avoid having to initialize
    3036        file->ifdef_stack_ptr ? */
    30373587    s1->ifdef_stack_ptr = s1->ifdef_stack;
    30383588    file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
    3039 
    3040     vtop = vstack - 1;
     3589    pp_expr = 0;
     3590    pp_counter = 0;
     3591    pp_debug_tok = pp_debug_symv = 0;
     3592    pp_once++;
     3593    pvtop = vtop = vstack - 1;
    30413594    s1->pack_stack[0] = 0;
    30423595    s1->pack_stack_ptr = s1->pack_stack;
    3043 }
    3044 
    3045 ST_FUNC void preprocess_new(void)
     3596
     3597    set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
     3598    set_idnum('.', is_asm ? IS_ID : 0);
     3599
     3600    cstr_new(&cstr);
     3601    cstr_cat(&cstr, "\"", -1);
     3602    cstr_cat(&cstr, file->filename, -1);
     3603    cstr_cat(&cstr, "\"", 0);
     3604    tcc_define_symbol(s1, "__BASE_FILE__", cstr.data);
     3605
     3606    cstr_reset(&cstr);
     3607    for (i = 0; i < s1->nb_cmd_include_files; i++) {
     3608        cstr_cat(&cstr, "#include \"", -1);
     3609        cstr_cat(&cstr, s1->cmd_include_files[i], -1);
     3610        cstr_cat(&cstr, "\"\n", -1);
     3611    }
     3612    if (cstr.size) {
     3613        *s1->include_stack_ptr++ = file;
     3614        tcc_open_bf(s1, "<command line>", cstr.size);
     3615        memcpy(file->buffer, cstr.data, cstr.size);
     3616    }
     3617    cstr_free(&cstr);
     3618
     3619    if (is_asm)
     3620        tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
     3621
     3622    parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
     3623    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
     3624}
     3625
     3626/* cleanup from error/setjmp */
     3627ST_FUNC void preprocess_end(TCCState *s1)
     3628{
     3629    while (macro_stack)
     3630        end_macro();
     3631    macro_ptr = NULL;
     3632}
     3633
     3634ST_FUNC void tccpp_new(TCCState *s)
    30463635{
    30473636    int i, c;
    30483637    const char *p, *r;
    30493638
     3639    /* might be used in error() before preprocess_start() */
     3640    s->include_stack_ptr = s->include_stack;
     3641    s->ppfp = stdout;
     3642
    30503643    /* init isid table */
    3051     for(i=CH_EOF;i<256;i++)
    3052         isidnum_table[i-CH_EOF] = isid(i) || isnum(i);
    3053 
    3054     /* add all tokens */
    3055     table_ident = NULL;
     3644    for(i = CH_EOF; i<128; i++)
     3645        set_idnum(i,
     3646            is_space(i) ? IS_SPC
     3647            : isid(i) ? IS_ID
     3648            : isnum(i) ? IS_NUM
     3649            : 0);
     3650
     3651    for(i = 128; i<256; i++)
     3652        set_idnum(i, IS_ID);
     3653
     3654    /* init allocators */
     3655    tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
     3656    tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE);
     3657    tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE);
     3658
    30563659    memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
     3660    cstr_new(&cstr_buf);
     3661    cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
     3662    tok_str_new(&tokstr_buf);
     3663    tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE);
    30573664   
    30583665    tok_ident = TOK_IDENT;
     
    30703677}
    30713678
     3679ST_FUNC void tccpp_delete(TCCState *s)
     3680{
     3681    int i, n;
     3682
     3683    /* free -D and compiler defines */
     3684    free_defines(NULL);
     3685
     3686    /* free tokens */
     3687    n = tok_ident - TOK_IDENT;
     3688    for(i = 0; i < n; i++)
     3689        tal_free(toksym_alloc, table_ident[i]);
     3690    tcc_free(table_ident);
     3691    table_ident = NULL;
     3692
     3693    /* free static buffers */
     3694    cstr_free(&tokcstr);
     3695    cstr_free(&cstr_buf);
     3696    cstr_free(&macro_equal_buf);
     3697    tok_str_free_str(tokstr_buf.str);
     3698
     3699    /* free allocators */
     3700    tal_delete(toksym_alloc);
     3701    toksym_alloc = NULL;
     3702    tal_delete(tokstr_alloc);
     3703    tokstr_alloc = NULL;
     3704    tal_delete(cstr_alloc);
     3705    cstr_alloc = NULL;
     3706}
     3707
     3708/* ------------------------------------------------------------------------- */
     3709/* tcc -E [-P[1]] [-dD} support */
     3710
     3711static void tok_print(const char *msg, const int *str)
     3712{
     3713    FILE *fp;
     3714    int t, s = 0;
     3715    CValue cval;
     3716
     3717    fp = tcc_state->ppfp;
     3718    fprintf(fp, "%s", msg);
     3719    while (str) {
     3720        TOK_GET(&t, &str, &cval);
     3721        if (!t)
     3722            break;
     3723        fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
     3724    }
     3725    fprintf(fp, "\n");
     3726}
     3727
     3728static void pp_line(TCCState *s1, BufferedFile *f, int level)
     3729{
     3730    int d = f->line_num - f->line_ref;
     3731
     3732    if (s1->dflag & 4)
     3733        return;
     3734
     3735    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) {
     3736        ;
     3737    } else if (level == 0 && f->line_ref && d < 8) {
     3738        while (d > 0)
     3739            fputs("\n", s1->ppfp), --d;
     3740    } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) {
     3741        fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename);
     3742    } else {
     3743        fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename,
     3744            level > 0 ? " 1" : level < 0 ? " 2" : "");
     3745    }
     3746    f->line_ref = f->line_num;
     3747}
     3748
     3749static void define_print(TCCState *s1, int v)
     3750{
     3751    FILE *fp;
     3752    Sym *s;
     3753
     3754    s = define_find(v);
     3755    if (NULL == s || NULL == s->d)
     3756        return;
     3757
     3758    fp = s1->ppfp;
     3759    fprintf(fp, "#define %s", get_tok_str(v, NULL));
     3760    if (s->type.t == MACRO_FUNC) {
     3761        Sym *a = s->next;
     3762        fprintf(fp,"(");
     3763        if (a)
     3764            for (;;) {
     3765                fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL));
     3766                if (!(a = a->next))
     3767                    break;
     3768                fprintf(fp,",");
     3769            }
     3770        fprintf(fp,")");
     3771    }
     3772    tok_print("", s->d);
     3773}
     3774
     3775static void pp_debug_defines(TCCState *s1)
     3776{
     3777    int v, t;
     3778    const char *vs;
     3779    FILE *fp;
     3780
     3781    t = pp_debug_tok;
     3782    if (t == 0)
     3783        return;
     3784
     3785    file->line_num--;
     3786    pp_line(s1, file, 0);
     3787    file->line_ref = ++file->line_num;
     3788
     3789    fp = s1->ppfp;
     3790    v = pp_debug_symv;
     3791    vs = get_tok_str(v, NULL);
     3792    if (t == TOK_DEFINE) {
     3793        define_print(s1, v);
     3794    } else if (t == TOK_UNDEF) {
     3795        fprintf(fp, "#undef %s\n", vs);
     3796    } else if (t == TOK_push_macro) {
     3797        fprintf(fp, "#pragma push_macro(\"%s\")\n", vs);
     3798    } else if (t == TOK_pop_macro) {
     3799        fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs);
     3800    }
     3801    pp_debug_tok = 0;
     3802}
     3803
     3804static void pp_debug_builtins(TCCState *s1)
     3805{
     3806    int v;
     3807    for (v = TOK_IDENT; v < tok_ident; ++v)
     3808        define_print(s1, v);
     3809}
     3810
     3811/* Add a space between tokens a and b to avoid unwanted textual pasting */
     3812static int pp_need_space(int a, int b)
     3813{
     3814    return 'E' == a ? '+' == b || '-' == b
     3815        : '+' == a ? TOK_INC == b || '+' == b
     3816        : '-' == a ? TOK_DEC == b || '-' == b
     3817        : a >= TOK_IDENT ? b >= TOK_IDENT
     3818        : a == TOK_PPNUM ? b >= TOK_IDENT
     3819        : 0;
     3820}
     3821
     3822/* maybe hex like 0x1e */
     3823static int pp_check_he0xE(int t, const char *p)
     3824{
     3825    if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E')
     3826        return 'E';
     3827    return t;
     3828}
     3829
    30723830/* Preprocess the current file */
    30733831ST_FUNC int tcc_preprocess(TCCState *s1)
    30743832{
    3075     Sym *define_start;
    3076 
    3077     BufferedFile *file_ref, **iptr, **iptr_new;
    3078     int token_seen, line_ref, d;
    3079     const char *s;
    3080 
    3081     preprocess_init(s1);
    3082     define_start = define_stack;
    3083     ch = file->buf_ptr[0];
    3084     tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
    3085     parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
    3086         PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
    3087     token_seen = 0;
    3088     line_ref = 0;
    3089     file_ref = NULL;
    3090     iptr = s1->include_stack_ptr;
    3091 
     3833    BufferedFile **iptr;
     3834    int token_seen, spcs, level;
     3835    const char *p;
     3836    char white[400];
     3837
     3838    parse_flags = PARSE_FLAG_PREPROCESS
     3839                | (parse_flags & PARSE_FLAG_ASM_FILE)
     3840                | PARSE_FLAG_LINEFEED
     3841                | PARSE_FLAG_SPACES
     3842                | PARSE_FLAG_ACCEPT_STRAYS
     3843                ;
     3844    /* Credits to Fabrice Bellard's initial revision to demonstrate its
     3845       capability to compile and run itself, provided all numbers are
     3846       given as decimals. tcc -E -P10 will do. */
     3847    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10)
     3848        parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1;
     3849
     3850#ifdef PP_BENCH
     3851    /* for PP benchmarks */
     3852    do next(); while (tok != TOK_EOF);
     3853    return 0;
     3854#endif
     3855
     3856    if (s1->dflag & 1) {
     3857        pp_debug_builtins(s1);
     3858        s1->dflag &= ~1;
     3859    }
     3860
     3861    token_seen = TOK_LINEFEED, spcs = 0;
     3862    pp_line(s1, file, 0);
    30923863    for (;;) {
     3864        iptr = s1->include_stack_ptr;
    30933865        next();
    3094         if (tok == TOK_EOF) {
     3866        if (tok == TOK_EOF)
    30953867            break;
    3096         } else if (file != file_ref) {
    3097             goto print_line;
     3868
     3869        level = s1->include_stack_ptr - iptr;
     3870        if (level) {
     3871            if (level > 0)
     3872                pp_line(s1, *iptr, 0);
     3873            pp_line(s1, file, level);
     3874        }
     3875        if (s1->dflag & 7) {
     3876            pp_debug_defines(s1);
     3877            if (s1->dflag & 4)
     3878                continue;
     3879        }
     3880
     3881        if (is_space(tok)) {
     3882            if (spcs < sizeof white - 1)
     3883                white[spcs++] = tok;
     3884            continue;
    30983885        } else if (tok == TOK_LINEFEED) {
    3099             if (!token_seen)
     3886            spcs = 0;
     3887            if (token_seen == TOK_LINEFEED)
    31003888                continue;
    3101             ++line_ref;
    3102             token_seen = 0;
    3103         } else if (!token_seen) {
    3104             d = file->line_num - line_ref;
    3105             if (file != file_ref || d < 0 || d >= 8) {
    3106 print_line:
    3107                 iptr_new = s1->include_stack_ptr;
    3108                 s = iptr_new > iptr ? " 1"
    3109                   : iptr_new < iptr ? " 2"
    3110                   : iptr_new > s1->include_stack ? " 3"
    3111                   : ""
    3112                   ;
    3113                 iptr = iptr_new;
    3114                 fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
    3115             } else {
    3116                 while (d)
    3117                     fputs("\n", s1->ppfp), --d;
    3118             }
    3119             line_ref = (file_ref = file)->line_num;
    3120             token_seen = tok != TOK_LINEFEED;
    3121             if (!token_seen)
    3122                 continue;
    3123         }
    3124         fputs(get_tok_str(tok, &tokc), s1->ppfp);
    3125     }
    3126     free_defines(define_start);
     3889            ++file->line_ref;
     3890        } else if (token_seen == TOK_LINEFEED) {
     3891            pp_line(s1, file, 0);
     3892        } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
     3893            white[spcs++] = ' ';
     3894        }
     3895
     3896        white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
     3897        fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
     3898        token_seen = pp_check_he0xE(tok, p);
     3899    }
    31273900    return 0;
    31283901}
     3902
     3903/* ------------------------------------------------------------------------- */
  • EcnlProtoTool/trunk/tcc-0.9.27/tccrun.c

    r321 r331  
    2424#ifdef TCC_IS_NATIVE
    2525
     26#ifndef _WIN32
     27# include <sys/mman.h>
     28#endif
     29
    2630#ifdef CONFIG_TCC_BACKTRACE
     31# ifndef _WIN32
     32#  include <signal.h>
     33#  ifndef __OpenBSD__
     34#   include <sys/ucontext.h>
     35#  endif
     36# else
     37#  define ucontext_t CONTEXT
     38# endif
    2739ST_DATA int rt_num_callers = 6;
    2840ST_DATA const char **rt_bound_error_msg;
    2941ST_DATA void *rt_prog_main;
    30 #endif
    31 
    32 #ifdef _WIN32
    33 #define ucontext_t CONTEXT
    34 #endif
    35 
    36 static void set_pages_executable(void *ptr, unsigned long length);
    37 static void set_exception_handler(void);
    3842static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level);
    3943static void rt_error(ucontext_t *uc, const char *fmt, ...);
    40 static int tcc_relocate_ex(TCCState *s1, void *ptr);
     44static void set_exception_handler(void);
     45#endif
     46
     47static void set_pages_executable(void *ptr, unsigned long length);
     48static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
    4149
    4250#ifdef _WIN64
    43 static void win64_add_function_table(TCCState *s1);
     51static void *win64_add_function_table(TCCState *s1);
     52static void win64_del_function_table(void *);
    4453#endif
    4554
     
    5059LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
    5160{
    52     int ret;
     61    int size;
     62    addr_t ptr_diff = 0;
    5363
    5464    if (TCC_RELOCATE_AUTO != ptr)
    55         return tcc_relocate_ex(s1, ptr);
    56 
    57     ret = tcc_relocate_ex(s1, NULL);
    58     if (ret < 0)
    59         return ret;
     65        return tcc_relocate_ex(s1, ptr, 0);
     66
     67    size = tcc_relocate_ex(s1, NULL, 0);
     68    if (size < 0)
     69        return -1;
    6070
    6171#ifdef HAVE_SELINUX
    62     {   /* Use mmap instead of malloc for Selinux.  Ref:
    63            http://www.gnu.org/s/libc/manual/html_node/File-Size.html */
    64 
    65         char tmpfname[] = "/tmp/.tccrunXXXXXX";
    66         int fd = mkstemp (tmpfname);
    67 
    68         s1->mem_size = ret;
    69         unlink (tmpfname);
    70         ftruncate (fd, s1->mem_size);
    71 
    72         s1->write_mem = mmap (NULL, ret, PROT_READ|PROT_WRITE,
    73             MAP_SHARED, fd, 0);
    74         if (s1->write_mem == MAP_FAILED)
    75             tcc_error("/tmp not writeable");
    76 
    77         s1->runtime_mem = mmap (NULL, ret, PROT_READ|PROT_EXEC,
    78             MAP_SHARED, fd, 0);
    79         if (s1->runtime_mem == MAP_FAILED)
    80             tcc_error("/tmp not executable");
    81 
    82         ret = tcc_relocate_ex(s1, s1->write_mem);
    83     }
    84 #else
    85     s1->runtime_mem = tcc_malloc(ret);
    86     ret = tcc_relocate_ex(s1, s1->runtime_mem);
    87 #endif
    88     return ret;
     72{
     73    /* Using mmap instead of malloc */
     74    void *prx;
     75    char tmpfname[] = "/tmp/.tccrunXXXXXX";
     76    int fd = mkstemp(tmpfname);
     77    unlink(tmpfname);
     78    ftruncate(fd, size);
     79
     80    ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
     81    prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
     82    if (ptr == MAP_FAILED || prx == MAP_FAILED)
     83        tcc_error("tccrun: could not map memory");
     84    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
     85    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
     86    ptr_diff = (char*)prx - (char*)ptr;
     87}
     88#else
     89    ptr = tcc_malloc(size);
     90#endif
     91    tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
     92    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
     93    return 0;
     94}
     95
     96ST_FUNC void tcc_run_free(TCCState *s1)
     97{
     98    int i;
     99
     100    for (i = 0; i < s1->nb_runtime_mem; ++i) {
     101#ifdef HAVE_SELINUX
     102        unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
     103        munmap(s1->runtime_mem[i++], size);
     104        munmap(s1->runtime_mem[i], size);
     105#else
     106#ifdef _WIN64
     107        win64_del_function_table(*(void**)s1->runtime_mem[i]);
     108#endif
     109        tcc_free(s1->runtime_mem[i]);
     110#endif
     111    }
     112    tcc_free(s1->runtime_mem);
    89113}
    90114
     
    93117{
    94118    int (*prog_main)(int, char **);
    95     int ret;
    96 
     119
     120    s1->runtime_main = "main";
     121    if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
     122        return 0;
    97123    if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
    98124        return -1;
    99 
    100     prog_main = tcc_get_symbol_err(s1, "main");
     125    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
    101126
    102127#ifdef CONFIG_TCC_BACKTRACE
     
    107132#endif
    108133
     134    errno = 0; /* clean errno value */
     135
    109136#ifdef CONFIG_TCC_BCHECK
    110137    if (s1->do_bounds_check) {
    111138        void (*bound_init)(void);
    112139        void (*bound_exit)(void);
     140        void (*bound_new_region)(void *p, addr_t size);
     141        int  (*bound_delete_region)(void *p);
     142        int i, ret;
     143
    113144        /* set error function */
    114145        rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
     
    116147        bound_init = tcc_get_symbol_err(s1, "__bound_init");
    117148        bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
     149        bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region");
     150        bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region");
     151
    118152        bound_init();
     153        /* mark argv area as valid */
     154        bound_new_region(argv, argc*sizeof(argv[0]));
     155        for (i=0; i<argc; ++i)
     156            bound_new_region(argv[i], strlen(argv[i]) + 1);
     157
    119158        ret = (*prog_main)(argc, argv);
     159
     160        /* unmark argv area */
     161        for (i=0; i<argc; ++i)
     162            bound_delete_region(argv[i]);
     163        bound_delete_region(argv);
    120164        bound_exit();
    121     } else
    122 #endif
    123         ret = (*prog_main)(argc, argv);
    124     return ret;
    125 }
     165        return ret;
     166    }
     167#endif
     168    return (*prog_main)(argc, argv);
     169}
     170
     171#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
     172 #define RUN_SECTION_ALIGNMENT 63
     173#else
     174 #define RUN_SECTION_ALIGNMENT 15
     175#endif
    126176
    127177/* relocate code. Return -1 on error, required size if ptr is NULL,
    128178   otherwise copy code into buffer passed by the caller */
    129 static int tcc_relocate_ex(TCCState *s1, void *ptr)
     179static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
    130180{
    131181    Section *s;
    132     unsigned long offset, length;
     182    unsigned offset, length, fill, i, k;
    133183    addr_t mem;
    134     int i;
    135184
    136185    if (NULL == ptr) {
     
    140189#else
    141190        tcc_add_runtime(s1);
    142         relocate_common_syms();
    143         tcc_add_linker_symbols(s1);
     191        resolve_common_syms(s1);
    144192        build_got_entries(s1);
    145193#endif
     
    149197
    150198    offset = 0, mem = (addr_t)ptr;
     199    fill = -mem & RUN_SECTION_ALIGNMENT;
     200#ifdef _WIN64
     201    offset += sizeof (void*);
     202#endif
     203    for (k = 0; k < 2; ++k) {
     204        for(i = 1; i < s1->nb_sections; i++) {
     205            s = s1->sections[i];
     206            if (0 == (s->sh_flags & SHF_ALLOC))
     207                continue;
     208            if (k != !(s->sh_flags & SHF_EXECINSTR))
     209                continue;
     210            offset += fill;
     211            if (!mem)
     212                s->sh_addr = 0;
     213            else if (s->sh_flags & SHF_EXECINSTR)
     214                s->sh_addr = mem + offset + ptr_diff;
     215            else
     216                s->sh_addr = mem + offset;
     217#if 0
     218            if (mem)
     219                printf("%-16s +%02lx %p %04x\n",
     220                    s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset);
     221#endif
     222            offset += s->data_offset;
     223            fill = -(mem + offset) & 15;
     224        }
     225#if RUN_SECTION_ALIGNMENT > 15
     226        /* To avoid that x86 processors would reload cached instructions each time
     227           when data is written in the near, we need to make sure that code and data
     228           do not share the same 64 byte unit */
     229        fill = -(mem + offset) & RUN_SECTION_ALIGNMENT;
     230#endif
     231    }
     232
     233    /* relocate symbols */
     234    relocate_syms(s1, s1->symtab, 1);
     235    if (s1->nb_errors)
     236        return -1;
     237
     238    if (0 == mem)
     239        return offset + RUN_SECTION_ALIGNMENT;
     240
     241#ifdef TCC_TARGET_PE
     242    s1->pe_imagebase = mem;
     243#endif
     244
     245    /* relocate each section */
     246    for(i = 1; i < s1->nb_sections; i++) {
     247        s = s1->sections[i];
     248        if (s->reloc)
     249            relocate_section(s1, s);
     250    }
     251    relocate_plt(s1);
     252
    151253    for(i = 1; i < s1->nb_sections; i++) {
    152254        s = s1->sections[i];
     
    154256            continue;
    155257        length = s->data_offset;
    156         s->sh_addr = mem ? (mem + offset + 15) & ~15 : 0;
    157         offset = (offset + length + 15) & ~15;
    158     }
    159     offset += 16;
    160 
    161     /* relocate symbols */
    162     relocate_syms(s1, 1);
    163     if (s1->nb_errors)
    164         return -1;
    165 
    166 #ifdef TCC_HAS_RUNTIME_PLTGOT
    167     s1->runtime_plt_and_got_offset = 0;
    168     s1->runtime_plt_and_got = (char *)(mem + offset);
    169     /* double the size of the buffer for got and plt entries
    170        XXX: calculate exact size for them? */
    171     offset *= 2;
    172 #endif
    173 
    174     if (0 == mem)
    175         return offset;
    176 
    177     /* relocate each section */
    178     for(i = 1; i < s1->nb_sections; i++) {
    179         s = s1->sections[i];
    180         if (s->reloc)
    181             relocate_section(s1, s);
    182     }
    183 
    184     for(i = 1; i < s1->nb_sections; i++) {
    185         s = s1->sections[i];
    186         if (0 == (s->sh_flags & SHF_ALLOC))
    187             continue;
    188         length = s->data_offset;
    189         // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length);
    190258        ptr = (void*)s->sh_addr;
     259        if (s->sh_flags & SHF_EXECINSTR)
     260            ptr = (char*)ptr - ptr_diff;
    191261        if (NULL == s->data || s->sh_type == SHT_NOBITS)
    192262            memset(ptr, 0, length);
     
    195265        /* mark executable sections as executable in memory */
    196266        if (s->sh_flags & SHF_EXECINSTR)
    197             set_pages_executable(ptr, length);
    198     }
    199 
    200 #ifdef TCC_HAS_RUNTIME_PLTGOT
    201     set_pages_executable(s1->runtime_plt_and_got,
    202                          s1->runtime_plt_and_got_offset);
    203 #endif
     267            set_pages_executable((char*)ptr + ptr_diff, length);
     268    }
    204269
    205270#ifdef _WIN64
    206     win64_add_function_table(s1);
    207 #endif
     271    *(void**)mem = win64_add_function_table(s1);
     272#endif
     273
    208274    return 0;
    209275}
     
    218284    VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
    219285#else
    220 #ifndef PAGESIZE
    221 # define PAGESIZE 4096
    222 #endif
     286    void __clear_cache(void *beginning, void *end);
     287# ifndef HAVE_SELINUX
    223288    addr_t start, end;
     289#  ifndef PAGESIZE
     290#   define PAGESIZE 4096
     291#  endif
    224292    start = (addr_t)ptr & ~(PAGESIZE - 1);
    225293    end = (addr_t)ptr + length;
    226294    end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
    227     mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
    228 #endif
    229 }
     295    if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
     296        tcc_error("mprotect failed: did you mean to configure --with-selinux?");
     297# endif
     298# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
     299    __clear_cache(ptr, (char *)ptr + length);
     300# endif
     301#endif
     302}
     303
     304#ifdef _WIN64
     305static void *win64_add_function_table(TCCState *s1)
     306{
     307    void *p = NULL;
     308    if (s1->uw_pdata) {
     309        p = (void*)s1->uw_pdata->sh_addr;
     310        RtlAddFunctionTable(
     311            (RUNTIME_FUNCTION*)p,
     312            s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
     313            s1->pe_imagebase
     314            );
     315        s1->uw_pdata = NULL;
     316    }
     317    return p;
     318}
     319
     320static void win64_del_function_table(void *p)
     321{
     322    if (p) {
     323        RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p);
     324    }
     325}
     326#endif
    230327
    231328/* ------------------------------------------------------------- */
     
    254351        stab_len = stab_section->data_offset;
    255352        stab_sym = (Stab_Sym *)stab_section->data;
    256         stab_str = stabstr_section->data;
     353        stab_str = (char *) stabstr_section->data;
    257354    }
    258355
     
    347444                    wanted_pc < sym->st_value + sym->st_size) {
    348445                    pstrcpy(last_func_name, sizeof(last_func_name),
    349                             strtab_section->data + sym->st_name);
     446                            (char *) symtab_section->link->data + sym->st_name);
    350447                    func_addr = sym->st_value;
    351448                    goto found;
     
    453550       runtime errors */
    454551    sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
    455     /*sigact.sa_sigaction = sig_error;*/
    456         sigact.sa_handler = sig_error;
     552    sigact.sa_sigaction = sig_error;
    457553    sigemptyset(&sigact.sa_mask);
    458554    sigaction(SIGFPE, &sigact, NULL);
     
    481577#if defined(__APPLE__)
    482578        *paddr = uc->uc_mcontext->__ss.__eip;
    483 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     579#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
    484580        *paddr = uc->uc_mcontext.mc_eip;
    485581#elif defined(__dietlibc__)
    486582        *paddr = uc->uc_mcontext.eip;
     583#elif defined(__NetBSD__)
     584        *paddr = uc->uc_mcontext.__gregs[_REG_EIP];
     585#elif defined(__OpenBSD__)
     586        *paddr = uc->sc_eip;
    487587#else
    488588        *paddr = uc->uc_mcontext.gregs[REG_EIP];
     
    492592#if defined(__APPLE__)
    493593        fp = uc->uc_mcontext->__ss.__ebp;
    494 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     594#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
    495595        fp = uc->uc_mcontext.mc_ebp;
    496596#elif defined(__dietlibc__)
    497597        fp = uc->uc_mcontext.ebp;
     598#elif defined(__NetBSD__)
     599        fp = uc->uc_mcontext.__gregs[_REG_EBP];
     600#elif defined(__OpenBSD__)
     601        *paddr = uc->sc_ebp;
    498602#else
    499603        fp = uc->uc_mcontext.gregs[REG_EBP];
     
    523627#if defined(__APPLE__)
    524628        *paddr = uc->uc_mcontext->__ss.__rip;
    525 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     629#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
    526630        *paddr = uc->uc_mcontext.mc_rip;
     631#elif defined(__NetBSD__)
     632        *paddr = uc->uc_mcontext.__gregs[_REG_RIP];
    527633#else
    528634        *paddr = uc->uc_mcontext.gregs[REG_RIP];
     
    532638#if defined(__APPLE__)
    533639        fp = uc->uc_mcontext->__ss.__rbp;
    534 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     640#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
    535641        fp = uc->uc_mcontext.mc_rbp;
     642#elif defined(__NetBSD__)
     643        fp = uc->uc_mcontext.__gregs[_REG_RBP];
    536644#else
    537645        fp = uc->uc_mcontext.gregs[REG_RBP];
     
    587695        /* XXX: check address validity with program info */
    588696        *paddr = ((addr_t *)fp)[-1];
     697        return 0;
     698    }
     699}
     700
     701/* ------------------------------------------------------------- */
     702#elif defined(__aarch64__)
     703
     704static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
     705{
     706    if (level < 0)
     707        return -1;
     708    else if (level == 0) {
     709        *paddr = uc->uc_mcontext.pc;
     710        return 0;
     711    }
     712    else {
     713        addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29];
     714        int i;
     715        for (i = 1; i < level; i++)
     716            fp = (addr_t *)fp[0];
     717        *paddr = fp[1];
    589718        return 0;
    590719    }
     
    635764}
    636765
    637 #ifdef _WIN64
    638 static void win64_add_function_table(TCCState *s1)
    639 {
    640     RtlAddFunctionTable(
    641         (RUNTIME_FUNCTION*)s1->uw_pdata->sh_addr,
    642         s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
    643         text_section->sh_addr
    644         );
    645 }
    646 #endif
    647 
    648766/* return the PC at frame level 'level'. Return non zero if not found */
    649767static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
     
    696814} TCCSyms;
    697815
     816#if !defined(CONFIG_TCCBOOT)
     817extern int __environ;
     818extern int __expand_heap;
     819extern int __get_handler_set;
     820extern int __get_locale;
     821extern int __gmt;
     822extern int __h_errno_location;
     823extern int __hwcap;
     824extern int __init_tls;
     825extern int __libc;
     826extern int __libc_sigaction;
     827extern int __libc_start_main;
     828extern int __malloc0;
     829extern int __ofl_lock;
     830extern int __ofl_unlock;
     831extern int __progname;
     832extern int __progname_full;
     833extern int __secs_to_zone;
     834extern int __sigaction;
     835extern int __sysinfo;
     836extern int __tm_to_tzname;
     837//extern int atexit;
     838//extern int environ;
     839//extern int free;
     840extern int gethostbyname2;
     841//extern int getopt;
     842extern int getpwnam;
     843//extern int gmtime;
     844//extern int localtime;
     845//extern int malloc;
     846extern int mbrtowc;
     847//extern int optarg;
     848extern int optind;
     849//extern int rand;
     850//extern int realloc;
     851//extern int setenv;
     852extern int setlocale;
     853//extern int sigaction;
     854//extern int srand;
     855//extern int stderr;
     856//extern int stdin;
     857//extern int stdout;
     858//extern int strtok;
     859extern int syslog;
     860extern int vsyslog;
     861#endif
    698862
    699863/* add the symbol you want here if no dynamic linking is done */
     
    701865#if !defined(CONFIG_TCCBOOT)
    702866#define TCCSYM(a) { #a, &a, },
    703     TCCSYM(printf)
    704     TCCSYM(fprintf)
    705     TCCSYM(fopen)
    706     TCCSYM(fclose)
     867    TCCSYM(__environ)
     868    TCCSYM(__expand_heap)
     869    TCCSYM(__get_handler_set)
     870    TCCSYM(__get_locale)
     871    TCCSYM(__gmt)
     872    TCCSYM(__h_errno_location)
     873    TCCSYM(__hwcap)
     874    TCCSYM(__init_tls)
     875    TCCSYM(__libc)
     876    TCCSYM(__libc_sigaction)
     877    TCCSYM(__libc_start_main)
     878    TCCSYM(__malloc0)
     879    TCCSYM(__ofl_lock)
     880    TCCSYM(__ofl_unlock)
     881    TCCSYM(__progname)
     882    TCCSYM(__progname_full)
     883    TCCSYM(__secs_to_zone)
     884    TCCSYM(__sigaction)
     885    TCCSYM(__sysinfo)
     886    TCCSYM(__tm_to_tzname)
     887    TCCSYM(atexit)
     888    TCCSYM(environ)
     889    TCCSYM(free)
     890    TCCSYM(gethostbyname2)
     891    TCCSYM(getopt)
     892    TCCSYM(getpwnam)
     893    TCCSYM(gmtime)
     894    TCCSYM(localtime)
     895    TCCSYM(malloc)
     896    TCCSYM(mbrtowc)
     897    TCCSYM(optarg)
     898    TCCSYM(optind)
     899    TCCSYM(rand)
     900    TCCSYM(realloc)
     901    TCCSYM(setenv)
     902    TCCSYM(setlocale)
     903    TCCSYM(sigaction)
     904    TCCSYM(srand)
     905    TCCSYM(stderr)
     906    TCCSYM(stdin)
     907    TCCSYM(stdout)
     908    TCCSYM(strtok)
     909    TCCSYM(syslog)
     910    TCCSYM(vsyslog)
    707911#undef TCCSYM
    708912#endif
     
    710914};
    711915
    712 ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol)
     916ST_FUNC void *dlsym(void *handle, const char *symbol)
    713917{
    714918    TCCSyms *p;
     
    722926}
    723927
    724 #elif !defined(_WIN32)
    725 
    726 ST_FUNC void *resolve_sym(TCCState *s1, const char *sym)
    727 {
    728     return dlsym(RTLD_DEFAULT, sym);
    729 }
    730 
    731928#endif /* CONFIG_TCC_STATIC */
    732929#endif /* TCC_IS_NATIVE */
  • EcnlProtoTool/trunk/tcc-0.9.27/tcctok.h

    r321 r331  
    3737     DEF(TOK_RESTRICT3, "__restrict__")
    3838     DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
    39      
     39
     40     DEF(TOK_GENERIC, "_Generic")
     41
    4042     DEF(TOK_FLOAT, "float")
    4143     DEF(TOK_DOUBLE, "double")
     
    5961     DEF(TOK_ASM2, "__asm")
    6062     DEF(TOK_ASM3, "__asm__")
     63
     64#ifdef TCC_TARGET_ARM64
     65     DEF(TOK_UINT128, "__uint128_t")
     66#endif
    6167
    6268/*********************************************************************/
     
    8288     DEF(TOK___FUNCTION__, "__FUNCTION__")
    8389     DEF(TOK___VA_ARGS__, "__VA_ARGS__")
     90     DEF(TOK___COUNTER__, "__COUNTER__")
    8491
    8592/* special identifiers */
     
    114121     DEF(TOK_FASTCALL2, "__fastcall")
    115122     DEF(TOK_FASTCALL3, "__fastcall__")
     123     DEF(TOK_REGPARM1, "regparm")
     124     DEF(TOK_REGPARM2, "__regparm__")
     125
    116126     DEF(TOK_MODE, "__mode__")
     127     DEF(TOK_MODE_QI, "__QI__")
    117128     DEF(TOK_MODE_DI, "__DI__")
    118129     DEF(TOK_MODE_HI, "__HI__")
    119130     DEF(TOK_MODE_SI, "__SI__")
     131     DEF(TOK_MODE_word, "__word__")
     132
    120133     DEF(TOK_DLLEXPORT, "dllexport")
    121134     DEF(TOK_DLLIMPORT, "dllimport")
    122135     DEF(TOK_NORETURN1, "noreturn")
    123136     DEF(TOK_NORETURN2, "__noreturn__")
     137     DEF(TOK_VISIBILITY1, "visibility")
     138     DEF(TOK_VISIBILITY2, "__visibility__")
     139
    124140     DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
     141     DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
    125142     DEF(TOK_builtin_constant_p, "__builtin_constant_p")
    126143     DEF(TOK_builtin_frame_address, "__builtin_frame_address")
    127 #ifdef TCC_TARGET_X86_64
     144     DEF(TOK_builtin_return_address, "__builtin_return_address")
     145     DEF(TOK_builtin_expect, "__builtin_expect")
     146     /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
     147#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
     148     DEF(TOK_builtin_va_start, "__builtin_va_start")
     149#elif defined TCC_TARGET_X86_64
    128150     DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
    129 #endif
    130      DEF(TOK_REGPARM1, "regparm")
    131      DEF(TOK_REGPARM2, "__regparm__")
     151#elif defined TCC_TARGET_ARM64
     152     DEF(TOK___va_start, "__va_start")
     153     DEF(TOK___va_arg, "__va_arg")
     154#endif
    132155
    133156/* pragma */
     
    138161     DEF(TOK_ASM_pop, "pop")
    139162#endif
     163     DEF(TOK_comment, "comment")
     164     DEF(TOK_lib, "lib")
     165     DEF(TOK_push_macro, "push_macro")
     166     DEF(TOK_pop_macro, "pop_macro")
     167     DEF(TOK_once, "once")
     168     DEF(TOK_option, "option")
    140169
    141170/* builtin functions or variables */
    142 #ifdef TCC_ARM_EABI
    143      DEF(TOK_memcpy, "__aeabi_memcpy")
    144      DEF(TOK_memcpy4, "__aeabi_memcpy4")
    145      DEF(TOK_memcpy8, "__aeabi_memcpy8")
    146      DEF(TOK_memset, "__aeabi_memset")
    147      DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
    148      DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
    149 #else
     171#ifndef TCC_ARM_EABI
    150172     DEF(TOK_memcpy, "memcpy")
     173     DEF(TOK_memmove, "memmove")
    151174     DEF(TOK_memset, "memset")
    152175     DEF(TOK___divdi3, "__divdi3")
     
    154177     DEF(TOK___udivdi3, "__udivdi3")
    155178     DEF(TOK___umoddi3, "__umoddi3")
    156 #endif
    157 #if defined(TCC_TARGET_ARM)
    158 #ifdef TCC_ARM_EABI
     179     DEF(TOK___ashrdi3, "__ashrdi3")
     180     DEF(TOK___lshrdi3, "__lshrdi3")
     181     DEF(TOK___ashldi3, "__ashldi3")
     182     DEF(TOK___floatundisf, "__floatundisf")
     183     DEF(TOK___floatundidf, "__floatundidf")
     184# ifndef TCC_ARM_VFP
     185     DEF(TOK___floatundixf, "__floatundixf")
     186     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
     187# endif
     188     DEF(TOK___fixunssfdi, "__fixunssfdi")
     189     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
     190#endif
     191
     192#if defined TCC_TARGET_ARM
     193# ifdef TCC_ARM_EABI
     194     DEF(TOK_memcpy, "__aeabi_memcpy")
     195     DEF(TOK_memcpy4, "__aeabi_memcpy4")
     196     DEF(TOK_memcpy8, "__aeabi_memcpy8")
     197     DEF(TOK_memmove, "__aeabi_memmove")
     198     DEF(TOK_memset, "__aeabi_memset")
     199     DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
     200     DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
    159201     DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
    160202     DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
     
    165207     DEF(TOK___fixsfdi, "__aeabi_f2lz")
    166208     DEF(TOK___fixdfdi, "__aeabi_d2lz")
    167 #else
    168      DEF(TOK___modsi3, "__modsi3")
    169      DEF(TOK___umodsi3, "__umodsi3")
    170      DEF(TOK___divsi3, "__divsi3")
    171      DEF(TOK___udivsi3, "__udivsi3")
    172      DEF(TOK___floatdisf, "__floatdisf")
    173      DEF(TOK___floatdidf, "__floatdidf")
    174 #ifndef TCC_ARM_VFP
    175      DEF(TOK___floatdixf, "__floatdixf")
    176      DEF(TOK___fixunssfsi, "__fixunssfsi")
    177      DEF(TOK___fixunsdfsi, "__fixunsdfsi")
    178      DEF(TOK___fixunsxfsi, "__fixunsxfsi")
    179      DEF(TOK___fixxfdi, "__fixxfdi")
    180 #endif
    181      DEF(TOK___fixsfdi, "__fixsfdi")
    182      DEF(TOK___fixdfdi, "__fixdfdi")
    183 #endif
    184 #elif defined(TCC_TARGET_C67)
    185      DEF(TOK__divi, "_divi")
    186      DEF(TOK__divu, "_divu")
    187      DEF(TOK__divf, "_divf")
    188      DEF(TOK__divd, "_divd")
    189      DEF(TOK__remi, "_remi")
    190      DEF(TOK__remu, "_remu")
    191 #endif
    192 #ifdef TCC_TARGET_I386
    193      DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
    194      DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
    195 #endif
    196 #ifdef TCC_ARM_EABI
    197209     DEF(TOK___ashrdi3, "__aeabi_lasr")
    198210     DEF(TOK___lshrdi3, "__aeabi_llsr")
     
    202214     DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
    203215     DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
    204 #else
    205      DEF(TOK___ashrdi3, "__ashrdi3")
    206      DEF(TOK___lshrdi3, "__lshrdi3")
    207      DEF(TOK___ashldi3, "__ashldi3")
    208      DEF(TOK___floatundisf, "__floatundisf")
    209      DEF(TOK___floatundidf, "__floatundidf")
    210 #ifndef TCC_ARM_VFP
    211      DEF(TOK___floatundixf, "__floatundixf")
    212      DEF(TOK___fixunsxfdi, "__fixunsxfdi")
    213 #endif
    214      DEF(TOK___fixunssfdi, "__fixunssfdi")
    215      DEF(TOK___fixunsdfdi, "__fixunsdfdi")
    216 #endif
    217 #ifdef TCC_TARGET_PE
     216# else
     217     DEF(TOK___modsi3, "__modsi3")
     218     DEF(TOK___umodsi3, "__umodsi3")
     219     DEF(TOK___divsi3, "__divsi3")
     220     DEF(TOK___udivsi3, "__udivsi3")
     221     DEF(TOK___floatdisf, "__floatdisf")
     222     DEF(TOK___floatdidf, "__floatdidf")
     223#  ifndef TCC_ARM_VFP
     224     DEF(TOK___floatdixf, "__floatdixf")
     225     DEF(TOK___fixunssfsi, "__fixunssfsi")
     226     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
     227     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
     228     DEF(TOK___fixxfdi, "__fixxfdi")
     229#  endif
     230     DEF(TOK___fixsfdi, "__fixsfdi")
     231     DEF(TOK___fixdfdi, "__fixdfdi")
     232# endif
     233#endif
     234
     235#if defined TCC_TARGET_C67
     236     DEF(TOK__divi, "_divi")
     237     DEF(TOK__divu, "_divu")
     238     DEF(TOK__divf, "_divf")
     239     DEF(TOK__divd, "_divd")
     240     DEF(TOK__remi, "_remi")
     241     DEF(TOK__remu, "_remu")
     242#endif
     243
     244#if defined TCC_TARGET_I386
     245     DEF(TOK___fixsfdi, "__fixsfdi")
     246     DEF(TOK___fixdfdi, "__fixdfdi")
     247     DEF(TOK___fixxfdi, "__fixxfdi")
     248#endif
     249
     250#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
     251     DEF(TOK_alloca, "alloca")
     252#endif
     253
     254#if defined TCC_TARGET_PE
    218255     DEF(TOK___chkstk, "__chkstk")
     256#endif
     257#ifdef TCC_TARGET_ARM64
     258     DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
     259     DEF(TOK___addtf3, "__addtf3")
     260     DEF(TOK___subtf3, "__subtf3")
     261     DEF(TOK___multf3, "__multf3")
     262     DEF(TOK___divtf3, "__divtf3")
     263     DEF(TOK___extendsftf2, "__extendsftf2")
     264     DEF(TOK___extenddftf2, "__extenddftf2")
     265     DEF(TOK___trunctfsf2, "__trunctfsf2")
     266     DEF(TOK___trunctfdf2, "__trunctfdf2")
     267     DEF(TOK___fixtfsi, "__fixtfsi")
     268     DEF(TOK___fixtfdi, "__fixtfdi")
     269     DEF(TOK___fixunstfsi, "__fixunstfsi")
     270     DEF(TOK___fixunstfdi, "__fixunstfdi")
     271     DEF(TOK___floatsitf, "__floatsitf")
     272     DEF(TOK___floatditf, "__floatditf")
     273     DEF(TOK___floatunsitf, "__floatunsitf")
     274     DEF(TOK___floatunditf, "__floatunditf")
     275     DEF(TOK___eqtf2, "__eqtf2")
     276     DEF(TOK___netf2, "__netf2")
     277     DEF(TOK___lttf2, "__lttf2")
     278     DEF(TOK___letf2, "__letf2")
     279     DEF(TOK___gttf2, "__gttf2")
     280     DEF(TOK___getf2, "__getf2")
    219281#endif
    220282
     
    228290     DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
    229291     DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
     292     DEF(TOK___bound_main_arg, "__bound_main_arg")
    230293     DEF(TOK___bound_local_new, "__bound_local_new")
    231294     DEF(TOK___bound_local_delete, "__bound_local_delete")
    232 #ifdef TCC_TARGET_PE
     295# ifdef TCC_TARGET_PE
    233296     DEF(TOK_malloc, "malloc")
    234297     DEF(TOK_free, "free")
     
    236299     DEF(TOK_memalign, "memalign")
    237300     DEF(TOK_calloc, "calloc")
    238 #endif
    239      DEF(TOK_memmove, "memmove")
     301# endif
    240302     DEF(TOK_strlen, "strlen")
    241303     DEF(TOK_strcpy, "strcpy")
    242304#endif
    243 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    244      DEF(TOK_alloca, "alloca")
    245 #endif
    246305
    247306/* Tiny Assembler */
    248  DEF_ASM(byte)
    249  DEF_ASM(word)
    250  DEF_ASM(align)
    251  DEF_ASM(skip)
    252  DEF_ASM(space)
    253  DEF_ASM(string)
    254  DEF_ASM(asciz)
    255  DEF_ASM(ascii)
    256  DEF_ASM(file)
    257  DEF_ASM(globl)
    258  DEF_ASM(global)
    259  DEF_ASM(ident)
    260  DEF_ASM(size)
    261  DEF_ASM(type)
    262  DEF_ASM(text)
    263  DEF_ASM(data)
    264  DEF_ASM(bss)
    265  DEF_ASM(previous)
    266  DEF_ASM(fill)
    267  DEF_ASM(org)
    268  DEF_ASM(quad)
     307 DEF_ASMDIR(byte)              /* must be first directive */
     308 DEF_ASMDIR(word)
     309 DEF_ASMDIR(align)
     310 DEF_ASMDIR(balign)
     311 DEF_ASMDIR(p2align)
     312 DEF_ASMDIR(set)
     313 DEF_ASMDIR(skip)
     314 DEF_ASMDIR(space)
     315 DEF_ASMDIR(string)
     316 DEF_ASMDIR(asciz)
     317 DEF_ASMDIR(ascii)
     318 DEF_ASMDIR(file)
     319 DEF_ASMDIR(globl)
     320 DEF_ASMDIR(global)
     321 DEF_ASMDIR(weak)
     322 DEF_ASMDIR(hidden)
     323 DEF_ASMDIR(ident)
     324 DEF_ASMDIR(size)
     325 DEF_ASMDIR(type)
     326 DEF_ASMDIR(text)
     327 DEF_ASMDIR(data)
     328 DEF_ASMDIR(bss)
     329 DEF_ASMDIR(previous)
     330 DEF_ASMDIR(pushsection)
     331 DEF_ASMDIR(popsection)
     332 DEF_ASMDIR(fill)
     333 DEF_ASMDIR(rept)
     334 DEF_ASMDIR(endr)
     335 DEF_ASMDIR(org)
     336 DEF_ASMDIR(quad)
    269337#if defined(TCC_TARGET_I386)
    270  DEF_ASM(code16)
    271  DEF_ASM(code32)
     338 DEF_ASMDIR(code16)
     339 DEF_ASMDIR(code32)
    272340#elif defined(TCC_TARGET_X86_64)
    273  DEF_ASM(code64)
    274 #endif
     341 DEF_ASMDIR(code64)
     342#endif
     343 DEF_ASMDIR(short)
     344 DEF_ASMDIR(long)
     345 DEF_ASMDIR(int)
     346 DEF_ASMDIR(section)            /* must be last directive */
    275347
    276348#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
  • EcnlProtoTool/trunk/tcc-0.9.27/tests/Makefile

    r279 r331  
    55TOP = ..
    66include $(TOP)/Makefile
    7 VPATH = $(top_srcdir)/tests
     7VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)
     8CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS)
    89
    910# what tests to run
     
    1314 libtest \
    1415 test3 \
    15  moretests
     16 memtest \
     17 dlltest \
     18 abitest \
     19 asm-c-connect-test \
     20 vla_test-run \
     21 cross-test \
     22 tests2-dir \
     23 pp-dir
     24
     25BTESTS = test1b test3b btest
    1626
    1727# test4 -- problem with -static
    18 # asmtest -- minor differences with gcc
     28# asmtest / asmtest2 -- minor differences with gcc
    1929# btest -- works on i386 (including win32)
    20 # test3 -- win32 does not know how to printf long doubles
    2130
    2231# bounds-checking is supported only on i386
    2332ifneq ($(ARCH),i386)
    24  TESTS := $(filter-out btest,$(TESTS))
     33 TESTS := $(filter-out $(BTESTS),$(TESTS))
    2534endif
    2635ifdef CONFIG_WIN32
     36 TESTS := $(filter-out $(BTESTS),$(TESTS))
     37endif
     38ifdef CONFIG_OSX # -run only
     39 TESTS := hello-run libtest tests2-dir pp-dir
     40endif
     41ifeq (,$(filter arm64 i386 x86_64,$(ARCH)))
     42 TESTS := $(filter-out vla_test-run,$(TESTS))
     43endif
     44ifeq ($(CONFIG_arm_eabi),yes)
    2745 TESTS := $(filter-out test3,$(TESTS))
    2846endif
    29 ifeq ($(TARGETOS),Darwin)
    30  TESTS := $(filter-out hello-exe test3 btest,$(TESTS))
    31 endif
    32 
    33 ifdef DISABLE_STATIC
    34  export LD_LIBRARY_PATH:=$(CURDIR)/..
    35 endif
    36 
    37 ifeq ($(TARGETOS),Darwin)
    38  CFLAGS+=-Wl,-flat_namespace,-undefined,warning
    39  export MACOSX_DEPLOYMENT_TARGET:=10.2
    40  NATIVE_DEFINES+=-D_ANSI_SOURCE
    41 endif
    42 
    43 # run local version of tcc with local libraries and includes
    44 TCCFLAGS = -B$(TOP)
    45 ifdef CONFIG_WIN32
    46  TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir)/include -L$(TOP)
    47 endif
    48 
    49 TCC = $(TOP)/tcc $(TCCFLAGS)
    50 RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(TOP)/tcc.c $(TCCFLAGS)
    51 
     47ifeq (,$(filter i386 x86_64,$(ARCH)))
     48 TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS))
     49endif
     50ifndef CONFIG_cross
     51 TESTS := $(filter-out cross-%,$(TESTS))
     52endif
     53
     54ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll
     55 PATH := $(CURDIR)/$(TOP)$(if $(findstring :\,$(PATH)),;,:)$(PATH)
     56endif
     57
     58RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
    5259DISAS = objdump -d
    53 
    54 # libtcc test
    55 ifdef LIBTCC1
    56  LIBTCC1:=$(TOP)/$(LIBTCC1)
    57 endif
    58 
    59 all test : $(TESTS)
     60DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1)
     61
     62all test : clean-s $(TESTS)
    6063
    6164hello-exe: ../examples/ex1.c
    6265        @echo ------------ $@ ------------
    63         $(TCC) $< -o hello$(EXESUF) || ($(TOP)/tcc -vv; exit 1) && ./hello$(EXESUF)
     66        $(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC)
    6467
    6568hello-run: ../examples/ex1.c
    6669        @echo ------------ $@ ------------
    67         $(TCC) -run $<
    68 
    69 libtest: libtcc_test$(EXESUF) $(LIBTCC1)
    70         @echo ------------ $@ ------------
    71         ./libtcc_test$(EXESUF) lib_path=..
    72 
    73 libtcc_test$(EXESUF): libtcc_test.c $(top_builddir)/$(LIBTCC)
    74         $(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS)
    75 
    76 moretests:
    77         @echo ------------ $@ ------------
    78         $(MAKE) -C tests2
    79 
    80 # test.ref - generate using gcc
    81 # copy only tcclib.h so GCC's stddef and stdarg will be used
     70        $(TCC) -run $< || $(DUMPTCC)
     71
     72libtest: libtcc_test$(EXESUF)
     73        @echo ------------ $@ ------------
     74        ./libtcc_test$(EXESUF) $(TCCFLAGS)
     75
     76libtcc_test$(EXESUF): libtcc_test.c $(LIBTCC)
     77        $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
     78
     79%-dir:
     80        @echo ------------ $@ ------------
     81        $(MAKE) -k -C $*
     82
     83# test.ref - generate using cc
    8284test.ref: tcctest.c
    83         cp ../include/tcclib.h .
    84         gcc -o tcctest.gcc $< -I. $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 -O0 -fno-omit-frame-pointer $(LDFLAGS)
     85        $(CC) -o tcctest.gcc $< $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
    8586        ./tcctest.gcc > $@
    8687
    8788# auto test
    88 test1: test.ref
    89         @echo ------------ $@ ------------
    90         $(TCC) -run tcctest.c > test.out1
    91         @if diff -u test.ref test.out1 ; then echo "Auto Test OK"; fi
     89test1 test1b: tcctest.c test.ref
     90        @echo ------------ $@ ------------
     91        $(TCC) -run $< > test.out1
     92        @diff -u test.ref test.out1 && echo "Auto Test OK"
    9293
    9394# iterated test2 (compile tcc then compile tcctest.c !)
    94 test2: test.ref
    95         @echo ------------ $@ ------------
    96         $(TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2
    97         @if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi
     95test2 test2b: tcctest.c test.ref
     96        @echo ------------ $@ ------------
     97        $(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2
     98        @diff -u test.ref test.out2 && echo "Auto Test2 OK"
    9899
    99100# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
    100 test3: test.ref
    101         @echo ------------ $@ ------------
    102         $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3
    103         @if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi
     101test3 test3b: tcctest.c test.ref
     102        @echo ------------ $@ ------------
     103        $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
     104        @diff -u test.ref test.out3 && echo "Auto Test3 OK"
     105
     106test%b : TCCFLAGS += -b
    104107
    105108# binary output test
    106 test4: test.ref
     109test4: tcctest.c test.ref
    107110        @echo ------------ $@ ------------
    108111# object + link output
    109         $(TCC) -c -o tcctest3.o tcctest.c
     112        $(TCC) -c -o tcctest3.o $<
    110113        $(TCC) -o tcctest3 tcctest3.o
    111114        ./tcctest3 > test3.out
    112115        @if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi
    113116# dynamic output
    114         $(TCC) -o tcctest1 tcctest.c
     117        $(TCC) -o tcctest1 $<
    115118        ./tcctest1 > test1.out
    116119        @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
    117120# dynamic output + bound check
    118         $(TCC) -b -o tcctest4 tcctest.c
     121        $(TCC) -b -o tcctest4 $<
    119122        ./tcctest4 > test4.out
    120123        @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
    121124# static output
    122         $(TCC) -static -o tcctest2 tcctest.c
     125        $(TCC) -static -o tcctest2 $<
    123126        ./tcctest2 > test2.out
    124127        @if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
     128
     129# use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them
     130dlltest:
     131        @echo ------------ $@ ------------
     132        $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
     133        $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
     134        ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
     135ifndef CONFIG_WIN32
     136        @echo ------------ $@ with PIC ------------
     137        $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
     138        $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)
     139        $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
     140        ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
     141endif
     142        @rm tcc2$(EXESUF) libtcc2$(DLLSUF)
     143
     144memtest:
     145        @echo ------------ $@ ------------
     146        $(CC) $(CFLAGS) $(NATIVE_DEFINES) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF)
     147        ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) $(TOPSRC)/tcc.c $(LIBS)
     148        ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) $(TOPSRC)/tests/tcctest.c
     149
    125150
    126151# memory and bound check auto test
     
    132157        @for i in $(BOUNDS_OK); do \
    133158           echo ; echo --- boundtest $$i ---; \
    134            if $(TCC) -b -run boundtest.c $$i ; then \
    135                echo succeded as expected; \
     159           if $(TCC) -b -run $< $$i ; then \
     160               echo succeeded as expected; \
    136161           else\
    137162               echo Failed positive test $$i ; exit 1 ; \
     
    140165        for i in $(BOUNDS_FAIL); do \
    141166           echo ; echo --- boundtest $$i ---; \
    142            if $(TCC) -b -run boundtest.c $$i ; then \
     167           if $(TCC) -b -run $< $$i ; then \
    143168               echo Failed negative test $$i ; exit 1 ;\
    144169           else\
     
    152177        @echo ------------ $@ ------------
    153178        time ./ex2 1238 2 3 4 10 13 4
    154         time $(TCC) -run $(top_srcdir)/examples/ex2.c 1238 2 3 4 10 13 4
     179        time $(TCC) -run $(TOPSRC)/examples/ex2.c 1238 2 3 4 10 13 4
    155180        time ./ex3 35
    156         time $(TCC) -run $(top_srcdir)/examples/ex3.c 35
    157 
    158 weaktest: test.ref
    159         $(TCC) -c tcctest.c -o weaktest.tcc.o $(CPPFLAGS) $(CFLAGS)
    160          $(CC) -c tcctest.c -o weaktest.gcc.o -I. $(CPPFLAGS) -w $(CFLAGS)
     181        time $(TCC) -run $(TOPSRC)/examples/ex3.c 35
     182
     183weaktest: tcctest.c test.ref
     184        $(TCC) -c $< -o weaktest.tcc.o
     185        $(CC) -c $< -o weaktest.gcc.o $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
    161186        objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt
    162187        objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt
    163188        diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK"
    164189
    165 ex%: $(top_srcdir)/examples/ex%.c
    166         $(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     190ex%: $(TOPSRC)/examples/ex%.c
     191        $(CC) -o $@ $< $(CFLAGS)
    167192
    168193# tiny assembler testing
     
    171196        objdump -D asmtest.ref.o > asmtest.ref
    172197
    173 asmtest: asmtest.ref
    174         @echo ------------ $@ ------------
    175         $(TCC) -c asmtest.S
     198asmtest asmtest2: asmtest.ref
     199        @echo ------------ $@ ------------
     200        $(TCC) $(MAYBE_RUN_TCC) -c asmtest.S
    176201        objdump -D asmtest.o > asmtest.out
    177202        @if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi
     203
     204# test assembler with tcc compiled by itself
     205asmtest2: MAYBE_RUN_TCC = $(RUN_TCC)
     206
     207# Check that code generated by libtcc is binary compatible with
     208# that generated by CC
     209abitest-cc$(EXESUF): abitest.c $(LIBTCC)
     210        $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w
     211
     212abitest-tcc$(EXESUF): abitest.c libtcc.c
     213        $(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS)
     214
     215ABITESTS := abitest-cc$(EXESUF)
     216ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
     217 ABITESTS += abitest-tcc$(EXESUF)
     218endif
     219
     220abitest: $(ABITESTS)
     221        @echo ------------ $@ ------------
     222        ./abitest-cc$(EXESUF) $(TCCFLAGS)
     223ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
     224        ./abitest-tcc$(EXESUF) $(TCCFLAGS)
     225endif
     226
     227vla_test$(EXESUF): vla_test.c
     228        $(TCC) -o $@ $^
     229
     230vla_test-run: vla_test$(EXESUF)
     231        @echo ------------ $@ ------------
     232        ./vla_test$(EXESUF)
     233
     234asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c
     235        $(TCC) -o $@ $^
     236
     237asm-c-connect-%.o: asm-c-connect-%.c
     238        $(TCC) -c -o $@ $<
     239
     240asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o
     241        $(TCC) -o $@ $^
     242
     243asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF)
     244        @echo ------------ $@ ------------
     245        ./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1
     246        ./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2
     247        @diff -u asm-c-connect.out1 asm-c-connect.out2 && echo "ok"
     248
     249cross-test :
     250        @echo ------------ $@ ------------
     251        $(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
     252        $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
     253        $(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
     254        $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
     255        $(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
     256        $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok"
     257        $(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
     258        $(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
     259        $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
     260        $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
     261        $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
    178262
    179263# targets for development
     
    194278# clean
    195279clean:
    196         $(MAKE) -C tests2 $@
    197         rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.gcc *.exe \
    198            hello libtcc_test tcctest[1234] ex? tcc_g tcclib.h
    199 
     280        rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc
     281        rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234]
     282        rm -f asm-c-connect$(EXESUF)
     283        rm -f ex? tcc_g weaktest.*.txt *.def
     284        @$(MAKE) -C tests2 $@
     285        @$(MAKE) -C pp $@
     286
     287# silent clean, used before running tests
     288clean-s:
     289        @$(MAKE) -s --no-print-directory clean
  • EcnlProtoTool/trunk/tcc-0.9.27/tests/asmtest.S

    • Property svn:keywords deleted
    r279 r331  
    1212   .byte 1
    1313/* .align 16, 0x90 gas is too clever for us with 0x90 fill */
     14   .balign 4, 0x92
    1415   .align 16, 0x91 /* 0x91 tests the non-clever behaviour */
    1516   .skip 3
    1617   .skip 15, 0x90
    1718   .string "hello\0world"
    18 
     19/* Macro expansion should work like with C, the #n shouldn't be parsed
     20   as asm line comment */
     21#define __stringify(n) #n
     22#define stringify(n) __stringify(n)
     23   .skip 8,0x90
     24   .asciz stringify(BLA)
     25   .skip 8,0x90
     26
     27# 28 "asmtest.S"        # a line directive (and a line comment)
     28        movl %eax, %ebx # some more asm comment
    1929/* some label tests */
    20 
    21         movl %eax, %ebx
    2230L1:
    2331        movl %eax, %ebx
     
    3947mov $1, %edx
    4048mov $1, %dx
    41 mov $1, %dl
     49mov $1, %cl
    4250movb $2, 0x100(%ebx,%edx,2)
    4351movw $2, 0x100(%ebx,%edx,2)
     
    4755movw %ax, 0x100(%ebx,%edx,2)
    4856
     57movw $0x1122,%si
     58movl $0x112233,%edx
     59movl $0x80000000, %esi
     60movl $-0x7fffffff, %edi
     61#ifdef __x86_64__
     62mov $0x11223344,%rbx
     63movq $0x11223344,%rbx
     64mov $0x1122334455,%rbx
     65movq $0x1122334455,%rbx
     66movl $0x11334455,(%rbx)
     67#endif
     68
    4969mov %eax, 0x12(,%edx,2)
    5070       
     71#ifdef __i386__
    5172mov %cr3, %edx
    5273mov %ecx, %cr3
     
    5576movl %db3, %ebx
    5677movl %dr6, %eax
     78#else
     79mov %cr3, %rdx
     80mov %rcx, %cr3
     81movq %cr3, %rax
     82movq %db3, %rbx
     83movq %dr6, %rax
     84mov %cr8, %rsi
     85mov %rdi, %cr8
     86#endif
    5787movl %fs, %ecx
    5888movl %ebx, %fs
     89
     90#ifdef __x86_64__
     91movq %r8, %r9
     92movq %r10, %r11
     93movq %r12, %r13
     94movq %r14, %r15
     95movq %rax, %r9
     96movq %r15, %rsi
     97inc %r9b
     98dec %r10w
     99not %r11d
     100negq %r12
     101decb %r13b
     102incw %r14w
     103notl %r15d
     104#endif
    59105
    60106     movsbl 0x1000, %eax
     
    69115     movzb 0x1000, %ax
    70116               
     117     mov $0x12345678,%eax
     118
     119#ifdef __x86_64__
     120     movzb 0x1000, %rax
     121     movzbq 0x1000, %rbx
     122     movsbq 0x1000, %rdx
     123     movzwq 0x1000, %rdi
     124     movswq 0x1000, %rdx
     125     movslq %eax, %rcx
     126     mov $0x12345678,%rax
     127     mov $0x12345678,%rdx
     128     mov $0x12345678,%r10
     129     mov $0x123456789abcdef0,%rax
     130     mov $0x123456789abcdef0,%rcx
     131     mov $0x123456789abcdef0,%r11
     132#endif
    71133       
     134#ifdef __i386__
    72135  pushl %eax
    73   pushw %ax
    74136  push %eax
    75137  push %cs
     138#else
     139  pushq %rax
     140  push %rax
     141#endif
     142  pushw %ax
    76143  push %gs
    77144  push $1
    78145  push $100
     146  push 0x42(%eax)
     147  pop 0x43(%esi)
    79148                                               
     149#ifdef __i386__
    80150  popl %eax
    81   popw %ax
    82151  pop %eax
    83152  pop %ds
     153#else
     154  popq %rax
     155  pop %rax
     156#endif
     157  popw %ax
    84158  pop %fs
    85159         
     
    112186  lea 0x1000(%ebx), %ecx
    113187
     188#ifdef __i386__
    114189  les 0x2000, %eax
    115190  lds 0x2000, %ebx
     191  lss 0x2000, %edx
     192#endif
    116193  lfs 0x2000, %ecx
    117194  lgs 0x2000, %edx
    118   lss 0x2000, %edx
    119195
    120196addl $0x123, %eax
    121197add $0x123, %ebx
     198add $-16, %ecx
     199add $-0x123, %esi
     200add $1, %bx
     201add $1, %ebx
     202add $-1, %bx
     203add $-1, %ebx
     204add $127, %bx
     205addl $127, %ebx
     206addl $-128, %ebx
     207addl $-128, %ebx
     208addl $-129, %ebx
     209addl $128, %ebx
     210addl $255, %ebx
     211addl $256, %ebx
     212andb $0xf, %ah
     213andb $-15, %cl
     214xorb $127, %dh
     215cmpb $42, (%eax)
    122216addl $0x123, 0x100
    123217addl $0x123, 0x100(%ebx)
     
    128222addl $0x123, (%esp)
    129223cmpl $0x123, (%esp)
     224
     225#ifdef __x86_64__
     226xor %bl,%ah
     227xor %bl,%r8b
     228xor %r9b,%bl
     229xor %sil,%cl
     230add %eax,(%r8d)
     231add %ebx,(%r9)
     232add %edx,(%r10d,%r11d)
     233add %ecx,(%r12,%r13)
     234add %esi,(%r14,%r15,4)
     235add %edi,0x1000(%rbx,%r12,8)
     236add %r11,0x1000(%ebp,%r9d,8)
     237movb $12, %ah
     238movb $13, %bpl
     239movb $14, %dil
     240movb $15, %r12b
     241#endif
    130242
    131243add %eax, (%ebx)
     
    180292    div %ecx, %eax
    181293
     294and $15,%bx
     295and $-20,%edx
    182296
    183297shl %edx
     
    196310call 0x1000
    197311call L4
     312#ifdef __i386__
    198313call *%eax
     314#else
     315call *%rax
     316#endif
    199317call *0x1000
    200318call func1
     
    205323L6:
    206324
     325#ifdef __i386__
    207326lcall $0x100, $0x1000
     327#else
     328lcall *0x100
     329lcall *(%rax)
     330#endif
    208331
    209332jmp 0x1000
     333jmp *(%edi)
     334#ifdef __i386__
    210335jmp *%eax
     336#else
     337jmp *%rax
     338#endif
    211339jmp *0x1000
    212340
     341#ifdef __i386__
    213342ljmp $0x100, $0x1000
     343#else
     344ljmp *0x100
     345ljmp *(%rdi)
     346ljmpl *(%esi)
     347ljmpw *(%esi)
     348#endif
    214349
    215350ret
     351ret $10
     352#ifdef __i386__
    216353retl
    217 
    218 ret $10
    219354retl $10
     355#else
     356retq
     357retq $10
     358#endif
    220359
    221360lret
     
    245384       
    246385 seto %al
     386 setc %al
     387 setcb %al
    247388 setnp 0x1000
    248389 setl 0xaaaa
     
    402543
    403544bswap %edx
     545bswapl %ecx
    404546xadd %ecx, %edx
    405547xaddb %dl, 0x1000
     
    412554invlpg 0x1000
    413555cmpxchg8b 0x1002
     556#ifdef __x86_64__
     557cmpxchg16b (%rax)
     558cmpxchg16b (%r10,%r11)
     559#endif
    414560
    415561fcmovb %st(5), %st
     
    431577 cmovs 0x1000, %eax
    432578 cmovns %edx, %edi
     579 cmovne %ax, %si
     580 cmovbw %ax, %di
     581 cmovnbel %edx, %ecx
     582#ifdef __x86_64__
     583 bswapq %rsi
     584 bswapq %r10
     585 cmovz %rdi,%rbx
     586 cmovpeq %rsi, %rdx
     587#endif
    433588
    434589int $3
    435590int $0x10
    436591
     592#ifdef __i386__
    437593    pusha
    438594    popa
    439     clc
    440     cld
     595#endif
     596    clc # another comment
     597    cld # a comment with embedded ' tick
    441598    cli
    442599    clts
     
    444601    lahf
    445602    sahf
     603#ifdef __i386__
    446604    pushfl
    447605    popfl
     606#else
     607    pushfq
     608    popfq
     609#endif
    448610    pushf
    449611    popf
     
    451613    std
    452614    sti
     615#ifdef __i386__
    453616    aaa
    454617    aas
     
    457620    aad
    458621    aam
     622    into
     623#endif
    459624    cbw
    460625    cwd
     
    467632    leave
    468633    int3
    469     into
    470634    iret
    471635    rsm
     
    512676    rdpmc
    513677    ud2
    514 
     678#ifdef __x86_64__
     679    syscall
     680    sysret
     681    sysretq
     682    lfence
     683    mfence
     684    sfence
     685    prefetchnta 0x18(%rdx)
     686    prefetcht0 (%rcx)
     687    prefetcht1 (%rsi)
     688    prefetcht2 (%rdi)
     689    prefetchw (%rdi)
     690    clflush 0x1000(%rax,%rcx)
     691    fxsaveq (%rdx)
     692    fxsaveq (%r11)
     693    fxrstorq (%rcx)
     694    fxrstorq (%r10)
     695
     696#endif
     697
     698    lar %ax,%dx
     699    lar %eax,%dx
     700    lar %ax,%edx
     701    lar %eax,%edx
     702#ifdef __x86_64__
     703    lar %ax,%rdx
     704    lar %eax,%rdx
     705#endif
    515706    emms
    516707    movd %edx, %mm3
     
    557748       
    558749       
     750#ifdef __i386__
    559751    boundl %edx, 0x10000
    560752    boundw %bx, 0x1000
    561    
     753
    562754    arpl %bx, 0x1000
     755#endif
    563756    lar 0x1000, %eax
    564757    lgdt 0x1000
    565758    lidt 0x1000
    566759    lldt 0x1000
     760    sgdt 0x1000
     761    sidt 0x1000
     762    sldt 0x1000
     763#ifdef __x86_64__
     764    lgdtq 0x1000
     765    lidtq 0x1000
     766    sgdtq 0x1000
     767    sidtq 0x1000
     768
     769    swapgs
     770
     771    str %rdx
     772    str %r9
     773#endif
     774
    567775    lmsw 0x1000
    568776    lsl 0x1000, %ecx
    569777    ltr 0x1000
    570    
    571     sgdt 0x1000
    572     sidt 0x1000
    573     sldt 0x1000
     778    ltr %si
    574779    smsw 0x1000
    575780    str 0x1000
     781    str %ecx
     782    str %dx
    576783   
    577784    verr 0x1000
    578785    verw 0x1000
    579786 
     787#ifdef __i386__
    580788    push %ds
    581789    pushw %ds
     
    584792    popw %ds
    585793    popl %ds
     794#endif
    586795    fxsave 1(%ebx)
    587796    fxrstor 1(%ecx)
     797#ifdef __i386__
    588798    pushl $1
     799#else
     800    pushq $1
     801#endif
    589802    pushw $1
    590803    push $1
     
    594807#endif
    595808
     809#ifndef _WIN32
    596810ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9:
    597811    xor %eax, %eax
     
    606820.type ft7,%function
    607821.type ft8,"function"
     822#endif
    608823
    609824    pause
     825.rept 6
     826    nop
     827.endr
     828.fill 4,1,0x90
     829
     830.section .text.one,"ax"
     831nop
     832.previous
     833.pushsection .text.one,"ax"
     834nop
     835.pushsection .text.two,"ax"
     836nop
     837.popsection
     838.popsection
     839
     8401: ud2
     841.pushsection __bug_table,"a"
     842.align 8
     8432: .long 1b - 2b
     844   .long 0x600000 - 2b
     845   .long 1b + 42
     846   .long 43 + 1b
     847   .long 2b + 144
     848   .long 145 + 2b
     849   .word 164, 0
     850   .org 2b+32
     851#ifdef __x86_64__
     852   .quad 1b
     853#else
     854   .long 1b
     855#endif
     856.popsection
     8573: mov %eax,%ecx
     8584:
     859.pushsection .text.three, "ax"
     860nop
     861.skip (-((4b-3b) > 0) * 2) , 0x90
     862.popsection
     863
     864.globl overrideme
     865.weak overrideme
     866  nop
     867.globl notimplemented
     868notimplemented:
     869  ret
     870.set overrideme, notimplemented
     871overrideme = notimplemented
     872overrideme:
     873  ret
     874
     875    movd %esi, %mm1
     876    movd %edi, %xmm2
     877    movd (%ebx), %mm3
     878    movd (%ebx), %xmm3
     879    movd %mm1, %esi
     880    movd %xmm2, %edi
     881    movd %mm3, (%edx)
     882    movd %xmm3, (%edx)
     883#ifdef __x86_64__
     884    movd %rsi, %mm1
     885    movd %rdi, %xmm2
     886    movd (%rbx), %mm3
     887    movd (%rbx), %xmm3
     888    movd %mm1, %r12
     889    movd %xmm2, %rdi
     890    movd %mm3, (%r8)
     891    movd %xmm3, (%r13)
     892#endif
     893
     894    movq (%ebp), %mm1
     895    movq %mm2, (%edi)
     896    movq (%edi), %xmm3
     897    movq %mm4, %mm5
     898#ifdef __x86_64__
     899    movq %rcx, %mm1
     900    movq %rdx, %xmm2
     901    movq %r13, %xmm3
     902    /* movq mem64->xmm is encoded as f30f7e by GAS, but as
     903       660f6e by tcc (which really is a movd and would need
     904       a REX.W prefix to be movq).  */
     905    movq (%rsi), %xmm3
     906    movq %mm1, %rdx
     907    movq %xmm3, %rcx
     908    movq %xmm4, (%rsi)
     909#endif
     910
     911#define TEST_MMX_SSE(insn) \
     912    insn %mm1, %mm2; \
     913    insn %xmm2, %xmm3; \
     914    insn (%ebx), %xmm3;
     915#define TEST_MMX_SSE_I8(insn) \
     916    TEST_MMX_SSE(insn) \
     917    insn $0x42, %mm4; \
     918    insn $0x42, %xmm4;
     919
     920    TEST_MMX_SSE(packssdw)
     921    TEST_MMX_SSE(packsswb)
     922    TEST_MMX_SSE(packuswb)
     923    TEST_MMX_SSE(paddb)
     924    TEST_MMX_SSE(paddw)
     925    TEST_MMX_SSE(paddd)
     926    TEST_MMX_SSE(paddsb)
     927    TEST_MMX_SSE(paddsw)
     928    TEST_MMX_SSE(paddusb)
     929    TEST_MMX_SSE(paddusw)
     930    TEST_MMX_SSE(pand)
     931    TEST_MMX_SSE(pandn)
     932    TEST_MMX_SSE(pcmpeqb)
     933    TEST_MMX_SSE(pcmpeqw)
     934    TEST_MMX_SSE(pcmpeqd)
     935    TEST_MMX_SSE(pcmpgtb)
     936    TEST_MMX_SSE(pcmpgtw)
     937    TEST_MMX_SSE(pcmpgtd)
     938    TEST_MMX_SSE(pmaddwd)
     939    TEST_MMX_SSE(pmulhw)
     940    TEST_MMX_SSE(pmullw)
     941    TEST_MMX_SSE(por)
     942    TEST_MMX_SSE(psllw)
     943TEST_MMX_SSE_I8(psllw)
     944    TEST_MMX_SSE(pslld)
     945TEST_MMX_SSE_I8(pslld)
     946    TEST_MMX_SSE(psllq)
     947TEST_MMX_SSE_I8(psllq)
     948    TEST_MMX_SSE(psraw)
     949TEST_MMX_SSE_I8(psraw)
     950    TEST_MMX_SSE(psrad)
     951TEST_MMX_SSE_I8(psrad)
     952    TEST_MMX_SSE(psrlw)
     953TEST_MMX_SSE_I8(psrlw)
     954    TEST_MMX_SSE(psrld)
     955TEST_MMX_SSE_I8(psrld)
     956    TEST_MMX_SSE(psrlq)
     957TEST_MMX_SSE_I8(psrlq)
     958    TEST_MMX_SSE(psubb)
     959    TEST_MMX_SSE(psubw)
     960    TEST_MMX_SSE(psubd)
     961    TEST_MMX_SSE(psubsb)
     962    TEST_MMX_SSE(psubsw)
     963    TEST_MMX_SSE(psubusb)
     964    TEST_MMX_SSE(psubusw)
     965    TEST_MMX_SSE(punpckhbw)
     966    TEST_MMX_SSE(punpckhwd)
     967    TEST_MMX_SSE(punpckhdq)
     968    TEST_MMX_SSE(punpcklbw)
     969    TEST_MMX_SSE(punpcklwd)
     970    TEST_MMX_SSE(punpckldq)
     971    TEST_MMX_SSE(pxor)
     972
     973    cvtpi2ps %mm1, %xmm2
     974    cvtpi2ps (%ebx), %xmm2
     975    TEST_MMX_SSE(pmaxsw)
     976    TEST_MMX_SSE(pmaxub)
     977    TEST_MMX_SSE(pminsw)
     978    TEST_MMX_SSE(pminub)
  • EcnlProtoTool/trunk/tcc-0.9.27/tests/boundtest.c

    r321 r331  
    11#include <stdlib.h>
    22#include <stdio.h>
     3#include <string.h>
    34
    45#define NB_ITS 1000000
     
    5051    int *tab4;
    5152
     53    fprintf(stderr, "%s start\n", __FUNCTION__);
     54
    5255    tab4 = malloc(20 * sizeof(int));
    5356    for(i=0;i<20;i++) {
     
    5659    free(tab4);
    5760
     61    fprintf(stderr, "%s end\n", __FUNCTION__);
    5862    return sum;
    5963}
     
    6468    int i, sum = 0;
    6569    int *tab4;
     70
     71    fprintf(stderr, "%s start\n", __FUNCTION__);
    6672
    6773    tab4 = malloc(20 * sizeof(int));
     
    7177    free(tab4);
    7278
     79    fprintf(stderr, "%s end\n", __FUNCTION__);
    7380    return sum;
    7481}
     
    187194}
    188195
     196/* ok */
     197int test16()
     198{
     199    char *demo = "This is only a test.";
     200    char *p;
     201
     202    fprintf(stderr, "%s start\n", __FUNCTION__);
     203
     204    p = alloca(16);
     205    strcpy(p,"12345678901234");
     206    printf("alloca: p is %s\n", p);
     207
     208    /* Test alloca embedded in a larger expression */
     209    printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
     210
     211    fprintf(stderr, "%s end\n", __FUNCTION__);
     212}
     213
     214/* error */
     215int test17()
     216{
     217    char *demo = "This is only a test.";
     218    char *p;
     219
     220    fprintf(stderr, "%s start\n", __FUNCTION__);
     221
     222    p = alloca(16);
     223    strcpy(p,"12345678901234");
     224    printf("alloca: p is %s\n", p);
     225
     226    /* Test alloca embedded in a larger expression */
     227    printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) );
     228
     229    fprintf(stderr, "%s end\n", __FUNCTION__);
     230}
     231
    189232int (*table_test[])(void) = {
    190     test1,
    191233    test1,
    192234    test2,
     
    204246    test14,
    205247    test15,
     248    test16,
     249    test17,
    206250};
    207251
     
    210254    int index;
    211255    int (*ftest)(void);
     256    int index_max = sizeof(table_test)/sizeof(table_test[0]);
    212257
    213258    if (argc < 2) {
    214         printf("usage: boundtest n\n"
    215                "test TCC bound checking system\n"
    216                );
     259        printf(
     260            "test TCC bound checking system\n"
     261            "usage: boundtest N\n"
     262            "  1 <= N <= %d\n", index_max);
    217263        exit(1);
    218264    }
     
    220266    index = 0;
    221267    if (argc >= 2)
    222         index = atoi(argv[1]);
     268        index = atoi(argv[1]) - 1;
     269
     270    if ((index < 0) || (index >= index_max)) {
     271        printf("N is outside of the valid range (%d)\n", index);
     272        exit(2);
     273    }
     274
    223275    /* well, we also use bounds on this ! */
    224276    ftest = table_test[index];
  • EcnlProtoTool/trunk/tcc-0.9.27/tests/libtcc_test.c

    r321 r331  
    1616}
    1717
     18/* this strinc is referenced by the generated code */
     19const char hello[] = "Hello World!";
     20
    1821char my_program[] =
     22"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
     23"extern int add(int a, int b);\n"
     24"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */
     25" __attribute__((dllimport))\n"
     26"#endif\n"
     27"extern const char hello[];\n"
    1928"int fib(int n)\n"
    2029"{\n"
     
    2736"int foo(int n)\n"
    2837"{\n"
    29 "    printf(\"Hello World!\\n\");\n"
     38"    printf(\"%s\\n\", hello);\n"
    3039"    printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
    3140"    printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
     
    3645{
    3746    TCCState *s;
     47    int i;
    3848    int (*func)(int);
    3949
     
    4555
    4656    /* if tcclib.h and libtcc1.a are not installed, where can we find them */
    47     if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
    48         tcc_set_lib_path(s, argv[1]+9);
     57    for (i = 1; i < argc; ++i) {
     58        char *a = argv[i];
     59        if (a[0] == '-') {
     60            if (a[1] == 'B')
     61                tcc_set_lib_path(s, a+2);
     62            else if (a[1] == 'I')
     63                tcc_add_include_path(s, a+2);
     64            else if (a[1] == 'L')
     65                tcc_add_library_path(s, a+2);
     66        }
     67    }
    4968
    5069    /* MUST BE CALLED before any compilation */
     
    5473        return 1;
    5574
    56     /* as a test, we add a symbol that the compiled program can use.
     75    /* as a test, we add symbols that the compiled program can use.
    5776       You may also open a dll with tcc_add_dll() and use symbols from that */
    5877    tcc_add_symbol(s, "add", add);
     78    tcc_add_symbol(s, "hello", hello);
    5979
    6080    /* relocate the code */
  • EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c

    r321 r331  
    22 * TCC auto test program
    33 */
    4 #include "../config.h"
     4#include "config.h"
    55
    66#if GCC_MAJOR >= 3
     
    1515#define CORRECT_CR_HANDLING
    1616
     17#endif
     18
     19#if defined(_WIN32)
     20#define LONG_LONG_FORMAT "%lld"
     21#define ULONG_LONG_FORMAT "%llu"
     22#else
     23#define LONG_LONG_FORMAT "%Ld"
     24#define ULONG_LONG_FORMAT "%Lu"
     25#endif
     26
     27// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
     28#if defined(_WIN32) && defined(__GNUC__)
     29#define LONG_DOUBLE double
     30#define LONG_DOUBLE_LITERAL(x) x
     31#else
     32#define LONG_DOUBLE long double
     33#define LONG_DOUBLE_LITERAL(x) x ## L
    1734#endif
    1835
     
    2845#define TCCLIB_INC1 <tcclib
    2946#define TCCLIB_INC2 h>
    30 #define TCCLIB_INC3 "tcclib"
     47#define TCCLIB_INC3 "tcclib.h"
    3148
    3249#include TCCLIB_INC
     
    3653#include TCCLIB_INC1.h>
    3754
    38 /* gcc 3.2 does not accept that (bug ?) */
    39 //#include TCCLIB_INC3 ".h"
     55#include TCCLIB_INC3
    4056
    4157#include <tcclib.h>
     
    4359#include "tcclib.h"
    4460
     61#include "tcctest.h"
     62
     63/* Test two more ways to include a file named like a pp-number */
     64#define INC(name) <tests/name.h>
     65#define funnyname 42test.h
     66#define incdir tests/
     67#define incname < incdir funnyname >
     68#define __stringify(x) #x
     69#define stringify(x) __stringify(x)
     70#include INC(42test)
     71#include incname
     72#include stringify(funnyname)
     73
     74void intdiv_test();
    4575void string_test();
    4676void expr_test();
     
    5989void expr_ptr_test();
    6090void bool_test();
     91void optimize_out();
    6192void expr2_test();
    6293void constant_expr_test();
     
    91122void callsave_test(void);
    92123void builtin_frame_address_test(void);
     124void attrib_test(void);
    93125
    94126int fib(int n);
     
    96128void forward_ref(void);
    97129int isid(int c);
     130
     131/* Line joining happens before tokenization, so the following
     132   must be parsed as ellipsis.  */
     133void funny_line_continuation (int, ..\
     134. );
     135
     136char via_volatile (char);
    98137
    99138#define A 2
     
    138177#endif
    139178
     179#ifdef __TINYC__
     180/* We try to handle this syntax.  Make at least sure it doesn't segfault.  */
     181char invalid_function_def()[] {}
     182#endif
     183
    140184#define __INT64_C(c)    c ## LL
    141185#define INT64_MIN       (-__INT64_C(9223372036854775807)-1)
     
    150194#define wq_spin_lock spin_lock
    151195#define TEST2() wq_spin_lock(a)
     196
     197#define UINT_MAX ((unsigned) -1)
     198
     199void intdiv_test(void)
     200{
     201    printf("18/21=%u\n", 18/21);
     202    printf("18%%21=%u\n", 18%21);
     203    printf("41/21=%u\n", 41/21);
     204    printf("41%%21=%u\n", 41%21);
     205    printf("42/21=%u\n", 42/21);
     206    printf("42%%21=%u\n", 42%21);
     207    printf("43/21=%u\n", 43/21);
     208    printf("43%%21=%u\n", 43%21);
     209    printf("126/21=%u\n", 126/21);
     210    printf("126%%21=%u\n", 126%21);
     211    printf("131/21=%u\n", 131/21);
     212    printf("131%%21=%u\n", 131%21);
     213    printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
     214    printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
     215
     216    printf("18/-21=%u\n", 18/-21);
     217    printf("18%%-21=%u\n", 18%-21);
     218    printf("41/-21=%u\n", 41/-21);
     219    printf("41%%-21=%u\n", 41%-21);
     220    printf("42/-21=%u\n", 42/-21);
     221    printf("42%%-21=%u\n", 42%-21);
     222    printf("43/-21=%u\n", 43/-21);
     223    printf("43%%-21=%u\n", 43%-21);
     224    printf("126/-21=%u\n", 126/-21);
     225    printf("126%%-21=%u\n", 126%-21);
     226    printf("131/-21=%u\n", 131/-21);
     227    printf("131%%-21=%u\n", 131%-21);
     228    printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
     229    printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
     230
     231    printf("-18/21=%u\n", -18/21);
     232    printf("-18%%21=%u\n", -18%21);
     233    printf("-41/21=%u\n", -41/21);
     234    printf("-41%%21=%u\n", -41%21);
     235    printf("-42/21=%u\n", -42/21);
     236    printf("-42%%21=%u\n", -42%21);
     237    printf("-43/21=%u\n", -43/21);
     238    printf("-43%%21=%u\n", -43%21);
     239    printf("-126/21=%u\n", -126/21);
     240    printf("-126%%21=%u\n", -126%21);
     241    printf("-131/21=%u\n", -131/21);
     242    printf("-131%%21=%u\n", -131%21);
     243    printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
     244    printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
     245
     246    printf("-18/-21=%u\n", -18/-21);
     247    printf("-18%%-21=%u\n", -18%-21);
     248    printf("-41/-21=%u\n", -41/-21);
     249    printf("-41%%-21=%u\n", -41%-21);
     250    printf("-42/-21=%u\n", -42/-21);
     251    printf("-42%%-21=%u\n", -42%-21);
     252    printf("-43/-21=%u\n", -43/-21);
     253    printf("-43%%-21=%u\n", -43%-21);
     254    printf("-126/-21=%u\n", -126/-21);
     255    printf("-126%%-21=%u\n", -126%-21);
     256    printf("-131/-21=%u\n", -131/-21);
     257    printf("-131%%-21=%u\n", -131%-21);
     258    printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
     259    printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
     260}
    152261
    153262void macro_test(void)
     
    236345    printf("__LINE__=%d __FILE__=%s\n",
    237346           __LINE__, __FILE__);
     347#if 0
    238348#line 200
    239349    printf("__LINE__=%d __FILE__=%s\n",
     
    243353           __LINE__, __FILE__);
    244354#line 227 "tcctest.c"
     355#endif
    245356
    246357    /* not strictly preprocessor, but we test it there */
     
    257368
    258369    /* complicated macros in glibc */
    259     printf("INT64_MIN=%Ld\n", INT64_MIN);
     370    printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
    260371    {
    261372        int a;
     
    276387    MF_t("hi");
    277388   
    278     /* test macro substituion inside args (should not eat stream) */
     389    /* test macro substitution inside args (should not eat stream) */
    279390    printf("qq=%d\n", qq(qq)(2));
    280391
     
    296407    TEST2();
    297408
    298     /* And again when the name and parenthes are separated by a
     409    /* And again when the name and parentheses are separated by a
    299410       comment.  */
    300411    TEST2 /* the comment */ ();
     412
     413    printf("%s\n", get_basefile_from_header());
     414    printf("%s\n", __BASE_FILE__);
     415    printf("%s\n", get_file_from_header());
     416    printf("%s\n", __FILE__);
     417
     418    /* Check that funnily named include was in fact included */
     419    have_included_42test_h = 1;
     420    have_included_42test_h_second = 1;
     421    have_included_42test_h_third = 1;
    301422}
    302423
     
    490611};
    491612
     613struct S_enum {
     614    enum {E6 = 42, E7, E8} e:8;
     615};
     616
     617enum ELong {
     618    /* This is either 0 on L32 machines, or a large number
     619       on L64 machines.  We should be able to store this.  */
     620    EL_large = ((unsigned long)0xf000 << 31) << 1,
     621};
     622
     623enum { BIASU = -1U<<31 };
     624enum { BIASS = -1 << 31 };
     625
     626static int getint(int i)
     627{
     628  if (i)
     629    return 0;
     630  else
     631    return (int)(-1U << 31);
     632}
     633
    492634void enum_test()
    493635{
    494636    enum test b1;
     637    /* The following should give no warning */
     638    unsigned *p = &b1;
     639    struct S_enum s = {E7};
     640    printf("enum: %d\n", s.e);
    495641    printf("enum:\n%d %d %d %d %d %d\n",
    496642           E0, E1, E2, E3, E4, E5);
    497643    b1 = 1;
    498644    printf("b1=%d\n", b1);
     645    printf("enum large: %ld\n", EL_large);
     646
     647    if (getint(0) == BIASU)
     648      printf("enum unsigned: ok\n");
     649    else
     650      printf("enum unsigned: wrong\n");
     651    if (getint(0) == BIASS)
     652      printf("enum unsigned: ok\n");
     653    else
     654      printf("enum unsigned: wrong\n");
    499655}
    500656
     
    552708
    553709struct struct1 st1, st2;
     710
     711struct empty_mem {
     712    /* nothing */ ;
     713    int x;
     714};
    554715
    555716int main(int argc, char **argv)
     
    571732    expr_ptr_test();
    572733    bool_test();
     734    optimize_out();
    573735    expr2_test();
    574736    constant_expr_test();
     
    605767    callsave_test();
    606768    builtin_frame_address_test();
     769    intdiv_test();
     770    if (via_volatile (42) != 42)
     771      printf ("via_volatile broken\n");
     772    attrib_test();
    607773    return 0;
    608774}
     
    816982        printf("%d\n", sp[j].i);
    817983    }
     984#ifdef __LP64__
     985    i = 1;
     986    p = (int*)0x100000000UL + i;
     987    i = ((long)p) >> 32;
     988    printf("largeptr: %p %d\n", p, i);
     989#endif
    818990}
    819991
     
    8621034};
    8631035
     1036struct __attribute__((aligned(16))) aligntest5
     1037{
     1038    int i;
     1039};
     1040struct aligntest6
     1041{
     1042    int i;
     1043} __attribute__((aligned(16)));
     1044struct aligntest7
     1045{
     1046    int i;
     1047};
     1048struct aligntest5 altest5[2];
     1049struct aligntest6 altest6[2];
     1050int pad1;
     1051/* altest7 is correctly aligned to 16 bytes also with TCC,
     1052   but __alignof__ returns the wrong result (4) because we
     1053   can't store the alignment yet when specified on symbols
     1054   directly (it's stored in the type so we'd need to make
     1055   a copy of it). -- FIXED */
     1056struct aligntest7 altest7[2] __attribute__((aligned(16)));
     1057
     1058struct aligntest8
     1059{
     1060  int i;
     1061} __attribute__((aligned(4096)));
     1062
     1063struct Large {
     1064    unsigned long flags;
     1065    union {
     1066        void *u1;
     1067        int *u2;
     1068    };
     1069
     1070    struct {
     1071        union {
     1072            unsigned long index;
     1073            void *freelist;
     1074        };
     1075        union {
     1076            unsigned long counters;
     1077            struct {
     1078                int bla;
     1079            };
     1080        };
     1081    };
     1082
     1083    union {
     1084        struct {
     1085            long u3;
     1086            long u4;
     1087        };
     1088        void *u5;
     1089        struct {
     1090            unsigned long compound_head;
     1091            unsigned int compound_dtor;
     1092            unsigned int compound_order;
     1093        };
     1094    };
     1095} __attribute__((aligned(2 * sizeof(long))));
     1096
     1097typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
     1098
     1099struct aligntest9 {
     1100    unsigned int buf_nr;
     1101    unaligned_u64 start_lba;
     1102};
     1103
     1104struct aligntest10 {
     1105    unsigned int buf_nr;
     1106    unsigned long long start_lba;
     1107};
     1108
    8641109void struct_test()
    8651110{
    8661111    struct1 *s;
    8671112    union union2 u;
     1113    struct Large ls;
    8681114
    8691115    printf("struct:\n");
     
    8731119           sizeof(union union1),
    8741120           sizeof(union union2));
     1121    printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
    8751122    st1.f1 = 1;
    8761123    st1.f2 = 2;
     
    9011148    printf("aligntest4 sizeof=%d alignof=%d\n",
    9021149           sizeof(struct aligntest4), __alignof__(struct aligntest4));
     1150    printf("aligntest5 sizeof=%d alignof=%d\n",
     1151           sizeof(struct aligntest5), __alignof__(struct aligntest5));
     1152    printf("aligntest6 sizeof=%d alignof=%d\n",
     1153           sizeof(struct aligntest6), __alignof__(struct aligntest6));
     1154    printf("aligntest7 sizeof=%d alignof=%d\n",
     1155           sizeof(struct aligntest7), __alignof__(struct aligntest7));
     1156    printf("aligntest8 sizeof=%d alignof=%d\n",
     1157           sizeof(struct aligntest8), __alignof__(struct aligntest8));
     1158    printf("aligntest9 sizeof=%d alignof=%d\n",
     1159           sizeof(struct aligntest9), __alignof__(struct aligntest9));
     1160    printf("aligntest10 sizeof=%d alignof=%d\n",
     1161           sizeof(struct aligntest10), __alignof__(struct aligntest10));
     1162    printf("altest5 sizeof=%d alignof=%d\n",
     1163           sizeof(altest5), __alignof__(altest5));
     1164    printf("altest6 sizeof=%d alignof=%d\n",
     1165           sizeof(altest6), __alignof__(altest6));
     1166    printf("altest7 sizeof=%d alignof=%d\n",
     1167           sizeof(altest7), __alignof__(altest7));
    9031168           
    9041169    /* empty structures (GCC extension) */
    9051170    printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
    9061171    printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
     1172
     1173    printf("Large: sizeof=%d\n", sizeof(ls));
     1174    memset(&ls, 0, sizeof(ls));
     1175    ls.compound_head = 42;
     1176    printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
    9071177}
    9081178
     
    9541224}
    9551225
     1226static unsigned int calc_vm_flags(unsigned int prot)
     1227{
     1228  unsigned int prot_bits;
     1229  /* This used to segfault in some revisions: */
     1230  prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
     1231  return prot_bits;
     1232}
     1233
    9561234void bool_test()
    9571235{
     
    10261304            printf("error %d\n", i);
    10271305    }
     1306    printf ("bits = 0x%x\n", calc_vm_flags (0x1));
     1307}
     1308
     1309extern int undefined_function(void);
     1310extern int defined_function(void);
     1311
     1312static inline void refer_to_undefined(void)
     1313{
     1314  undefined_function();
     1315}
     1316
     1317void optimize_out(void)
     1318{
     1319  int i = 0 ? undefined_function() : defined_function();
     1320  printf ("oo:%d\n", i);
     1321  int j = 1 ? defined_function() : undefined_function();
     1322  printf ("oo:%d\n", j);
     1323  if (0)
     1324    printf("oo:%d\n", undefined_function());
     1325  else
     1326    printf("oo:%d\n", defined_function());
     1327  if (1)
     1328    printf("oo:%d\n", defined_function());
     1329  else
     1330    printf("oo:%d\n", undefined_function());
     1331  while (1) {
     1332      printf("oow:%d\n", defined_function());
     1333      break;
     1334      printf("oow:%d\n", undefined_function());
     1335  }
     1336  j = 1;
     1337  /* Following is a switch without {} block intentionally.  */
     1338  switch (j)
     1339    case 1: break;
     1340  printf ("oos:%d\n", defined_function());
     1341  /* The following break shouldn't lead to disabled code after
     1342     the while.  */
     1343  while (1)
     1344    break;
     1345  printf ("ool1:%d\n", defined_function());
     1346  /* Same for the other types of loops.  */
     1347  do
     1348    break;
     1349  while (1);
     1350  printf ("ool2:%d\n", defined_function());
     1351  for (;;)
     1352    break;
     1353  printf ("ool3:%d\n", defined_function());
     1354  /* Normal {} blocks without controlling statements
     1355     shouldn't reactivate code emission */
     1356  while (1) {
     1357        {
     1358          break;
     1359        }
     1360      printf ("ool4:%d\n", undefined_function());
     1361  }
     1362  j = 1;
     1363  while (j) {
     1364      if (j == 0)
     1365        break; /* this break shouldn't disable code outside the if. */
     1366      printf("ool5:%d\n", defined_function());
     1367      j--;
     1368  }
     1369
     1370  j = 1;
     1371  while (j) {
     1372      if (1)
     1373        j--;
     1374      else
     1375        breakhere: break;
     1376      printf("ool6:%d\n", defined_function());
     1377      goto breakhere;
     1378  }
     1379
     1380  /* Test that constants in logical && are optimized: */
     1381  i = 0 && undefined_function();
     1382  i = defined_function() && 0 && undefined_function();
     1383  if (0 && undefined_function())
     1384    undefined_function();
     1385  if (defined_function() && 0)
     1386    undefined_function();
     1387  if (0 && 0)
     1388    undefined_function();
     1389  if (defined_function() && 0 && undefined_function())
     1390    undefined_function();
     1391  /* The same for || : */
     1392  i = 1 || undefined_function();
     1393  i = defined_function() || 1 || undefined_function();
     1394  if (1 || undefined_function())
     1395    ;
     1396  else
     1397    undefined_function();
     1398  if (defined_function() || 1)
     1399    ;
     1400  else
     1401    undefined_function();
     1402  if (1 || 1)
     1403    ;
     1404  else
     1405    undefined_function();
     1406  if (defined_function() || 1 || undefined_function())
     1407    ;
     1408  else
     1409    undefined_function();
     1410
     1411  if (defined_function() && 0)
     1412    refer_to_undefined();
     1413
     1414  if (0) {
     1415      (void)sizeof( ({
     1416                     do { } while (0);
     1417                     0;
     1418                     }) );
     1419      undefined_function();
     1420  }
     1421
     1422  /* Leave the "if(1)return; printf()" in this order and last in the function */
     1423  if (1)
     1424    return;
     1425  printf ("oor:%d\n", undefined_function());
     1426}
     1427
     1428int defined_function(void)
     1429{
     1430  static int i = 40;
     1431  return i++;
    10281432}
    10291433
     
    13401744};
    13411745
     1746typedef int arrtype1[];
     1747arrtype1 sinit19 = {1};
     1748arrtype1 sinit20 = {2,3};
     1749typedef int arrtype2[3];
     1750arrtype2 sinit21 = {4};
     1751arrtype2 sinit22 = {5,6,7};
     1752
     1753/* Address comparisons of non-weak symbols with zero can be const-folded */
     1754int sinit23[2] = { "astring" ? sizeof("astring") : -1,
     1755                   &sinit23 ? 42 : -1 };
     1756
     1757extern int external_inited = 42;
     1758
    13421759void init_test(void)
    13431760{
     
    13541771    struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
    13551772    int linit17 = sizeof(linit17);
     1773    int zero = 0;
     1774    /* Addresses on non-weak symbols are non-zero, but not the access itself */
     1775    int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
    13561776   
    13571777    printf("init_test:\n");
     
    14401860    printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
    14411861    printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
    1442 }
    1443 
     1862
     1863    printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
     1864    printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
     1865    printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
     1866    printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
     1867    printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
     1868    printf("arrtype6: %d\n", sizeof(arrtype2));
     1869
     1870    printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
     1871    printf("linit18= %d %d\n", linit18[0], linit18[1]);
     1872}
     1873
     1874void switch_uc(unsigned char uc)
     1875{
     1876        switch (uc) {
     1877            case 0xfb ... 0xfe:
     1878                printf("ucsw:1\n");
     1879                break;
     1880            case 0xff:
     1881                printf("ucsw:2\n");
     1882                break;
     1883            case 0 ... 5:
     1884                printf("ucsw:3\n");
     1885                break;
     1886            default:
     1887                printf("ucsw: broken!\n");
     1888        }
     1889}
     1890
     1891void switch_sc(signed char sc)
     1892{
     1893        switch (sc) {
     1894            case -5 ... -2:
     1895                printf("scsw:1\n");
     1896                break;
     1897            case -1:
     1898                printf("scsw:2\n");
     1899                break;
     1900            case 0 ... 5:
     1901                printf("scsw:3\n");
     1902                break;
     1903            default:
     1904                printf("scsw: broken!\n");
     1905        }
     1906}
    14441907
    14451908void switch_test()
    14461909{
    14471910    int i;
     1911    unsigned long long ull;
     1912    long long ll;
    14481913
    14491914    for(i=0;i<15;i++) {
     
    14621927            printf("b");
    14631928            break;
     1929        case 0xc33c6b9fU:
     1930        case 0x7c9eeeb9U:
     1931            break;
    14641932        }
    14651933    }
    14661934    printf("\n");
     1935
     1936    for (i = 1; i <= 5; i++) {
     1937        ull = (unsigned long long)i << 61;
     1938        switch (ull) {
     1939            case 1ULL << 61:
     1940                printf("ullsw:1\n");
     1941                break;
     1942            case 2ULL << 61:
     1943                printf("ullsw:2\n");
     1944                break;
     1945            case 3ULL << 61:
     1946                printf("ullsw:3\n");
     1947                break;
     1948            case 4ULL << 61:
     1949                printf("ullsw:4\n");
     1950                break;
     1951            case 5ULL << 61:
     1952                printf("ullsw:5\n");
     1953                break;
     1954            default:
     1955                printf("ullsw: broken!\n");
     1956        }
     1957    }
     1958
     1959    for (i = 1; i <= 5; i++) {
     1960        ll = (long long)i << 61;
     1961        switch (ll) {
     1962            case 1LL << 61:
     1963                printf("llsw:1\n");
     1964                break;
     1965            case 2LL << 61:
     1966                printf("llsw:2\n");
     1967                break;
     1968            case 3LL << 61:
     1969                printf("llsw:3\n");
     1970                break;
     1971            case 4LL << 61:
     1972                printf("llsw:4\n");
     1973                break;
     1974            case 5LL << 61:
     1975                printf("llsw:5\n");
     1976                break;
     1977            default:
     1978                printf("llsw: broken!\n");
     1979        }
     1980    }
     1981
     1982    for (i = -5; i <= 5; i++) {
     1983        switch_uc((unsigned char)i);
     1984    }
     1985
     1986    for (i = -5; i <= 5; i++) {
     1987        switch_sc ((signed char)i);
     1988    }
    14671989}
    14681990
     
    15252047        printf("st1.f2 != -1\n");
    15262048
    1527     /* bit sizes below must be bigger than 32 since GCC doesn't allow
    1528        long-long bitfields whose size is not bigger than int */
    15292049    struct sbf2 {
    15302050        long long f1 : 45;
     
    15392059    st2.f2++;
    15402060    printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
     2061
     2062#if 0
     2063    Disabled for now until further clarification re GCC compatibility
     2064    struct sbf3 {
     2065        int f1 : 7;
     2066        int f2 : 1;
     2067        char f3;
     2068        int f4 : 8;
     2069        int f5 : 1;
     2070        int f6 : 16;
     2071    } st3;
     2072    printf("sizeof(st3) = %d\n", sizeof(st3));
     2073#endif
     2074
     2075    struct sbf4 {
     2076        int x : 31;
     2077        char y : 2;
     2078    } st4;
     2079    st4.y = 1;
     2080    printf("st4.y == %d\n", st4.y);
     2081    struct sbf5 {
     2082        int a;
     2083        char b;
     2084        int x : 12, y : 4, : 0, : 4, z : 3;
     2085        char c;
     2086    } st5 = { 1, 2, 3, 4, -3, 6 };
     2087    printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
     2088    struct sbf6 {
     2089        short x : 12;
     2090        unsigned char y : 2;
     2091    } st6;
     2092    st6.y = 1;
     2093    printf("st6.y == %d\n", st6.y);
    15412094}
    15422095
     
    15502103/* declare strto* functions as they are C99 */
    15512104double strtod(const char *nptr, char **endptr);
     2105
     2106#if defined(_WIN32)
     2107float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
     2108LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
     2109#else
    15522110float strtof(const char *nptr, char **endptr);
    1553 long double strtold(const char *nptr, char **endptr);
    1554 
    1555 #define FTEST(prefix, type, fmt)\
     2111LONG_DOUBLE strtold(const char *nptr, char **endptr);
     2112#endif
     2113
     2114#define FTEST(prefix, typename, type, fmt)\
    15562115void prefix ## cmp(type a, type b)\
    15572116{\
     
    15812140    float fa;\
    15822141    double da;\
    1583     long double la;\
     2142    LONG_DOUBLE la;\
    15842143    int ia;\
     2144    long long llia;\
    15852145    unsigned int ua;\
     2146    unsigned long long llua;\
    15862147    type b;\
    15872148    fa = a;\
     
    15902151    printf("ftof: %f %f %Lf\n", fa, da, la);\
    15912152    ia = (int)a;\
     2153    llia = (long long)a;\
     2154    a = (a >= 0) ? a : -a;\
    15922155    ua = (unsigned int)a;\
    1593     printf("ftoi: %d %u\n", ia, ua);\
     2156    llua = (unsigned long long)a;\
     2157    printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
    15942158    ia = -1234;\
    15952159    ua = 0x81234500;\
     2160    llia = -0x123456789012345LL;\
     2161    llua = 0xf123456789012345LLU;\
    15962162    b = ia;\
    15972163    printf("itof: " fmt "\n", b);\
    15982164    b = ua;\
    15992165    printf("utof: " fmt "\n", b);\
     2166    b = llia;\
     2167    printf("lltof: " fmt "\n", b);\
     2168    b = llua;\
     2169    printf("ulltof: " fmt "\n", b);\
    16002170}\
    16012171\
    16022172float prefix ## retf(type a) { return a; }\
    16032173double prefix ## retd(type a) { return a; }\
    1604 long double prefix ## retld(type a) { return a; }\
     2174LONG_DOUBLE prefix ## retld(type a) { return a; }\
    16052175\
    16062176void prefix ## call(void)\
     
    16122182}\
    16132183\
     2184void prefix ## signed_zeros(void) \
     2185{\
     2186  type x = 0.0, y = -0.0, n, p;\
     2187  if (x == y)\
     2188    printf ("Test 1.0 / x != 1.0 / y  returns %d (should be 1).\n",\
     2189            1.0 / x != 1.0 / y);\
     2190  else\
     2191    printf ("x != y; this is wrong!\n");\
     2192\
     2193  n = -x;\
     2194  if (x == n)\
     2195    printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
     2196            1.0 / x != 1.0 / n);\
     2197  else\
     2198    printf ("x != -x; this is wrong!\n");\
     2199\
     2200  p = +y;\
     2201  if (x == p)\
     2202    printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
     2203            1.0 / x != 1.0 / p);\
     2204  else\
     2205    printf ("x != +y; this is wrong!\n");\
     2206  p = -y;\
     2207  if (x == p)\
     2208    printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
     2209            1.0 / x != 1.0 / p);\
     2210  else\
     2211    printf ("x != -y; this is wrong!\n");\
     2212}\
    16142213void prefix ## test(void)\
    16152214{\
    1616     printf("testing '%s'\n", #type);\
     2215    printf("testing '%s'\n", #typename);\
    16172216    prefix ## cmp(1, 2.5);\
    16182217    prefix ## cmp(2, 1.5);\
     
    16212220    prefix ## fcast(-2334.6);\
    16222221    prefix ## call();\
    1623 }
    1624 
    1625 FTEST(f, float, "%f")
    1626 FTEST(d, double, "%f")
    1627 FTEST(ld, long double, "%Lf")
     2222    prefix ## signed_zeros();\
     2223}
     2224
     2225FTEST(f, float, float, "%f")
     2226FTEST(d, double, double, "%f")
     2227FTEST(ld, long double, LONG_DOUBLE, "%Lf")
    16282228
    16292229double ftab1[3] = { 1.2, 3.4, -5.6 };
     
    16322232void float_test(void)
    16332233{
     2234#if !defined(__arm__) || defined(__ARM_PCS_VFP)
    16342235    float fa, fb;
    16352236    double da, db;
     
    16402241    printf("sizeof(float) = %d\n", sizeof(float));
    16412242    printf("sizeof(double) = %d\n", sizeof(double));
    1642     printf("sizeof(long double) = %d\n", sizeof(long double));
     2243    printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
    16432244    ftest();
    16442245    dtest();
     
    16572258    db = b;
    16582259    printf("db = %f\n", db);
     2260#endif
    16592261}
    16602262
     
    16752277        void (*func)(int);
    16762278    } st1;
     2279    long diff;
    16772280
    16782281    printf("funcptr:\n");
     
    16902293    printf("sizeof3 = %d\n", sizeof(&funcptr_test));
    16912294    printf("sizeof4 = %d\n", sizeof &funcptr_test);
     2295    a = 0;
     2296    func = num + a;
     2297    diff = func - num;
     2298    func(42);
     2299    (func + diff)(42);
     2300    (num + a)(43);
    16922301}
    16932302
     
    16992308    ub = b;
    17002309    /* arith */
    1701     printf("arith: %Ld %Ld %Ld\n",
     2310    printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
    17022311           a + b,
    17032312           a - b,
     
    17052314   
    17062315    if (b != 0) {
    1707         printf("arith1: %Ld %Ld\n",
     2316        printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
    17082317           a / b,
    17092318           a % b);
     
    17112320
    17122321    /* binary */
    1713     printf("bin: %Ld %Ld %Ld\n",
     2322    printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
    17142323           a & b,
    17152324           a | b,
     
    17362345    a++;
    17372346    b++;
    1738     printf("arith2: %Ld %Ld\n", a, b);
    1739     printf("arith2: %Ld %Ld\n", a++, b++);
    1740     printf("arith2: %Ld %Ld\n", --a, --b);
    1741     printf("arith2: %Ld %Ld\n", a, b);
     2347    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
     2348    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
     2349    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
     2350    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
    17422351    b = ub = 0;
    17432352    printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
     
    17462355void llshift(long long a, int b)
    17472356{
    1748     printf("shift: %Ld %Ld %Ld\n",
     2357    printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
    17492358           (unsigned long long)a >> b,
    17502359           a >> b,
    17512360           a << b);
    1752     printf("shiftc: %Ld %Ld %Ld\n",
     2361    printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
    17532362           (unsigned long long)a >> 3,
    17542363           a >> 3,
    17552364           a << 3);
    1756     printf("shiftc: %Ld %Ld %Ld\n",
     2365    printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
    17572366           (unsigned long long)a >> 35,
    17582367           a >> 35,
     
    17642373    float fa;
    17652374    double da;
    1766     long double lda;
     2375    LONG_DOUBLE lda;
    17672376    long long la, lb, lc;
    17682377    unsigned long long ula, ulb, ulc;
     
    17712380    la = (la << 20) | 0x12345;
    17722381    ula = ula << 33;
    1773     printf("la=%Ld ula=%Lu\n", la, ula);
     2382    printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
    17742383
    17752384    fa = la;
     
    17812390    lb = da;
    17822391    lc = lda;
    1783     printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc);
     2392    printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
    17842393
    17852394    fa = ula;
     
    17912400    ulb = da;
    17922401    ulc = lda;
    1793     printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc);
     2402    printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
    17942403}
    17952404
     
    18072416{
    18082417    return ((long long int)v->item);
     2418}
     2419
     2420long long llfunc2(long long x, long long y, int z)
     2421{
     2422    return x * y * z;
    18092423}
    18102424
     
    18202434    a = ia;
    18212435    b = ua;
    1822     printf("%Ld %Ld\n", a, b);
    1823     printf("%Ld %Ld %Ld %Lx\n",
     2436    printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
     2437    printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
    18242438           (long long)1,
    18252439           (long long)-2,
     
    18272441           0x1234567812345679);
    18282442    a = llfunc1(-3);
    1829     printf("%Ld\n", a);
     2443    printf(LONG_LONG_FORMAT "\n", a);
    18302444
    18312445    lloptest(1000, 23);
     
    18552469    lloptest(0x80000000, 0);
    18562470
    1857     /* another long long spill test */
    18582471    {
    1859         long long *p, v;
     2472        long long *p, v, **pp;
    18602473        v = 1;
    18612474        p = &v;
    18622475        p[0]++;
    1863         printf("%lld\n", *p);
     2476        printf("another long long spill test : %lld\n", *p);
     2477        pp = &p;
     2478
     2479        v = llfunc2(**pp, **pp, ia);
     2480        printf("a long long function (arm-)reg-args test : %lld\n", v);
    18642481    }
    1865 
    18662482    a = 68719476720LL;
    18672483    b = 4294967295LL;
    18682484    printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
    18692485
    1870     printf("%Ld\n", 0x123456789LLU);
     2486    printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
     2487
     2488    /* long long pointer deref in argument passing test */
     2489    a = 0x123;
     2490    long long *p = &a;
     2491    llshift(*p, 5);
    18712492}
    18722493
    18732494void manyarg_test(void)
    18742495{
    1875     long double ld = 1234567891234LL;
     2496    LONG_DOUBLE ld = 1234567891234LL;
    18762497    printf("manyarg_test:\n");
    18772498    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
     
    18792500           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
    18802501    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
    1881            "%Ld %Ld %f %f\n",
     2502           LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
    18822503           1, 2, 3, 4, 5, 6, 7, 8,
    18832504           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
     
    18852506           42.0, 43.0);
    18862507    printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
    1887            "%Ld %Ld %f %f\n",
     2508           LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
    18882509           ld, 1, 2, 3, 4, 5, 6, 7, 8,
    18892510           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
    18902511           1234567891234LL, 987654321986LL,
    18912512           42.0, 43.0);
    1892     /* XXX: known bug of x86-64 */
    1893 #ifndef __x86_64__
    18942513    printf("%d %d %d %d %d %d %d %d %Lf\n",
    18952514           1, 2, 3, 4, 5, 6, 7, 8, ld);
    18962515    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
    1897            "%Ld %Ld %f %f %Lf\n",
     2516           LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
    18982517           1, 2, 3, 4, 5, 6, 7, 8,
    18992518           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
     
    19012520           42.0, 43.0, ld);
    19022521    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
    1903            "%Lf %Ld %Ld %f %f %Lf\n",
     2522           "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
    19042523           1, 2, 3, 4, 5, 6, 7, 8,
    19052524           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
    19062525           ld, 1234567891234LL, 987654321986LL,
    19072526           42.0, 43.0, ld);
    1908 #endif
    19092527}
    19102528
     
    19162534    double d;
    19172535    long long ll;
    1918     long double ld;
     2536    LONG_DOUBLE ld;
    19192537
    19202538    va_start(aq, fmt);
     
    19422560            case 'l':
    19432561                ll = va_arg(ap, long long);
    1944                 printf("%Ld", ll);
     2562                printf(LONG_LONG_FORMAT, ll);
    19452563                break;
    19462564            case 'F':
    1947                 ld = va_arg(ap, long double);
     2565                ld = va_arg(ap, LONG_DOUBLE);
    19482566                printf("%Lf", ld);
    19492567                break;
     
    19782596}
    19792597
     2598void stdarg_for_libc(const char *fmt, ...)
     2599{
     2600    va_list args;
     2601    va_start(args, fmt);
     2602    vprintf(fmt, args);
     2603    va_end(args);
     2604}
     2605
    19802606void stdarg_test(void)
    19812607{
    1982     long double ld = 1234567891234LL;
     2608    LONG_DOUBLE ld = 1234567891234LL;
    19832609    struct myspace bob;
    19842610
     
    19862612    vprintf1("%f %d %f\n", 1.0, 2, 3.0);
    19872613    vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
    1988     vprintf1("%F %F %F\n", 1.2L, 2.3L, 3.4L);
    1989 #ifdef __x86_64__
    1990     /* a bug of x86's TCC */
     2614    vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
    19912615    vprintf1("%d %f %l %F %d %f %l %F\n",
    1992              1, 1.2, 3L, 4.5L, 6, 7.8, 9L, 0.1L);
    1993 #endif
     2616             1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
    19942617    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
    19952618             1, 2, 3, 4, 5, 6, 7, 8,
     
    20272650    bob.profile = 42;
    20282651    stdarg_for_struct(bob, bob, bob, bob.profile);
     2652    stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
    20292653}
    20302654
     
    20722696int *rel2 = &reltab[2];
    20732697
     2698#ifdef _WIN64
     2699void relocation_test(void) {}
     2700#else
     2701void getmyaddress(void)
     2702{
     2703    printf("in getmyaddress\n");
     2704}
     2705
     2706#ifdef __LP64__
     2707long __pa_symbol(void)
     2708{
     2709    /* This 64bit constant was handled incorrectly, it was used as addend
     2710       (which can hold 64bit just fine) in connection with a symbol,
     2711       and TCC generates wrong code for that (displacements are 32bit only).
     2712       This effectively is "+ 0x80000000", and if addresses of globals
     2713       are below 2GB the result should be a number without high 32 bits set.  */
     2714       return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
     2715}
     2716#endif
     2717
     2718unsigned long theaddress = (unsigned long)getmyaddress;
    20742719void relocation_test(void)
    20752720{
     2721    void (*fptr)(void) = (void (*)(void))theaddress;
    20762722    printf("*rel1=%d\n", *rel1);
    20772723    printf("*rel2=%d\n", *rel2);
    2078 }
     2724    fptr();
     2725#ifdef __LP64__
     2726    printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
     2727#endif
     2728}
     2729#endif
    20792730
    20802731void old_style_f(a,b,c)
     
    21052756void alloca_test()
    21062757{
    2107 #if defined __i386__ || defined __x86_64__
     2758#if defined __i386__ || defined __x86_64__ || defined __arm__
    21082759    char *p = alloca(16);
    21092760    strcpy(p,"123456789012345");
     
    21382789    tab1_ptr = tab1;
    21392790    tab2_ptr = tab2;
    2140     printf("Test C99 VLA 2 (ptrs substract): ");
     2791    printf("Test C99 VLA 2 (ptrs subtract): ");
    21412792    printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
    21422793    printf("Test C99 VLA 3 (ptr add): ");
     
    21742825}
    21752826
     2827#ifndef __TINYC__
    21762828typedef __SIZE_TYPE__ uintptr_t;
     2829#endif
    21772830
    21782831void sizeof_test(void)
     
    22182871    printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
    22192872    printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
     2873
     2874    /* sizes of VLAs need to be evaluated even inside sizeof: */
     2875    a = 2;
     2876    printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
     2877    /* And checking if sizeof compound literal works.  Parenthesized: */
     2878    printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
     2879           sizeof( (struct {int i; int j;}){4,5} ));
     2880    /* And as direct sizeof argument (as unary expression): */
     2881    printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
     2882           sizeof (struct {short i; short j;}){4,5} );
     2883
     2884    /* sizeof(x && y) should be sizeof(int), even if constant
     2885       evaluating is possible. */
     2886    printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
     2887    printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
     2888    printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
     2889    printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
    22202890}
    22212891
     
    22322902}
    22332903
     2904
     2905struct hlist_node;
     2906struct hlist_head {
     2907    struct hlist_node *first, *last;
     2908};
     2909
     2910void consume_ulong (unsigned long i)
     2911{
     2912    i = 0;
     2913}
     2914
    22342915void statement_expr_test(void)
    22352916{
    22362917    int a, i;
    22372918
     2919    /* Basic stmt expr test */
    22382920    a = 0;
    22392921    for(i=0;i<10;i++) {
     
    22472929    printf("a=%d\n", a);
    22482930   
     2931    /* Test that symbols aren't freed prematurely.
     2932       With SYM_DEBUG valgrind will show a read from a freed
     2933       symbol, and tcc will show an (invalid) warning on the initialization
     2934       of 'ptr' below, if symbols are popped after the stmt expr.  */
     2935    void *v = (void*)39;
     2936    typeof(({
     2937            (struct hlist_node *)v;
     2938            })) x;
     2939    typeof (x)
     2940        ptr = (struct hlist_node *)v;
     2941
     2942    /* This part used to segfault when symbols were popped prematurely.
     2943       The symbols for the static local would be overwritten with
     2944       helper symbols from the pre-processor expansions in between.  */
     2945#define some_attr     __attribute__((aligned(1)))
     2946#define tps(str) ({                  \
     2947            static const char *t some_attr = str; \
     2948            t;                                    \
     2949          })
     2950    printf ("stmtexpr: %s %s\n",
     2951            tps("somerandomlongstring"),
     2952            tps("anotherlongstring"));
     2953
     2954    /* Test that the three decls of 't' don't interact.  */
     2955    int t = 40;
     2956    int b = ({ int t = 41; t; });
     2957    int c = ({ int t = 42; t; });
     2958
     2959    /* Test that aggregate return values work.  */
     2960    struct hlist_head h
     2961        = ({
     2962           typedef struct hlist_head T;
     2963           long pre = 48;
     2964           T t = { (void*)43, (void*)44 };
     2965           long post = 49;
     2966           t;
     2967           });
     2968    printf ("stmtexpr: %d %d %d\n", t, b, c);
     2969    printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
     2970
     2971    /* Test that we can give out addresses of local labels.  */
     2972    consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
    22492973}
    22502974
     
    22803004
    22813005/* inline assembler test */
    2282 #ifdef __i386__
     3006#if defined(__i386__) || defined(__x86_64__)
    22833007
    22843008/* from linux kernel */
    22853009static char * strncat1(char * dest,const char * src,size_t count)
    22863010{
    2287 int d0, d1, d2, d3;
     3011long d0, d1, d2, d3;
    22883012__asm__ __volatile__(
    22893013        "repne\n\t"
    22903014        "scasb\n\t"
    2291         "decl %1\n\t"
    2292         "movl %8,%3\n"
    2293         "1:\tdecl %3\n\t"
     3015        "dec %1\n\t"
     3016        "mov %8,%3\n"
     3017        "1:\tdec %3\n\t"
    22943018        "js 2f\n\t"
    22953019        "lodsb\n\t"
     
    22973021        "testb %%al,%%al\n\t"
    22983022        "jne 1b\n"
    2299         "2:\txorl %2,%2\n\t"
     3023        "2:\txor %2,%2\n\t"
    23003024        "stosb"
    23013025        : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
     
    23073031static char * strncat2(char * dest,const char * src,size_t count)
    23083032{
    2309 int d0, d1, d2, d3;
     3033long d0, d1, d2, d3;
    23103034__asm__ __volatile__(
    23113035        "repne scasb\n\t" /* one-line repne prefix + string op */
    2312         "decl %1\n\t"
    2313         "movl %8,%3\n"
    2314         "1:\tdecl %3\n\t"
     3036        "dec %1\n\t"
     3037        "mov %8,%3\n"
     3038        "1:\tdec %3\n\t"
    23153039        "js 2f\n\t"
    23163040        "lodsb\n\t"
     
    23183042        "testb %%al,%%al\n\t"
    23193043        "jne 1b\n"
    2320         "2:\txorl %2,%2\n\t"
     3044        "2:\txor %2,%2\n\t"
    23213045        "stosb"
    23223046        : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
     
    23283052static inline void * memcpy1(void * to, const void * from, size_t n)
    23293053{
    2330 int d0, d1, d2;
     3054long d0, d1, d2;
    23313055__asm__ __volatile__(
    23323056        "rep ; movsl\n\t"
     
    23463070static inline void * memcpy2(void * to, const void * from, size_t n)
    23473071{
    2348 int d0, d1, d2;
     3072long d0, d1, d2;
    23493073__asm__ __volatile__(
    23503074        "rep movsl\n\t"  /* one-line rep prefix + string op */
     
    23693093static __inline__ void sigdelset1(unsigned int *set, int _sig)
    23703094{
    2371         asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
     3095        asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
    23723096}
    23733097
     
    23773101                "rorl $16,%0\n\t"       /* swap words           */
    23783102                "xchgb %b0,%h0"         /* swap higher bytes    */
    2379                 :"=q" (x)
     3103                :"=" "q" (x)
    23803104                : "0" (x));
    23813105        return x;
     
    23853109{
    23863110    unsigned long long res;
     3111#ifdef __x86_64__
     3112    /* Using the A constraint is wrong (it means rdx:rax, which is too large)
     3113       but still test the 32bit->64bit mull.  */
     3114    unsigned int resh, resl;
     3115    __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
     3116    res = ((unsigned long long)resh << 32) | resl;
     3117#else
    23873118    __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
     3119#endif
    23883120    return res;
    23893121}
     
    23923124{
    23933125    unsigned long long res;
     3126#ifdef __x86_64__
     3127    /* Using the A constraint is wrong, and increments are tested
     3128       elsewhere.  */
     3129    res = a + 1;
     3130#else
    23943131    __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
     3132#endif
    23953133    return res;
    23963134}
    23973135
     3136struct struct123 {
     3137    int a;
     3138    int b;
     3139};
     3140struct struct1231 {
     3141    unsigned long addr;
     3142};
     3143
     3144unsigned long mconstraint_test(struct struct1231 *r)
     3145{
     3146    unsigned long ret;
     3147    unsigned int a[2];
     3148    a[0] = 0;
     3149    __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
     3150                     : "=&r" (ret), "=m" (a)
     3151                     : "m" (*(struct struct123 *)r->addr));
     3152    return ret + a[0];
     3153}
     3154
     3155#ifdef __x86_64__
     3156int fls64(unsigned long long x)
     3157{
     3158  int bitpos = -1;
     3159  asm("bsrq %1,%q0"
     3160      : "+r" (bitpos)
     3161      : "rm" (x));
     3162  return bitpos + 1;
     3163}
     3164#endif
     3165
     3166void other_constraints_test(void)
     3167{
     3168    unsigned long ret;
     3169    int var;
     3170#ifndef _WIN64
     3171    __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
     3172    printf ("oc1: %d\n", ret == (unsigned long)&var);
     3173#endif
     3174}
     3175
     3176#ifndef _WIN32
     3177/* Test global asm blocks playing with aliases.  */
     3178void base_func(void)
     3179{
     3180  printf ("asmc: base\n");
     3181}
     3182
     3183extern void override_func1 (void);
     3184extern void override_func2 (void);
     3185
     3186asm(".weak override_func1\n.set override_func1, base_func");
     3187asm(".set override_func1, base_func");
     3188asm(".set override_func2, base_func");
     3189
     3190void override_func2 (void)
     3191{
     3192  printf ("asmc: override2\n");
     3193}
     3194
     3195/* This checks a construct used by the linux kernel to encode
     3196   references to strings by PC relative references.  */
     3197extern int bug_table[] __attribute__((section("__bug_table")));
     3198char * get_asm_string (void)
     3199{
     3200  extern int some_symbol;
     3201  asm volatile (".globl some_symbol\n"
     3202                "jmp .+6\n"
     3203                "1:\n"
     3204                "some_symbol: .long 0\n"
     3205                ".pushsection __bug_table, \"a\"\n"
     3206                ".globl bug_table\n"
     3207                "bug_table:\n"
     3208                /* The first entry (1b-2b) is unused in this test,
     3209                   but we include it to check if cross-section
     3210                   PC-relative references work.  */
     3211                "2:\t.long 1b - 2b, %c0 - 2b\n"
     3212                ".popsection\n" : : "i" ("A string"));
     3213  char * str = ((char*)bug_table) + bug_table[1];
     3214  return str;
     3215}
     3216
     3217/* This checks another constructs with local labels.  */
     3218extern unsigned char alld_stuff[];
     3219asm(".data\n"
     3220    ".byte 41\n"
     3221    "alld_stuff:\n"
     3222    "661:\n"
     3223    ".byte 42\n"
     3224    "662:\n"
     3225    ".pushsection .data.ignore\n"
     3226    ".long 661b - .\n" /* This reference to 661 generates an external sym
     3227                          which shouldn't somehow overwrite the offset that's
     3228                          already determined for it.  */
     3229    ".popsection\n"
     3230    ".byte 662b - 661b\n"  /* So that this value is undeniably 1.  */);
     3231
     3232void asm_local_label_diff (void)
     3233{
     3234  printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
     3235}
     3236
     3237/* This checks that static local variables are available from assembler.  */
     3238void asm_local_statics (void)
     3239{
     3240  static int localint = 41;
     3241  asm("incl %0" : "+m" (localint));
     3242  printf ("asm_local_statics: %d\n", localint);
     3243}
     3244#endif
     3245
     3246static
    23983247unsigned int set;
    23993248
     3249void fancy_copy (unsigned *in, unsigned *out)
     3250{
     3251  asm volatile ("" : "=r" (*out) : "0" (*in));
     3252}
     3253
     3254void fancy_copy2 (unsigned *in, unsigned *out)
     3255{
     3256  asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
     3257}
     3258
     3259#if defined __x86_64__ && !defined _WIN64
     3260void clobber_r12(void)
     3261{
     3262    asm volatile("mov $1, %%r12" ::: "r12");
     3263}
     3264#endif
     3265
     3266void test_high_clobbers(void)
     3267{
     3268#if defined __x86_64__ && !defined _WIN64
     3269    register long val asm("r12");
     3270    long val2;
     3271    /* This tests if asm clobbers correctly save/restore callee saved
     3272       registers if they are clobbered and if it's the high 8 x86-64
     3273       registers.  This is fragile for GCC as the constraints do not
     3274       correctly capture the data flow, but good enough for us.  */
     3275    asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
     3276    clobber_r12();
     3277    asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
     3278    printf("asmhc: 0x%x\n", val2);
     3279#endif
     3280}
     3281
     3282static long cpu_number;
     3283void trace_console(long len, long len2)
     3284{
     3285#ifdef __x86_64__
     3286    /* This generated invalid code when the emission of the switch
     3287       table isn't disabled.  The asms are necessary to show the bug,
     3288       normal statements don't work (they need to generate some code
     3289       even under nocode_wanted, which normal statements don't do,
     3290       but asms do).  Also at least these number of cases is necessary
     3291       to generate enough "random" bytes.  They ultimately are enough
     3292       to create invalid instruction patterns to which the first
     3293       skip-to-decision-table jump jumps.  If decision table emission
     3294       is disabled all of this is no problem.
     3295
     3296       It also is necessary that the switches are in a statement expression
     3297       (which has the property of not being enterable from outside. no
     3298       matter what).  */
     3299    if (0
     3300        &&
     3301            ({
     3302              long pscr_ret__;
     3303              switch(len) {
     3304                case 4:
     3305                    {
     3306                       long pfo_ret__;
     3307                       switch (len2) {
     3308                         case 8:        printf("bla"); pfo_ret__ = 42; break;
     3309                       }
     3310                       pscr_ret__ = pfo_ret__;
     3311                    }
     3312                  break;
     3313                case 8:
     3314                    {
     3315                       long pfo_ret__;
     3316                       switch (len2) {
     3317                         case 1:asm("movq %1,%0": "=r" (pfo_ret__)      : "m" (cpu_number));    break;
     3318                         case 2:asm("movq %1,%0": "=r" (pfo_ret__)      : "m" (cpu_number));    break;
     3319                         case 4:asm("movq %1,%0": "=r" (pfo_ret__)      : "m" (cpu_number));    break;
     3320                         case 8:asm("movq %1,%0": "=r" (pfo_ret__)      : "m" (cpu_number));    break;
     3321                         default: printf("impossible\n");
     3322                       }
     3323                       pscr_ret__ = pfo_ret__;
     3324                    };
     3325                  break;
     3326              }
     3327              pscr_ret__;
     3328            }))
     3329      {
     3330        printf("huh?\n");
     3331      }
     3332#endif
     3333}
     3334
     3335void test_asm_dead_code(void)
     3336{
     3337  long rdi;
     3338  /* Try to make sure that xdi contains a zero, and hence will
     3339     lead to a segfault if the next asm is evaluated without
     3340     arguments being set up.  */
     3341  asm volatile ("" : "=D" (rdi) : "0" (0));
     3342  (void)sizeof (({
     3343      int var;
     3344      /* This shouldn't trigger a segfault, either the argument
     3345         registers need to be set up and the asm emitted despite
     3346         this being in an unevaluated context, or both the argument
     3347         setup _and_ the asm emission need to be suppressed.  The latter
     3348         is better.  Disabling asm code gen when suppression is on
     3349         also fixes the above trace_console bug, but that came earlier
     3350         than asm suppression.  */
     3351      asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
     3352      var;
     3353  }));
     3354}
     3355
     3356void test_asm_call(void)
     3357{
     3358#if defined __x86_64__ && !defined _WIN64
     3359  static char str[] = "PATH";
     3360  char *s;
     3361  /* This tests if a reference to an undefined symbol from an asm
     3362     block, which isn't otherwise referenced in this file, is correctly
     3363     regarded as global symbol, so that it's resolved by other object files
     3364     or libraries.  We chose getenv here, which isn't used anywhere else
     3365     in this file.  (If we used e.g. printf, which is used we already
     3366     would have a global symbol entry, not triggering the bug which is
     3367     tested here).  */
     3368  /* two pushes so stack remains aligned */
     3369  asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
     3370#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__))
     3371                "call getenv@plt;"
     3372#else
     3373                "call getenv;"
     3374#endif
     3375                "pop %%rdi; pop %%rdi"
     3376                : "=a" (s) : "r" (str));
     3377  printf("asmd: %s\n", s);
     3378#endif
     3379}
     3380
     3381#if defined __x86_64__
     3382# define RX "(%rip)"
     3383#else
     3384# define RX
     3385#endif
     3386
     3387void asm_dot_test(void)
     3388{
     3389    int x;
     3390    for (x = 1;; ++x) {
     3391        int r = x;
     3392        switch (x) {
     3393        case 1:
     3394            asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
     3395        case 2:
     3396            asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
     3397        case 3:
     3398            asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4");
     3399            asm(".text; mov X"RX",%eax; jmp p0");
     3400        case 4:
     3401            asm(".data; X=.; .int 789; Y=.; .int 999");
     3402            asm(".text; mov X"RX",%eax; X=Y; jmp p0");
     3403        case 0:
     3404            asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
     3405        }
     3406        if (r == x)
     3407            break;
     3408        printf("asm_dot_test %d: %d\n", x, r);
     3409    }
     3410}
     3411
    24003412void asm_test(void)
    24013413{
    24023414    char buf[128];
    2403     unsigned int val;
     3415    unsigned int val, val2;
     3416    struct struct123 s1;
     3417    struct struct1231 s2 = { (unsigned long)&s1 };
     3418    /* Hide the outer base_func, but check later that the inline
     3419       asm block gets the outer one.  */
     3420    int base_func = 42;
     3421    void override_func3 (void);
     3422    unsigned long asmret;
     3423#ifdef BOOL_ISOC99
     3424    _Bool somebool;
     3425#endif
     3426    register int regvar asm("%esi");
    24043427
    24053428    printf("inline asm:\n");
     3429
     3430    // parse 0x1E-1 as 3 tokens in asm mode
     3431    asm volatile ("mov $0x1E-1,%eax");
     3432
    24063433    /* test the no operand case */
    24073434    asm volatile ("xorl %eax, %eax");
     
    24193446    printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
    24203447
     3448    s1.a = 42;
     3449    s1.b = 43;
     3450    printf("mconstraint: %d", mconstraint_test(&s2));
     3451    printf(" %d %d\n", s1.a, s1.b);
     3452    other_constraints_test();
    24213453    set = 0xff;
    24223454    sigdelset1(&set, 2);
     
    24273459 label2:
    24283460    __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
    2429 #ifdef __GNUC__ // works strange with GCC 4.3
    2430     set=0x1080fd;
    2431 #endif
    24323461    printf("set=0x%x\n", set);
    24333462    val = 0x01020304;
    24343463    printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
     3464#ifndef _WIN32
     3465    override_func1();
     3466    override_func2();
     3467    /* The base_func ref from the following inline asm should find
     3468       the global one, not the local decl from this function.  */
     3469    asm volatile(".weak override_func3\n.set override_func3, base_func");
     3470    override_func3();
     3471    printf("asmstr: %s\n", get_asm_string());
     3472    asm_local_label_diff();
     3473    asm_local_statics();
     3474#endif
     3475    /* Check that we can also load structs of appropriate layout
     3476       into registers.  */
     3477    asm volatile("" : "=r" (asmret) : "0"(s2));
     3478    if (asmret != s2.addr)
     3479      printf("asmstr: failed\n");
     3480#ifdef BOOL_ISOC99
     3481    /* Check that the typesize correctly sets the register size to
     3482       8 bit.  */
     3483    asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
     3484    if (!somebool)
     3485      printf("asmbool: failed\n");
     3486#endif
     3487    val = 43;
     3488    fancy_copy (&val, &val2);
     3489    printf ("fancycpy(%d)=%d\n", val, val2);
     3490    val = 44;
     3491    fancy_copy2 (&val, &val2);
     3492    printf ("fancycpy2(%d)=%d\n", val, val2);
     3493    asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
     3494    printf ("regvar=%x\n", regvar);
     3495    test_high_clobbers();
     3496    trace_console(8, 8);
     3497    test_asm_dead_code();
     3498    test_asm_call();
     3499    asm_dot_test();
    24353500    return;
    24363501 label1:
     
    24563521void builtin_test(void)
    24573522{
     3523    short s;
     3524    int i;
     3525    long long ll;
    24583526#if GCC_MAJOR >= 3
    24593527    COMPAT_TYPE(int, int);
     
    24663534    COMPAT_TYPE(int *, const int *);
    24673535    COMPAT_TYPE(char *, unsigned char *);
     3536    COMPAT_TYPE(char *, signed char *);
     3537    COMPAT_TYPE(char *, char *);
    24683538/* space is needed because tcc preprocessor introduces a space between each token */
    24693539    COMPAT_TYPE(char * *, void *);
     
    24733543    printf("res = %d\n", __builtin_constant_p(&constant_p_var));
    24743544    printf("res = %d\n", __builtin_constant_p(constant_p_var));
     3545    printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
     3546    s = 1;
     3547    ll = 2;
     3548    i = __builtin_choose_expr (1 != 0, ll, s);
     3549    printf("bce: %d\n", i);
     3550    i = __builtin_choose_expr (1 != 1, ll, s);
     3551    printf("bce: %d\n", i);
     3552    i = sizeof (__builtin_choose_expr (1, ll, s));
     3553    printf("bce: %d\n", i);
     3554    i = sizeof (__builtin_choose_expr (0, ll, s));
     3555    printf("bce: %d\n", i);
     3556
     3557    //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
    24753558}
    24763559
     
    25253608        printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
    25263609        printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
     3610        printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
    25273611}
    25283612
     
    26783762void callsave_test(void)
    26793763{
    2680 #if defined __i386__ || defined __x86_64__
     3764#if defined __i386__ || defined __x86_64__ || defined __arm__
    26813765  int i, s; double *d; double t;
    26823766  s = sizeof (double);
     
    27073791{
    27083792    printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
    2709 #if defined(__arm__) && !defined(__GNUC__)
    27103793    bfa2(str_offset);
    2711 #endif
    27123794}
    27133795
    27143796void builtin_frame_address_test(void)
    27153797{
     3798/* builtin_frame_address fails on ARM with gcc which make test3 fail */
     3799#ifndef __arm__
    27163800    char str[] = "__builtin_frame_address";
    27173801    char *fp0 = __builtin_frame_address(0);
     
    27193803    printf("str: %s\n", str);
    27203804    bfa1(str-fp0);
    2721 }
     3805#endif
     3806}
     3807
     3808char via_volatile (char i)
     3809{
     3810  char volatile vi;
     3811  vi = i;
     3812  return vi;
     3813}
     3814
     3815struct __attribute__((__packed__)) Spacked {
     3816    char a;
     3817    short b;
     3818    int c;
     3819};
     3820struct Spacked spacked;
     3821typedef struct __attribute__((__packed__)) {
     3822    char a;
     3823    short b;
     3824    int c;
     3825} Spacked2;
     3826Spacked2 spacked2;
     3827typedef struct Spacked3_s {
     3828    char a;
     3829    short b;
     3830    int c;
     3831} __attribute__((__packed__)) Spacked3;
     3832Spacked3 spacked3;
     3833struct gate_struct64 {
     3834    unsigned short offset_low;
     3835    unsigned short segment;
     3836    unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
     3837    unsigned short offset_middle;
     3838    unsigned offset_high;
     3839    unsigned zero1;
     3840} __attribute__((packed));
     3841typedef struct gate_struct64 gate_desc;
     3842gate_desc a_gate_desc;
     3843void attrib_test(void)
     3844{
     3845#ifndef _WIN32
     3846  printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
     3847         sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
     3848  printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
     3849  printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
     3850#endif
     3851}
     3852extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
     3853strange_attrib_placement (void);
     3854
     3855void * __attribute__((__unused__)) get_void_ptr (void *a)
     3856{
     3857  return a;
     3858}
     3859
     3860/* This part checks for a bug in TOK_GET (used for inline expansion),
     3861   where the large long long constant left the the high bits set for
     3862   the integer constant token.  */
     3863static inline
     3864int __get_order(unsigned long long size)
     3865{
     3866  int order;
     3867  size -= 0xffff880000000000ULL; // this const left high bits set in the token
     3868    {
     3869      struct S { int i : 1; } s; // constructed for this '1'
     3870    }
     3871  order = size;
     3872  return order;
     3873}
     3874
     3875/* This just forces the above inline function to be actually emitted.  */
     3876int force_get_order(unsigned long s)
     3877{
     3878    return __get_order(s);
     3879}
  • EcnlProtoTool/trunk/tcc-0.9.27/x86_64-asm.h

    r321 r331  
    66     DEF_ASM_OP0(lahf, 0x9f)
    77     DEF_ASM_OP0(sahf, 0x9e)
    8      DEF_ASM_OP0(pushfl, 0x9c)
    9      DEF_ASM_OP0(popfl, 0x9d)
     8     DEF_ASM_OP0(pushfq, 0x9c)
     9     DEF_ASM_OP0(popfq, 0x9d)
    1010     DEF_ASM_OP0(pushf, 0x9c)
    1111     DEF_ASM_OP0(popf, 0x9d)
     
    3535     DEF_ASM_OP0(wait, 0x9b)
    3636     DEF_ASM_OP0(nop, 0x90)
     37     DEF_ASM_OP0(pause, 0xf390)
    3738     DEF_ASM_OP0(xlat, 0xd7)
    3839
    3940     /* strings */
    40 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLQ))
    41 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLQ))
    42 
    43 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWLQ))
    44 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWLQ))
    45 
    46 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLQ))
    47 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLQ))
    48 
    49 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLQ))
    50 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLQ))
    51 
    52 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLQ))
    53 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLQ))
    54 
    55 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLQ))
    56 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLQ))
     41ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
     42ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
     43
     44ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
     45ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
     46
     47ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
     48ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
     49
     50ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
     51ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
     52
     53ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
     54ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
     55
     56ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
     57ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
    5758
    5859     /* bits */
    5960
    60 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA, OPT_REGW))
    61 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA, OPT_REGW))
    62 
    63 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
    64 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
    65 
    66 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
    67 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
    68 
    69 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
    70 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
    71 
    72 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
    73 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
     61ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
     62ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
     63
     64ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     65ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
     66
     67ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     68ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
     69
     70ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     71ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
     72
     73ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
     74ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
    7475
    7576     /* prefixes */
     
    8889     DEF_ASM_OP0(rdmsr, 0x0f32)
    8990     DEF_ASM_OP0(rdpmc, 0x0f33)
     91
     92     DEF_ASM_OP0(syscall, 0x0f05)
     93     DEF_ASM_OP0(sysret, 0x0f07)
     94     DEF_ASM_OP0L(sysretq, 0x480f07, 0, 0)
    9095     DEF_ASM_OP0(ud2, 0x0f0b)
    9196
    9297     /* NOTE: we took the same order as gas opcode definition order */
    93 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLQ, OPT_ADDR, OPT_EAX))
    94 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLQ, OPT_EAX, OPT_ADDR))
    95 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG))
    96 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
    97 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLQ, OPT_IM, OPT_REG))
    98 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLQ, OPT_IM, OPT_REG | OPT_EA))
    99 
    100 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLQ, OPT_SEG, OPT_EA | OPT_REG))
    101 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLQ, OPT_EA | OPT_REG, OPT_SEG))
    102 
    103 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLQ, OPT_CR, OPT_REG64))
    104 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLQ, OPT_DB, OPT_REG64))
    105 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLQ, OPT_TR, OPT_REG64))
    106 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_CR))
    107 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_DB))
    108 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_TR))
    109 
     98/* Right now we can't express the fact that 0xa1/0xa3 can't use $eax and a
     99   32 bit moffset as operands.
     100ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
     101ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR)) */
     102ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
     103ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
     104/* The moves are special: the 0xb8 form supports IM64 (the only insn that
     105   does) with REG64.  It doesn't support IM32 with REG64, it would use
     106   the full movabs form (64bit immediate).  For IM32->REG64 we prefer
     107   the 0xc7 opcode.  So disallow all 64bit forms and code the rest by hand. */
     108ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
     109ALT(DEF_ASM_OP2(mov,  0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
     110ALT(DEF_ASM_OP2(movq, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
     111ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
     112
     113ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
     114ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
     115
     116ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG64))
     117ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG64))
     118ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_CR))
     119ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_DB))
     120
     121ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
    110122ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
    111 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
     123ALT(DEF_ASM_OP2(movsbq, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REGW))
    112124ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
    113 ALT(DEF_ASM_OP2(movslq, 0x4863, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG))
    114 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
     125ALT(DEF_ASM_OP2(movswq, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
     126ALT(DEF_ASM_OP2(movslq, 0x63, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG))
     127ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
    115128ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
    116 
    117 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLQ, OPT_REG64))
    118 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLQ, OPT_REG64 | OPT_EA))
    119 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLQ, OPT_IM32))
    120 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLQ, OPT_SEG))
    121     DEF_ASM_OP1(pushb, 0x6a, 0, OPC_B, OPT_IM8S)
    122 
    123 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLQ, OPT_REGW))
    124 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA))
    125 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLQ, OPT_SEG))
    126 
    127 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLQ, OPT_REG, OPT_EAX))
    128 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLQ, OPT_EAX, OPT_REG))
    129 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG))
    130 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
     129ALT(DEF_ASM_OP2(movzwq, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
     130
     131ALT(DEF_ASM_OP1(pushq, 0x6a, 0, 0, OPT_IM8S))
     132ALT(DEF_ASM_OP1(push, 0x6a, 0, 0, OPT_IM8S))
     133ALT(DEF_ASM_OP1(pushw, 0x666a, 0, 0, OPT_IM8S))
     134ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG64))
     135ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG16))
     136ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REG64 | OPT_EA))
     137ALT(DEF_ASM_OP1(pushw, 0x6668, 0, 0, OPT_IM16))
     138ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
     139ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
     140
     141ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG64))
     142ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG16))
     143ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
     144ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
     145
     146ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
     147ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
     148ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
     149ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
    131150
    132151ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
     
    140159ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
    141160
    142 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLQ, OPT_EA, OPT_REG))
     161ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
    143162
    144163ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
     
    149168
    150169     /* arith */
    151 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
    152 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
    153 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLQ, OPT_IMNO64, OPT_EAX))
    154 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_IMNO64, OPT_EA | OPT_REG))
    155 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_EA | OPT_REG))
    156 
    157 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
    158 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG))
    159 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLQ, OPT_IMNO64, OPT_EAX))
    160 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLQ, OPT_IMNO64, OPT_EA | OPT_REG))
    161 
    162 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLQ, OPT_REGW))
    163 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    164 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLQ, OPT_REGW))
    165 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    166 
    167 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    168 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    169 
    170 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    171 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    172 
    173 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLQ, OPT_REG | OPT_EA, OPT_REG))
    174 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
    175 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_REGW))
    176 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLQ, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
    177 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLQ, OPT_IMW, OPT_REGW))
    178 
    179 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    180 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA, OPT_EAX))
    181 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
    182 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA, OPT_EAX))
     170ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
     171ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
     172ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
     173ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
     174ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
     175
     176ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
     177ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
     178ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
     179ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
     180
     181ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     182ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     183
     184ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     185ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     186
     187ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     188ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     189
     190ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
     191ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
     192ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
     193ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
     194ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
     195
     196ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     197ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
     198ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
     199ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
    183200
    184201     /* shifts */
    185 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
    186 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
    187 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_EA | OPT_REG))
    188 
    189 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
    190 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLQ, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
    191 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_EA | OPT_REGW))
    192 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
    193 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLQ, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
    194 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_EA | OPT_REGW))
     202ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
     203ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
     204ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
     205
     206ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
     207ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
     208ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
     209ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
     210ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
     211ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
    195212
    196213ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
    197 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
     214ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
    198215ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
    199 ALT(DEF_ASM_OP1(jmp, 0xff, 0, OPC_JMP | OPC_WL, OPT_REGW))
    200 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
    201 
    202 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
    203 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
     216ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
     217
     218ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
     219ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
     220    DEF_ASM_OP1(ljmpw, 0x66ff, 5, OPC_MODRM, OPT_EA)
     221    DEF_ASM_OP1(ljmpl, 0xff, 5, OPC_MODRM, OPT_EA)
    204222
    205223ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
    206224ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
     225ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
    207226    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
    208227    DEF_ASM_OP0(leave, 0xc9)
    209228    DEF_ASM_OP0(ret, 0xc3)
     229    DEF_ASM_OP0(retq, 0xc3)
     230ALT(DEF_ASM_OP1(retq, 0xc2, 0, 0, OPT_IM16))
    210231ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
    211232    DEF_ASM_OP0(lret, 0xcb)
    212233ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
    213234
    214 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
    215     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
    216     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
    217     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
    218     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
    219     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
    220     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
     235ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
     236    DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
     237    DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
     238    DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
     239    DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
     240    DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
     241    DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8)
    221242
    222243     /* float */
     
    226247ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
    227248ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
     249ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
     250ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
    228251ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
    229252ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
     
    328351    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
    329352    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
     353    /* The *q forms of fxrstor/fxsave use a REX prefix.
     354       If the operand would use extended registers we would have to modify
     355       it instead of generating a second one.  Currently that's no
     356       problem with TCC, we don't use extended registers.  */
     357    DEF_ASM_OP1(fxsaveq, 0x0fae, 0, OPC_MODRM | OPC_48, OPT_EA )
     358    DEF_ASM_OP1(fxrstorq, 0x0fae, 1, OPC_MODRM | OPC_48, OPT_EA )
    330359
    331360    /* segments */
    332361    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
    333     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
     362ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
    334363    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
     364    DEF_ASM_OP1(lgdtq, 0x0f01, 2, OPC_MODRM, OPT_EA)
    335365    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
     366    DEF_ASM_OP1(lidtq, 0x0f01, 3, OPC_MODRM, OPT_EA)
    336367    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
    337368    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
    338 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
    339     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
     369ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
     370    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG16)
    340371    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
     372    DEF_ASM_OP1(sgdtq, 0x0f01, 0, OPC_MODRM, OPT_EA)
    341373    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
     374    DEF_ASM_OP1(sidtq, 0x0f01, 1, OPC_MODRM, OPT_EA)
    342375    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
    343376    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
    344     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
     377    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG32 | OPT_EA)
     378ALT(DEF_ASM_OP1(str, 0x660f00, 1, OPC_MODRM, OPT_REG16))
     379ALT(DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM | OPC_48, OPT_REG64))
    345380    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
    346381    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
     382    DEF_ASM_OP0L(swapgs, 0x0f01, 7, OPC_MODRM)
    347383
    348384    /* 486 */
     385    /* bswap can't be applied to 16bit regs */
    349386    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
    350 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
    351 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
     387    DEF_ASM_OP1(bswapl, 0x0fc8, 0, OPC_REG, OPT_REG32 )
     388    DEF_ASM_OP1(bswapq, 0x0fc8, 0, OPC_REG | OPC_48, OPT_REG64 )
     389
     390ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
     391ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
    352392    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
    353 
    354     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
    355     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
    356393
    357394    /* pentium */
    358395    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
    359396
     397    /* AMD 64 */
     398    DEF_ASM_OP1(cmpxchg16b, 0x0fc7, 1, OPC_MODRM | OPC_48, OPT_EA )
     399
    360400    /* pentium pro */
    361 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    362 ALT(DEF_ASM_OP2(cmovno, 0x0f41, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    363 ALT(DEF_ASM_OP2(cmovc, 0x0f42, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    364 ALT(DEF_ASM_OP2(cmovnc, 0x0f43, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    365 ALT(DEF_ASM_OP2(cmovz, 0x0f44, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    366 ALT(DEF_ASM_OP2(cmovnz, 0x0f45, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    367 ALT(DEF_ASM_OP2(cmovna, 0x0f46, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
    368 ALT(DEF_ASM_OP2(cmova, 0x0f47, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
     401ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
    369402
    370403    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
     
    384417    /* mmx */
    385418    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
    386     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
    387 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
     419    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
     420    /* movd shouldn't accept REG64, but AMD64 spec uses it for 32 and 64 bit
     421       moves, so let's be compatible. */
     422ALT(DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG64, OPT_MMXSSE ))
     423ALT(DEF_ASM_OP2(movq, 0x0f6e, 0, OPC_MODRM | OPC_48, OPT_REG64, OPT_MMXSSE ))
    388424ALT(DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ))
     425ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
     426ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
    389427ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
    390     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    391     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    392     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    393     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    394     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    395     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    396     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    397     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    398     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    399     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    400     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    401     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    402     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    403     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    404     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    405     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    406     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    407     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    408     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    409     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    410     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    411     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    412     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    413 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
    414     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    415 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
    416     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    417 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
    418     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    419 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
    420     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    421 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
    422     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    423 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
    424     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    425 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
    426     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    427 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
    428     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    429     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    430     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    431     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    432     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    433     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    434     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    435     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    436     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    437     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    438     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    439     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    440     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    441     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
    442 
     428ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
     429ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
     430ALT(DEF_ASM_OP2(movq, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
     431
     432    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     433    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     434    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     435    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     436    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     437    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     438    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     439    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     440    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     441    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     442    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     443    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     444    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     445    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     446    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     447    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     448    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     449    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     450    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     451    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     452    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     453    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     454    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     455ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     456    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     457ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     458    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     459ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     460    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     461ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     462    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     463ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     464    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     465ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     466    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     467ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     468    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     469ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
     470    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     471    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     472    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     473    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     474    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     475    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     476    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     477    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     478    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     479    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     480    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     481    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     482    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     483    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     484
     485    /* sse */
     486    DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
     487ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
     488    DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
     489ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
     490    DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
     491ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
     492    DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     493    DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
     494    DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
     495    DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
     496    DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     497    DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     498    DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     499    DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     500    DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     501    DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     502    DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     503    DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     504    DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     505    DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
     506    DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     507    DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     508    DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     509    DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
     510
     511    DEF_ASM_OP1(prefetchnta, 0x0f18, 0, OPC_MODRM, OPT_EA)
     512    DEF_ASM_OP1(prefetcht0, 0x0f18, 1, OPC_MODRM, OPT_EA)
     513    DEF_ASM_OP1(prefetcht1, 0x0f18, 2, OPC_MODRM, OPT_EA)
     514    DEF_ASM_OP1(prefetcht2, 0x0f18, 3, OPC_MODRM, OPT_EA)
     515    DEF_ASM_OP1(prefetchw, 0x0f0d, 1, OPC_MODRM, OPT_EA)
     516    DEF_ASM_OP0L(lfence, 0x0fae, 5, OPC_MODRM)
     517    DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM)
     518    DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM)
     519    DEF_ASM_OP1(clflush, 0x0fae, 7, OPC_MODRM, OPT_EA)
    443520#undef ALT
    444521#undef DEF_ASM_OP0
  • EcnlProtoTool/trunk/tcc-0.9.27/x86_64-gen.c

    r321 r331  
    2424
    2525/* number of available registers */
    26 #define NB_REGS         5
    27 #define NB_ASM_REGS     8
     26#define NB_REGS         25
     27#define NB_ASM_REGS     16
     28#define CONFIG_TCC_ASM
    2829
    2930/* a register can belong to several classes. The classes must be
     
    3536#define RC_RCX     0x0008
    3637#define RC_RDX     0x0010
     38#define RC_ST0     0x0080 /* only for long double */
    3739#define RC_R8      0x0100
    3840#define RC_R9      0x0200
    3941#define RC_R10     0x0400
    4042#define RC_R11     0x0800
    41 #define RC_XMM0    0x0020
    42 #define RC_ST0     0x0040 /* only for long double */
     43#define RC_XMM0    0x1000
     44#define RC_XMM1    0x2000
     45#define RC_XMM2    0x4000
     46#define RC_XMM3    0x8000
     47#define RC_XMM4    0x10000
     48#define RC_XMM5    0x20000
     49#define RC_XMM6    0x40000
     50#define RC_XMM7    0x80000
    4351#define RC_IRET    RC_RAX /* function return: integer register */
    4452#define RC_LRET    RC_RDX /* function return: second integer register */
    4553#define RC_FRET    RC_XMM0 /* function return: float register */
     54#define RC_QRET    RC_XMM1 /* function return: second float register */
    4655
    4756/* pretty names for the registers */
     
    5059    TREG_RCX = 1,
    5160    TREG_RDX = 2,
    52     TREG_XMM0 = 3,
    53     TREG_ST0 = 4,
    54 
     61    TREG_RSP = 4,
    5562    TREG_RSI = 6,
    5663    TREG_RDI = 7,
     64
    5765    TREG_R8  = 8,
    5866    TREG_R9  = 9,
    59 
    6067    TREG_R10 = 10,
    6168    TREG_R11 = 11,
    6269
    63     TREG_MEM = 0x10,
     70    TREG_XMM0 = 16,
     71    TREG_XMM1 = 17,
     72    TREG_XMM2 = 18,
     73    TREG_XMM3 = 19,
     74    TREG_XMM4 = 20,
     75    TREG_XMM5 = 21,
     76    TREG_XMM6 = 22,
     77    TREG_XMM7 = 23,
     78
     79    TREG_ST0 = 24,
     80
     81    TREG_MEM = 0x20
    6482};
    6583
     
    7189#define REG_LRET TREG_RDX /* second word return register (for long long) */
    7290#define REG_FRET TREG_XMM0 /* float return register */
     91#define REG_QRET TREG_XMM1 /* second float return register */
    7392
    7493/* defined if function parameters must be evaluated in reverse order */
     
    8099/* long double size and alignment, in bytes */
    81100#define LDOUBLE_SIZE  16
    82 #define LDOUBLE_ALIGN 8
     101#define LDOUBLE_ALIGN 16
    83102/* maximum alignment (for aligned attribute support) */
    84 #define MAX_ALIGN     8
    85 
    86 /******************************************************/
    87 /* ELF defines */
    88 
    89 #define EM_TCC_TARGET EM_X86_64
    90 
    91 /* relocation type for 32 bit data relocation */
    92 #define R_DATA_32   R_X86_64_32
    93 #define R_DATA_PTR  R_X86_64_64
    94 #define R_JMP_SLOT  R_X86_64_JUMP_SLOT
    95 #define R_COPY      R_X86_64_COPY
    96 
    97 #define ELF_START_ADDR 0x08048000
    98 #define ELF_PAGE_SIZE  0x1000
     103#define MAX_ALIGN     16
    99104
    100105/******************************************************/
     
    104109#include <assert.h>
    105110
    106 ST_DATA const int reg_classes[NB_REGS+7] = {
     111ST_DATA const int reg_classes[NB_REGS] = {
    107112    /* eax */ RC_INT | RC_RAX,
    108113    /* ecx */ RC_INT | RC_RCX,
    109114    /* edx */ RC_INT | RC_RDX,
    110     /* xmm0 */ RC_FLOAT | RC_XMM0,
    111     /* st0 */ RC_ST0,
    112115    0,
    113116    0,
    114117    0,
    115     RC_INT | RC_R8,
    116     RC_INT | RC_R9,
    117     RC_INT | RC_R10,
    118     RC_INT | RC_R11
     118    0,
     119    0,
     120    RC_R8,
     121    RC_R9,
     122    RC_R10,
     123    RC_R11,
     124    0,
     125    0,
     126    0,
     127    0,
     128    /* xmm0 */ RC_FLOAT | RC_XMM0,
     129    /* xmm1 */ RC_FLOAT | RC_XMM1,
     130    /* xmm2 */ RC_FLOAT | RC_XMM2,
     131    /* xmm3 */ RC_FLOAT | RC_XMM3,
     132    /* xmm4 */ RC_FLOAT | RC_XMM4,
     133    /* xmm5 */ RC_FLOAT | RC_XMM5,
     134    /* xmm6 an xmm7 are included so gv() can be used on them,
     135       but they are not tagged with RC_FLOAT because they are
     136       callee saved on Windows */
     137    RC_XMM6,
     138    RC_XMM7,
     139    /* st0 */ RC_ST0
    119140};
    120141
     
    123144
    124145/* XXX: make it faster ? */
    125 void g(int c)
     146ST_FUNC void g(int c)
    126147{
    127148    int ind1;
     149    if (nocode_wanted)
     150        return;
    128151    ind1 = ind + 1;
    129152    if (ind1 > cur_text_section->data_allocated)
     
    133156}
    134157
    135 void o(unsigned int c)
     158ST_FUNC void o(unsigned int c)
    136159{
    137160    while (c) {
     
    141164}
    142165
    143 void gen_le16(int v)
     166ST_FUNC void gen_le16(int v)
    144167{
    145168    g(v);
     
    147170}
    148171
    149 void gen_le32(int c)
     172ST_FUNC void gen_le32(int c)
    150173{
    151174    g(c);
     
    155178}
    156179
    157 void gen_le64(int64_t c)
     180ST_FUNC void gen_le64(int64_t c)
    158181{
    159182    g(c);
     
    167190}
    168191
    169 void orex(int ll, int r, int r2, int b)
     192static void orex(int ll, int r, int r2, int b)
    170193{
    171194    if ((r & VT_VALMASK) >= VT_CONST)
     
    179202
    180203/* output a symbol and patch all calls to it */
    181 void gsym_addr(int t, int a)
    182 {
    183     int n, *ptr;
     204ST_FUNC void gsym_addr(int t, int a)
     205{
    184206    while (t) {
    185         ptr = (int *)(cur_text_section->data + t);
    186         n = *ptr; /* next value */
    187         *ptr = a - t - 4;
     207        unsigned char *ptr = cur_text_section->data + t;
     208        uint32_t n = read32le(ptr); /* next value */
     209        write32le(ptr, a - t - 4);
    188210        t = n;
    189211    }
     
    195217}
    196218
    197 /* psym is used to put an instruction with a data field which is a
    198    reference to a symbol. It is in fact the same as oad ! */
    199 #define psym oad
    200219
    201220static int is64_type(int t)
     
    206225}
    207226
    208 static int is_sse_float(int t) {
    209     int bt;
    210     bt = t & VT_BTYPE;
    211     return bt == VT_DOUBLE || bt == VT_FLOAT;
    212 }
    213 
    214 
    215227/* instruction + 4 bytes data. Return the address of the data */
    216 ST_FUNC int oad(int c, int s)
    217 {
    218     int ind1;
    219 
     228static int oad(int c, int s)
     229{
     230    int t;
     231    if (nocode_wanted)
     232        return s;
    220233    o(c);
    221     ind1 = ind + 4;
    222     if (ind1 > cur_text_section->data_allocated)
    223         section_realloc(cur_text_section, ind1);
    224     *(int *)(cur_text_section->data + ind) = s;
    225     s = ind;
    226     ind = ind1;
    227     return s;
    228 }
     234    t = ind;
     235    gen_le32(s);
     236    return t;
     237}
     238
     239/* generate jmp to a label */
     240#define gjmp2(instr,lbl) oad(instr,lbl)
    229241
    230242ST_FUNC void gen_addr32(int r, Sym *sym, int c)
    231243{
    232244    if (r & VT_SYM)
    233         greloc(cur_text_section, sym, ind, R_X86_64_32);
     245        greloca(cur_text_section, sym, ind, R_X86_64_32S, c), c=0;
    234246    gen_le32(c);
    235247}
     
    239251{
    240252    if (r & VT_SYM)
    241         greloc(cur_text_section, sym, ind, R_X86_64_64);
     253        greloca(cur_text_section, sym, ind, R_X86_64_64, c), c=0;
    242254    gen_le64(c);
    243255}
     
    247259{
    248260    if (r & VT_SYM)
    249         greloc(cur_text_section, sym, ind, R_X86_64_PC32);
     261        greloca(cur_text_section, sym, ind, R_X86_64_PC32, c-4), c=4;
    250262    gen_le32(c-4);
    251263}
     
    254266static void gen_gotpcrel(int r, Sym *sym, int c)
    255267{
    256 #ifndef TCC_TARGET_PE
    257     Section *sr;
    258     ElfW(Rela) *rel;
    259     greloc(cur_text_section, sym, ind, R_X86_64_GOTPCREL);
    260     sr = cur_text_section->reloc;
    261     rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela)));
    262     rel->r_addend = -4;
    263 #else
    264     printf("picpic: %s %x %x | %02x %02x %02x\n", get_tok_str(sym->v, NULL), c, r,
     268#ifdef TCC_TARGET_PE
     269    tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n",
     270        get_tok_str(sym->v, NULL), c, r,
    265271        cur_text_section->data[ind-3],
    266272        cur_text_section->data[ind-2],
    267273        cur_text_section->data[ind-1]
    268274        );
    269     greloc(cur_text_section, sym, ind, R_X86_64_PC32);
    270275#endif
     276    greloca(cur_text_section, sym, ind, R_X86_64_GOTPCREL, -4);
    271277    gen_le32(0);
    272278    if (c) {
     
    283289    if ((r & VT_VALMASK) == VT_CONST) {
    284290        /* constant memory reference */
    285         o(0x05 | op_reg);
    286         if (is_got) {
    287             gen_gotpcrel(r, sym, c);
    288         } else {
    289             gen_addrpc32(r, sym, c);
    290         }
     291        if (!(r & VT_SYM)) {
     292            /* Absolute memory reference */
     293            o(0x04 | op_reg); /* [sib] | destreg */
     294            oad(0x25, c);     /* disp32 */
     295        } else {
     296            o(0x05 | op_reg); /* (%rip)+disp32 | destreg */
     297            if (is_got) {
     298                gen_gotpcrel(r, sym, c);
     299            } else {
     300                gen_addrpc32(r, sym, c);
     301            }
     302        }
    291303    } else if ((r & VT_VALMASK) == VT_LOCAL) {
    292304        /* currently, we use only ebp as base */
     
    310322}
    311323
    312 /* generate a modrm reference. 'op_reg' contains the addtionnal 3
     324/* generate a modrm reference. 'op_reg' contains the additional 3
    313325   opcode bits */
    314326static void gen_modrm(int op_reg, int r, Sym *sym, int c)
     
    317329}
    318330
    319 /* generate a modrm reference. 'op_reg' contains the addtionnal 3
     331/* generate a modrm reference. 'op_reg' contains the additional 3
    320332   opcode bits */
    321333static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c)
     
    340352
    341353    fr = sv->r;
    342     ft = sv->type.t;
    343     fc = sv->c.ul;
     354    ft = sv->type.t & ~VT_DEFSIGN;
     355    fc = sv->c.i;
     356    if (fc != sv->c.i && (fr & VT_SYM))
     357      tcc_error("64 bit addend in load");
     358
     359    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    344360
    345361#ifndef TCC_TARGET_PE
     
    366382            v1.type.t = VT_PTR;
    367383            v1.r = VT_LOCAL | VT_LVAL;
    368             v1.c.ul = fc;
     384            v1.c.i = fc;
    369385            fr = r;
    370             if (!(reg_classes[fr] & RC_INT))
     386            if (!(reg_classes[fr] & (RC_INT|RC_R11)))
    371387                fr = get_reg(RC_INT);
    372388            load(fr, &v1);
    373389        }
     390        if (fc != sv->c.i) {
     391            /* If the addends doesn't fit into a 32bit signed
     392               we must use a 64bit move.  We've checked above
     393               that this doesn't have a sym associated.  */
     394            v1.type.t = VT_LLONG;
     395            v1.r = VT_CONST;
     396            v1.c.i = sv->c.i;
     397            fr = r;
     398            if (!(reg_classes[fr] & (RC_INT|RC_R11)))
     399                fr = get_reg(RC_INT);
     400            load(fr, &v1);
     401            fc = 0;
     402        }
    374403        ll = 0;
     404        /* Like GCC we can load from small enough properly sized
     405           structs and unions as well.
     406           XXX maybe move to generic operand handling, but should
     407           occur only with asm, so tccasm.c might also be a better place */
     408        if ((ft & VT_BTYPE) == VT_STRUCT) {
     409            int align;
     410            switch (type_size(&sv->type, &align)) {
     411                case 1: ft = VT_BYTE; break;
     412                case 2: ft = VT_SHORT; break;
     413                case 4: ft = VT_INT; break;
     414                case 8: ft = VT_LLONG; break;
     415                default:
     416                    tcc_error("invalid aggregate type for register load");
     417                    break;
     418            }
     419        }
    375420        if ((ft & VT_BTYPE) == VT_FLOAT) {
    376             b = 0x6e0f66, r = 0; /* movd */
     421            b = 0x6e0f66;
     422            r = REG_VALUE(r); /* movd */
    377423        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
    378             b = 0x7e0ff3, r = 0; /* movq */
     424            b = 0x7e0ff3; /* movq */
     425            r = REG_VALUE(r);
    379426        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
    380427            b = 0xdb, r = 5; /* fldt */
    381         } else if ((ft & VT_TYPE) == VT_BYTE) {
     428        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
    382429            b = 0xbe0f;   /* movsbl */
    383430        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
     
    388435            b = 0xb70f;   /* movzwl */
    389436        } else {
     437            assert(((ft & VT_BTYPE) == VT_INT)
     438                   || ((ft & VT_BTYPE) == VT_LLONG)
     439                   || ((ft & VT_BTYPE) == VT_PTR)
     440                   || ((ft & VT_BTYPE) == VT_FUNC)
     441                );
    390442            ll = is64_type(ft);
    391443            b = 0x8b;
     
    417469            } else if (is64_type(ft)) {
    418470                orex(1,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
    419                 gen_le64(sv->c.ull);
     471                gen_le64(sv->c.i);
    420472            } else {
    421473                orex(0,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
     
    451503            oad(0xb8 + REG_VALUE(r), t ^ 1); /* mov $0, r */
    452504        } else if (v != r) {
    453             if (r == TREG_XMM0) {
    454                 assert(v == TREG_ST0);
    455                 /* gen_cvt_ftof(VT_DOUBLE); */
    456                 o(0xf0245cdd); /* fstpl -0x10(%rsp) */
    457                 /* movsd -0x10(%rsp),%xmm0 */
    458                 o(0x44100ff2);
    459                 o(0xf024);
     505            if ((r >= TREG_XMM0) && (r <= TREG_XMM7)) {
     506                if (v == TREG_ST0) {
     507                    /* gen_cvt_ftof(VT_DOUBLE); */
     508                    o(0xf0245cdd); /* fstpl -0x10(%rsp) */
     509                    /* movsd -0x10(%rsp),%xmmN */
     510                    o(0x100ff2);
     511                    o(0x44 + REG_VALUE(r)*8); /* %xmmN */
     512                    o(0xf024);
     513                } else {
     514                    assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
     515                    if ((ft & VT_BTYPE) == VT_FLOAT) {
     516                        o(0x100ff3);
     517                    } else {
     518                        assert((ft & VT_BTYPE) == VT_DOUBLE);
     519                        o(0x100ff2);
     520                    }
     521                    o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8);
     522                }
    460523            } else if (r == TREG_ST0) {
    461                 assert(v == TREG_XMM0);
     524                assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
    462525                /* gen_cvt_ftof(VT_LDOUBLE); */
    463                 /* movsd %xmm0,-0x10(%rsp) */
    464                 o(0x44110ff2);
     526                /* movsd %xmmN,-0x10(%rsp) */
     527                o(0x110ff2);
     528                o(0x44 + REG_VALUE(r)*8); /* %xmmN */
    465529                o(0xf024);
    466530                o(0xf02444dd); /* fldl -0x10(%rsp) */
     
    486550#endif
    487551
     552    fr = v->r & VT_VALMASK;
    488553    ft = v->type.t;
    489     fc = v->c.ul;
    490     fr = v->r & VT_VALMASK;
     554    fc = v->c.i;
     555    if (fc != v->c.i && (fr & VT_SYM))
     556      tcc_error("64 bit addend in store");
     557    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    491558    bt = ft & VT_BTYPE;
    492559
     
    496563        /* mov xx(%rip), %r11 */
    497564        o(0x1d8b4c);
    498         gen_gotpcrel(TREG_R11, v->sym, v->c.ul);
     565        gen_gotpcrel(TREG_R11, v->sym, v->c.i);
    499566        pic = is64_type(bt) ? 0x49 : 0x41;
    500567    }
     
    506573        o(pic);
    507574        o(0x7e0f); /* movd */
    508         r = 0;
     575        r = REG_VALUE(r);
    509576    } else if (bt == VT_DOUBLE) {
    510577        o(0x66);
    511578        o(pic);
    512579        o(0xd60f); /* movq */
    513         r = 0;
     580        r = REG_VALUE(r);
    514581    } else if (bt == VT_LDOUBLE) {
    515582        o(0xc0d9); /* fld %st(0) */
     
    556623{
    557624    int r;
    558     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
     625    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
     626        ((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
    559627        /* constant case */
    560628        if (vtop->r & VT_SYM) {
    561629            /* relocation case */
    562             greloc(cur_text_section, vtop->sym,
    563                    ind + 1, R_X86_64_PC32);
     630#ifdef TCC_TARGET_PE
     631            greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
     632#else
     633            greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
     634#endif
    564635        } else {
    565636            /* put an empty PC32 relocation */
    566             put_elf_reloc(symtab_section, cur_text_section,
    567                           ind + 1, R_X86_64_PC32, 0);
    568         }
    569         oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
     637            put_elf_reloca(symtab_section, cur_text_section,
     638                          ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4));
     639        }
     640        oad(0xe8 + is_jmp, 0); /* call/jmp im */
    570641    } else {
    571642        /* otherwise, indirect call */
     
    578649}
    579650
     651#if defined(CONFIG_TCC_BCHECK)
     652#ifndef TCC_TARGET_PE
     653static addr_t func_bound_offset;
     654static unsigned long func_bound_ind;
     655#endif
     656
     657static void gen_static_call(int v)
     658{
     659    Sym *sym = external_global_sym(v, &func_old_type, 0);
     660    oad(0xe8, 0);
     661    greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
     662}
     663
     664/* generate a bounded pointer addition */
     665ST_FUNC void gen_bounded_ptr_add(void)
     666{
     667    /* save all temporary registers */
     668    save_regs(0);
     669
     670    /* prepare fast x86_64 function call */
     671    gv(RC_RAX);
     672    o(0xc68948); // mov  %rax,%rsi ## second arg in %rsi, this must be size
     673    vtop--;
     674
     675    gv(RC_RAX);
     676    o(0xc78948); // mov  %rax,%rdi ## first arg in %rdi, this must be ptr
     677    vtop--;
     678
     679    /* do a fast function call */
     680    gen_static_call(TOK___bound_ptr_add);
     681
     682    /* returned pointer is in rax */
     683    vtop++;
     684    vtop->r = TREG_RAX | VT_BOUNDED;
     685
     686
     687    /* relocation offset of the bounding function call point */
     688    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
     689}
     690
     691/* patch pointer addition in vtop so that pointer dereferencing is
     692   also tested */
     693ST_FUNC void gen_bounded_ptr_deref(void)
     694{
     695    addr_t func;
     696    int size, align;
     697    ElfW(Rela) *rel;
     698    Sym *sym;
     699
     700    size = 0;
     701    /* XXX: put that code in generic part of tcc */
     702    if (!is_float(vtop->type.t)) {
     703        if (vtop->r & VT_LVAL_BYTE)
     704            size = 1;
     705        else if (vtop->r & VT_LVAL_SHORT)
     706            size = 2;
     707    }
     708    if (!size)
     709    size = type_size(&vtop->type, &align);
     710    switch(size) {
     711    case  1: func = TOK___bound_ptr_indir1; break;
     712    case  2: func = TOK___bound_ptr_indir2; break;
     713    case  4: func = TOK___bound_ptr_indir4; break;
     714    case  8: func = TOK___bound_ptr_indir8; break;
     715    case 12: func = TOK___bound_ptr_indir12; break;
     716    case 16: func = TOK___bound_ptr_indir16; break;
     717    default:
     718        tcc_error("unhandled size when dereferencing bounded pointer");
     719        func = 0;
     720        break;
     721    }
     722
     723    sym = external_global_sym(func, &func_old_type, 0);
     724    if (!sym->c)
     725        put_extern_sym(sym, NULL, 0, 0);
     726
     727    /* patch relocation */
     728    /* XXX: find a better solution ? */
     729
     730    rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);
     731    rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));
     732}
     733#endif
     734
    580735#ifdef TCC_TARGET_PE
    581736
    582737#define REGN 4
    583 static const uint8_t arg_regs[] = {
     738static const uint8_t arg_regs[REGN] = {
    584739    TREG_RCX, TREG_RDX, TREG_R8, TREG_R9
    585740};
    586741
    587 static int func_scratch;
     742/* Prepare arguments in R10 and R11 rather than RCX and RDX
     743   because gv() will not ever use these */
     744static int arg_prepare_reg(int idx) {
     745  if (idx == 0 || idx == 1)
     746      /* idx=0: r10, idx=1: r11 */
     747      return idx + 10;
     748  else
     749      return arg_regs[idx];
     750}
     751
     752static int func_scratch, func_alloca;
    588753
    589754/* Generate function call. The function address is pushed first, then
     
    591756   parameters and the function address. */
    592757
    593 void gen_offs_sp(int b, int r, int d)
     758static void gen_offs_sp(int b, int r, int d)
    594759{
    595760    orex(1,0,r & 0x100 ? 0 : r, b);
     
    603768}
    604769
     770static int using_regs(int size)
     771{
     772    return !(size > 8 || (size & (size - 1)));
     773}
     774
     775/* Return the number of registers needed to return the struct, or 0 if
     776   returning via struct pointer. */
     777ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
     778{
     779    int size, align;
     780    *ret_align = 1; // Never have to re-align return values for x86-64
     781    *regsize = 8;
     782    size = type_size(vt, &align);
     783    if (!using_regs(size))
     784        return 0;
     785    if (size == 8)
     786        ret->t = VT_LLONG;
     787    else if (size == 4)
     788        ret->t = VT_INT;
     789    else if (size == 2)
     790        ret->t = VT_SHORT;
     791    else
     792        ret->t = VT_BYTE;
     793    ret->ref = NULL;
     794    return 1;
     795}
     796
     797static int is_sse_float(int t) {
     798    int bt;
     799    bt = t & VT_BTYPE;
     800    return bt == VT_DOUBLE || bt == VT_FLOAT;
     801}
     802
     803static int gfunc_arg_size(CType *type) {
     804    int align;
     805    if (type->t & (VT_ARRAY|VT_BITFIELD))
     806        return 8;
     807    return type_size(type, &align);
     808}
     809
    605810void gfunc_call(int nb_args)
    606811{
    607     int size, align, r, args_size, i, d, j, bt, struct_size;
    608     int nb_reg_args, gen_reg;
    609 
    610     nb_reg_args = nb_args;
    611     args_size = (nb_reg_args < REGN ? REGN : nb_reg_args) * PTR_SIZE;
     812    int size, r, args_size, i, d, bt, struct_size;
     813    int arg;
     814
     815    args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
     816    arg = nb_args;
    612817
    613818    /* for struct arguments, we need to call memcpy and the function
     
    616821    struct_size = args_size;
    617822    for(i = 0; i < nb_args; i++) {
    618         SValue *sv = &vtop[-i];
     823        SValue *sv;
     824       
     825        --arg;
     826        sv = &vtop[-i];
    619827        bt = (sv->type.t & VT_BTYPE);
     828        size = gfunc_arg_size(&sv->type);
     829
     830        if (using_regs(size))
     831            continue; /* arguments smaller than 8 bytes passed in registers or on stack */
     832
    620833        if (bt == VT_STRUCT) {
    621             size = type_size(&sv->type, &align);
    622834            /* align to stack align size */
    623835            size = (size + 15) & ~15;
     
    632844            vstore();
    633845            --vtop;
    634 
    635846        } else if (bt == VT_LDOUBLE) {
    636 
    637847            gv(RC_ST0);
    638848            gen_offs_sp(0xdb, 0x107, struct_size);
    639849            struct_size += 16;
    640 
    641850        }
    642851    }
     
    644853    if (func_scratch < struct_size)
    645854        func_scratch = struct_size;
    646 #if 1
    647     for (i = 0; i < REGN; ++i)
    648         save_reg(arg_regs[i]);
    649     save_reg(TREG_RAX);
    650 #endif
    651     gen_reg = nb_reg_args;
     855
     856    arg = nb_args;
    652857    struct_size = args_size;
    653858
    654859    for(i = 0; i < nb_args; i++) {
     860        --arg;
    655861        bt = (vtop->type.t & VT_BTYPE);
    656862
    657         if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
    658             if (bt == VT_LDOUBLE)
    659                 size = 16;
    660             else
    661                 size = type_size(&vtop->type, &align);
     863        size = gfunc_arg_size(&vtop->type);
     864        if (!using_regs(size)) {
    662865            /* align to stack align size */
    663866            size = (size + 15) & ~15;
    664             j = --gen_reg;
    665             if (j >= REGN) {
    666                 d = TREG_RAX;
     867            if (arg >= REGN) {
     868                d = get_reg(RC_INT);
    667869                gen_offs_sp(0x8d, d, struct_size);
    668                 gen_offs_sp(0x89, d, j*8);
     870                gen_offs_sp(0x89, d, arg*8);
    669871            } else {
    670                 d = arg_regs[j];
     872                d = arg_prepare_reg(arg);
    671873                gen_offs_sp(0x8d, d, struct_size);
    672874            }
    673875            struct_size += size;
    674 
    675         } else if (is_sse_float(vtop->type.t)) {
    676             gv(RC_FLOAT); /* only one float register */
    677             j = --gen_reg;
    678             if (j >= REGN) {
    679                 /* movq %xmm0, j*8(%rsp) */
    680                 gen_offs_sp(0xd60f66, 0x100, j*8);
     876        } else {
     877            if (is_sse_float(vtop->type.t)) {
     878                if (tcc_state->nosse)
     879                  tcc_error("SSE disabled");
     880                gv(RC_XMM0); /* only use one float register */
     881                if (arg >= REGN) {
     882                    /* movq %xmm0, j*8(%rsp) */
     883                    gen_offs_sp(0xd60f66, 0x100, arg*8);
     884                } else {
     885                    /* movaps %xmm0, %xmmN */
     886                    o(0x280f);
     887                    o(0xc0 + (arg << 3));
     888                    d = arg_prepare_reg(arg);
     889                    /* mov %xmm0, %rxx */
     890                    o(0x66);
     891                    orex(1,d,0, 0x7e0f);
     892                    o(0xc0 + REG_VALUE(d));
     893                }
    681894            } else {
    682                 /* movaps %xmm0, %xmmN */
    683                 o(0x280f);
    684                 o(0xc0 + (j << 3));
    685                 d = arg_regs[j];
    686                 /* mov %xmm0, %rxx */
    687                 o(0x66);
    688                 orex(1,d,0, 0x7e0f);
    689                 o(0xc0 + REG_VALUE(d));
    690             }
    691         } else {
    692             j = --gen_reg;
    693             if (j >= REGN) {
     895                if (bt == VT_STRUCT) {
     896                    vtop->type.ref = NULL;
     897                    vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
     898                        : size > 1 ? VT_SHORT : VT_BYTE;
     899                }
     900               
    694901                r = gv(RC_INT);
    695                 gen_offs_sp(0x89, r, j*8);
    696             } else {
    697                 d = arg_regs[j];
    698                 if (d < NB_REGS) {
    699                     gv(reg_classes[d] & ~RC_INT);
     902                if (arg >= REGN) {
     903                    gen_offs_sp(0x89, r, arg*8);
    700904                } else {
    701                     r = gv(RC_INT);
    702                     if (d != r) {
    703                         orex(1,d,r, 0x89);
    704                         o(0xc0 + REG_VALUE(d) + REG_VALUE(r) * 8);
    705                     }
     905                    d = arg_prepare_reg(arg);
     906                    orex(1,d,r,0x89); /* mov */
     907                    o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
    706908                }
    707 
    708909            }
    709910        }
     
    711912    }
    712913    save_regs(0);
     914   
     915    /* Copy R10 and R11 into RCX and RDX, respectively */
     916    if (nb_args > 0) {
     917        o(0xd1894c); /* mov %r10, %rcx */
     918        if (nb_args > 1) {
     919            o(0xda894c); /* mov %r11, %rdx */
     920        }
     921    }
     922   
    713923    gcall_or_jmp(0);
     924
     925    if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
     926        /* need to add the "func_scratch" area after alloca */
     927        o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
     928    }
     929
     930    /* other compilers don't clear the upper bits when returning char/short */
     931    bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
     932    if (bt == (VT_BYTE | VT_UNSIGNED))
     933        o(0xc0b60f);  /* movzbl %al, %eax */
     934    else if (bt == VT_BYTE)
     935        o(0xc0be0f); /* movsbl %al, %eax */
     936    else if (bt == VT_SHORT)
     937        o(0x98); /* cwtl */
     938    else if (bt == (VT_SHORT | VT_UNSIGNED))
     939        o(0xc0b70f);  /* movzbl %al, %eax */
     940#if 0 /* handled in gen_cast() */
     941    else if (bt == VT_INT)
     942        o(0x9848); /* cltq */
     943    else if (bt == (VT_INT | VT_UNSIGNED))
     944        o(0xc089); /* mov %eax,%eax */
     945#endif
    714946    vtop--;
    715947}
     
    721953void gfunc_prolog(CType *func_type)
    722954{
    723     int addr, reg_param_index, bt;
     955    int addr, reg_param_index, bt, size;
    724956    Sym *sym;
    725957    CType *type;
     
    727959    func_ret_sub = 0;
    728960    func_scratch = 0;
     961    func_alloca = 0;
    729962    loc = 0;
    730963
     
    739972       implicit pointer parameter */
    740973    func_vt = sym->type;
    741     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
     974    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
     975    size = gfunc_arg_size(&func_vt);
     976    if (!using_regs(size)) {
    742977        gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
     978        func_vc = addr;
    743979        reg_param_index++;
    744         addr += PTR_SIZE;
     980        addr += 8;
    745981    }
    746982
     
    749985        type = &sym->type;
    750986        bt = type->t & VT_BTYPE;
    751         if (reg_param_index < REGN) {
    752             /* save arguments passed by register */
     987        size = gfunc_arg_size(type);
     988        if (!using_regs(size)) {
     989            if (reg_param_index < REGN) {
     990                gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
     991            }
     992            sym_push(sym->v & ~SYM_FIELD, type, VT_LLOCAL | VT_LVAL, addr);
     993        } else {
     994            if (reg_param_index < REGN) {
     995                /* save arguments passed by register */
     996                if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) {
     997                    if (tcc_state->nosse)
     998                      tcc_error("SSE disabled");
     999                    o(0xd60f66); /* movq */
     1000                    gen_modrm(reg_param_index, VT_LOCAL, NULL, addr);
     1001                } else {
     1002                    gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
     1003                }
     1004            }
     1005            sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
     1006        }
     1007        addr += 8;
     1008        reg_param_index++;
     1009    }
     1010
     1011    while (reg_param_index < REGN) {
     1012        if (func_type->ref->f.func_type == FUNC_ELLIPSIS) {
    7531013            gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
    754         }
    755         if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
    756             sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL | VT_REF, addr);
    757         } else {
    758             sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
     1014            addr += 8;
    7591015        }
    7601016        reg_param_index++;
    761         addr += PTR_SIZE;
    762     }
    763 
    764     while (reg_param_index < REGN) {
    765         if (func_type->ref->c == FUNC_ELLIPSIS)
    766             gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
    767         reg_param_index++;
    768         addr += PTR_SIZE;
    7691017    }
    7701018}
     
    7871035    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
    7881036    /* align local size to word & save local variables */
     1037    func_scratch = (func_scratch + 15) & -16;
    7891038    v = (func_scratch + -loc + 15) & -16;
    7901039
     
    7921041        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
    7931042        oad(0xb8, v); /* mov stacksize, %eax */
    794         oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
    795         greloc(cur_text_section, sym, ind-4, R_X86_64_PC32);
     1043        oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */
     1044        greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
    7961045        o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
    7971046    } else {
     
    8011050    }
    8021051
     1052    /* add the "func_scratch" area after each alloca seen */
     1053    while (func_alloca) {
     1054        unsigned char *ptr = cur_text_section->data + func_alloca;
     1055        func_alloca = read32le(ptr);
     1056        write32le(ptr, func_scratch);
     1057    }
     1058
    8031059    cur_text_section->data_offset = saved_ind;
    8041060    pe_add_unwind_data(ind, saved_ind, v);
     
    8181074}
    8191075
     1076typedef enum X86_64_Mode {
     1077  x86_64_mode_none,
     1078  x86_64_mode_memory,
     1079  x86_64_mode_integer,
     1080  x86_64_mode_sse,
     1081  x86_64_mode_x87
     1082} X86_64_Mode;
     1083
     1084static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
     1085{
     1086    if (a == b)
     1087        return a;
     1088    else if (a == x86_64_mode_none)
     1089        return b;
     1090    else if (b == x86_64_mode_none)
     1091        return a;
     1092    else if ((a == x86_64_mode_memory) || (b == x86_64_mode_memory))
     1093        return x86_64_mode_memory;
     1094    else if ((a == x86_64_mode_integer) || (b == x86_64_mode_integer))
     1095        return x86_64_mode_integer;
     1096    else if ((a == x86_64_mode_x87) || (b == x86_64_mode_x87))
     1097        return x86_64_mode_memory;
     1098    else
     1099        return x86_64_mode_sse;
     1100}
     1101
     1102static X86_64_Mode classify_x86_64_inner(CType *ty)
     1103{
     1104    X86_64_Mode mode;
     1105    Sym *f;
     1106   
     1107    switch (ty->t & VT_BTYPE) {
     1108    case VT_VOID: return x86_64_mode_none;
     1109   
     1110    case VT_INT:
     1111    case VT_BYTE:
     1112    case VT_SHORT:
     1113    case VT_LLONG:
     1114    case VT_BOOL:
     1115    case VT_PTR:
     1116    case VT_FUNC:
     1117        return x86_64_mode_integer;
     1118   
     1119    case VT_FLOAT:
     1120    case VT_DOUBLE: return x86_64_mode_sse;
     1121   
     1122    case VT_LDOUBLE: return x86_64_mode_x87;
     1123     
     1124    case VT_STRUCT:
     1125        f = ty->ref;
     1126
     1127        mode = x86_64_mode_none;
     1128        for (f = f->next; f; f = f->next)
     1129            mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type));
     1130       
     1131        return mode;
     1132    }
     1133    assert(0);
     1134    return 0;
     1135}
     1136
     1137static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
     1138{
     1139    X86_64_Mode mode;
     1140    int size, align, ret_t = 0;
     1141   
     1142    if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
     1143        *psize = 8;
     1144        *palign = 8;
     1145        *reg_count = 1;
     1146        ret_t = ty->t;
     1147        mode = x86_64_mode_integer;
     1148    } else {
     1149        size = type_size(ty, &align);
     1150        *psize = (size + 7) & ~7;
     1151        *palign = (align + 7) & ~7;
     1152   
     1153        if (size > 16) {
     1154            mode = x86_64_mode_memory;
     1155        } else {
     1156            mode = classify_x86_64_inner(ty);
     1157            switch (mode) {
     1158            case x86_64_mode_integer:
     1159                if (size > 8) {
     1160                    *reg_count = 2;
     1161                    ret_t = VT_QLONG;
     1162                } else {
     1163                    *reg_count = 1;
     1164                    ret_t = (size > 4) ? VT_LLONG : VT_INT;
     1165                }
     1166                break;
     1167               
     1168            case x86_64_mode_x87:
     1169                *reg_count = 1;
     1170                ret_t = VT_LDOUBLE;
     1171                break;
     1172
     1173            case x86_64_mode_sse:
     1174                if (size > 8) {
     1175                    *reg_count = 2;
     1176                    ret_t = VT_QFLOAT;
     1177                } else {
     1178                    *reg_count = 1;
     1179                    ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;
     1180                }
     1181                break;
     1182            default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/
     1183            }
     1184        }
     1185    }
     1186   
     1187    if (ret) {
     1188        ret->ref = NULL;
     1189        ret->t = ret_t;
     1190    }
     1191   
     1192    return mode;
     1193}
     1194
     1195ST_FUNC int classify_x86_64_va_arg(CType *ty)
     1196{
     1197    /* This definition must be synced with stdarg.h */
     1198    enum __va_arg_type {
     1199        __va_gen_reg, __va_float_reg, __va_stack
     1200    };
     1201    int size, align, reg_count;
     1202    X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);
     1203    switch (mode) {
     1204    default: return __va_stack;
     1205    case x86_64_mode_integer: return __va_gen_reg;
     1206    case x86_64_mode_sse: return __va_float_reg;
     1207    }
     1208}
     1209
     1210/* Return the number of registers needed to return the struct, or 0 if
     1211   returning via struct pointer. */
     1212ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
     1213{
     1214    int size, align, reg_count;
     1215    *ret_align = 1; // Never have to re-align return values for x86-64
     1216    *regsize = 8;
     1217    return (classify_x86_64_arg(vt, ret, &size, &align, &reg_count) != x86_64_mode_memory);
     1218}
     1219
    8201220#define REGN 6
    8211221static const uint8_t arg_regs[REGN] = {
     
    8231223};
    8241224
     1225static int arg_prepare_reg(int idx) {
     1226  if (idx == 2 || idx == 3)
     1227      /* idx=2: r10, idx=3: r11 */
     1228      return idx + 8;
     1229  else
     1230      return arg_regs[idx];
     1231}
     1232
    8251233/* Generate function call. The function address is pushed first, then
    8261234   all the parameters in call order. This functions pops all the
     
    8281236void gfunc_call(int nb_args)
    8291237{
    830     int size, align, r, args_size, i;
     1238    X86_64_Mode mode;
     1239    CType type;
     1240    int size, align, r, args_size, stack_adjust, i, reg_count;
    8311241    int nb_reg_args = 0;
    8321242    int nb_sse_args = 0;
    8331243    int sse_reg, gen_reg;
    834 
    835     /* calculate the number of integer/float arguments */
    836     args_size = 0;
    837     for(i = 0; i < nb_args; i++) {
    838         if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) {
    839             args_size += type_size(&vtop[-i].type, &align);
    840             args_size = (args_size + 7) & ~7;
    841         } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) {
    842             args_size += 16;
    843         } else if (is_sse_float(vtop[-i].type.t)) {
    844             nb_sse_args++;
    845             if (nb_sse_args > 8) args_size += 8;
    846         } else {
    847             nb_reg_args++;
    848             if (nb_reg_args > REGN) args_size += 8;
    849         }
    850     }
     1244    char _onstack[nb_args], *onstack = _onstack;
     1245
     1246    /* calculate the number of integer/float register arguments, remember
     1247       arguments to be passed via stack (in onstack[]), and also remember
     1248       if we have to align the stack pointer to 16 (onstack[i] == 2).  Needs
     1249       to be done in a left-to-right pass over arguments.  */
     1250    stack_adjust = 0;
     1251    for(i = nb_args - 1; i >= 0; i--) {
     1252        mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
     1253        if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
     1254            nb_sse_args += reg_count;
     1255            onstack[i] = 0;
     1256        } else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) {
     1257            nb_reg_args += reg_count;
     1258            onstack[i] = 0;
     1259        } else if (mode == x86_64_mode_none) {
     1260            onstack[i] = 0;
     1261        } else {
     1262            if (align == 16 && (stack_adjust &= 15)) {
     1263                onstack[i] = 2;
     1264                stack_adjust = 0;
     1265            } else
     1266              onstack[i] = 1;
     1267            stack_adjust += size;
     1268        }
     1269    }
     1270
     1271    if (nb_sse_args && tcc_state->nosse)
     1272      tcc_error("SSE disabled but floating point arguments passed");
     1273
     1274    /* fetch cpu flag before generating any code */
     1275    if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
     1276      gv(RC_INT);
    8511277
    8521278    /* for struct arguments, we need to call memcpy and the function
     
    8551281    gen_reg = nb_reg_args;
    8561282    sse_reg = nb_sse_args;
    857 
    858     /* adjust stack to align SSE boundary */
    859     if (args_size &= 15) {
    860         /* fetch cpu flag before the following sub will change the value */
    861         if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
    862             gv(RC_INT);
    863 
    864         args_size = 16 - args_size;
    865         o(0x48);
    866         oad(0xec81, args_size); /* sub $xxx, %rsp */
    867     }
    868 
    869     for(i = 0; i < nb_args; i++) {
    870         /* Swap argument to top, it will possibly be changed here,
    871            and might use more temps.  All arguments must remain on the
    872            stack, so that get_reg can correctly evict some of them onto
    873            stack.  We could use also use a vrott(nb_args) at the end
    874            of this loop, but this seems faster.  */
    875         SValue tmp = vtop[0];
    876         vtop[0] = vtop[-i];
    877         vtop[-i] = tmp;
    878         if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
    879             size = type_size(&vtop->type, &align);
    880             /* align to stack align size */
    881             size = (size + 7) & ~7;
    882             /* allocate the necessary size on stack */
    883             o(0x48);
    884             oad(0xec81, size); /* sub $xxx, %rsp */
    885             /* generate structure store */
    886             r = get_reg(RC_INT);
    887             orex(1, r, 0, 0x89); /* mov %rsp, r */
    888             o(0xe0 + REG_VALUE(r));
    889             vset(&vtop->type, r | VT_LVAL, 0);
    890             vswap();
    891             vstore();
    892             args_size += size;
    893         } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
    894             gv(RC_ST0);
    895             size = LDOUBLE_SIZE;
    896             oad(0xec8148, size); /* sub $xxx, %rsp */
    897             o(0x7cdb); /* fstpt 0(%rsp) */
    898             g(0x24);
    899             g(0x00);
    900             args_size += size;
    901         } else if (is_sse_float(vtop->type.t)) {
    902             int j = --sse_reg;
    903             if (j >= 8) {
    904                 gv(RC_FLOAT);
    905                 o(0x50); /* push $rax */
    906                 /* movq %xmm0, (%rsp) */
    907                 o(0x04d60f66);
    908                 o(0x24);
    909                 args_size += 8;
    910             }
    911         } else {
    912             int j = --gen_reg;
    913             /* simple type */
    914             /* XXX: implicit cast ? */
    915             if (j >= REGN) {
    916                 r = gv(RC_INT);
    917                 orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
    918                 args_size += 8;
    919             }
    920         }
    921 
    922         /* And swap the argument back to it's original position.  */
    923         tmp = vtop[0];
    924         vtop[0] = vtop[-i];
    925         vtop[-i] = tmp;
     1283    args_size = 0;
     1284    stack_adjust &= 15;
     1285    for (i = 0; i < nb_args;) {
     1286        mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
     1287        if (!onstack[i]) {
     1288            ++i;
     1289            continue;
     1290        }
     1291        /* Possibly adjust stack to align SSE boundary.  We're processing
     1292           args from right to left while allocating happens left to right
     1293           (stack grows down), so the adjustment needs to happen _after_
     1294           an argument that requires it.  */
     1295        if (stack_adjust) {
     1296            o(0x50); /* push %rax; aka sub $8,%rsp */
     1297            args_size += 8;
     1298            stack_adjust = 0;
     1299        }
     1300        if (onstack[i] == 2)
     1301          stack_adjust = 1;
     1302
     1303        vrotb(i+1);
     1304
     1305        switch (vtop->type.t & VT_BTYPE) {
     1306            case VT_STRUCT:
     1307                /* allocate the necessary size on stack */
     1308                o(0x48);
     1309                oad(0xec81, size); /* sub $xxx, %rsp */
     1310                /* generate structure store */
     1311                r = get_reg(RC_INT);
     1312                orex(1, r, 0, 0x89); /* mov %rsp, r */
     1313                o(0xe0 + REG_VALUE(r));
     1314                vset(&vtop->type, r | VT_LVAL, 0);
     1315                vswap();
     1316                vstore();
     1317                break;
     1318
     1319            case VT_LDOUBLE:
     1320                gv(RC_ST0);
     1321                oad(0xec8148, size); /* sub $xxx, %rsp */
     1322                o(0x7cdb); /* fstpt 0(%rsp) */
     1323                g(0x24);
     1324                g(0x00);
     1325                break;
     1326
     1327            case VT_FLOAT:
     1328            case VT_DOUBLE:
     1329                assert(mode == x86_64_mode_sse);
     1330                r = gv(RC_FLOAT);
     1331                o(0x50); /* push $rax */
     1332                /* movq %xmmN, (%rsp) */
     1333                o(0xd60f66);
     1334                o(0x04 + REG_VALUE(r)*8);
     1335                o(0x24);
     1336                break;
     1337
     1338            default:
     1339                assert(mode == x86_64_mode_integer);
     1340                /* simple type */
     1341                /* XXX: implicit cast ? */
     1342                r = gv(RC_INT);
     1343                orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
     1344                break;
     1345        }
     1346        args_size += size;
     1347
     1348        vpop();
     1349        --nb_args;
     1350        onstack++;
    9261351    }
    9271352
     
    9331358       may break these temporary registers. Let's use R10 and R11
    9341359       instead of them */
    935     gen_reg = nb_reg_args;
    936     sse_reg = nb_sse_args;
     1360    assert(gen_reg <= REGN);
     1361    assert(sse_reg <= 8);
    9371362    for(i = 0; i < nb_args; i++) {
    938         if ((vtop->type.t & VT_BTYPE) == VT_STRUCT ||
    939             (vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
    940         } else if (is_sse_float(vtop->type.t)) {
    941             int j = --sse_reg;
    942             if (j < 8) {
    943                 gv(RC_FLOAT); /* only one float register */
    944                 /* movaps %xmm0, %xmmN */
    945                 o(0x280f);
    946                 o(0xc0 + (sse_reg << 3));
    947             }
    948         } else {
    949             int j = --gen_reg;
     1363        mode = classify_x86_64_arg(&vtop->type, &type, &size, &align, &reg_count);
     1364        /* Alter stack entry type so that gv() knows how to treat it */
     1365        vtop->type = type;
     1366        if (mode == x86_64_mode_sse) {
     1367            if (reg_count == 2) {
     1368                sse_reg -= 2;
     1369                gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */
     1370                if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
     1371                    /* movaps %xmm0, %xmmN */
     1372                    o(0x280f);
     1373                    o(0xc0 + (sse_reg << 3));
     1374                    /* movaps %xmm1, %xmmN */
     1375                    o(0x280f);
     1376                    o(0xc1 + ((sse_reg+1) << 3));
     1377                }
     1378            } else {
     1379                assert(reg_count == 1);
     1380                --sse_reg;
     1381                /* Load directly to register */
     1382                gv(RC_XMM0 << sse_reg);
     1383            }
     1384        } else if (mode == x86_64_mode_integer) {
    9501385            /* simple type */
    9511386            /* XXX: implicit cast ? */
    952             if (j < REGN) {
    953                 int d = arg_regs[j];
    954                 r = gv(RC_INT);
    955                 if (j == 2 || j == 3)
    956                     /* j=2: r10, j=3: r11 */
    957                     d = j + 8;
    958                 orex(1,d,r,0x89); /* mov */
    959                 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
     1387            int d;
     1388            gen_reg -= reg_count;
     1389            r = gv(RC_INT);
     1390            d = arg_prepare_reg(gen_reg);
     1391            orex(1,d,r,0x89); /* mov */
     1392            o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
     1393            if (reg_count == 2) {
     1394                d = arg_prepare_reg(gen_reg+1);
     1395                orex(1,d,vtop->r2,0x89); /* mov */
     1396                o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
    9601397            }
    9611398        }
    9621399        vtop--;
    9631400    }
     1401    assert(gen_reg == 0);
     1402    assert(sse_reg == 0);
    9641403
    9651404    /* We shouldn't have many operands on the stack anymore, but the
     
    9771416    }
    9781417
    979     oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
     1418    if (vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
     1419        oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
    9801420    gcall_or_jmp(0);
    9811421    if (args_size)
     
    9951435void gfunc_prolog(CType *func_type)
    9961436{
    997     int i, addr, align, size;
    998     int param_index, param_addr, reg_param_index, sse_param_index;
     1437    X86_64_Mode mode;
     1438    int i, addr, align, size, reg_count;
     1439    int param_addr = 0, reg_param_index, sse_param_index;
    9991440    Sym *sym;
    10001441    CType *type;
     
    10071448    func_ret_sub = 0;
    10081449
    1009     if (func_type->ref->c == FUNC_ELLIPSIS) {
     1450    if (sym->f.func_type == FUNC_ELLIPSIS) {
    10101451        int seen_reg_num, seen_sse_num, seen_stack_size;
    10111452        seen_reg_num = seen_sse_num = 0;
     
    10161457        while ((sym = sym->next) != NULL) {
    10171458            type = &sym->type;
    1018             if (is_sse_float(type->t)) {
    1019                 if (seen_sse_num < 8) {
    1020                     seen_sse_num++;
    1021                 } else {
    1022                     seen_stack_size += 8;
    1023                 }
    1024             } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
    1025                 size = type_size(type, &align);
    1026                 size = (size + 7) & ~7;
    1027                 seen_stack_size += size;
    1028             } else if ((type->t & VT_BTYPE) == VT_LDOUBLE) {
    1029                 seen_stack_size += LDOUBLE_SIZE;
    1030             } else {
    1031                 if (seen_reg_num < REGN) {
    1032                     seen_reg_num++;
    1033                 } else {
    1034                     seen_stack_size += 8;
    1035                 }
     1459            mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
     1460            switch (mode) {
     1461            default:
     1462            stack_arg:
     1463                seen_stack_size = ((seen_stack_size + align - 1) & -align) + size;
     1464                break;
     1465               
     1466            case x86_64_mode_integer:
     1467                if (seen_reg_num + reg_count > REGN)
     1468                    goto stack_arg;
     1469                seen_reg_num += reg_count;
     1470                break;
     1471               
     1472            case x86_64_mode_sse:
     1473                if (seen_sse_num + reg_count > 8)
     1474                    goto stack_arg;
     1475                seen_sse_num += reg_count;
     1476                break;
    10361477            }
    10371478        }
     
    10511492        for (i = 0; i < 8; i++) {
    10521493            loc -= 16;
    1053             o(0xd60f66); /* movq */
    1054             gen_modrm(7 - i, VT_LOCAL, NULL, loc);
     1494            if (!tcc_state->nosse) {
     1495                o(0xd60f66); /* movq */
     1496                gen_modrm(7 - i, VT_LOCAL, NULL, loc);
     1497            }
    10551498            /* movq $0, loc+8(%rbp) */
    10561499            o(0x85c748);
     
    10641507
    10651508    sym = func_type->ref;
    1066     param_index = 0;
    10671509    reg_param_index = 0;
    10681510    sse_param_index = 0;
     
    10711513       implicit pointer parameter */
    10721514    func_vt = sym->type;
    1073     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
     1515    mode = classify_x86_64_arg(&func_vt, NULL, &size, &align, &reg_count);
     1516    if (mode == x86_64_mode_memory) {
    10741517        push_arg_reg(reg_param_index);
    1075         param_addr = loc;
    1076 
    10771518        func_vc = loc;
    1078         param_index++;
    10791519        reg_param_index++;
    10801520    }
     
    10821522    while ((sym = sym->next) != NULL) {
    10831523        type = &sym->type;
    1084         size = type_size(type, &align);
    1085         size = (size + 7) & ~7;
    1086         if (is_sse_float(type->t)) {
    1087             if (sse_param_index < 8) {
     1524        mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
     1525        switch (mode) {
     1526        case x86_64_mode_sse:
     1527            if (tcc_state->nosse)
     1528                tcc_error("SSE disabled but floating point arguments used");
     1529            if (sse_param_index + reg_count <= 8) {
    10881530                /* save arguments passed by register */
    1089                 loc -= 8;
    1090                 o(0xd60f66); /* movq */
    1091                 gen_modrm(sse_param_index, VT_LOCAL, NULL, loc);
     1531                loc -= reg_count * 8;
    10921532                param_addr = loc;
     1533                for (i = 0; i < reg_count; ++i) {
     1534                    o(0xd60f66); /* movq */
     1535                    gen_modrm(sse_param_index, VT_LOCAL, NULL, param_addr + i*8);
     1536                    ++sse_param_index;
     1537                }
    10931538            } else {
     1539                addr = (addr + align - 1) & -align;
    10941540                param_addr = addr;
    10951541                addr += size;
    10961542            }
    1097             sse_param_index++;
    1098 
    1099         } else if ((type->t & VT_BTYPE) == VT_STRUCT ||
    1100                    (type->t & VT_BTYPE) == VT_LDOUBLE) {
     1543            break;
     1544           
     1545        case x86_64_mode_memory:
     1546        case x86_64_mode_x87:
     1547            addr = (addr + align - 1) & -align;
    11011548            param_addr = addr;
    11021549            addr += size;
    1103         } else {
    1104             if (reg_param_index < REGN) {
     1550            break;
     1551           
     1552        case x86_64_mode_integer: {
     1553            if (reg_param_index + reg_count <= REGN) {
    11051554                /* save arguments passed by register */
    1106                 push_arg_reg(reg_param_index);
     1555                loc -= reg_count * 8;
    11071556                param_addr = loc;
     1557                for (i = 0; i < reg_count; ++i) {
     1558                    gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8);
     1559                    ++reg_param_index;
     1560                }
    11081561            } else {
     1562                addr = (addr + align - 1) & -align;
    11091563                param_addr = addr;
    1110                 addr += 8;
    1111             }
    1112             reg_param_index++;
     1564                addr += size;
     1565            }
     1566            break;
     1567        }
     1568        default: break; /* nothing to be done for x86_64_mode_none */
    11131569        }
    11141570        sym_push(sym->v & ~SYM_FIELD, type,
    11151571                 VT_LOCAL | VT_LVAL, param_addr);
    1116         param_index++;
    1117     }
     1572    }
     1573
     1574#ifdef CONFIG_TCC_BCHECK
     1575    /* leave some room for bound checking code */
     1576    if (tcc_state->do_bounds_check) {
     1577        func_bound_offset = lbounds_section->data_offset;
     1578        func_bound_ind = ind;
     1579        oad(0xb8, 0); /* lbound section pointer */
     1580        o(0xc78948);  /* mov  %rax,%rdi ## first arg in %rdi, this must be ptr */
     1581        oad(0xb8, 0); /* call to function */
     1582    }
     1583#endif
    11181584}
    11191585
     
    11231589    int v, saved_ind;
    11241590
     1591#ifdef CONFIG_TCC_BCHECK
     1592    if (tcc_state->do_bounds_check
     1593        && func_bound_offset != lbounds_section->data_offset)
     1594    {
     1595        addr_t saved_ind;
     1596        addr_t *bounds_ptr;
     1597        Sym *sym_data;
     1598
     1599        /* add end of table info */
     1600        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
     1601        *bounds_ptr = 0;
     1602
     1603        /* generate bound local allocation */
     1604        sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
     1605                               func_bound_offset, lbounds_section->data_offset);
     1606        saved_ind = ind;
     1607        ind = func_bound_ind;
     1608        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
     1609        ind = ind + 5 + 3;
     1610        gen_static_call(TOK___bound_local_new);
     1611        ind = saved_ind;
     1612
     1613        /* generate bound check local freeing */
     1614        o(0x5250); /* save returned value, if any */
     1615        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
     1616        oad(0xb8, 0); /* mov xxx, %rax */
     1617        o(0xc78948);  /* mov %rax,%rdi # first arg in %rdi, this must be ptr */
     1618        gen_static_call(TOK___bound_local_delete);
     1619        o(0x585a); /* restore returned value, if any */
     1620    }
     1621#endif
    11251622    o(0xc9); /* leave */
    11261623    if (func_ret_sub == 0) {
     
    11461643int gjmp(int t)
    11471644{
    1148     return psym(0xe9, t);
     1645    return gjmp2(0xe9, t);
    11491646}
    11501647
     
    11621659}
    11631660
     1661ST_FUNC void gtst_addr(int inv, int a)
     1662{
     1663    int v = vtop->r & VT_VALMASK;
     1664    if (v == VT_CMP) {
     1665        inv ^= (vtop--)->c.i;
     1666        a -= ind + 2;
     1667        if (a == (char)a) {
     1668            g(inv - 32);
     1669            g(a);
     1670        } else {
     1671            g(0x0f);
     1672            oad(inv - 16, a - 4);
     1673        }
     1674    } else if ((v & ~1) == VT_JMP) {
     1675        if ((v & 1) != inv) {
     1676            gjmp_addr(a);
     1677            gsym(vtop->c.i);
     1678        } else {
     1679            gsym(vtop->c.i);
     1680            o(0x05eb);
     1681            gjmp_addr(a);
     1682        }
     1683        vtop--;
     1684    }
     1685}
     1686
    11641687/* generate a test. set 'inv' to invert test. Stack entry is popped */
    1165 int gtst(int inv, int t)
    1166 {
    1167     int v, *p;
    1168 
    1169     v = vtop->r & VT_VALMASK;
    1170     if (v == VT_CMP) {
     1688ST_FUNC int gtst(int inv, int t)
     1689{
     1690    int v = vtop->r & VT_VALMASK;
     1691
     1692    if (nocode_wanted) {
     1693        ;
     1694    } else if (v == VT_CMP) {
    11711695        /* fast case : can jump directly since flags are set */
    11721696        if (vtop->c.i & 0x100)
     
    11801704               otherwise if unordered we don't want to jump.  */
    11811705            vtop->c.i &= ~0x100;
    1182             if (!inv == (vtop->c.i != TOK_NE))
     1706            if (inv == (vtop->c.i == TOK_NE))
    11831707              o(0x067a);  /* jp +6 */
    11841708            else
    11851709              {
    11861710                g(0x0f);
    1187                 t = psym(0x8a, t); /* jp t */
     1711                t = gjmp2(0x8a, t); /* jp t */
    11881712              }
    11891713          }
    11901714        g(0x0f);
    1191         t = psym((vtop->c.i - 16) ^ inv, t);
     1715        t = gjmp2((vtop->c.i - 16) ^ inv, t);
    11921716    } else if (v == VT_JMP || v == VT_JMPI) {
    11931717        /* && or || optimization */
    11941718        if ((v & 1) == inv) {
    11951719            /* insert vtop->c jump list in t */
    1196             p = &vtop->c.i;
    1197             while (*p != 0)
    1198                 p = (int *)(cur_text_section->data + *p);
    1199             *p = t;
    1200             t = vtop->c.i;
     1720            uint32_t n1, n = vtop->c.i;
     1721            if (n) {
     1722                while ((n1 = read32le(cur_text_section->data + n)))
     1723                    n = n1;
     1724                write32le(cur_text_section->data + n, t);
     1725                t = vtop->c.i;
     1726            }
    12011727        } else {
    12021728            t = gjmp(t);
    12031729            gsym(vtop->c.i);
    1204         }
    1205     } else {
    1206         if (is_float(vtop->type.t) ||
    1207             (vtop->type.t & VT_BTYPE) == VT_LLONG) {
    1208             vpushi(0);
    1209             gen_op(TOK_NE);
    1210         }
    1211         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    1212             /* constant jmp optimization */
    1213             if ((vtop->c.i != 0) != inv)
    1214                 t = gjmp(t);
    1215         } else {
    1216             v = gv(RC_INT);
    1217             orex(0,v,v,0x85);
    1218             o(0xc0 + REG_VALUE(v) * 9);
    1219             g(0x0f);
    1220             t = psym(0x85 ^ inv, t);
    12211730        }
    12221731    }
     
    12401749        opc = 0;
    12411750    gen_op8:
    1242         if (cc && (!ll || (int)vtop->c.ll == vtop->c.ll)) {
     1751        if (cc && (!ll || (int)vtop->c.i == vtop->c.i)) {
    12431752            /* constant case */
    12441753            vswap();
     
    13591868
    13601869/* generate a floating point operation 'v = t1 op t2' instruction. The
    1361    two operands are guaranted to have the same floating point type */
     1870   two operands are guaranteed to have the same floating point type */
    13621871/* XXX: need to use ST1 too */
    13631872void gen_opf(int op)
     
    14011910            if (swapped)
    14021911                o(0xc9d9); /* fxch %st(1) */
    1403             o(0xe9da); /* fucompp */
     1912            if (op == TOK_EQ || op == TOK_NE)
     1913                o(0xe9da); /* fucompp */
     1914            else
     1915                o(0xd9de); /* fcompp */
    14041916            o(0xe0df); /* fnstsw %ax */
    14051917            if (op == TOK_EQ) {
     
    14451957            }
    14461958            ft = vtop->type.t;
    1447             fc = vtop->c.ul;
     1959            fc = vtop->c.i;
    14481960            o(0xde); /* fxxxp %st, %st(1) */
    14491961            o(0xc1 + (a << 3));
     
    14541966            /* if saved lvalue, then we must reload it */
    14551967            r = vtop->r;
    1456             fc = vtop->c.ul;
     1968            fc = vtop->c.i;
    14571969            if ((r & VT_VALMASK) == VT_LLOCAL) {
    14581970                SValue v1;
     
    14601972                v1.type.t = VT_PTR;
    14611973                v1.r = VT_LOCAL | VT_LVAL;
    1462                 v1.c.ul = fc;
     1974                v1.c.i = fc;
    14631975                load(r, &v1);
    14641976                fc = 0;
     
    14781990
    14791991            if (swapped) {
    1480                 o(0x7e0ff3); /* movq */
    1481                 gen_modrm(1, r, vtop->sym, fc);
    1482 
    1483                 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
    1484                     o(0x66);
    1485                 }
    1486                 o(0x2e0f); /* ucomisd %xmm0, %xmm1 */
    1487                 o(0xc8);
     1992                gv(RC_FLOAT);
     1993                vswap();
     1994            }
     1995            assert(!(vtop[-1].r & VT_LVAL));
     1996           
     1997            if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
     1998                o(0x66);
     1999            if (op == TOK_EQ || op == TOK_NE)
     2000                o(0x2e0f); /* ucomisd */
     2001            else
     2002                o(0x2f0f); /* comisd */
     2003
     2004            if (vtop->r & VT_LVAL) {
     2005                gen_modrm(vtop[-1].r, r, vtop->sym, fc);
    14882006            } else {
    1489                 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
    1490                     o(0x66);
    1491                 }
    1492                 o(0x2e0f); /* ucomisd */
    1493                 gen_modrm(0, r, vtop->sym, fc);
     2007                o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
    14942008            }
    14952009
     
    14982012            vtop->c.i = op | 0x100;
    14992013        } else {
    1500             /* no memory reference possible for long double operations */
    1501             if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
    1502                 load(TREG_XMM0, vtop);
    1503                 swapped = !swapped;
    1504             }
     2014            assert((vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
    15052015            switch(op) {
    15062016            default:
     
    15192029            }
    15202030            ft = vtop->type.t;
    1521             fc = vtop->c.ul;
    1522             if ((ft & VT_BTYPE) == VT_LDOUBLE) {
    1523                 o(0xde); /* fxxxp %st, %st(1) */
    1524                 o(0xc1 + (a << 3));
     2031            fc = vtop->c.i;
     2032            assert((ft & VT_BTYPE) != VT_LDOUBLE);
     2033           
     2034            r = vtop->r;
     2035            /* if saved lvalue, then we must reload it */
     2036            if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
     2037                SValue v1;
     2038                r = get_reg(RC_INT);
     2039                v1.type.t = VT_PTR;
     2040                v1.r = VT_LOCAL | VT_LVAL;
     2041                v1.c.i = fc;
     2042                load(r, &v1);
     2043                fc = 0;
     2044            }
     2045           
     2046            assert(!(vtop[-1].r & VT_LVAL));
     2047            if (swapped) {
     2048                assert(vtop->r & VT_LVAL);
     2049                gv(RC_FLOAT);
     2050                vswap();
     2051            }
     2052           
     2053            if ((ft & VT_BTYPE) == VT_DOUBLE) {
     2054                o(0xf2);
    15252055            } else {
    1526                 /* if saved lvalue, then we must reload it */
    1527                 r = vtop->r;
    1528                 if ((r & VT_VALMASK) == VT_LLOCAL) {
    1529                     SValue v1;
    1530                     r = get_reg(RC_INT);
    1531                     v1.type.t = VT_PTR;
    1532                     v1.r = VT_LOCAL | VT_LVAL;
    1533                     v1.c.ul = fc;
    1534                     load(r, &v1);
    1535                     fc = 0;
    1536                 }
    1537                 if (swapped) {
    1538                     /* movq %xmm0,%xmm1 */
    1539                     o(0x7e0ff3);
    1540                     o(0xc8);
    1541                     load(TREG_XMM0, vtop);
    1542                     /* subsd  %xmm1,%xmm0 (f2 0f 5c c1) */
    1543                     if ((ft & VT_BTYPE) == VT_DOUBLE) {
    1544                         o(0xf2);
    1545                     } else {
    1546                         o(0xf3);
    1547                     }
    1548                     o(0x0f);
    1549                     o(0x58 + a);
    1550                     o(0xc1);
    1551                 } else {
    1552                     if ((ft & VT_BTYPE) == VT_DOUBLE) {
    1553                         o(0xf2);
    1554                     } else {
    1555                         o(0xf3);
    1556                     }
    1557                     o(0x0f);
    1558                     o(0x58 + a);
    1559                     gen_modrm(0, r, vtop->sym, fc);
    1560                 }
    1561             }
     2056                o(0xf3);
     2057            }
     2058            o(0x0f);
     2059            o(0x58 + a);
     2060           
     2061            if (vtop->r & VT_LVAL) {
     2062                gen_modrm(vtop[-1].r, r, vtop->sym, fc);
     2063            } else {
     2064                o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
     2065            }
     2066
    15622067            vtop--;
    15632068        }
     
    15942099        vtop->r = TREG_ST0;
    15952100    } else {
    1596         save_reg(TREG_XMM0);
     2101        int r = get_reg(RC_FLOAT);
    15972102        gv(RC_INT);
    1598         o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT));
     2103        o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0));
    15992104        if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
    16002105            (VT_INT | VT_UNSIGNED) ||
     
    16032108        }
    16042109        o(0x2a0f);
    1605         o(0xc0 + (vtop->r & VT_VALMASK)); /* cvtsi2sd */
    1606         vtop->r = TREG_XMM0;
     2110        o(0xc0 + (vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
     2111        vtop->r = r;
    16072112    }
    16082113}
     
    16162121    bt = ft & VT_BTYPE;
    16172122    tbt = t & VT_BTYPE;
    1618 
     2123   
    16192124    if (bt == VT_FLOAT) {
    16202125        gv(RC_FLOAT);
    16212126        if (tbt == VT_DOUBLE) {
    1622             o(0xc0140f); /* unpcklps */
    1623             o(0xc05a0f); /* cvtps2pd */
     2127            o(0x140f); /* unpcklps */
     2128            o(0xc0 + REG_VALUE(vtop->r)*9);
     2129            o(0x5a0f); /* cvtps2pd */
     2130            o(0xc0 + REG_VALUE(vtop->r)*9);
    16242131        } else if (tbt == VT_LDOUBLE) {
     2132            save_reg(RC_ST0);
    16252133            /* movss %xmm0,-0x10(%rsp) */
    1626             o(0x44110ff3);
     2134            o(0x110ff3);
     2135            o(0x44 + REG_VALUE(vtop->r)*8);
    16272136            o(0xf024);
    16282137            o(0xf02444d9); /* flds -0x10(%rsp) */
     
    16322141        gv(RC_FLOAT);
    16332142        if (tbt == VT_FLOAT) {
    1634             o(0xc0140f66); /* unpcklpd */
    1635             o(0xc05a0f66); /* cvtpd2ps */
     2143            o(0x140f66); /* unpcklpd */
     2144            o(0xc0 + REG_VALUE(vtop->r)*9);
     2145            o(0x5a0f66); /* cvtpd2ps */
     2146            o(0xc0 + REG_VALUE(vtop->r)*9);
    16362147        } else if (tbt == VT_LDOUBLE) {
     2148            save_reg(RC_ST0);
    16372149            /* movsd %xmm0,-0x10(%rsp) */
    1638             o(0x44110ff2);
     2150            o(0x110ff2);
     2151            o(0x44 + REG_VALUE(vtop->r)*8);
    16392152            o(0xf024);
    16402153            o(0xf02444dd); /* fldl -0x10(%rsp) */
     
    16422155        }
    16432156    } else {
     2157        int r;
    16442158        gv(RC_ST0);
     2159        r = get_reg(RC_FLOAT);
    16452160        if (tbt == VT_DOUBLE) {
    16462161            o(0xf0245cdd); /* fstpl -0x10(%rsp) */
    16472162            /* movsd -0x10(%rsp),%xmm0 */
    1648             o(0x44100ff2);
     2163            o(0x100ff2);
     2164            o(0x44 + REG_VALUE(r)*8);
    16492165            o(0xf024);
    1650             vtop->r = TREG_XMM0;
     2166            vtop->r = r;
    16512167        } else if (tbt == VT_FLOAT) {
    16522168            o(0xf0245cd9); /* fstps -0x10(%rsp) */
    16532169            /* movss -0x10(%rsp),%xmm0 */
    1654             o(0x44100ff3);
     2170            o(0x100ff3);
     2171            o(0x44 + REG_VALUE(r)*8);
    16552172            o(0xf024);
    1656             vtop->r = TREG_XMM0;
     2173            vtop->r = r;
    16572174        }
    16582175    }
     
    16852202    }
    16862203    orex(size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */
    1687     o(0xc0 + (REG_VALUE(r) << 3));
     2204    o(0xc0 + REG_VALUE(vtop->r) + REG_VALUE(r)*8);
    16882205    vtop->r = r;
    16892206}
     
    16952212    vtop--;
    16962213}
     2214
     2215/* Save the stack pointer onto the stack and return the location of its address */
     2216ST_FUNC void gen_vla_sp_save(int addr) {
     2217    /* mov %rsp,addr(%rbp)*/
     2218    gen_modrm64(0x89, TREG_RSP, VT_LOCAL, NULL, addr);
     2219}
     2220
     2221/* Restore the SP from a location on the stack */
     2222ST_FUNC void gen_vla_sp_restore(int addr) {
     2223    gen_modrm64(0x8b, TREG_RSP, VT_LOCAL, NULL, addr);
     2224}
     2225
     2226#ifdef TCC_TARGET_PE
     2227/* Save result of gen_vla_alloc onto the stack */
     2228ST_FUNC void gen_vla_result(int addr) {
     2229    /* mov %rax,addr(%rbp)*/
     2230    gen_modrm64(0x89, TREG_RAX, VT_LOCAL, NULL, addr);
     2231}
     2232#endif
     2233
     2234/* Subtract from the stack pointer, and push the resulting value onto the stack */
     2235ST_FUNC void gen_vla_alloc(CType *type, int align) {
     2236#ifdef TCC_TARGET_PE
     2237    /* alloca does more than just adjust %rsp on Windows */
     2238    vpush_global_sym(&func_old_type, TOK_alloca);
     2239    vswap(); /* Move alloca ref past allocation size */
     2240    gfunc_call(1);
     2241#else
     2242    int r;
     2243    r = gv(RC_INT); /* allocation size */
     2244    /* sub r,%rsp */
     2245    o(0x2b48);
     2246    o(0xe0 | REG_VALUE(r));
     2247    /* We align to 16 bytes rather than align */
     2248    /* and ~15, %rsp */
     2249    o(0xf0e48348);
     2250    vpop();
     2251#endif
     2252}
     2253
    16972254
    16982255/* end of x86-64 code generator */
Note: See TracChangeset for help on using the changeset viewer.