📄 usrlib.c
字号:
} if (adrs == 0) /* no address specified: use last address */ adrs = last_adrs; else last_adrs = adrs; /* round address down to appropriate boundary */ last_adrs = (void *)((int) last_adrs & ~(width - 1)); /* print leading spaces on first line */ bfill (ascii, 16, '.'); printf ("%08x: ", (int) last_adrs & ~0xf); for (item = 0; item < ((int) last_adrs & 0xf) / width; item++) { printf ("%*s ", 2*width, " "); bfill (&ascii[item * width], 2*width, ' '); } /* print out all the words */ while (nunits-- > 0) { if (item == MAX_BYTES_PER_LINE/width) { /* end of line: * print out ascii format values and address of next line */ printf (" *%16s*\n%08x: ", ascii, (int) last_adrs); bfill (ascii, MAX_BYTES_PER_LINE, '.'); /* clear out ascii buffer */ item = 0; /* reset word count */ } switch (width) /* display in appropriate format */ { case 1: tmpByte = (UINT8 *)last_adrs; printf ("%02x", *tmpByte); break; case 2: tmpShort = (USHORT *)last_adrs; printf ("%04x", *tmpShort); break; case 4: tmpLong = (ULONG *)last_adrs; printf ("%08lx", *tmpLong); break; case 8: tmpLong = (ULONG *)last_adrs;#if _BYTE_ORDER==_LITTLE_ENDIAN printf ("%08lx%08lx", *(tmpLong+1), *tmpLong);#endif#if _BYTE_ORDER==_BIG_ENDIAN printf ("%08lx%08lx", *tmpLong, *(tmpLong+1));#endif break; default: tmpByte = (UINT8 *)last_adrs; printf ("%02x", *tmpByte); break; } printf (" "); /* space between words */ /* set ascii buffer */ pByte = (UINT8 *) last_adrs; for (ix = 0; ix < width; ix ++) { if (*pByte == ' ' || (isascii (*pByte) && isprint (*pByte))) { ascii[item*width + ix] = *pByte; } pByte ++; } last_adrs = (void *)((int)last_adrs + width); item++; } /* print remainder of last line */ for (; item < MAX_BYTES_PER_LINE/width; item++) printf ("%*s ", 2*width, " "); printf (" *%16s*\n", ascii); /* print out ascii format values */ }/********************************************************************************* ld - load an object module into memory** This command loads an object module from a file or from standard input.* The object module must be in UNIX `a.out' format. External references in* the module are resolved during loading. The <syms> parameter determines how* symbols are loaded; possible values are:** 0 - Add global symbols to the system symbol table.* 1 - Add global and local symbols to the system symbol table.* -1 - Add no symbols to the system symbol table.** If there is an error during loading (e.g., externals undefined, too many* symbols, etc.), then shellScriptAbort() is called to stop any script that* this routine was called from. If <noAbort> is TRUE, errors are noted but* ignored.** The normal way of using ld() is to load all symbols (<syms> = 1) during* debugging and to load only global symbols later.** The routine ld() is a 'shell command'. That is, it is designed to* be used only in the shell, and not in code running on the target.* In future releases, calling ld() directly from code may not be* supported.** COMMON SYMBOLS* On the target shell, for the 'ld' command only, common symbol behavior is * determined by the value of the global variable, ldCommonMatchAll.* The reasoning for ldCommonMatchAll matches the purpose* of the windsh environment variable, LD_COMMON_MATCH_ALL as explained below.** If ldCommonMatchAll is set to TRUE (equivalent to windsh* "LD_COMMON_MATCH_ALL=on"), the loader trys to match a common symbol* with an existing one. If a symbol with the same name is already* defined, the loader takes its address. Otherwise, the loader creates* a new entry. If set to FALSE (equivalent to windsh* "LD_COMMON_MATCH_ALL=off"), the loader does not try to find an* existing symbol. It creates an entry for each common symbol.** EXAMPLE* The following example loads the `a.out' file `module' from the default file* device into memory, and adds any global symbols to the symbol table:* .CS* -> ld <module* .CE* This example loads `test.o' with all symbols:* .CS* -> ld 1,0,"test.o"* .CE* RETURNS:* MODULE_ID, or* NULL if there are too many symbols, the object file format is invalid, or* there is an error reading the file.** SEE ALSO: loadLib,* .pG "Target Shell,"* windsh,* .tG "Shell" */MODULE_ID ld ( int syms, /* -1, 0, or 1 */ BOOL noAbort, /* TRUE = don't abort script on error */ char *name /* name of object module, NULL = standard input */ ) { MODULE_ID moduleId; int fd; int loadFlags; if (name != NULL) { fd = open (name, O_RDONLY, 0); if (fd == ERROR) { printErr ("ld error: unable to open \"%s\"\n", name); return (NULL); } } else fd = STD_IN; /* convert to basic flags */ switch (syms) { case NO_SYMBOLS: loadFlags = LOAD_NO_SYMBOLS; break; case GLOBAL_SYMBOLS: loadFlags = LOAD_GLOBAL_SYMBOLS; break; case ALL_SYMBOLS: loadFlags = LOAD_ALL_SYMBOLS; break; default: loadFlags = syms; } if (ldCommonMatchAll) loadFlags = (loadFlags | LOAD_COMMON_MATCH_ALL); moduleId = loadModule (fd, loadFlags); if (name != NULL) close (fd); if (moduleId == NULL) { switch (errno) { case S_loadLib_TOO_MANY_SYMBOLS: printErr ("ld error: too many symbols.\n"); break; case S_symLib_SYMBOL_NOT_FOUND: printErr ("ld error: Module contains undefined symbol(s) " "and may be unusable.\n"); break; default: printErr ("ld error: error loading file (errno = %#x).\n", errno); break; } if (! noAbort) shellScriptAbort (); } return (moduleId); }/********************************************************************************* devs - list all system-known devices** This command displays a list of all devices known to the I/O system.** RETURNS: N/A** SEE ALSO: iosDevShow(),* .pG "Target Shell,"* windsh,* .tG "Shell"*/void devs (void) { iosDevShow (); }/********************************************************************************* lkup - list symbols** This command lists all symbols in the system symbol table whose names* contain the string <substr>. If <substr> is omitted or is 0, a short* summary of symbol table statistics is printed. If <substr> is the empty* string (""), all symbols in the table are listed. ** This command also displays symbols that are local, i.e., symbols found in* the system symbol table only because their module was loaded by ld().** By default, lkup() displays 22 symbols at a time. This can be changed * by modifying the global variable `symLkupPgSz'. If this variable is set* to 0, lkup() displays all the symbols without interruption.** RETURNS: N/A** SEE ALSO: symLib, symEach(),* .pG "Target Shell,"* windsh,* .tG "Shell"*/void lkup ( char *substr /* substring to match */ ) { show ((int) sysSymTbl, (int) substr); /* symShow() does the work */ }/********************************************************************************* lkAddr - list symbols whose values are near a specified value** This command lists the symbols in the system symbol table that* are near a specified value. The symbols that are displayed include:* .iP "" 4* symbols whose values are immediately less than the specified value* .iP* symbols with the specified value* .iP* succeeding symbols, until at least 12 symbols have been displayed* .LP** This command also displays symbols that are local, i.e., symbols found in* the system symbol table only because their module was loaded by ld().** INTERNAL* The LKADDR_ARG structure is used to hold the target address, count, and* the `best' symbols found by lkAddrFind() and lkAddrNext(), which are the* routines that get called by symEach() for each symbol in the system* symbol table.** RETURNS: N/A** SEE ALSO: symLib, symEach(),* .pG "Target Shell,"* windsh,* .tG "Shell"*/void lkAddr ( unsigned int addr /* address around which to look */ ) { FAST int ix; LKADDR_ARG arg; arg.count = 0; /* haven't printed anything yet */ arg.addr = addr; for (ix = 0; ix < NUM_SYMBLS; ++ix) arg.symbl[ix].addr = (unsigned int)NULL; /* clear little symbol table */ /* call lkAddrFind for each symbol */ symEach (sysSymTbl, (FUNCPTR)lkAddrFind, (int)&arg); /* print out the symbols found */ for (ix = 0; ix < NUM_SYMBLS; ix++) { if (arg.symbl[ix].addr != (unsigned int)NULL) { arg.addr = arg.symbl[ix].addr; symEach (sysSymTbl, (FUNCPTR)lkAddrPrintSame, (int)&arg); } } if (arg.symbl[2].addr == (unsigned int)NULL) return; /* couldn't find anything greater */ /* print until there are enough entries */ while (arg.count < 12) { arg.addr = arg.symbl[2].addr; arg.symbl[2].addr = (unsigned int)NULL; /* find next entry */ symEach (sysSymTbl, (FUNCPTR)lkAddrNext, (int)&arg); if (arg.symbl[2].addr == (unsigned int)NULL) break; /* couldn't find anything greater */ /* print them */ arg.addr = arg.symbl[2].addr; symEach (sysSymTbl, (FUNCPTR)lkAddrPrintSame, (int)&arg); } }/********************************************************************************* lkAddrFind - support routine for lkAddr()** This command is called by symEach() to deal with each symbol in the table.* If the value associated with the symbol is equal to lkAddrTarg(), or closer* to it than previous close values, the appropriate slot in the array `symbl'* is filled with the data for this symbol.** RETURNS: TRUE*/LOCAL BOOL lkAddrFind ( char * name, /* name in system symbol table */ unsigned int value, /* value associated with name */ SYM_TYPE type, /* type of this symbol table entry */ LKADDR_ARG * arg /* handle for search parameters */ ) { FAST unsigned int addr = value; if (addr < arg->addr) { if (addr > arg->symbl[0].addr) { /* found closer symbol that is less than target */ arg->symbl[0].addr = addr; arg->symbl[0].name = name; arg->symbl[0].type = type; } } else if (addr == arg->addr) { /* found target, fill in target entry */ arg->symbl[1].addr = addr; arg->symbl[1].name = name; arg->symbl[1].type = type; } else if (addr > arg->addr) { if ((addr < arg->symbl[2].addr) || (arg->symbl[2].addr == (unsigned int)NULL)) { /* found closer symbol that is greater than target */ arg->symbl[2].addr = addr; arg->symbl[2].name = name; arg->symbl[2].type = type; } } return (TRUE); }/********************************************************************************* lkAddrNex
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -