From ff35d0f11a9a8b46e64a9aed52908b2cf040c7e8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 24 Jan 2014 11:58:30 -0600 Subject: [PATCH] Add a patch to work around the bug in the ZDS-II 5.0.1 toolchain --- configs/16z/README.txt | 147 ++++++---------- configs/16z/nsh/README.txt | 11 +- configs/16z/nsh/setenv.sh | 18 +- configs/16z/ostest/README.txt | 6 + configs/16z/ostest/setenv.sh | 18 +- configs/16z/tools/dopatch.sh | 59 +++++++ .../zneo-zdsii-5_0_1-variadic-func-fix.patch | 159 ++++++++++++++++++ configs/z16f2800100zcog/README.txt | 139 +++++---------- configs/z16f2800100zcog/nsh/README.txt | 9 +- configs/z16f2800100zcog/nsh/setenv.sh | 18 +- configs/z16f2800100zcog/ostest/README.txt | 6 + configs/z16f2800100zcog/ostest/setenv.sh | 20 ++- configs/z16f2800100zcog/pashello/setenv.sh | 20 ++- configs/z16f2800100zcog/tools/dopatch.sh | 59 +++++++ .../zneo-zdsii-5_0_1-variadic-func-fix.patch | 159 ++++++++++++++++++ 15 files changed, 606 insertions(+), 242 deletions(-) create mode 100755 configs/16z/tools/dopatch.sh create mode 100644 configs/16z/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch create mode 100755 configs/z16f2800100zcog/tools/dopatch.sh create mode 100644 configs/z16f2800100zcog/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch diff --git a/configs/16z/README.txt b/configs/16z/README.txt index 4f9d2d397e..d0b73201e0 100644 --- a/configs/16z/README.txt +++ b/configs/16z/README.txt @@ -10,6 +10,7 @@ Contents - GPIO Configuration - ZDS-II Compiler Versions + - Patches - Serial Console - LEDs - RAM @@ -128,6 +129,40 @@ Other Versions two files: (1) configs/16z/*/setenv.sh and (2) configs/16z/*/Make.defs. Simply edit these two files, changing 5.0.1 to whatever. +Patches +======= + +A bug has been found in the ZDS-II toolchain version 5.0.1. a patch is +available to work around the bug. A summary of the nature the bug and +instructions for applying the patch follow. + +Parameters are passed different to variadic functions (i.e., functions +that accept a varying number of parameters) than to regular functions. For +most functions, parameters are passed in registers, beginning with R1. But +for variadic functions, all parameters must be passed on the stack. + +The logic works correctly for global functions, local functions, and most +function pointers. It does not work correctly for the case where a variadic +function point is included within a structure. In that case, the caller +inappropriately passes the parameters in registers; the receiver will +attempt to recover the parameters from the stack and a failure then follows. + +This bug prevents the use of NSH with the ZNEO. However, a patch has been +developed that works around the problem. That patch can be found at +configs/16z/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch. In that +directory is also a bash script that will apply that patch for you. + +The patch would be applied when NuttX is configured as follows: + + cd tools + ./configure.sh 16z/nsh + cd .. + . ./setenv.sh + dopath.sh $PWD + make + +See the section "Selecting Configurations" below. + Serial Console ============== @@ -186,7 +221,9 @@ To configure any specific configuration, do the following steps: make Where is the specific board configuration that you wish to -build. The following board-specific configurations are available. +build. The following board-specific configurations are available. You may +also need to apply a path to NuttX before making. Please refer the the +section "Patches" above" Before entering the make command, make certain that the path to the ZNEO compiler is in you PATH variable. You make modify and use the setenv.sh @@ -197,7 +234,6 @@ before making like: . ./setenv.sh make - Configuration Sub-directories ============================= @@ -249,106 +285,12 @@ nsh for the ostest configuration.. STATUS: - Currently, NSH failes nsh_consoleoutput(). Here is an example. - This echo command causes the system to hang: - nsh> echo abc + 1. Note that you must apply the ZNEO patch if you are using ZDS-II 5.0.1. + See the README.txt file in the parent directory for more information. - Below is some annotated output from the debugger. Here is the 30,000 ft view: - - - cmd_echo loops for each argv[i], 1 >=i > argc. - - - It calls: - - vtbl->output(vtbl, "%s ", argv[i]) - - where the prototype for output is: - - int (*output)(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...); - - - vtbl->output maps to nsh_consoleoutput() in this case. - - - cmd_echo passes all of the arguments to output in registers. - - - nsh_consoleoutput expects all of the parameters on the stack. - - - nsh_console calls vfprintf() using bad values from the stack. - - - vfprintf crashes and never returns. - - Looks like a compiler bug to me. - - # int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) - # - # All input parameters are in registers - # - # R1=00802DA0 # vtbl - # R2=00000002 # argc - # R3=00802D15 # argv - # # argv[0]=00802DD7 - # # argv[1]=00802DDC - # # 00802DD7="echo\0abc\0" - # SP=00802CDD - - 0001024C 05F0 PUSHMHI # SP=00802CCD - 0001024E 4418 LD R8,R1 # R8=00802DA0 vtbl - 00010250 442A LD R10,R2 # R10=00000002 argc - 00010252 443B LD R11,R3 # R11=00802D15 argv - 00010254 3901 LD R9,#%1 # R9=00000001 arg index - 00010256 C00C JP %10270 - - 00010270 A5A9 CP R9,R10 # Bottom of loop - 00010272 E1F2 JP lt,%10258 - - 00010258 48840010 LD R4,%10(R8) # R4=00011156 adddress of output() method - 0001025C 4490 LD R0,R9 # R0=00000001 Index of argv[1] - 0001025E BC20 SLL R0,#%2 # R0=00000004 Offset to argv[1] - 00010260 A0B0 ADD R0,R11 # R0=00802D19 Address of argv[1] - 00010262 4481 LD R1,R8 # R1=00802DA0 vtbl address - 00010264 452200008ADB LD R2,#%8ADB # R2=00008ADB = "%s " - 0001026A 1203 LD R3,(R0) # R3=00802DDC Value of argv[1] - 0001026C F214 CALL (R4) # Call vtbl->output(vtbl, "%s ", argv[i]); - # vtbl->output is nsh_consoleoutput - - # static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...) - # - # All parameters are in registers: - # - # R1=00802DA0 vtbl address - # R2=00008ADB "%s " - # R3=00802DDC Value of argv[1] - - # First is a check if the output file is open - # - # if (nsh_openifnotopen(pstate) != 0) - # { - # return ERROR; - # } - - 00011156 0800 LINK #%0 # SP=00802CC9, R14=00802CC9 - 00011158 5C81 LD R1,%8(FP) # R1=0000017F Should be value file FILE * for output - 0001115A DF96 CALL %11088 # Call nsh_openifnotopen(), returns R0=00000000 - 0001115C 9000 CP R0,#%0 - 0001115E E602 JP z,%11164 # Skip over error return - - 00011160 30FF LD R0,#-%1 - 00011162 C007 JP %11172 - - # Then the failing call to vfprintf: - # - # va_start(ap, fmt); - # ret = vfprintf(pstate->cn_outstream, fmt, ap); - # va_end(ap); - # - # return ret; - - 00011164 4D03 LEA R3,%10(FP) # R3=00802CD5 ap=GARBAGE - 00011166 5C80 LD R0,%8(FP) # R0=0000017F Should be value of pstate - 00011168 48010033 LD R1,%33(R0) # R1=01000000 pstate->cn_outstream. Looks suspicious - 0001116C 5CC2 LD R2,%C(FP) # R2=00802DA0 - 0001116E F10003FB CALL %11968 # Call vfprintf(01000000, 00802DA0, 00802CD5) - # All arguments are bad - # Does not survive call to vfprintf + 2. This configuration does not run correctly. There is currently a + problem with the SRAM accesses. ostest ------ @@ -398,4 +340,9 @@ ostest trailing bad characters are manually eliminated, then the build will succeed on the next try. + STATUS: + + 1. This configuration does not run correctly. There is currently a + problem with the SRAM accesses. + Check out any README.txt files in these s. diff --git a/configs/16z/nsh/README.txt b/configs/16z/nsh/README.txt index 8280f98015..b772f43a91 100644 --- a/configs/16z/nsh/README.txt +++ b/configs/16z/nsh/README.txt @@ -39,11 +39,12 @@ Interaction with NSH is via the serial console at 57600 8N1 baud. STATUS ------ -1. This configuration does not run correctly. There is a problem with the - serial driver. When started, some garbled characters appear on the - console. I suspect (a) the UART is not being configured correctly, and - (2) UART interrupts are not be set up correctly. +1. Note that you must apply the ZNEO patch if you are using ZDS-II 5.0.1. + See the README.txt file in the parent directory for more information. -2. I bet that this code, like ostest, will not run if started by a hardware +2. This configuration does not run correctly. There is currently a problem + with the SRAM accesses. + +3. I bet that this code, like ostest, will not run if started by a hardware reset. It may only run when started via the debugger. diff --git a/configs/16z/nsh/setenv.sh b/configs/16z/nsh/setenv.sh index 5f7d583142..462be15d68 100755 --- a/configs/16z/nsh/setenv.sh +++ b/configs/16z/nsh/setenv.sh @@ -50,15 +50,21 @@ if [ -z "${PATH_ORIG}" ]; then fi # -# This is the Cygwin path to location where the XDS-II tools were installed +# This is the Cygwin path to location where the ZDS-II tools were installed # TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/ZiLOG/ZDSII_ZNEO_5.0.1/bin" # -# Add the path to the toolchain to the PATH variable. NOTE that /bin and /usr/bin -# preceded the toolchain bin directory. This is because the ZDSII bin directory -# includes binaries like make.exe that will interfere with the normal build process -# if we do not give priority to the versions at /bin and /usr/bin. +# This is the path to the 16z tool directory # -export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" +TOOL_DIR="${WD}/configs/16z/tools" + +# +# Add the path to the toolchain and tool directory to the PATH variable. NOTE +# that /bin and /usr/bin preceded the toolchain bin directory. This is because +# the ZDSII bin directory includes binaries like make.exe that will interfere +# with the normal build process if we do not give priority to the versions at +# /bin and /usr/bin. +# +export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:${TOOL_DIR}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/configs/16z/ostest/README.txt b/configs/16z/ostest/README.txt index fc5e36fead..1116dabc12 100644 --- a/configs/16z/ostest/README.txt +++ b/configs/16z/ostest/README.txt @@ -31,3 +31,9 @@ Console Output -------------- OS test results will be provided on the serial console at 57600 8N1 baud. + +STATUS +------ + +1. This configuration does not run correctly. There is currently a problem + with the SRAM accesses. diff --git a/configs/16z/ostest/setenv.sh b/configs/16z/ostest/setenv.sh index 8187b38860..a989dcdcef 100755 --- a/configs/16z/ostest/setenv.sh +++ b/configs/16z/ostest/setenv.sh @@ -49,15 +49,21 @@ if [ -z "${PATH_ORIG}" ]; then fi # -# This is the Cygwin path to location where the XDS-II tools were installed +# This is the Cygwin path to location where the ZDS-II tools were installed # TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/ZiLOG/ZDSII_ZNEO_5.0.1/bin" # -# Add the path to the toolchain to the PATH variable. NOTE that /bin and /usr/bin -# preceded the toolchain bin directory. This is because the ZDSII bin directory -# includes binaries like make.exe that will interfere with the normal build process -# if we do not give priority to the versions at /bin and /usr/bin. +# This is the path to the 16z tool directory # -export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" +TOOL_DIR="${WD}/configs/16z/tools" + +# +# Add the path to the toolchain and tool directory to the PATH variable. NOTE +# that /bin and /usr/bin preceded the toolchain bin directory. This is because +# the ZDSII bin directory includes binaries like make.exe that will interfere +# with the normal build process if we do not give priority to the versions at +# /bin and /usr/bin. +# +export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:${TOOL_DIR}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/configs/16z/tools/dopatch.sh b/configs/16z/tools/dopatch.sh new file mode 100755 index 0000000000..5eaa8b881d --- /dev/null +++ b/configs/16z/tools/dopatch.sh @@ -0,0 +1,59 @@ +#!/bin/sh +############################################################################ +# configs/16z/tools/dopatch.sh +# +# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +USAGE="${0} \$PWD" +WD=`pwd` +TOOLDIR=${WD}/configs/16z/tools +ME=${TOOLDIR}/dopatch.sh +PATCH=${TOOLDIR}/zneo-zdsii-5_0_1-variadic-func-fix.patch + +if [ ! -x ${ME} ]; then + echo "ERROR: This script must be executed from the top-level NuttX directory" + echo ${USAGE} + exit 1 +fi + +if [ ! -r ${PATCH} ]; then + echo "ERROR: Readable patch not found at ${PATCH}" + echo ${USAGE} + exit 1 +fi + +cd .. || \ + { echo "ERROR: failed to CD to the parent directory"; exit 1; } + +cat ${PATCH} | patch -p1 || \ + { echo "ERROR: patch failed" ; exit 1; } diff --git a/configs/16z/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch b/configs/16z/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch new file mode 100644 index 0000000000..b1464f340b --- /dev/null +++ b/configs/16z/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch @@ -0,0 +1,159 @@ +diff --git a/apps/nshlib/nsh_console.c b/apps/nshlib/nsh_console.c +index ba7dbe7..b9f9991 100644 +--- a/apps/nshlib/nsh_console.c ++++ b/apps/nshlib/nsh_console.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -79,8 +80,13 @@ static FAR struct nsh_vtbl_s *nsh_consoleclone(FAR struct nsh_vtbl_s *vtbl); + static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl); + static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, + FAR const void *buffer, size_t nbytes); ++#if 0 + static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, + FAR const char *fmt, ...); ++#else ++static int nsh_consolevoutput(FAR struct nsh_vtbl_s *vtbl, ++ FAR const char *fmt, va_list ap); ++#endif + static FAR char *nsh_consolelinebuffer(FAR struct nsh_vtbl_s *vtbl); + + #if CONFIG_NFILE_DESCRIPTORS > 0 +@@ -213,6 +219,7 @@ static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buf + * + ****************************************************************************/ + ++#if 0 + static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, + FAR const char *fmt, ...) + { +@@ -263,6 +270,51 @@ static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, + #endif + } + ++#else ++static int nsh_consolevoutput(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, va_list ap) ++{ ++#if CONFIG_NFILE_DESCRIPTORS > 0 ++ FAR struct console_stdio_s *pstate = (FAR struct console_stdio_s *)vtbl; ++ int ret; ++ ++ /* The stream is open in a lazy fashion. This is done because the file ++ * descriptor may be opened on a different task than the stream. The ++ * actual open will then occur with the first output from the new task. ++ */ ++ ++ if (nsh_openifnotopen(pstate) != 0) ++ { ++ return ERROR; ++ } ++ ++ ret = vfprintf(pstate->cn_outstream, fmt, ap); ++ ++ return ret; ++#else ++ char *str; ++ ++ /* Use avsprintf() to allocate a buffer and fill it with the formatted ++ * data ++ */ ++ ++ str = NULL; ++ (void)avsprintf(&str, fmt, ap); ++ ++ /* Was a string allocated? */ ++ ++ if (str) ++ { ++ /* Yes.. Print then free the allocated string */ ++ ++ printf("%s", str); ++ free(str); ++ } ++ ++ return 0; ++#endif ++} ++#endif ++ + /**************************************************************************** + * Name: nsh_consolelinebuffer + * +@@ -452,7 +504,11 @@ FAR struct console_stdio_s *nsh_newconsole(void) + pstate->cn_vtbl.release = nsh_consolerelease; + #endif + pstate->cn_vtbl.write = nsh_consolewrite; ++#if 0 + pstate->cn_vtbl.output = nsh_consoleoutput; ++#else ++ pstate->cn_vtbl.voutput = nsh_consolevoutput; ++#endif + pstate->cn_vtbl.linebuffer = nsh_consolelinebuffer; + pstate->cn_vtbl.exit = nsh_consoleexit; + +@@ -489,3 +545,15 @@ FAR struct console_stdio_s *nsh_newconsole(void) + } + return pstate; + } ++ ++int nsh_output(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, ...) ++{ ++ va_list ap; ++ int ret; ++ ++ va_start(ap, fmt); ++ ret = vtbl->voutput(vtbl, fmt, ap); ++ va_end(ap); ++ ++ return ret; ++} +diff --git a/apps/nshlib/nsh_console.h b/apps/nshlib/nsh_console.h +index c78362f..59bd8d7 100644 +--- a/apps/nshlib/nsh_console.h ++++ b/apps/nshlib/nsh_console.h +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + #include + + /**************************************************************************** +@@ -62,11 +63,13 @@ + #define nsh_undirect(v,s) (v)->undirect(v,s) + #define nsh_exit(v,s) (v)->exit(v,s) + ++#if 0 + #ifdef CONFIG_CPP_HAVE_VARARGS + # define nsh_output(v, fmt...) (v)->output(v, ##fmt) + #else + # define nsh_output vtbl->output + #endif ++#endif + + /* Size of info to be saved in call to nsh_redirect */ + +@@ -107,7 +110,11 @@ struct nsh_vtbl_s + void (*release)(FAR struct nsh_vtbl_s *vtbl); + #endif + ssize_t (*write)(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes); ++#if 0 + int (*output)(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, ...); ++#else ++ int (*voutput)(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, va_list ap); ++#endif + FAR char *(*linebuffer)(FAR struct nsh_vtbl_s *vtbl); + #if CONFIG_NFILE_DESCRIPTORS > 0 + void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save); +@@ -159,5 +166,6 @@ struct console_stdio_s + /* Defined in nsh_console.c *************************************************/ + + FAR struct console_stdio_s *nsh_newconsole(void); ++int nsh_output(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, ...); + + #endif /* __APPS_NSHLIB_NSH_CONSOLE_H */ diff --git a/configs/z16f2800100zcog/README.txt b/configs/z16f2800100zcog/README.txt index a71d26975a..d0a93a0462 100644 --- a/configs/z16f2800100zcog/README.txt +++ b/configs/z16f2800100zcog/README.txt @@ -53,6 +53,40 @@ Other Versions configs/z16f2800100zcog/*/Make.defs. Simply edit these two files, changing 5.0.1 to whatever. +Patches +======= + +A bug has been found in the ZDS-II toolchain version 5.0.1. a patch is +available to work around the bug. A summary of the nature the bug and +instructions for applying the patch follow. + +Parameters are passed different to variadic functions (i.e., functions +that accept a varying number of parameters) than to regular functions. For +most functions, parameters are passed in registers, beginning with R1. But +for variadic functions, all parameters must be passed on the stack. + +The logic works correctly for global functions, local functions, and most +function pointers. It does not work correctly for the case where a variadic +function point is included within a structure. In that case, the caller +inappropriately passes the parameters in registers; the receiver will +attempt to recover the parameters from the stack and a failure then follows. + +This bug prevents the use of NSH with the ZNEO. However, a patch has been +developed that works around the problem. That patch can be found at +configs/z16f2800100zcog/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch. In +that directory is also a bash script that will apply that patch for you. + +The patch would be applied when NuttX is configured as follows: + + cd tools + ./configure.sh z16f2800100zcog/nsh + cd .. + . ./setenv.sh + dopath.sh $PWD + make + +See the section "Selecting Configurations" below. + Selecting Configurations ======================== @@ -67,7 +101,8 @@ following steps: Where is the specific board configuration that you wish to build. The following board-specific configurations are -available. +available. You may also need to apply a path to NuttX before making. +Please refer the the section "Patches" above" Configuration Sub-directories ============================= @@ -121,106 +156,10 @@ nsh for the ostest configuration.. STATUS: - Currently, NSH failes nsh_consoleoutput(). Here is an example. - This echo command causes the system to hang: - nsh> echo abc - - Below is some annotated output from the debugger. Here is the 30,000 ft view: - - - cmd_echo loops for each argv[i], 1 >=i > argc. - - - It calls: - - vtbl->output(vtbl, "%s ", argv[i]) - - where the prototype for output is: - - int (*output)(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...); - - - vtbl->output maps to nsh_consoleoutput() in this case. - - - cmd_echo passes all of the arguments to output in registers. - - - nsh_consoleoutput expects all of the parameters on the stack. - - - nsh_console calls vfprintf() using bad values from the stack. - - - vfprintf crashes and never returns. - - Looks like a compiler bug to me. - - # int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) - # - # All input parameters are in registers - # - # R1=00802DA0 # vtbl - # R2=00000002 # argc - # R3=00802D15 # argv - # # argv[0]=00802DD7 - # # argv[1]=00802DDC - # # 00802DD7="echo\0abc\0" - # SP=00802CDD - - 0001024C 05F0 PUSHMHI # SP=00802CCD - 0001024E 4418 LD R8,R1 # R8=00802DA0 vtbl - 00010250 442A LD R10,R2 # R10=00000002 argc - 00010252 443B LD R11,R3 # R11=00802D15 argv - 00010254 3901 LD R9,#%1 # R9=00000001 arg index - 00010256 C00C JP %10270 - - 00010270 A5A9 CP R9,R10 # Bottom of loop - 00010272 E1F2 JP lt,%10258 - - 00010258 48840010 LD R4,%10(R8) # R4=00011156 adddress of output() method - 0001025C 4490 LD R0,R9 # R0=00000001 Index of argv[1] - 0001025E BC20 SLL R0,#%2 # R0=00000004 Offset to argv[1] - 00010260 A0B0 ADD R0,R11 # R0=00802D19 Address of argv[1] - 00010262 4481 LD R1,R8 # R1=00802DA0 vtbl address - 00010264 452200008ADB LD R2,#%8ADB # R2=00008ADB = "%s " - 0001026A 1203 LD R3,(R0) # R3=00802DDC Value of argv[1] - 0001026C F214 CALL (R4) # Call vtbl->output(vtbl, "%s ", argv[i]); - # vtbl->output is nsh_consoleoutput - - # static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...) - # - # All parameters are in registers: - # - # R1=00802DA0 vtbl address - # R2=00008ADB "%s " - # R3=00802DDC Value of argv[1] - - # First is a check if the output file is open - # - # if (nsh_openifnotopen(pstate) != 0) - # { - # return ERROR; - # } - - 00011156 0800 LINK #%0 # SP=00802CC9, R14=00802CC9 - 00011158 5C81 LD R1,%8(FP) # R1=0000017F Should be value file FILE * for output - 0001115A DF96 CALL %11088 # Call nsh_openifnotopen(), returns R0=00000000 - 0001115C 9000 CP R0,#%0 - 0001115E E602 JP z,%11164 # Skip over error return - - 00011160 30FF LD R0,#-%1 - 00011162 C007 JP %11172 - - # Then the failing call to vfprintf: - # - # va_start(ap, fmt); - # ret = vfprintf(pstate->cn_outstream, fmt, ap); - # va_end(ap); - # - # return ret; - - 00011164 4D03 LEA R3,%10(FP) # R3=00802CD5 ap=GARBAGE - 00011166 5C80 LD R0,%8(FP) # R0=0000017F Should be value of pstate - 00011168 48010033 LD R1,%33(R0) # R1=01000000 pstate->cn_outstream. Looks suspicious - 0001116C 5CC2 LD R2,%C(FP) # R2=00802DA0 - 0001116E F10003FB CALL %11968 # Call vfprintf(01000000, 00802DA0, 00802CD5) - # All arguments are bad - # Does not survive call to vfprintf + 1. Note that you must apply the ZNEO patch if you are using ZDS-II 5.0.1. + See the README.txt file in the parent directory for more information. + The configuration will run correctly with the patch applied. ostest ------ diff --git a/configs/z16f2800100zcog/nsh/README.txt b/configs/z16f2800100zcog/nsh/README.txt index 8280f98015..009dd146ca 100644 --- a/configs/z16f2800100zcog/nsh/README.txt +++ b/configs/z16f2800100zcog/nsh/README.txt @@ -39,11 +39,10 @@ Interaction with NSH is via the serial console at 57600 8N1 baud. STATUS ------ -1. This configuration does not run correctly. There is a problem with the - serial driver. When started, some garbled characters appear on the - console. I suspect (a) the UART is not being configured correctly, and - (2) UART interrupts are not be set up correctly. + +1. Note that you must apply the ZNEO patch if you are using ZDS-II 5.0.1. + See the README.txt file in the parent directory for more information. + This configuration does run correctly with the path applied. 2. I bet that this code, like ostest, will not run if started by a hardware reset. It may only run when started via the debugger. - diff --git a/configs/z16f2800100zcog/nsh/setenv.sh b/configs/z16f2800100zcog/nsh/setenv.sh index 726b980f89..22408b498a 100755 --- a/configs/z16f2800100zcog/nsh/setenv.sh +++ b/configs/z16f2800100zcog/nsh/setenv.sh @@ -50,15 +50,21 @@ if [ -z "${PATH_ORIG}" ]; then fi # -# This is the Cygwin path to location where the XDS-II tools were installed +# This is the Cygwin path to location where the ZDS-II tools were installed # TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/ZiLOG/ZDSII_ZNEO_5.0.1/bin" # -# Add the path to the toolchain to the PATH variable. NOTE that /bin and /usr/bin -# preceded the toolchain bin directory. This is because the ZDSII bin directory -# includes binaries like make.exe that will interfere with the normal build process -# if we do not give priority to the versions at /bin and /usr/bin. +# This is the path to the z16f2800100zcog tool directory # -export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" +TOOL_DIR="${WD}/configs/z16f2800100zcog/tools" + +# +# Add the path to the toolchain and tool directory to the PATH variable. NOTE +# that /bin and /usr/bin preceded the toolchain bin directory. This is because +# the ZDSII bin directory includes binaries like make.exe that will interfere +# with the normal build process if we do not give priority to the versions at +# /bin and /usr/bin. +# +export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:${TOOL_DIR}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/configs/z16f2800100zcog/ostest/README.txt b/configs/z16f2800100zcog/ostest/README.txt index fc5e36fead..8042634ebb 100644 --- a/configs/z16f2800100zcog/ostest/README.txt +++ b/configs/z16f2800100zcog/ostest/README.txt @@ -31,3 +31,9 @@ Console Output -------------- OS test results will be provided on the serial console at 57600 8N1 baud. + +STATUS +------ + +This exemple works fine when started from ZDS-II. But I have seen problems +when starting from a hardware reset. diff --git a/configs/z16f2800100zcog/ostest/setenv.sh b/configs/z16f2800100zcog/ostest/setenv.sh index 8a696fdcbb..edc62a07e3 100755 --- a/configs/z16f2800100zcog/ostest/setenv.sh +++ b/configs/z16f2800100zcog/ostest/setenv.sh @@ -1,7 +1,7 @@ #!/bin/bash # configs/z16f2800100zcog/ostest/setenv.sh # -# Copyright (C) 2008, 2009, 2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2008, 2009, 2012, 2014 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -49,15 +49,21 @@ if [ -z "${PATH_ORIG}" ]; then fi # -# This is the Cygwin path to location where the XDS-II tools were installed +# This is the Cygwin path to location where the ZDS-II tools were installed # TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/ZiLOG/ZDSII_ZNEO_5.0.1/bin" # -# Add the path to the toolchain to the PATH variable. NOTE that /bin and /usr/bin -# preceded the toolchain bin directory. This is because the ZDSII bin directory -# includes binaries like make.exe that will interfere with the normal build process -# if we do not give priority to the versions at /bin and /usr/bin. +# This is the path to the z16f2800100zcog tool directory # -export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" +TOOL_DIR="${WD}/configs/z16f2800100zcog/tools" + +# +# Add the path to the toolchain and tool directory to the PATH variable. NOTE +# that /bin and /usr/bin preceded the toolchain bin directory. This is because +# the ZDSII bin directory includes binaries like make.exe that will interfere +# with the normal build process if we do not give priority to the versions at +# /bin and /usr/bin. +# +export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:${TOOL_DIR}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/configs/z16f2800100zcog/pashello/setenv.sh b/configs/z16f2800100zcog/pashello/setenv.sh index 2db93c5ef7..4ade86cff9 100755 --- a/configs/z16f2800100zcog/pashello/setenv.sh +++ b/configs/z16f2800100zcog/pashello/setenv.sh @@ -1,7 +1,7 @@ #!/bin/bash # configs/z16f2800100zcog/pashello/setenv.sh # -# Copyright (C) 2008, 2009, 2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2008, 2009, 2012, 2014 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -49,15 +49,21 @@ if [ -z "${PATH_ORIG}" ]; then fi # -# This is the Cygwin path to location where the XDS-II tools were installed +# This is the Cygwin path to location where the ZDS-II tools were installed # TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/ZiLOG/ZDSII_ZNEO_5.0.1/bin" # -# Add the path to the toolchain to the PATH variable. NOTE that /bin and /usr/bin -# preceded the toolchain bin directory. This is because the ZDSII bin directory -# includes binaries like make.exe that will interfere with the normal build process -# if we do not give priority to the versions at /bin and /usr/bin. +# This is the path to the z16f2800100zcog tool directory # -export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" +TOOL_DIR="${WD}/configs/z16f2800100zcog/tools" + +# +# Add the path to the toolchain and tool directory to the PATH variable. NOTE +# that /bin and /usr/bin preceded the toolchain bin directory. This is because +# the ZDSII bin directory includes binaries like make.exe that will interfere +# with the normal build process if we do not give priority to the versions at +# /bin and /usr/bin. +# +export PATH="/bin:/usr/bin:${TOOLCHAIN_BIN}:${TOOL_DIR}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/configs/z16f2800100zcog/tools/dopatch.sh b/configs/z16f2800100zcog/tools/dopatch.sh new file mode 100755 index 0000000000..9f738184a8 --- /dev/null +++ b/configs/z16f2800100zcog/tools/dopatch.sh @@ -0,0 +1,59 @@ +#!/bin/sh +############################################################################ +# configs/z16f2800100zcog/tools/dopatch.sh +# +# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +USAGE="${0} \$PWD" +WD=`pwd` +TOOLDIR=${WD}/configs/z16f2800100zcog/tools +ME=${TOOLDIR}/dopatch.sh +PATCH=${TOOLDIR}/zneo-zdsii-5_0_1-variadic-func-fix.patch + +if [ ! -x ${ME} ]; then + echo "ERROR: This script must be executed from the top-level NuttX directory" + echo ${USAGE} + exit 1 +fi + +if [ ! -r ${PATCH} ]; then + echo "ERROR: Readable patch not found at ${PATCH}" + echo ${USAGE} + exit 1 +fi + +cd .. || \ + { echo "ERROR: failed to CD to the parent directory"; exit 1; } + +cat ${PATCH} | patch -p1 || \ + { echo "ERROR: patch failed" ; exit 1; } diff --git a/configs/z16f2800100zcog/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch b/configs/z16f2800100zcog/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch new file mode 100644 index 0000000000..b1464f340b --- /dev/null +++ b/configs/z16f2800100zcog/tools/zneo-zdsii-5_0_1-variadic-func-fix.patch @@ -0,0 +1,159 @@ +diff --git a/apps/nshlib/nsh_console.c b/apps/nshlib/nsh_console.c +index ba7dbe7..b9f9991 100644 +--- a/apps/nshlib/nsh_console.c ++++ b/apps/nshlib/nsh_console.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -79,8 +80,13 @@ static FAR struct nsh_vtbl_s *nsh_consoleclone(FAR struct nsh_vtbl_s *vtbl); + static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl); + static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, + FAR const void *buffer, size_t nbytes); ++#if 0 + static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, + FAR const char *fmt, ...); ++#else ++static int nsh_consolevoutput(FAR struct nsh_vtbl_s *vtbl, ++ FAR const char *fmt, va_list ap); ++#endif + static FAR char *nsh_consolelinebuffer(FAR struct nsh_vtbl_s *vtbl); + + #if CONFIG_NFILE_DESCRIPTORS > 0 +@@ -213,6 +219,7 @@ static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buf + * + ****************************************************************************/ + ++#if 0 + static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, + FAR const char *fmt, ...) + { +@@ -263,6 +270,51 @@ static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, + #endif + } + ++#else ++static int nsh_consolevoutput(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, va_list ap) ++{ ++#if CONFIG_NFILE_DESCRIPTORS > 0 ++ FAR struct console_stdio_s *pstate = (FAR struct console_stdio_s *)vtbl; ++ int ret; ++ ++ /* The stream is open in a lazy fashion. This is done because the file ++ * descriptor may be opened on a different task than the stream. The ++ * actual open will then occur with the first output from the new task. ++ */ ++ ++ if (nsh_openifnotopen(pstate) != 0) ++ { ++ return ERROR; ++ } ++ ++ ret = vfprintf(pstate->cn_outstream, fmt, ap); ++ ++ return ret; ++#else ++ char *str; ++ ++ /* Use avsprintf() to allocate a buffer and fill it with the formatted ++ * data ++ */ ++ ++ str = NULL; ++ (void)avsprintf(&str, fmt, ap); ++ ++ /* Was a string allocated? */ ++ ++ if (str) ++ { ++ /* Yes.. Print then free the allocated string */ ++ ++ printf("%s", str); ++ free(str); ++ } ++ ++ return 0; ++#endif ++} ++#endif ++ + /**************************************************************************** + * Name: nsh_consolelinebuffer + * +@@ -452,7 +504,11 @@ FAR struct console_stdio_s *nsh_newconsole(void) + pstate->cn_vtbl.release = nsh_consolerelease; + #endif + pstate->cn_vtbl.write = nsh_consolewrite; ++#if 0 + pstate->cn_vtbl.output = nsh_consoleoutput; ++#else ++ pstate->cn_vtbl.voutput = nsh_consolevoutput; ++#endif + pstate->cn_vtbl.linebuffer = nsh_consolelinebuffer; + pstate->cn_vtbl.exit = nsh_consoleexit; + +@@ -489,3 +545,15 @@ FAR struct console_stdio_s *nsh_newconsole(void) + } + return pstate; + } ++ ++int nsh_output(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, ...) ++{ ++ va_list ap; ++ int ret; ++ ++ va_start(ap, fmt); ++ ret = vtbl->voutput(vtbl, fmt, ap); ++ va_end(ap); ++ ++ return ret; ++} +diff --git a/apps/nshlib/nsh_console.h b/apps/nshlib/nsh_console.h +index c78362f..59bd8d7 100644 +--- a/apps/nshlib/nsh_console.h ++++ b/apps/nshlib/nsh_console.h +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + #include + + /**************************************************************************** +@@ -62,11 +63,13 @@ + #define nsh_undirect(v,s) (v)->undirect(v,s) + #define nsh_exit(v,s) (v)->exit(v,s) + ++#if 0 + #ifdef CONFIG_CPP_HAVE_VARARGS + # define nsh_output(v, fmt...) (v)->output(v, ##fmt) + #else + # define nsh_output vtbl->output + #endif ++#endif + + /* Size of info to be saved in call to nsh_redirect */ + +@@ -107,7 +110,11 @@ struct nsh_vtbl_s + void (*release)(FAR struct nsh_vtbl_s *vtbl); + #endif + ssize_t (*write)(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes); ++#if 0 + int (*output)(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, ...); ++#else ++ int (*voutput)(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, va_list ap); ++#endif + FAR char *(*linebuffer)(FAR struct nsh_vtbl_s *vtbl); + #if CONFIG_NFILE_DESCRIPTORS > 0 + void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save); +@@ -159,5 +166,6 @@ struct console_stdio_s + /* Defined in nsh_console.c *************************************************/ + + FAR struct console_stdio_s *nsh_newconsole(void); ++int nsh_output(FAR struct nsh_vtbl_s *vtbl, FAR const char *fmt, ...); + + #endif /* __APPS_NSHLIB_NSH_CONSOLE_H */