📄 loadsomcofflib.c
字号:
else if (pSym->symbol_type == ST_STORAGE) { if (pSym->secondary_def) continue; vxSymType = N_BSS | N_EXT; pSym->symbol_value += (unsigned int)pComm; DBG_PUT ("new STORAGE symbol %s (0x%x)\n", name, pSym->symbol_value); if (externSymAdd (symTbl, name, (char*)pSym->symbol_value, vxSymType, group, 0) != OK) { printErr ("can't add symbol %s (errno=%#x)\n", name, errnoGet()); } } /* look up external symbols */ else { if (externSymResolve (symTbl, name, pSym) != OK) { printErr ("undefined symbol: %s\n", name); status = ERROR; } } } DBG_PUT ("done with rdSymtab\n"); return (status); }/********************************************************************************* de_assemble_21 - encode a 21 bit immediate.** The PA-RISC encode immediate values in the instruction word in bizaar* ways. See the PA-RISC architecture manual for details.*/static int de_assemble_21 ( unsigned int x ) { return ((x & 0x100000) >> 20 | (x & 0xffe00) >> 8 | (x & 0x180) << 7 | ( x & 0x7c) << 14 | (x & 0x3) << 12); }/********************************************************************************* de_assemble_17 - encode a 17 bit immediate.** The PA-RISC encode immediate values in the instruction word in bizaar* ways. See the PA-RISC architecture manual for details.*/static int de_assemble_17 ( unsigned int x ) { return ((x & 0x10000) >> 16 | (x & 0xf800) << 5 | (x & 0x400) >> 8 | (x & 0x3ff) << 3); }/********************************************************************************* de_assemble_12 - encode a 12 bit immediate.** The PA-RISC encode immediate values in the instruction word in bizaar* ways. See the PA-RISC architecture manual for details.*/static int de_assemble_12 ( unsigned int x ) { return ((x & 0x800) >> 11 | (x & 0x400) >> 8 | (x & 0x3ff) << 3); }/********************************************************************************* de_low_sign_ext - encode a sign extended immediate of length len** The PA-RISC encode immediate values in the instruction word in bizaar* ways. See the PA-RISC architecture manual for details.*/static int de_low_sign_ext ( int x, int len ) { int tmp; if (len > 32) return (x); tmp = x & ((1 << len) - 1); return ((tmp & ((1 << (len - 1)))) >> (len - 1) | ((tmp & ((1 << (len -1)) - 1)) << 1)); }/********************************************************************************* L_fixValue - mask off the low bits.*/static unsigned long L_fixValue ( unsigned long x ) { return (x & 0xfffff800); }/********************************************************************************* R_fixValue - mask off the high bits.*/static unsigned long R_fixValue ( unsigned long x ) { return (x & 0x000007ff); }/********************************************************************************* RND_fixValue - round to nearest 8k (0x2000) byte boundary*/static unsigned long RND_fixValue ( unsigned long x ) { return ((x + 0x1000) & 0xffffe000); }/******************************************************************************** LR_fixValue - mask off low bits after rounding.*/static unsigned long LR_fixValue ( unsigned long x, unsigned long fixConst ) { return (L_fixValue (x + RND_fixValue(fixConst))); }/******************************************************************************** RR_fixValue - mask off high bits after rounding.*/static unsigned long RR_fixValue ( unsigned long x, unsigned long fixConst ) { return (R_fixValue (x + RND_fixValue(fixConst)) + (fixConst - RND_fixValue(fixConst))); }/********************************************************************************* fieldValue - perform rounding.** This function performs rounding during a fixup request.* The field selector, mode selector, and round constant are computed* by the fuction fieldGetDefault() (see below) and passed to us.** RETURNS: A rounded value, based on the original value, field selector,* mode selector, and round constant.*/static UINT fieldValue ( UINT value, UINT fSel, UINT mSel, UINT roundConst ) { UINT retVal = value; switch (fSel) { /* FSEL = no rounding needed */ case R_FSEL: retVal = value + roundConst; break; /* LSEL = "left" bits (round first, then zero out the right bits) */ case R_LSEL: switch (mSel) { case R_N_MODE: /* round down (L') mode */ retVal = L_fixValue (value + roundConst); break; case R_S_MODE: /* round to nearest page (LS') mode */ value += roundConst; if (value & 0x00000400) retVal = L_fixValue (value + 0x800); else retVal = value; break; case R_D_MODE: /* round up (LD') mode */ retVal = L_fixValue (value + roundConst + 0x800); break; case R_R_MODE: /* round up with adjust (LR') mode */ retVal = LR_fixValue (value, roundConst); break; } break; /* RSEL = "right" bits (round first, then zero out the left bits) */ case R_RSEL: switch (mSel) { case R_N_MODE: /* round down (R') mode */ retVal = R_fixValue (value + roundConst); break; case R_S_MODE: /* round to nearest page (RS') mode */ value += roundConst; if (value & 0x00000400) retVal = value | 0xfffff800; else retVal = value; break; case R_D_MODE: /* round up (RD') mode */ retVal = (value + roundConst) | 0xfffff800; break; case R_R_MODE: /* round with adjust (RR') mode */ retVal = RR_fixValue (value, roundConst); break; } break; default: WARN ("Warning: unknown field selector %d\n", fSel); break; } return (retVal); }/********************************************************************************* fieldGetDefault - compute the field selector and rounding mode.** This function looks at the current instruction to determine* the field value, rounding mode, and rounding constant.*/static void fieldGetDefault ( UINT instr, /* machine instruction */ int fieldOverride, /* field selector override flag */ int dataOverride, /* fixed constant override flag */ int * pFieldSel, /* where to return field selector */ int * pFormat, /* how to deposit bits */ int * pFixConst /* where to return fixup constant */ ) { unsigned int disp; unsigned int majorCode = (instr & 0xfc000000) >> 26; /* set field selector */ if (!fieldOverride) { switch (majorCode) { case LDIL_CODE: case ADDIL_CODE: *pFieldSel = R_LSEL; break; case BL_CODE: case COMBT_CODE: case COMBF_CODE: case ADDB_CODE: case ADDBF_CODE: case BB_CODE: *pFieldSel = R_FSEL; break; default: *pFieldSel = R_RSEL; break; } } /* get relocation bit */ switch (majorCode) { /* i_exp14 */ case LDW_CODE: case LDH_CODE: case LDB_CODE: case STW_CODE: case STH_CODE: case STB_CODE: case LDWM_CODE: case STWM_CODE: case LDO_CODE: disp = instr & 0x3fff; disp = low_sign_ext (disp, 14); *pFormat = i_exp14; break; /* i_exp11 */ case ADDI_CODE: case ADDIT_CODE: case SUBI_CODE: case COMICKR_CODE: disp = instr & 0x7ff; disp = low_sign_ext (disp, 11); *pFormat = i_exp11; break; /* i_exp21 */ case LDIL_CODE: case ADDIL_CODE: disp = assemble_21 (instr & 0x1fffff); disp = disp & 0x3fff; *pFormat = i_exp21; break; /* i_rel17 */ case BL_CODE: /* i_abs17 */ case BE_CODE: case BLE_CODE: disp = instr & 0x1fffff; disp = sign_ext(assemble_17 ((disp & 0x1f0000)>>16, (disp & 0x1ffc) >> 2, disp & 0x1), 17) << 2; *pFormat = i_rel17; /* i_rel17 and i_abs17 same format */ break; /* i_rel12 */ case ADDIBT_CODE: case ADDIBF_CODE: case COMIBT_CODE: case COMIBF_CODE: disp = instr & 0x1ffd; disp = sign_ext (assemble_12 ((disp & 0x1ffc) >> 2, disp & 0x1), 12) << 2; *pFormat = i_rel12; break; default: disp = 0; *pFormat = i_none; break; } if (!dataOverride) *pFixConst = disp; }/********************************************************************************* fixBits - Perform a linker fixup to modify an instruction.*/static void fixBits ( INSTR * adrs, /* where to fix */ int value, /* value to fix */ int format /* fixup format */ ) { int mask; switch (format) { case i_exp14: value = de_low_sign_ext (value, 14); mask = 0x3fff; break; case i_exp21: value = de_assemble_21 (value >> 11);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -