📄 modulelib.c
字号:
if (objFree (moduleClassId, (char *) moduleId) != OK) return (ERROR); return (OK); }/******************************************************************************** moduleIdFigure - translate a module name or ID to a module ID** Some routines take either a module ID (an integer) or a module name. This* routine determines whether the parameter is a module name or a module ID and* returns the module ID. ** RETURNS: A module ID (type MODULE_ID), or NULL.** NOMANUAL*/MODULE_ID moduleIdFigure ( void * moduleNameOrId /* module name or module ID */ ) { MODULE_ID moduleId = NULL; /* default is NULL */ /* * Make sure we're not getting a NULL pointer, OBJ_VERIFY doesn't check * for that. */ if (moduleNameOrId == NULL) return (NULL); /* If moduleNameOrId is a moduleId, just return it. */ if (OBJ_VERIFY (moduleNameOrId, moduleClassId) == OK) { return ((MODULE_ID) moduleNameOrId); } /* * moduleNameOrId isn't a legitmate object - see if it's the name * of a module. */ if ((moduleId = moduleFindByName (moduleNameOrId)) == NULL) { /* * It's neither an object module nor a module name. Set errno and * return NULL. */ errnoSet (S_moduleLib_MODULE_NOT_FOUND); return (NULL); } else return (moduleId); }/******************************************************************************** moduleShow - show the current status for all the loaded modules** This routine displays a list of the currently loaded modules and* some information about where the modules are loaded.* * The specific information displayed depends on the format of the object* modules. In the case of a.out and ECOFF object modules, moduleShow() displays* the start of the text, data, and BSS segments.* * If moduleShow() is called with no arguments, a summary list of all* loaded modules is displayed. It can also be called with an argument,* <moduleNameOrId>, which can be either the name of a loaded module or a* module ID. If it is called with either of these, more information* about the specified module will be displayed.* * RETURNS: OK or ERROR.** SEE ALSO:* .pG "Target Shell,"* windsh,* .tG "Shell"*/STATUS moduleShow ( char * moduleNameOrId, /* name or ID of the module to show */ int options /* display options */ ) { MODULE_ID moduleId; static char * moduleShowHdr [] = {"\n\MODULE NAME MODULE ID GROUP # TEXT START DATA START BSS START\n\--------------- ---------- ---------- ---------- ---------- ----------\n"}; /* * If moduleNameOrId isn't NULL, translate it into a module ID, and * display information about that specific module. * If it is NULL, set moduleId to NULL, and display info about all * loaded modules. */ if (moduleNameOrId != NULL) { if ((moduleId = moduleIdFigure (moduleNameOrId)) == NULL) { /* moduleIdFigure couldn't find a match */ printf ("Module not found\n"); return (ERROR); } } else moduleId = NULL; /* print the module display header */ printf ("%s", moduleShowHdr [MODULE_A_OUT]); /* * If moduleId is a specific module ID, print information about that * specific module. Otherwise, print the summary. */ if (moduleId != NULL) { /* * We've got a specific module to show. If no options are specified, * then display all information, otherwise use what's specified. */ moduleDisplayGeneric (moduleId, options == 0 ? MODDISPLAY_ALL : options); } else { /* We need to display all the modules. */ semTake (moduleListSem, WAIT_FOREVER); dllEach (&moduleList, moduleDisplayGeneric, options | MODDISPLAY_IS_DLL_NODE); semGive (moduleListSem); } /* * There's nothing that can fail - always return OK */ return (OK); }/******************************************************************************** moduleDisplayGeneric - support routine to show stats for an object module** This routine is normally called via a dllEach() call from moduleShow.* It prints a single line of information about the specified module.* Note that the parameter is _not_ of type MODULE_ID, but rather is a* DL_NODE *.* * RETURNS: TRUE, or FALSE if display should be aborted.* * NOMANUAL*/LOCAL STATUS moduleDisplayGeneric ( MODULE_ID moduleId, /* pointer to the module node to display */ UINT options /* display options */ ) { static char moduleShowFmt[] = "%15s %#10x %10d %#10x %#10x %#10x\n"; MODULE_SEG_INFO segInfo; /* segment information */ /* If MODDISPLAY_IS_DLL_NODE is set, need to convert node to module id */ if (options & MODDISPLAY_IS_DLL_NODE) moduleId = NODE_TO_ID (moduleId); /* If HIDDEN_MODULE is set, return OK without displaying anything */ if (moduleId->flags & HIDDEN_MODULE) return (TRUE); /* Return FALSE if we can't get information about the module segments */ if (moduleSegInfoGet (moduleId, &segInfo) != OK) { printErr ("Can\'t get information about module %#x\n", moduleId); return (FALSE); } /* * Print out the module summary line. * We only want to print the file name, not the entire path. */ printf (moduleShowFmt, moduleId->name, moduleId, moduleId->group, segInfo.textAddr, segInfo.dataAddr, segInfo.bssAddr); /* * Print out all the optional information */ if (options & MODDISPLAY_CODESIZE) { /* Print specific information about the size of module's segments */ printf ("\nSize of text segment: %8d\n", segInfo.textSize); printf ("Size of data segment: %8d\n", segInfo.dataSize); printf ("Size of bss segment: %8d\n", segInfo.bssSize); printf ("Total size : %8d\n\n", segInfo.textSize + segInfo.dataSize + segInfo.bssSize); } /* * Return TRUE to continue displaying modules */ return (TRUE); }/******************************************************************************** moduleSegAdd - add a segment to a module* * This routine adds segment information to an object module descriptor. The* specific information recorded depends on the format of the object module.* * The <type> parameter is one of the following:* .iP SEGMENT_TEXT 25* The segment is for TEXT.* .iP SEGMENT_DATA* The segment is for DATA* .iP SEGMENT_BSS* The segment is for BSS* * NOMANUAL* * RETURNS: OK, or ERROR.*/STATUS moduleSegAdd ( MODULE_ID moduleId, /* module to add segment to*/ int type, /* segment type */ void * location, /* segment address */ int length, /* segment length */ int flags /* segment flags */ ) { SEGMENT_ID seg; /* * Validate module id */ if (OBJ_VERIFY (moduleId, moduleClassId) != OK) { return (ERROR); } /* * Allocate space for the segment record */ seg = (SEGMENT_ID) malloc (sizeof (*seg)); if (seg == NULL) { return (ERROR); } /* * Set the fields of the segment record */ seg->address = location; seg->size = length; seg->type = type; seg->flags = flags; seg->checksum = checksum (location, length); /* * Add the segment to the module's segment list */ semTake (moduleSegSem, WAIT_FOREVER); dllAdd (&moduleId->segmentList, (DL_NODE *) seg); semGive (moduleSegSem); return (OK); }/******************************************************************************** moduleSegGet - get (delete and return) the first segment from a module* * This routine returns information about the first segment of a module* descriptor, and then deletes the segment from the module.* * RETURNS: A pointer to the segment ID, or NULL if the segment list is empty.** SEE ALSO: moduleSegFirst()*/SEGMENT_ID moduleSegGet ( MODULE_ID moduleId /* module to get segment from */ ) { SEGMENT_ID segmentId; /* * Validate module id */ if (OBJ_VERIFY (moduleId, moduleClassId) != OK) { return (NULL); } semTake (moduleSegSem, WAIT_FOREVER); segmentId = (SEGMENT_ID) dllGet (&moduleId->segmentList); semGive (moduleSegSem); return (segmentId); }/******************************************************************************** moduleSegFirst - find the first segment in a module* * This routine returns information about the first segment of a module* descriptor.* * RETURNS: A pointer to the segment ID, or NULL if the segment list is empty.** SEE ALSO: moduleSegGet()*/SEGMENT_ID moduleSegFirst ( MODULE_ID moduleId /* module to get segment from */ ) { SEGMENT_ID newSegId; /* * Validate module id */ if (OBJ_VERIFY (moduleId, moduleClassId) != OK) { return (NULL); } semTake (moduleSegSem, WAIT_FOREVER); newSegId = (SEGMENT_ID) DLL_FIRST (&moduleId->segmentList); semGive (moduleSegSem); return (newSegId); }/******************************************************************************** moduleSegNext - find the next segment in a module* * This routine returns the segment in the list immediately following* <segmentId>.* * RETURNS: A pointer to the segment ID, or NULL if there is no next segment.*/SEGMENT_ID moduleSegNext ( SEGMENT_ID segmentId /* segment whose successor is to be found */ ) { SEGMENT_ID newSegId; semTake (moduleSegSem, WAIT_FOREVER); newSegId = (SEGMENT_ID) DLL_NEXT (segmentId); semGive (moduleSegSem); return (newSegId); }/******************************************************************************** moduleSegEach - call a routine to examine each segment in a module* * This routine calls a user-supplied routine to examine each segment* associated with a given module. The routine should be declared as* follows:* * .CS* BOOL routine* (* SEGMENT_ID segmentId, /@ The segment to examine @/* MODULE_ID moduleId, /@ The associated module @/* int userArg /@ An arbitrary user-supplied argument @/* )* .CE* * The user routine should return TRUE if moduleSegEach() is to continue* calling it for the other segments, or FALSE if moduleSegEach() should* exit.* * RETURNS: NULL if all segments were examined, or the segment ID that* caused the support routine to return FALSE.* * NOMANUAL*/SEGMENT_ID moduleSegEach ( MODULE_ID moduleId, /* The module to examine */ FUNCPTR routine, /* The routine to call */ int userArg /* arbitrary user-supplied argument */ ) { SEGMENT_ID segmentId; semTake (moduleSegSem, WAIT_FOREVER); for (segmentId = moduleSegFirst (moduleId); segmentId != NULL; segmentId = moduleSegNext (segmentId)) { if ((*routine) (segmentId, moduleId, userArg) == FALSE) { semGive (moduleSegSem); return (segmentId); } } semGive (moduleSegSem); return (NULL); } /******************************************************************************** moduleCreateHookAdd - add a routine to be called when a module is added* * This routine adds a specified routine to a list of routines to be* called when a module is created. The specified routine should be* declared as follows:* .CS* void moduleCreateHook* (* MODULE_ID moduleId /@ the module ID @/* )* .CE* * This routine is called after all fields of the module ID have been filled in.* * NOTE:* Modules do not have information about their object segments when they are* created. This information is not available until after the entire load* process has finished.* * RETURNS: OK or ERROR.* * SEE ALSO: moduleCreateHookDelete()*/STATUS moduleCreateHookAdd ( FUNCPTR moduleCreateHookRtn /* routine called when module is added */ ) { MODCREATE_HOOK * pHook; /* pointer to hook node */ if (!moduleCreateHookInitialized) { dllInit (&moduleCreateHookList); moduleCreateHookInitialized = TRUE; } /* allocate and initialize hook node */ if ((pHook = (MODCREATE_HOOK *) malloc (sizeof (MODCREATE_HOOK))) == NULL) { return (ERROR); } pHook->func = moduleCreateHookRtn; /* add it to end of hook list */ semTake (moduleCreateHookSem, WAIT_FOREVER); dllAdd (&moduleCreateHookList, &pHook->node); semGive (moduleCreateHookSem); return (OK); }/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -