diff --git a/librz/arch/opcodes/meson.build b/librz/arch/opcodes/meson.build index 5c1cc0f96a5..2cb76f72ba2 100644 --- a/librz/arch/opcodes/meson.build +++ b/librz/arch/opcodes/meson.build @@ -18,6 +18,8 @@ sdb_opcodes_files = [ 'ppc', 'propeller', 'riscv', + 'rx', + 'rl78', 'sh', 'sparc', 'sysz', diff --git a/librz/arch/opcodes/rx.sdb.txt b/librz/arch/opcodes/rx.sdb.txt new file mode 100644 index 00000000000..f84cd6e0e91 --- /dev/null +++ b/librz/arch/opcodes/rx.sdb.txt @@ -0,0 +1,129 @@ +abs=absolute value +add=byte data addition without carry +sub=subtract data +adc=addition of byte data with carry +and=logical and +bclr=clear a bit +bnot=inverts a bit +bset=set a bit +btst=test a bit to set C/Z flag +clrpsw=clear a flag in the PSW reg +cmp=compare two operands +div=divide signed +divu=divide unsigned +emul=extended multiply signed +emulu=extended multiply unsigned +fadd=float-point addition +fcmp=compare float-point +fdiv=divide float-point +fmul=multiply float-point +fsub=subtract float-point +ftoi=convert float-point to signed integer +itof=convert signed integer to float-point +machi=multiply-accumulate the upper words +maclo=multiply-accumulate the lower words +max=maximum of two signed integers +min=minimum of two signed integers +mov=move data +mov=move data unsigned +xchg=exchange data +mul=multiply data +mulhi=multiply the upper words +mullo=multiply the lower words +mvfachi=move data from upper longword([b32,b63]) of the accumulator(acc) +mvfacmi=move data from middle longword([b16, b47]) of the accumulator(acc) +mvtachi=move data to upper longword([b32,b63]) of the accumulator(acc) +mvtaclo=move data to lower longword([b0, b31]) of the accumulator(acc) +mvfc=move data from a control register +mvtc=move data to a control register +mvtipl=move data to IPL +neg=negate operand (2's complement) +not=logical not (1's complement) +or=logical or +xor=logical xor +nop=do nothing +pop=pop register from stack +popc=pop a control register from stack +popm=pop multiple registers from stack +push= push a register to stack +pushc=push a control register to stack +pushm=push multiple registers to stack +racw=round the accumulator into a word and stores result +revl=reverse endian within longword +revw=reverse endian within word +rmpa=repeat multiply-accumulate +rolc=rotate left with carry +rorc=rotate right with carry +rotl=rotate left +rotr=rotate right +round=round float-point to signed integer +rte=return from exception +rtfi=return from fast interrupt +rts=return from subroutine +rtsd=return from subroutine after deallocating stack frames +sat=saturate (generate 7FFFFFFFh if flag O and S are set to 1 else generate 80000000) +satr=saturate from rmpa +sbb=subtract with borrow +setpsw=set a flag or bit in PSW +shar=arithmetic shift right +shlr=logical shift right +shll=logical shift left +scmpu=string compare until not equal +smovb=string move backward +smovf=string move forward +smovu=string move until zero detected +sstr=string store +suntil=string search until equal +swhile=string search while equal +stnz=store(move) data on not zero +stz=store(move) on zero +tst=test logical (S = MSB(op1&op2) Z = !(op1&op2)) +wait=pause and wait interrupt +int=software interrupt +jmp=unconditional +jsr=jump to a subroutine +bra=unconditional relative branch +brk=unconditional trap +bsr=relative branch to a subroutine +scgeu=store truth value of condition if C == 1 (unsigned <=) +sceq=store truth value of condition if Z == 1 (==) +scgtu=store truth value of condition if (C & ~Z) == 1 (unsigned <) +scpz=store truth value of condition if S == 0 ( >= 0) +scge=store truth value of condition if (S ^ O) == 0 (signed <=) +scgt=store truth value of condition if ((S ^ O) | Z) == 0 (signed <) +sco=store truth value of condition if O == 1 (overflow) +scltu=store truth value of condition if C == 0 (unsigned >) +scne=store truth value of condition if Z == 0 (!=) +scleu=store truth value of condition if (C & ~Z) == 0 (unsigned >=) +scn=store truth value of condition if S == 1 ( < 0 ) +scle=store truth value of condition if ((S ^ O) | Z) == 1 (<) +sclt=store truth value of condition if (S ^ O) == 1 (>) +scno=store truth value of condition if O == 0 +bgeu=conditional relative branch if C == 1 (unsigned <=) +beq=conditional relative branch if Z == 1 (==) +bgtu=conditional relative branch if (C & ~Z) == 1 (unsigned <) +bpz=conditional relative branch if S == 0 ( >= 0) +bge=conditional relative branch if (S ^ O) == 0 (signed <=) +bgt=conditional relative branch if ((S ^ O) | Z) == 0 (signed <) +bo=conditional relative branch if O == 1 (overflow) +bltu=conditional relative branch if C == 0 (unsigned >) +bne=conditional relative branch if Z == 0 (!=) +bleu=conditional relative branch if (C & ~Z) == 0 (unsigned >=) +bn=conditional relative branch if S == 1 ( < 0 ) +ble=conditional relative branch if ((S ^ O) | Z) == 1 (<) +blt=conditional relative branch if (S ^ O) == 1 (>) +bno=conditional relative branch if O == 0 +bmgeu=store truth value of condition to a bit if C == 1 (unsigned <=) +bmeq=store truth value of condition to a bit if Z == 1 (==) +bmgtu=store truth value of condition to a bit if (C & ~Z) == 1 (unsigned <) +bmpz=store truth value of condition to a bit if S == 0 ( >= 0) +bmge=store truth value of condition to a bit if (S ^ O) == 0 (signed <=) +bmgt=store truth value of condition to a bit if ((S ^ O) | Z) == 0 (signed <) +bmo=store truth value of condition to a bit if O == 1 (overflow) +bmltu=store truth value of condition to a bit if C == 0 (unsigned >) +bmne=store truth value of condition to a bit if Z == 0 (!=) +bmleu=store truth value of condition to a bit if (C & ~Z) == 0 (unsigned >=) +bmn=store truth value of condition to a bit if S == 1 ( < 0 ) +bmle=store truth value of condition to a bit if ((S ^ O) | Z) == 1 (<) +bmlt=store truth value of condition to a bit if (S ^ O) == 1 (>) +bmno=store truth value of condition to a bit if O == 0 diff --git a/librz/arch/p/analysis/analysis_rx.c b/librz/arch/p/analysis/analysis_rx.c index 08058130589..2f9332d458c 100644 --- a/librz/arch/p/analysis/analysis_rx.c +++ b/librz/arch/p/analysis/analysis_rx.c @@ -29,6 +29,38 @@ static void calculate_jmp_addr(RxInst *inst, RzAnalysisOp *op) { op->fail = op->addr + op->size; } +static int rx_operand_cnt(RxInst *inst) { + int cnt = 0; + if (inst->v0.kind != RX_OPERAND_NULL) { + cnt++; + } + if (inst->v1.kind != RX_OPERAND_NULL) { + cnt++; + } + if (inst->v2.kind != RX_OPERAND_NULL) { + cnt++; + } + return cnt; +} + +static inline RxOperand *rx_operand_get(RxInst *inst, int idx) { + if (idx >= rx_operand_cnt(inst)) { + RZ_LOG_WARN("Failed to get operand%d of ISA Renesas Rx\n", idx); + rz_warn_if_reached(); + return NULL; + } + switch (idx) { + case 0: + return &inst->v0; + case 1: + return &inst->v1; + case 2: + return &inst->v2; + default: + return NULL; + } +} + static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) { op->addr = addr; @@ -46,12 +78,16 @@ static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, switch (inst.op) { // jump related instructions case RX_OP_RTS: + op->type = RZ_ANALYSIS_OP_TYPE_RET; + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = 4; + break; + case RX_OP_RTSD: + // use register to deallocate stack frames op->type = RZ_ANALYSIS_OP_TYPE_RET; break; case RX_OP_BSR_A: - case RX_OP_BSR_L: case RX_OP_BSR_W: - case RX_OP_JSR: op->type = RZ_ANALYSIS_OP_TYPE_CALL; calculate_jmp_addr(&inst, op); break; @@ -61,7 +97,6 @@ static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, op->type = RZ_ANALYSIS_OP_TYPE_CJMP; calculate_jmp_addr(&inst, op); break; - case RX_OP_BRA_L: case RX_OP_BRA_A: case RX_OP_BRA_B: case RX_OP_BRA_S: @@ -69,17 +104,77 @@ static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, op->type = RZ_ANALYSIS_OP_TYPE_JMP; calculate_jmp_addr(&inst, op); break; + case RX_OP_BRA_L: case RX_OP_JMP: - // use register - op->type = RZ_ANALYSIS_OP_TYPE_JMP; + // use register to jump unconditionally + op->type = RZ_ANALYSIS_OP_TYPE_IRJMP; + break; + case RX_OP_BSR_L: + case RX_OP_JSR: + // use register to call unconditionally + op->type = RZ_ANALYSIS_OP_TYPE_IRCALL; + break; + + // stack related operations + case RX_OP_PUSH: + case RX_OP_PUSHC: + op->type = RZ_ANALYSIS_OP_TYPE_PUSH; + op->stackop = RZ_ANALYSIS_STACK_DEC; + op->stackptr = 4; + break; + case RX_OP_PUSHM: + op->type = RZ_ANALYSIS_OP_TYPE_PUSH; + op->stackop = RZ_ANALYSIS_STACK_DEC; + op->stackptr = 4 * (inst.v1.v.reg.reg - inst.v0.v.reg.reg + 1); + break; + case RX_OP_POP: + case RX_OP_POPM: + op->type = RZ_ANALYSIS_OP_TYPE_POP; + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = 4; break; + case RX_OP_POPC: + op->type = RZ_ANALYSIS_OP_TYPE_POP; + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = 4 * (inst.v1.v.reg.reg - inst.v0.v.reg.reg + 1); + break; + // normal instruction - case RX_OP_ADD: case RX_OP_ADD_UB: case RX_OP_ADC: + // add imm, rn, rm op->type = RZ_ANALYSIS_OP_TYPE_ADD; break; + case RX_OP_ADD: + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + if (rx_operand_cnt(&inst) == 2) { + // add imm, sp + const RxOperand *op0 = rx_operand_get(&inst, 0); + if (op0->kind == RX_OPERAND_IMM) { + const RxOperand *op1 = rx_operand_get(&inst, 1); + if (op1->kind == RX_OPERAND_REG && op1->v.reg.reg == RX_REG_R0) { + // modify SP + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = op0->v.imm.imm; + } + } + } + break; case RX_OP_SUB: + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + if (rx_operand_cnt(&inst) == 2) { + // sub imm, sp + const RxOperand *op0 = rx_operand_get(&inst, 0); + if (op0->kind == RX_OPERAND_IMM) { + const RxOperand *op1 = rx_operand_get(&inst, 1); + if (op1->kind == RX_OPERAND_REG && op1->v.reg.reg == RX_REG_R0) { + // modify SP + op->stackop = RZ_ANALYSIS_STACK_DEC; + op->stackptr = op0->v.imm.imm; + } + } + } + break; case RX_OP_SUB_UB: op->type = RZ_ANALYSIS_OP_TYPE_SUB; break; @@ -115,20 +210,13 @@ static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, case RX_OP_NOP: op->type = RZ_ANALYSIS_OP_TYPE_NOP; break; + case RX_OP_NEG: + op->type = RZ_ANALYSIS_OP_TYPE_CPL; + break; case RX_OP_CMP: case RX_OP_CMP_UB: op->type = RZ_ANALYSIS_OP_TYPE_CMP; break; - case RX_OP_PUSH: - case RX_OP_PUSHM: - case RX_OP_PUSHC: - op->type = RZ_ANALYSIS_OP_TYPE_PUSH; - break; - case RX_OP_POP: - case RX_OP_POPM: - case RX_OP_POPC: - op->type = RZ_ANALYSIS_OP_TYPE_POP; - break; case RX_OP_ROTL: case RX_OP_ROLC: op->type = RZ_ANALYSIS_OP_TYPE_ROL; @@ -154,15 +242,26 @@ static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, case RX_OP_XOR_UB: op->type = RZ_ANALYSIS_OP_TYPE_XOR; break; - case RX_OP_ITOF: - case RX_OP_FTOI: - case RX_OP_ITOF_UB: - op->type = RZ_ANALYSIS_OP_TYPE_CAST; - break; case RX_OP_INT: + case RX_OP_RTE: + case RX_OP_RTFI: op->type = RZ_ANALYSIS_OP_TYPE_SWI; break; case RX_OP_MOV: + op->type = RZ_ANALYSIS_OP_TYPE_MOV; + if (rx_operand_cnt(&inst) == 2) { + // mov sp, rn + const RxOperand *op0 = rx_operand_get(&inst, 0); + const RxOperand *op1 = rx_operand_get(&inst, 1); + if (op0->kind == RX_OPERAND_IMM) { + if (op1->kind == RX_OPERAND_REG && op1->v.reg.reg == RX_REG_R0) { + // modify SP + op->stackop = RZ_ANALYSIS_STACK_SET; + op->stackptr = op0->v.imm.imm; + } + } + } + break; case RX_OP_MOVU: case RX_OP_MVTIPL: case RX_OP_MVTC: @@ -173,7 +272,39 @@ static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, case RX_OP_MVFC: op->type = RZ_ANALYSIS_OP_TYPE_MOV; break; + case RX_OP_ABS: + op->type = RZ_ANALYSIS_OP_TYPE_ABS; + break; + + // FPU + case RX_OP_FADD: + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; + case RX_OP_FSUB: + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; + case RX_OP_FMUL: + op->type = RZ_ANALYSIS_OP_TYPE_MUL; + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; + case RX_OP_FDIV: + op->type = RZ_ANALYSIS_OP_TYPE_DIV; + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; + case RX_OP_FCMP: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; + case RX_OP_ITOF: + case RX_OP_FTOI: + case RX_OP_ITOF_UB: + op->type = RZ_ANALYSIS_OP_TYPE_CAST; + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; default: + op->type = RZ_ANALYSIS_OP_TYPE_UNK; break; } diff --git a/librz/bin/format/elf/glibc_elf.h b/librz/bin/format/elf/glibc_elf.h index 63b8bb91f82..070db55d1ba 100644 --- a/librz/bin/format/elf/glibc_elf.h +++ b/librz/bin/format/elf/glibc_elf.h @@ -4248,6 +4248,101 @@ enum { #define DT_HEXAGON_VER 0x70000001 #define DT_HEXAGON_PLT 0x70000002 +/* Renesas RX specific elf format */ +/* From Renesas RX toolchain source: binutils/bfd/elf32-rx.c & binutils/include/elf/rx.h */ +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_RX_CPU_MASK 0x000003FF /* specific cpu bits. */ +#define EF_RX_ALL_FLAGS (EF_RX_CPU_MASK) +#define EF_RX_64BIT_DOUBLES (1 << 0) +#define EF_RX_DSP (1 << 1) /* Defined in the RX CPU Object file specification, but not explained. */ +#define EF_RX_PID (1 << 2) /* Unofficial - DJ */ +#define EF_RX_ABI (1 << 3) /* Binary passes stacked arguments using natural alignment. Unofficial - NC. */ +#define EF_RX_SINSNS_SET (1 << 6) /* Set if bit-5 is significant. */ +#define EF_RX_SINSNS_YES (1 << 7) /* Set if string instructions are used in the binary. */ +#define EF_RX_SINSNS_NO 0 /* Bit-5 if this binary must not be linked with a string instruction using binary. */ +#define EF_RX_SINSNS_MASK (3 << 6) /* Mask of bits used to determine string instruction use. */ +#define EF_RX_V1 (1 << 4) /* RX v1 instructions */ +#define EF_RX_V2 (1 << 5) /* RX v2 instructions */ +#define EF_RX_V3 (1 << 8) /* RX v3 instructions */ +#define EF_RX_V3_DFPU (1 << 9) /* instructions with DFPU (only for RX v3)*/ +#define EF_RX_V_MASK (19 << 4) /* Mask of bits used to determine ISA */ + +/* Renesas RX relocation type */ +#define R_RX_NONE 0x00 +/* These are for data, and are bi-endian. */ +#define R_RX_DIR32 0x01 /* Was: R_RX_32. */ +#define R_RX_DIR24S 0x02 /* Was: R_RX_24. */ +#define R_RX_DIR16 0x03 +#define R_RX_DIR16U 0x04 /* Was: R_RX_16_UNS. */ +#define R_RX_DIR16S 0x05 /* Was: R_RX_16. */ +#define R_RX_DIR8 0x06 +#define R_RX_DIR8U 0x07 /* Was: R_RX_8_UNS. */ +#define R_RX_DIR8S 0x08 /* Was: R_RX_8. */ +/* Signed pc-relative values. */ +#define R_RX_DIR24S_PCREL 0x09 /* Was: R_RX_24_PCREL. */ +#define R_RX_DIR16S_PCREL 0x0a /* Was: R_RX_16_PCREL. */ +#define R_RX_DIR8S_PCREL 0x0b /* Was: R_RX_8_PCREL. */ +/* These are for fields in the instructions. */ +#define R_RX_DIR16UL 0x0c +#define R_RX_DIR16UW 0x0d +#define R_RX_DIR8UL 0x0e +#define R_RX_DIR8UW 0x0f +#define R_RX_DIR32_REV 0x10 +#define R_RX_DIR16_REV 0x11 +#define R_RX_DIR3U_PCREL 0x12 +/* These are extensions added by Red Hat. */ +#define R_RX_RH_3_PCREL 0x20 /* Like R_RX_DIR8S_PCREL but only 3-bits. */ +#define R_RX_RH_16_OP 0x21 /* Like R_RX_DIR16 but for opcodes - always big endian. */ +#define R_RX_RH_24_OP 0x22 /* Like R_RX_DIR24S but for opcodes - always big endian. */ +#define R_RX_RH_32_OP 0x23 /* Like R_RX_DIR32 but for opcodes - always big endian. */ +#define R_RX_RH_24_UNS 0x24 /* Like R_RX_DIR24S but for unsigned values. */ +#define R_RX_RH_8_NEG 0x25 /* Like R_RX_DIR8 but -x is stored. */ +#define R_RX_RH_16_NEG 0x26 /* Like R_RX_DIR16 but -x is stored. */ +#define R_RX_RH_24_NEG 0x27 /* Like R_RX_DIR24S but -x is stored. */ +#define R_RX_RH_32_NEG 0x28 /* Like R_RX_DIR32 but -x is stored. */ +#define R_RX_RH_DIFF 0x29 /* Subtract from a previous relocation. */ +#define R_RX_RH_GPRELB 0x2a /* Byte value, relative to __gp. */ +#define R_RX_RH_GPRELW 0x2b /* Word value, relative to __gp. */ +#define R_RX_RH_GPRELL 0x2c /* Long value, relative to __gp. */ +#define R_RX_RH_RELAX 0x2d /* Marks opcodes suitable for linker relaxation. */ +/* These are for complex relocs. */ +// TODO: maybe implement reloc_convert for those +#define R_RX_ABS32 0x41 +#define R_RX_ABS24S 0x42 +#define R_RX_ABS16 0x43 +#define R_RX_ABS16U 0x44 +#define R_RX_ABS16S 0x45 +#define R_RX_ABS8 0x46 +#define R_RX_ABS8U 0x47 +#define R_RX_ABS8S 0x48 +#define R_RX_ABS24S_PCREL 0x49 +#define R_RX_ABS16S_PCREL 0x4a +#define R_RX_ABS8S_PCREL 0x4b +#define R_RX_ABS16UL 0x4c +#define R_RX_ABS16UW 0x4d +#define R_RX_ABS8UL 0x4e +#define R_RX_ABS8UW 0x4f +#define R_RX_ABS32_REV 0x50 +#define R_RX_ABS16_REV 0x51 +/* For RX operation */ +#define R_RX_SYM 0x80 +#define R_RX_OPneg 0x81 +#define R_RX_OPadd 0x82 +#define R_RX_OPsub 0x83 +#define R_RX_OPmul 0x84 +#define R_RX_OPdiv 0x85 +#define R_RX_OPshla 0x86 +#define R_RX_OPshra 0x87 +#define R_RX_OPsctsize 0x88 +#define R_RX_OPscttop 0x8d +#define R_RX_OPand 0x90 +#define R_RX_OPor 0x91 +#define R_RX_OPxor 0x92 +#define R_RX_OPnot 0x93 +#define R_RX_OPmod 0x94 +#define R_RX_OPromtop 0x95 +#define R_RX_OPramtop 0x96 + __END_DECLS #endif /* elf.h */ diff --git a/librz/bin/p/bin_elf.inc b/librz/bin/p/bin_elf.inc index aebf8592f94..6cd4e1fafc8 100644 --- a/librz/bin/p/bin_elf.inc +++ b/librz/bin/p/bin_elf.inc @@ -1285,6 +1285,34 @@ static void patch_reloc(struct Elf_(rz_bin_elf_obj_t) * obj, RzBinElfReloc *rel, } break; } + case EM_RX: + // no dynamic for rx-elf program, handle rx elf object reloc type (emulate linkage map) + // and no GOT/PLT for existed for rx-elf, leave no imports info for extern symbol + switch (rel->type) { + // simply use rizin default symbol resolution to map OBJECT variable symbol to vaddr + case R_RX_NONE: break; + case R_RX_DIR32: + val = S + A; + rz_buf_write_ble32_at(obj->buf_patched, patch_addr, val, obj->big_endian); + break; + case R_RX_DIR24S_PCREL: + val = S + A - P + 1; + if (obj->big_endian) { + buf[2] = val; + buf[1] = val >> 8; + buf[0] = val >> 16; + } else { + buf[0] = val; + buf[1] = val >> 8; + buf[2] = val >> 16; + } + // write 3 Bytes + rz_buf_write_at(obj->buf_patched, patch_addr, buf, 3); + break; + default: + RZ_LOG_WARN("Reloc type %d for Renesas RX family not implemented yet.\n", rel->type); + break; + } } } @@ -1482,6 +1510,15 @@ static RzBinReloc *reloc_convert(ELFOBJ *bin, RzBinElfReloc *rel, ut64 GOT) { break; } break; + case EM_RX: + switch (rel->type) { + case R_RX_NONE: break; + case R_RX_DIR24S_PCREL: ADD(24, -P); + case R_RX_DIR32: SET(32); + default: + RZ_LOG_WARN("unimplemented ELF/RX reloc type %d\n", rel->type); + break; + } default: break; } diff --git a/test/db/analysis/rx b/test/db/analysis/rx index d71fa1d8009..e733d13dd70 100644 --- a/test/db/analysis/rx +++ b/test/db/analysis/rx @@ -54,6 +54,26 @@ NX false EOF RUN +NAME=RX reloc info +FILE=bins/rx/reloc_tmp +ARGS= +CMDS=< 81 sym.___strtok_r +0xfff4037c 12 103 -> 73 sym.___strtok_r 0xfff403e3 1 6 sym._strtok_r 0xfff403e9 35 4023 -> 411 sym.__vfprintf_r 0xfff413ee 1 18 sym._vfprintf @@ -243,8 +263,8 @@ EXPECT=< 79 sym.___call_exitprocs -0xfff41657 11 263 -> 215 sym._quorem -0xfff4175e 33 2479 -> 400 sym.__dtoa_r +0xfff41657 11 263 -> 211 sym._quorem +0xfff4175e 232 2479 -> 2275 sym.__dtoa_r 0xfff4210d 6 223 -> 53 sym.___sflush_r 0xfff42229 5 43 -> 34 sym.__fflush_r 0xfff42254 3 35 sym._fflush @@ -290,7 +310,7 @@ EXPECT=< 85 sym.___lo0bits 0xfff42ea8 3 44 sym.___i2b 0xfff42ed4 22 291 -> 287 sym.___multiply -0xfff42ffc 13 122 -> 98 sym.___pow5mult +0xfff42ffc 13 122 sym.___pow5mult 0xfff43076 12 179 -> 153 sym.___lshift 0xfff4312b 7 45 sym.___mcmp 0xfff4315a 12 190 sym.___mdiff @@ -342,7 +362,7 @@ EXPECT=< 50 sym.__init_signal_r 0xfff44822 6 50 sym.__signal_r -0xfff44856 9 81 -> 75 sym.__raise_r +0xfff44856 9 81 -> 68 sym.__raise_r 0xfff448a7 12 81 -> 78 sym.___sigtramp_r 0xfff448f8 1 14 sym._raise 0xfff44906 1 16 sym._signal @@ -364,4 +384,65 @@ EXPECT=<