📄 loadcofflib.c
字号:
/* loadCoffLib.c - UNIX coff object module loader *//* Copyright 1984-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02o,22may01,h_k fixed R_RELTHUMB23 for big-endian02n,08feb99,pcn Added pai changes: fix MAX_SYS_SYM_LEN (SPR #9028) and added functionality to boot an image with multiple text and / or multiple data sections (SPR #22452).02m,30nov98,dbt no longer clear seg.flags<xxx> after loadSegmentAllocate() call. (SPR #23553).02m,13nov98,cdp added support for ARM generic Thumb library (ARM_THUMB); merged ARM big-endian support - check object file endianness.02l,05oct98,pcn Set to _ALLOC_ALIGN_SIZE the flags field in seg structure (SPR #21836).02k,02sep98,cym fix static constructor/multiple text segments (SPR #21809)02h,10aug98,jgn fix loadModuleAt problem with bss segment (SPR #21635)02i,17jul98,pcn Fixed SPR #21836: alignment mismatch between sections and target.02h,19jun98,c_c Ignore STYP_REG relocations.02g,03mar98,cdp make bootCoffModule skip bytes between scnhdrs and raw data (fixes loading of ARM stripped kernels).02f,07nov97,yp made changes to work with tool-chain fix related to 02d.02e,24oct97,cdp add support for THUMB23D relocs and trap THUMB9 and THUMB12.02d,16oct97,cdp temporary fix to THUMB23 relocs while waiting tool-chain fix.02c,13aug97,cdp added Thumb (ARM7TDMI_T) support; tighten up RELARM26 overflow test; initialise 'bias' in coffSymTab to prevent warning.02b,04mar97,pad Prevented relocations associated with STYP_INFO, STYP_NOLOAD and STYP_PAD section to be done. Now refuses STYP_REG sections. Silently ignore sections with NOLOAD bit set and symbols from such sections. coffSecHdrRead() now sets the errno.02a,04feb97,cdp Fix ARM non-common relocs, 16-bit transfers, overflow tests.01z,08jan97,cdp added ARM support.01y,31oct96,elp Replaced symAdd() call by symSAdd() call (symtbls synchro).01x,02jul96,dbt removed all references to ANSI C library (SPR #4321). Updated copyright.01w,19jun95,jmb fix memory leak -- BSS wasn't freed and the open object file wasn't closed.01v,06jan95,yp we now recognize C_STAT T_NULL symbols for 29k01u,10dec94,pad now recompute bss sections base addresses for Am29K also and store then in scnAddr array. 01t,10dec94,kdl Merge cleanup - restore fast_load handling (SPR 3852).01s,03nov94,pad Fixed bugs, fixed history, added comments, achieved separation of i960 and Am29k architectures. Multiple Text segments is not supported by Am29k architecture.01r,09sep94,ism integrated a fix from Japan to allow multiple Text segments01q,14mar94,pme fixed nested const/consth relocation carry propagation +tpr in coffRelSegmentAm29K() (SPR #3074). Added comments about relocation. Removed AM29030 tests around VM_STATE_SET().01p,16dec93,tpr fixed address computation bug. 01o,29oct93,tpr added carry out management into coffRelSegmentAm29K().01n,09jul93,pme added text protection for AM29030. added Am29K family support. Need to be reworked one day to really support .lit sections.01m,19apr93,wmd+ added flag to check to choose between faster load without 01nov94,kdl bal optimizations, or normal load with bal optimizations.01l,11mar93,wmd changed coffSymTab() so that it returns ERROR for undefined symbols correctly (SPR # 2056). Modified to use buffered I/O to speedup loader. Moved call to symFindByValue() in coffRelSegment() to after the check for BAL_ENTRY. Fixed SPR # 2031 - use new style loader flags. Modified coffSymTab() not to load common symbols if NO_SYMBOLS option is passed.01k,11sep92,ajm changed OFFSET_MASK to OFFSET24_MASK due to b.out redefines, got rid of b.out.h reference, fixed warnings01j,28aug92,wmd changed to allow loader to handle absolute symbols which allows two pass compilation to occur, courtesy of F.Opila at Intel.01i,31jul92,jmm changed doc for return value of ldCoffModAtSym01h,28jul92,jmm removed ifdefs for I960, now compiles for all arch's. installed moduleLib and unloader support01g,24jul92,jmm changed SEG_COFF_INFO back to SEG_INFO forced symFlags to 1 for ldCoffModAtSym() forced return value of for ldCoffModAtSym()01f,24jul92,rrr change SEG_INFO to SEG_COFF_INFO to avoid conflict also changed addSegNames to _addSegNames01e,18jul92,smb Changed errno.h to errnoLib.h.01d,17jul92,rrr ifdef the file to only compile on 96001c,21may92,wmd modified per Intel to support multiple loaders.01b,26jan92,ajm cleaned up from review01a,21oct91,ajm written: some culled from loadLib.c*//*DESCRIPTIONThis library provides an object module loading facility for loadingCOFF format object files.The object files are loaded into memory, relocated properly, theirexternal references resolved, and their external definitions added tothe system symbol table for use by other modules and from the shell.Modules may be loaded from any I/O stream.EXAMPLE.CS fdX = open ("/devX/objFile", READ); loadModule (fdX, ALL_SYMBOLS); close (fdX);.CEThis code fragment would load the COFF file "objFile" located ondevice "/devX/" into memory which would be allocated from the systemmemory pool. All external and static definitions from the file would beadded to the system symbol table.This could also have been accomplished from the shell, by typing:.CS -> ld (1) </devX/objFile.CEINCLUDE FILE: loadLib.hSEE ALSO: usrLib, symLib, memLib,.pG "Basic OS"*//* LINTLIBRARY */#include "vxWorks.h"#include "bootLoadLib.h"#include "cacheLib.h"#include "errnoLib.h"#include "fioLib.h"#include "ioLib.h"#include "loadCoffLib.h"#include "loadLib.h"#include "memLib.h"#include "pathLib.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "symLib.h"#include "symbol.h" /* for SYM_TYPE typedef */#include "sysSymTbl.h"#include "private/vmLibP.h"/* VxWorks Symbol Type definitions. * * These are the symbol types for symbols stored in the vxWorks symbol table. * These are currently defined in b_out.h as N_xxx (e.g. N_ABS). * They are defined with new macro names so that they are * independent of the object format. * It would probably be better to define these in symLib.h. */#define VX_ABS 2 /* Absolute symbol */#define VX_TEXT 4 /* Text symbol */#define VX_DATA 6 /* Data symbol */#define VX_BSS 8 /* BSS symbol */#define VX_EXT 1 /* External symbol (OR'd in with one of above) *//* fast download */#define BAL_LOAD 0x80 /* flag indicating download with branch-and-link optimization - results in slower download */LOCAL int fast_load = TRUE;/* * DEBUG Stuff * #define DEBUG */#ifdef DEBUGint debug = 2; /* 2 = printf relocation info */#endif /* DEBUG */#ifdef DEBUG#define DPRINTF if (debug >= 2) printf#else#define DPRINTF noopvoid noop() { }#endif/* #define DEBUG_MALLOC */#ifdef DEBUG_MALLOCchar *debugMalloc(nbytes) int nbytes; { printf("Calling malloc(%d)\n", nbytes); memShow(0); return( (char *) malloc(nbytes)); }#define malloc debugMalloc#endif/* * Abridged edition of a object file symbol entry SYMENT * * This is used to minimize the amount of malloc'd memory. * The abridged edition contains all elements of SYMENT required * to perform relocation. */#ifdef __GNUC__#pragma align 1 /* tell gcc960 to not pad structures */#endifstruct symentAbridged { long n_value; /* value of symbol */ short n_scnum; /* section number */ char n_sclass; /* storage class */ char n_numaux; /* number of auxiliary entries */};#define SYMENT_A struct symentAbridged#define SYMESZ_A sizeof(SYMENT_A) #ifdef __GNUC__#pragma align 0 /* turn off alignment requirement */#endif/* * COFF symbol types and classes as macros * * 'sym' in the macro defintion must be defined as: SYMENT *sym; */#define U_SYM_VALUE n_value#if (CPU_FAMILY == I960)#define COFF_EXT(sym) \ (((sym)->n_sclass == C_EXT) || ((sym)->n_sclass == C_LEAFEXT))#else /* (CPU_FAMILY == I960) */#if (CPU_FAMILY == ARM)#define COFF_EXT(sym) \ (((sym)->n_sclass == C_EXT) || \ ((sym)->n_sclass == C_THUMBEXT) || \ ((sym)->n_sclass == C_THUMBEXTFUNC))#else /* (CPU_FAMILY == ARM) */#define COFF_EXT(sym) \ ((sym)->n_sclass == C_EXT)#endif /* (CPU_FAMILY == ARM) */#endif /* (CPU_FAMILY == I960) *//* COFF Undefined External Symbol */#define COFF_UNDF(sym) \ (((sym)->n_sclass == C_EXT) && ((sym)->n_scnum == N_UNDEF))/* COFF Common Symbol * A common symbol type is denoted by undefined external * with its value set to non-zero. */#define COFF_COMM(sym) ((COFF_UNDF(sym)) && ((sym)->n_value != 0))/* COFF Unassigned type * An unassigned type symbol of class C_STAT generated by * some assemblers */#define COFF_UNASSIGNED(sym) (((sym)->n_sclass == C_STAT) && ((sym)->n_type == T_NULL))/* misc defines */#define INSERT_HWORD(WORD,HWORD) \ (((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff))#define EXTRACT_HWORD(WORD) \ (((WORD) & 0x00ff0000) >> 8) | ((WORD)& 0xff)#define SIGN_EXTEND_HWORD(HWORD) \ ((HWORD) & 0x8000 ? (HWORD)|0xffff0000 : (HWORD))#define SWAB_SHORT(s) \ ((((unsigned short) s & 0x00ff) << 8) | (((unsigned short) s & 0xff00) >> 8))#define MAX_SCNS 11 /* max sections supported */#define NO_SCNS 0#if (CPU_FAMILY == I960)#define MAX_ALIGNMENT 16 /* max boundary for architecture */#else /* (CPU_FAMILY == I960) */#define MAX_ALIGNMENT 4 /* max boundary for architecture */#endif /* (CPU_FAMILY == I960) */#if (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM)LOCAL int textSize; /* size of the "real" text not */ /* including the .lit section size */ /* needed by the 29K coff files */#endif /* (CPU_FAMILY == AM29XXX) || (CPU_FAMILY == ARM) */char *addrScn[MAX_SCNS]; /* where each section is located */LOCAL int max_scns = MAX_SCNS; /* load with MAX */LOCAL char stringMemErrMsg [] = "loadLib error: insufficient memory for strings table (need %d bytes).\n";LOCAL char extMemErrMsg [] = "loadLib error: insufficient memory for externals table (need %d bytes).\n";LOCAL char cantConvSymbolType [] = "loadLib error: can't convert '%s' symbol type - error = %#x.\n";LOCAL char cantAddSymErrMsg [] = "loadLib error: can't add '%s' to system symbol table - error = %#x.\n";#ifndef MULTIPLE_LOADERSLOCAL char fileTypeUnsupported [] = "loadLib error: File type with magic number %#x is not supported.\n";#endif#if (CPU_FAMILY == I960)LOCAL char symNotFoundErrMsg [] = "loadLib error: trying to relocate to non-existent symbol\n";#endif /* (CPU_FAMILY == I960) */#if (CPU_FAMILY == AM29XXX)LOCAL char outOfRangeErrMsg [] = "loadLib error: relative address out of range\n";LOCAL char hiHalfErrMsg [] = "loadLib error: IHIHALF missing in module\n";#endif /* (CPU_FAMILY == AM29XXX) */#if (CPU_FAMILY == ARM)LOCAL int sprFixTextOff[100]; /* SPR 21809 */LOCAL char outOfRangeErrMsg [] = "loadLib error: relative address out of range\n";LOCAL char symNotFoundErrMsg [] = "loadLib error: trying to relocate to non-existent symbol\n";LOCAL char incorrectEndiannessErrMsg [] = "loadLib error: incorrect endianness for target\n";#endif /* (CPU_FAMILY == ARM) *//* forward declarations */LOCAL void coffFree ();LOCAL void coffSegSizes ();LOCAL STATUS coffReadSym ();#if (CPU_FAMILY == AM29XXX)LOCAL STATUS coffRelSegmentAm29K ();#endif /* (CPU_FAMILY == AM29XXX) */#if (CPU_FAMILY == I960)LOCAL STATUS coffRelSegmentI960 ();#endif /* (CPU_FAMILY == I960) */#if (CPU_FAMILY == ARM)LOCAL STATUS coffRelSegmentArm ();#endif /* (CPU_FAMILY == ARM) */LOCAL STATUS softSeek ();LOCAL STATUS fileRead ();LOCAL STATUS swabData ();LOCAL void swabLong ();LOCAL ULONG coffTotalCommons ();LOCAL ULONG dataAlign ();LOCAL STATUS coffHdrRead ();LOCAL STATUS coffOpthdrRead ();LOCAL STATUS coffSecHdrRead ();LOCAL STATUS coffLoadSections ();LOCAL STATUS coffReadRelocInfo ();LOCAL STATUS coffReadExtSyms ();LOCAL STATUS coffReadExtStrings ();LOCAL STATUS coffSymTab (int fd, struct filehdr *pHdr, SYMENT *pSymbols, char ** *externals, int symFlag, SEG_INFO *pSeg, char *symStrings, SYMTAB_ID symTbl, char *pNextCommon, struct scnhdr *pScnHdrArray, char **pScnAddr, BOOL symsAbsolute, BOOL swapTables, UINT16 group);/******************************************************************************** loadCoffInit - initialize the system for coff load modules.** This routine initializes VxWorks to use a COFF format for loading * modules.** RETURNS: OK** SEE ALSO: loadModuleAt()*/STATUS loadCoffInit ( ) { /* XXX check for installed? */ loadRoutine = (FUNCPTR) ldCoffModAtSym; return (OK); }/******************************************************************************** ldCoffModAtSym - load object module into memory with specified symbol table** This routine is the underlying routine to loadModuleAtSum(). This interface* allows specification of the the symbol table used to resolve undefined* external references and to which to add new symbols.** RETURNS:* MODULE_ID, or* NULL if can't read file or not enough memory or illegal file format** NOMANUAL*/MODULE_ID ldCoffModAtSym ( FAST int fd, /* fd from which to read module */ int symFlag, /* symbols to be added to table * ([NO | GLOBAL | ALL]_SYMBOLS) */ char **ppText, /* load text segment at address pointed to by this * pointer, return load address via this pointer */ char **ppData, /* load data segment at address pointed to by this * pointer, return load address via this pointer */ char **ppBss, /* load bss segment at address pointed to by this * pointer, return load address via this pointer */ SYMTAB_ID symTbl /* symbol table to use */ ) { char *pText = (ppText == NULL) ? LD_NO_ADDRESS : *ppText; char *pData = (ppData == NULL) ? LD_NO_ADDRESS : *ppData; char *pBss = (ppBss == NULL) ? LD_NO_ADDRESS : *ppBss; char **externalsBuf = NULL; /* array of symbol absolute values */ char *externalSyms = NULL; /* buffer for object file symbols */ char *stringsBuf = NULL; /* string table pointer */ FILHDR hdr; /* module's COFF header */ AOUTHDR optHdr; /* module's COFF optional header */ SCNHDR scnHdr[MAX_SCNS]; /* module's COFF section headers */ char *scnAddr[MAX_SCNS]; /* array of section loaded address */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -