Tool/software: Code Composer Studio
Hi,
loadProgram() does not fill the .args section correctly, because it lacks the doubleword pointer alignment for *argv.
Here is the prototype used for main():
int main(int argc, char **argv)
The code is built with --args=0x200.
The debugger is started with the Scripting Console:
args=["foo","bar"];ccxmlFile="<some path>/C5501_NoSDRAM.ccxml";app="<some path>/test.out";core=".*";ds.setConfig(ccxmlFile);mySession=ds.openSession(core);mySession.target.connect();mySession.memory.loadProgram(app, args);
argc is correct, but *argv is loaded one word ahead of the expected location:
0x005A30 __c_args
0x005A30 0002 0000 5A37 0000 5A3B 0000 0000 0066 006F 006F 0000 0062 0061 0072 0000
C:\ti\ccsv8\tools\compiler\c5500_4.4.1\lib\rtssrc.zip\args_main.c:_args_main() expects argc to be located at 0x005A30 (correct), and *argv to be located at 0x005A32:
typedef struct { int argc; char *argv[1]; } ARGS; extern ARGS __c_args__; extern int main(int argc, char *argv[]); #define NO_C_ARGS ((unsigned long)-1) extern void __tdeh_init(); int _args_main() { #pragma diag_suppress 1107 register ARGS *pargs = (ARGS*)_symval(&__c_args__); #pragma diag_default 1107 register int argc = 0; register char **argv = 0; /*------------------------------------------------------------------------*/ /* For those targets that support table driven exception handling, */ /* initialize the global data structure here before main() to prepare */ /* for the first exception, especially from new(). */ /*------------------------------------------------------------------------*/ #if defined(__TI_TABLE_DRIVEN_EXCEPTIONS) __tdeh_init(); #endif if (_symval(&__c_args__) != NO_C_ARGS) { argc = pargs->argc; argv = pargs->argv; } return main(argc, argv); }
However, loadProgram() fills *argv at 0x005A31, so main() gets an invalid argv[0] pointing to 0x5A370000 instead of the expected 0x00005A37. Moreover, pointers such as argv[0] have to be located at a doubleword-aligned address, so that instructions such as "MOV dbl(*AR3),XAR3" can work, so it's not possible to work around this issue by hacking the argv value from within main() or by making the ARGS structure packed in cargs.h. Therefore, the issue is actually in loadProgram(). The following workaround works if one does not rely on argv[argc] being NULL as it should be:
memmove(argv, (void *)((uint32_t)argv - 1), argc * sizeof(*argv));
Is there a way of forcing loadProgram() to work correctly?
Regards,
Benoît