⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadsomcofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* loadSomCoffLib.c - HP-PA SOM COFF object module loader *//* Copyright 1984-1994 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02n,30nov98,dbt  no longer clear seg.flags<xxx> after loadSegmentAllocate()                 call. (SPR #23553).02m,05oct98,pcn  Initialize all the fields in the SEG_INFO structure.02l,16sep98,pcn  Set to SEG_ALIGN the flags field in seg structure                 (SPR #21836).02k,19aug98,cym  Fixed SPR #22030: Target Loader won't load partially linked		 objects.02j,17jul98,pcn  Fixed SPR #21836: alignment mismatch between sections and                 target.02i,01apr97,jmb  propagated an arg_reloc patch from the target server loader.02h,14nov96,mem  rewrote handling of branch stubs in order to fix some		 link problems.  Stubs now have the arg_reloc bits of the		 symbol they represent stored with them, rather than		 the bits of the call they where originally created with.02g,02aug96,jmb  merged in ease patch (mem) for sign_ext.02f,19dec95,mem  fixed fieldValue() function which did not always use the		 roundConst value.		 Modified section placement for GNU.		 Fixed B{1,2,3,4} macros which had multiple uses of		 pThisFixup++ in a single expression, (which is		 undefined behavior).02e,14nov94,kdl  removed conditional for CPU==SIMHPPA.02d,09nov94,ms   made R_UNINIT fixup act just like R_ZEROS fixup.02c,07nov94,kdl  merge cleanup - made conditional for CPU==SIMHPPA.02b,02aug94,ms   cleaned up the code a bit.02a,07jul94,ms   too many bug fixes to count. Major rewrite.                 Added "long branch stub" generation.                 Added "parameter relocation stub" generation                 Added "unwind" segment generation.01g,03may94,ms   fixed the handling of R_PREV_FIXUP requests.01f,02may94,ms   checked in yaos work. Added minor bug fix (bssFlag).01e,18apr94,yao  added fileType paramater to rdSymtab().  changed to add                 DATA_SEGMENT_BASE to symbol of data type for shared                  object files.01d,28mar94,yao  changed to call lst operation routines in relSegments().01c,28feb94,yao  added loadBssSizeGet () for relocatable files.  removed                  macro STORE(), added routine fixBits() to deposit relocation                  bits.  added fieldGetDefault(). added deassemble control                  functions de_assemble_X(). added fixup rounding functions                  X_fixup().01c,02feb94,yao  included dsmLib.h.01b,06dec93,gae  fixed warnings.01a,12sep93,yao  written.*//*DESCRIPTIONThis library provides an object module loading facility for theHP-PA compiler environment.  Relocatable SOM COFF format files may be loaded into memory, relocated, their external references resolved, and their external definitions added to the system symbol table for use by other modules and from the shell.  Modules may be loaded from any I/O streamwhich supports FIOSEEK.EXAMPLE.CS    fdX = open ("/devX/objFile", O_RDONLY);    loadModule (fdX, ALL_SYMBOLS);    close (fdX);.CEThis code fragment would load the HP-PA SOM 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: loadSomCoffLib.hSEE ALSO: loadLib, usrLib, symLib, memLib,.pG "Basic OS"*//*INTERNALThe HP-PA SOM COFF linking loader is complicated as hell.This is due to a combination of the fact that the PA-RISChas a very un-RISC like instruction set, and that thecalling conventions have a strange parameter passing mechanism.The following is an attempt to describesome of the differences between this loader and other VxWorksloaders.Subspace to segment mapping---------------------------The current VxWorks paradigm assumes there are three "segments" -text, data, and bss. The SOM COFF format instead uses the conceptof spaces and subspaces. There are two loadable spaces; text and data.Each of these spaces is divided into many subspaces.For example, each function is put in its own text subspace,and each global variable is put in its own data subspace.To fit the VxWorks paradigm we must map the subspaces into VxWorks segments.The routine subspaceToSegment() performs this function by looping througheach subspace and deciding what segment to put it in. The array pSubInfois initialized with information on each subspace: It's loadType (text,data, or bss), and it's loadAddr (we compute a relative load address foreach subspace - it's final load address won't be know until weallocate memory for the text, data, and bss segments).Uninitailized global (but non-static) variables are treated by thecompiler as "request for storage" (sometimes called "common data" or"weak externals"). All VxWorks loaders simply add these variablesas bss, so we do likewise. The routine commSizeGet() computes the numberof bytes needed for these variables, and this size is added to the bss size.This is more efficient than performing a malloc() for each variable,as is done in other VxWorks loaders.A "stack unwind" segment is also generated for the stack tracer to use.See src/arch/simhppa/trcLib.c for details.Long branch stubs-----------------When code is compiled with optimization, the compiler generatesa PC-relative "BL" (branch and link) instruction for all procedure calls.The problem is that the displacement must fit into 19 bits, so if thecalled procedure is further than 256k bytes away, we have no way tofixup the instruction.The solution is to generate a two instruction "long branch stub",and make that stub the target of the "BL" instruction. It is ourresponsibility to generate this stub, and to make sure that the stubitself is close enough to the caller of "BL".For each text subspace, the procedure subspaceSizeExtra() computesthe amount of space needed by that subspace for possible long branch stubs.Thus when we map the text subspaces to the "text segment", we actually leavea bit of room between each subspace according to the value ofsubspaceSizeExtra() for that subspace.Parameter relocation--------------------The PA-RISC passes the first four words of the parameter list inregisters, and the return value also goes in a register.floating point parameters are passed in floating point registers,and other parameters are passed in general purpose registers.The problem is that the caller and the callee may not agree asto where the parameters are located. For example, printf() expectsits parameters to be in the general purpose registers, whereas a calllike   printf ("%f", myFloat)passes the second parameter in a floating point register.The compiler generates information on how a procedure expectsto be called, and on how it is actually called. It is our job tomake sure they match, and if they don't, to insert a "parameterrelocation stub" between the caller and the callee.Parameter relocation information is encoded in 10 bits - 2 bitseach for the first four arguments words and the return value.Each 2 bit quantity specifies "unused, general register, floatregister, or double persion float register".When a new function is loaded, the 10 bit relocation info generatedby the compiler must be stored away in the VxWorks symbol table forfuture reference, In order to do this I had tocreate a new structure called "MY_SYMBOL", which is just likethe VxWorks "SYMBOL", but has an extra 8 bit field at the end. It turnsout that the size of MY_SYMBOL is the same as the size of SYMBOLbecause of compiler padding, so no harm was done. The functionsexternSymResolve() and externSymAdd() perform VxWorks symboltable manipulation with MY_SYMBOL stuctures.When a function is called, the 10 parameter relocation bitsare encoded in the fixup request associated with the function call.The routines rbits1() and rbits2() get the bits from the fixup request(actually, the 10 bits are encoded in 9 or fewer bits in the fixuprequest, so rbits1() and rbits2() do some work to extract the infoand decode it to 10 bits). We then compare the callers reclocationbits with the callees and if they differ, we may ned to generatea stub (if we hadn't previously generated a stub for that function).Currently, this is only done if the callee expects general registersand the caller passses a double - which takes care of functionslike printf, sprintf, etc. The loader prints an error message ifany other type of parameter reloction is needed. It would be easy to addother parameter relocation stubs at a later time.Fixup requests--------------The linking fixup requests are passed to us as a byte stream.The number of bytes in each fixup request depends on thefixup request, and there are 71 different types of fixup requests!The routine linkSubspaces() performs the linker fixup requests, andit is complicated as hell. The comments in that routine describe it further.just to give you an idea of how complicated our friends at HP have madethings: The linker must keep a queue of the last four multi-bytefixup requests. There is a one byte fixup requests called "repeatprevious fixup" which directs us to repeat one of the previous fixupsfrom the queue, and then move the fixup to the front of the queue!Currently there are many branches in linkSubspaces() that havenot been tested.*/#include "vxWorks.h"#include "stdio.h"#include "som_coff.h"#include "ioLib.h"#include "dsmLib.h"#include "fioLib.h"#include "bootLoadLib.h"#include "loadLib.h"#include "loadSomCoffLib.h"#include "memLib.h"#include "pathLib.h"#include "lstLib.h"#include "string.h"#include "symLib.h"#include "sysSymTbl.h"#include "errnoLib.h"#include "stdlib.h"#include "symbol.h"#include "moduleLib.h"#include "cacheLib.h"#define LOAD_NONE   0#define LOAD_TEXT   1#define LOAD_DATA   2#define LOAD_BSS    3#define SEG_ALIGN  8/* Some PA-RISC opCodes */#define LDIL_CODE       0x08#define ADDIL_CODE      0x0a#define BL_CODE         0x3a#define COMBT_CODE      0x20#define COMBF_CODE      0x22#define ADDB_CODE       0x28#define ADDBF_CODE      0x2a#define BB_CODE         0x31#define LDW_CODE        0x12#define LDH_CODE        0x11#define LDB_CODE        0x10#define STW_CODE        0x1a#define STH_CODE        0x19#define STB_CODE        0x18#define LDWM_CODE       0x13#define STWM_CODE       0x1b#define LDO_CODE        0x0d#define ADDI_CODE       0x2d#define ADDIT_CODE      0x2c#define SUBI_CODE       0x25#define COMICKR_CODE    0x24#define ADDIBT_CODE     0x29#define ADDIBF_CODE     0x2b#define COMIBT_CODE     0x21#define COMIBF_CODE     0x23#define BE_CODE         0x38#define BLE_CODE        0x39/* some handy macros for linkSubspaces() */#define B1 (*(pThisFixup++))#define B2 ((int)(pThisFixup += 2), \    (int) ((pThisFixup[-2] << 8) + pThisFixup[-1]))#define B3 ((int)(pThisFixup += 3), \    (int) ((pThisFixup[-3] << 16) + (pThisFixup[-2] << 8) + pThisFixup[-1]))#define B4 ((int)(pThisFixup += 4), \    (int) ((pThisFixup[-4] << 24) + (pThisFixup[-3] << 16) \           + (pThisFixup[-2] << 8) + pThisFixup[-1]))#define REL_STACK_SIZE  (10000)   /* size of relocation stack pointer */#define POP_EXPR        (*--sp)#define PUSH_EXPR(x)    (*sp ++ = (x))#define CHECK_STACK_OVER  if (sp >= pExpStack + REL_STACK_SIZE) \                              { \                              printErr ("ld error: stack overflow\n");\                              status = ERROR; \                              }#define CHECK_STACK_UNDER if (sp <= pExpStack) \                              { \                              printErr ("ld error: stack underflow\n");\                              status = ERROR; \                              }#define FLAG_RESET(flag)  if (flag) flag = FALSE;/* subspace relocation info */typedef struct    {    char * loadAddr;    int loadType;    } SUB_INFO;/* "previous fixup" queue */typedef struct    {    NODE node;    UCHAR *pFixup;    } PREV_FIXUP;/* stack unwind structures */typedef struct    {    char *startAddr;    char *endAddr;    UINT word3;    UINT word4;    } UNWIND_DESC;typedef struct    {    NODE node;    UNWIND_DESC unwindDesc;    } UNWIND_NODE;/* list of long branch stubs */typedef struct stubListNode    {    NODE node;    int symNum;    int arg_reloc;    } STUB_LIST_NODE;/* list of argument relocation stubs */typedef struct    {    NODE     node;    SYMREC * pSym;    int      arg_reloc;    char *   stubAddr;    } ARG_RELOC_NODE;/* modified symbol table entry */typedef struct                  /* MY_SYMBOL - entry in symbol table */    {    SL_NODE     nameHNode;      /* hash node (must come first) */    char        *name;          /* pointer to symbol name */    char        *value;         /* symbol value */    UINT16      group;          /* symbol group */    SYM_TYPE    type;           /* symbol type */    UCHAR       arg_reloc;      /* relocation bits */    } MY_SYMBOL;/* local variables *//* SPR 22030: changed entry for fixup 62 from 0 to 1 */static int fixupLen [256] =    {    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 19 */    1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 2, 4, 2, 4, 1, 2, 4, 2, /* 20 - 39 */    4, 1, 2, 3, 5, 8, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, /* 40 - 59 */    5, 5, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 5, 5, 0, 0, /* 60 - 79 */    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 99 */    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 0, 0, 0, 0, 0, 0, /* 100 - 119 */    2, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 120 - 139 */    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 140 - 159 */    2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 4, 1, 9, /* 160 - 179 */    6, 1, 1, 1, 1, 2, 4, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, /* 180 - 199 */    1, 1, 2, 3, 4, 5, 1,12, 2, 5, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* 200 - 219 */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 220 - 239 */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0              /* 240 - 255 */    };static UINT longBranchStub[] =        {        0x20200000,     /* LDIL    0, r1 */        0xe0202002      /* BE,n    0(s4, r1) */        };static stubSize = 8;/* externals */extern low_sign_ext (int x, int len);extern sign_ext     (int x, int len);extern assemble_21  (int x);extern assemble_17  (int x, int y, int z);extern assemble_12  (int x, int y);extern sysMemTop    (void);/* forward static functions */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -