1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: dbg_Argument.cpp 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev:$ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn.h> 17 #include <nn/dbg/dbg_Argument.h> 18 #include <nn/dbg/dbg_ArgumentPrivate.h> 19 20 #ifdef NN_CTR_ARG_AVAILABLE 21 22 using namespace nn::dbg::CTR; 23 24 namespace 25 { 26 //---- argument buffer 27 bit8 s_ArgBuffer[ NN_DBG_ARG_BUFFER_SIZE ] = {1}; // The default data is dummy data. So it won't be set to the bss region 28 29 //---- current argument buffer 30 const void* s_pCurrentArgBuffer; 31 size_t s_CurrentArgBufferSize; 32 33 //---- argv[0] equivalent string 34 const char* s_pApplicationStr = NN_DBG_ARG_ARGV0_STRING; 35 36 //---- argumento information structure (fixed region) 37 const nn::dbg::CTR::ArgArea s_ArgInfo __attribute__((section(".ARM.__at_0x100ff0"))) = 38 { 39 NN_DBG_ARG_MAGIC_NUM, 40 reinterpret_cast<const void*>(&s_ArgBuffer), 41 sizeof(s_ArgBuffer), 42 NN_DBG_ARG_MAGIC_NUM, 43 }; 44 45 //---- argc, argv information 46 int s_Argc = 0; 47 const char* s_pArgv = NULL; 48 bool s_IsInitialized = false; 49 50 //---- binary information 51 const void* s_pBinaryArea = NULL; 52 size_t s_BinaryAreaSize = 0; 53 54 //---- for option parsing 55 const char* s_pOptArg = NULL; 56 int s_OptInd = 1; 57 int s_OptOpt = 0; 58 } 59 60 //#define offsetof(type, member) ((size_t)&(type*)0->member) 61 62 namespace nn { 63 namespace dbg { 64 namespace CTR { 65 static const char *match_opt(int optchar, const char *optstring); 66 67 //---------------------------------------------------------------- Setup(const void * pBuffer,size_t size)68 static void Setup( const void* pBuffer, size_t size ) 69 { 70 if ( ! s_IsInitialized ) 71 { 72 s_Argc = 0; 73 s_pArgv = NULL; 74 s_pBinaryArea = NULL; 75 s_BinaryAreaSize = 0; 76 77 s_pOptArg = NULL; 78 s_OptInd = 1; 79 s_OptOpt = 0; 80 81 s_pCurrentArgBuffer = pBuffer; 82 s_CurrentArgBufferSize = size; 83 84 // Magic number check 85 const ArgInfoHeader* pHeader = reinterpret_cast<const ArgInfoHeader*>(pBuffer); 86 if ( pHeader->magic == NN_DBG_ARG_MAGIC_NUM_ARG ) 87 { 88 // Gets information from the obtained buffer 89 s_pArgv = reinterpret_cast<const char*>( reinterpret_cast<const bit8*>(pHeader) + pHeader->argStart ); 90 s_Argc = pHeader->argNum + 1; // +1 since includes self 91 s_pBinaryArea = reinterpret_cast<const void*>( reinterpret_cast<const bit8*>(pHeader) + pHeader->binaryStart ); 92 s_BinaryAreaSize = pHeader->binarySize; 93 } 94 95 s_IsInitialized = true; 96 } 97 } 98 //---------------------------------------------------------------- Setup(void)99 static void Setup(void) 100 { 101 if ( ! s_IsInitialized ) 102 { 103 // Magic number check 104 if ( s_ArgInfo.magic1 == NN_DBG_ARG_MAGIC_NUM && s_ArgInfo.magic2 == NN_DBG_ARG_MAGIC_NUM ) 105 { 106 Setup( s_ArgInfo.pArgArea, s_ArgInfo.areaSize ); 107 } 108 } 109 } 110 //---------------------------------------------------------------- Reset(void)111 static void Reset(void) 112 { 113 s_IsInitialized = false; 114 } 115 116 //---------------------------------------------------------------- 117 // Gets as a binary GetArgBinary(void)118 const void* GetArgBinary( void ) 119 { 120 Setup(); 121 return s_pBinaryArea; 122 } 123 //---------------------------------------------------------------- 124 // Gets as a binary GetArgBinarySize(void)125 size_t GetArgBinarySize( void ) 126 { 127 Setup(); 128 return s_BinaryAreaSize; 129 } 130 131 //---------------------------------------------------------------- 132 // Gets the number of arguments 133 // For example, return value is 3 when "-T 123" is given 134 // 1 when there are no arguments 135 // 0 when there is no argument information region GetArgc(void)136 int GetArgc(void) 137 { 138 Setup(); 139 return s_Argc; 140 } 141 142 //---------------------------------------------------------------- 143 // Gets arguments 144 // For example, when "-T 123" is set in the arguments 145 // argv[0]=Arg0String argv[1]="-T" argv[2]="123" 146 // When there is no argument information region, NULL is returned regardless of the index GetArgv(int index)147 const char* GetArgv( int index ) 148 { 149 Setup(); 150 int argc = GetArgc(); 151 152 // When specification is outside the argument range or when there is no argument buffer 153 if ( index < 0 || index >= argc || ! s_pArgv ) 154 { 155 return NULL; 156 } 157 158 // When argv[0] is acquired 159 if ( index == 0 ) 160 { 161 return s_pApplicationStr; 162 } 163 164 const char* p = s_pArgv; 165 for( index--; index>0; index-- ) 166 { 167 int argsize = *(p + offsetof(ArgvFormat, size)) + *(p + offsetof(ArgvFormat, size) + 1)*256; 168 p += 2 + argsize + 1; // Advances size information 2 bytes + string + "\0" 169 } 170 171 return (p + offsetof(ArgvFormat, string)); 172 } 173 174 //---------------------------------------------------------------- 175 // Option analysis GetOpt(const char * optstring)176 int GetOpt( const char *optstring ) 177 { 178 Setup(); 179 180 static bool end_of_option = false; 181 int optchar; 182 const char *arg; 183 const char *opt; 184 const char *optarg; 185 186 s_pOptArg = NULL; 187 s_OptOpt = 0; 188 189 // Reset if optstring is NULL 190 if (optstring == NULL) 191 { 192 s_OptInd = 1; 193 end_of_option = false; 194 return 0; 195 } 196 197 // Get command line arguments 198 arg = GetArgv(s_OptInd); 199 200 if (arg == NULL) 201 { 202 return -1; 203 } 204 205 if (optstring[0] == '-') // Minus Mode 206 { 207 s_OptInd++; // Consume arguments 208 209 // Normal argument when it does not start with '-' 210 if (end_of_option || arg[0] != '-') 211 { 212 s_pOptArg = arg; // Normal arguments are also set to OptArg. 213 return 1; 214 } 215 216 // Option analysis 217 optchar = arg[1]; 218 219 if (optchar == '-') // End of options when '--' is encountered 220 { 221 end_of_option = true; // Normal arguments from here on 222 return GetOpt(optstring); 223 } 224 } 225 else // normal mode 226 { 227 // Normal argument when it does not start with '-' 228 if (end_of_option || arg[0] != '-') 229 { 230 return -1; // OptArg remains NULL 231 } 232 233 s_OptInd++; // Consume arguments 234 235 // Option analysis 236 optchar = arg[1]; 237 238 if (optchar == '-') // End of options when '--' is encountered 239 { 240 end_of_option = true; // Normal arguments from here on 241 return -1; 242 } 243 244 } 245 246 opt = match_opt(optchar, optstring); 247 248 if (opt == NULL) 249 { 250 s_OptOpt = optchar; // Unknown option 251 return '?'; 252 } 253 254 if (opt[1] == ':') // OptArg search specification? 255 { 256 // Continuously specified similar to -oAAA (gnu expansion) 257 if ( arg[2] != '\0' ) 258 { 259 s_pOptArg = &arg[2]; // Current options are viewed as-is 260 } 261 // Determine with the next argument 262 else 263 { 264 optarg = GetArgv(s_OptInd); 265 266 if (optarg == NULL || optarg[0] == '-') 267 { 268 s_pOptArg = NULL; 269 270 if (opt[2] != ':') // '::' Or not? 271 { 272 s_OptOpt = optchar; // OptArg not present. 273 return '?'; 274 } 275 } 276 else 277 { 278 s_pOptArg = optarg; 279 s_OptInd++; // Consume arguments 280 } 281 } 282 } 283 return optchar; 284 } 285 286 //---------------- 287 // GetOpt() sub-routine match_opt(int optchar,const char * optstring)288 static const char *match_opt(int optchar, const char *optstring) 289 { 290 if (optstring[0] == '-' || optstring[0] == '+') 291 { 292 optstring++; 293 } 294 295 if (optchar != ':') 296 { 297 while (*optstring) 298 { 299 if (optchar == *optstring) 300 { 301 return optstring; 302 } 303 optstring++; 304 } 305 } 306 return NULL; 307 } 308 309 //---------------------------------------------------------------- 310 // Force assignment of the argument buffer SetArgumentBuffer(const void * pBuffer,size_t size)311 void SetArgumentBuffer( const void *pBuffer, size_t size ) 312 { 313 Reset(); 314 Setup( pBuffer, size ); 315 } 316 //---------------------------------------------------------------- 317 // Get argument buffer row region GetArgumentBuffer(void)318 const void *GetArgumentBuffer(void) 319 { 320 return s_pCurrentArgBuffer; 321 } GetArgumentBufferSize(void)322 size_t GetArgumentBufferSize(void) 323 { 324 return s_CurrentArgBufferSize; 325 } 326 //---------------------------------------------------------------- 327 // Equivalent to option parsing optind GetOptInd(void)328 int GetOptInd( void ) 329 { 330 return s_OptInd; 331 } 332 //---------------------------------------------------------------- 333 // Equivalent to option parsing optarg GetOptArg(void)334 const char* GetOptArg( void ) 335 { 336 return s_pOptArg; 337 } 338 //---------------------------------------------------------------- 339 // Equivalent to option parsing optopt GetOptOpt(void)340 int GetOptOpt( void ) 341 { 342 return s_OptOpt; 343 } 344 } 345 } 346 } 347 348 #else 349 350 //---------------------------------------------------------------- 351 // For Release ROM 352 353 namespace 354 { 355 //---- argumento information structure (fixed region) 356 const nn::dbg::CTR::ArgArea s_ArgInfo __attribute__((section(".ARM.__at_0x100ff0"))) = 357 { 358 0, 359 NULL, 360 NULL, 361 1, // Set to a value different than the first member's 362 }; 363 } 364 365 namespace nn { 366 namespace dbg { 367 namespace CTR { 368 GetArgBinary(void)369 const void* GetArgBinary( void ) 370 { 371 return NULL; 372 } GetArgBinarySize(void)373 size_t GetArgBinarySize( void ) 374 { 375 return 0; 376 } GetArgc(void)377 int GetArgc(void) 378 { 379 return 0; 380 } GetArgv(int)381 const char* GetArgv( int ) 382 { 383 return NULL; 384 } GetOpt(const char *)385 int GetOpt(const char *) 386 { 387 return -1; 388 } SetArgumentBuffer(const void *,size_t)389 void SetArgumentBuffer( const void*, size_t ) 390 { 391 } GetArgumentBuffer(void)392 const void *GetArgumentBuffer(void) 393 { 394 return NULL; 395 } GetArgumentBufferSize(void)396 size_t GetArgumentBufferSize(void) 397 { 398 return 0; 399 } GetOptInd(void)400 int GetOptInd( void ) 401 { 402 return -1; 403 } GetOptArg(void)404 const char* GetOptArg( void ) 405 { 406 return NULL; 407 } GetOptOpt(void)408 int GetOptOpt( void ) 409 { 410 return -1; 411 } 412 } 413 } 414 } 415 #endif 416