assert(rs != 0);
return mkFormD(14, rd, rs, N & 0xFFFF); /* addi rd,rs,N */
}
+static UInt gen_addis_rd_rs_N ( UInt rd, UInt rs, UInt N ) {
+ assert(rs != 0);
+ return mkFormD(15, rd, rs, N & 0xFFFF); /* addis rd,rs,N */
+}
static UInt gen_crorc_6_6_6 ( void ) {
return 0x4CC63342; /* crorc 6,6,6 */
}
}
static Int emit_li32 ( UInt* code, Int ix, UInt rd, UInt imm32 ) {
code[ix++] = gen_lis_r_N(rd, imm32 >> 16);
- code[ix++] = gen_ori_r_r_N(rd, imm32 & 0xFFFF);
+ if (imm32 & 0xFFFF)
+ code[ix++] = gen_ori_r_r_N(rd, imm32 & 0xFFFF);
return ix;
}
static Int emit_dosc ( UInt* code, Int ix ) {
/* So, the code. First, prepare for and do a _loadx syscall, to
get the tool aboard:
+ addis 1, 1, -4
imm 2, __NR__loadx
imm 3, VKI_DL_LOAD
- imm 4, 0
- mr 5, 4
+ mr 4, 1
+ imm 5, 3<<16
addi 6, 31, offset_of_toolfile
mr 7, 4
mr 8, 4
mr 9, 4
mr 10,4
SYSCALL_SEQUENCE
+ addis 1, 1, 4
If the syscall failed, r4 will be nonzero. Branch elsewhere if so.
cmpi 4, 0
} else {
/* 32-bit sequence */
+ ix = emit_insn( &block.code[0],ix,
+ gen_addis_rd_rs_N(1,1,-4) );
ix = emit_li32( &block.code[0],ix, 2, __nr___loadx );
ix = emit_li32( &block.code[0],ix, 3, VKI_DL_LOAD );
- ix = emit_li32( &block.code[0],ix, 4, 0 );
- ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(5,4) );
+ ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(4,1) );
+ ix = emit_li32( &block.code[0],ix, 5, 3<<16 );
ix = emit_insn( &block.code[0],ix,
gen_addi_rd_rs_N(6,31,offsetof(AIX5Bootblock,toolfile)));
- ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(7,4) );
- ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(8,4) );
- ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(9,4) );
- ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(10,4) );
+ ix = emit_li32( &block.code[0],ix, 7, 0);
+ ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(8,7) );
+ ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(9,7) );
+ ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(10,7) );
ix = emit_dosc( &block.code[0],ix );
+ ix = emit_insn( &block.code[0],ix,
+ gen_addis_rd_rs_N(1,1,4) );
ix = emit_insn( &block.code[0],ix, gen_cmpli_cr7_r_N(4,0) );
Int ix_bne = ix; /* Patch this later */
ix = emit_insn( &block.code[0],ix, 0 );
"lwz 4,0(28)\n\t" /* set %r4 = buf */
"lwz 5,4(28)\n\t" /* set %r5 = n */
+ "crorc 6,6,6\n\t"
".long 0x48000005\n\t" /* bl .+4 */
"mflr 29\n\t"
- "addi 29,29,20\n\t"
+ "addi 29,29,16\n\t"
"mtlr 29\n\t"
- "crorc 6,6,6\n\t"
"sc\n\t" /* write() */
"stw 3,0(28)\n\t" /* result */
"lwz 2,0(28)\n\t" /* set %r2 = __NR_getpid */
+ "crorc 6,6,6\n\t"
".long 0x48000005\n\t" /* bl .+4 */
"mflr 29\n\t"
- "addi 29,29,20\n\t"
+ "addi 29,29,16\n\t"
"mtlr 29\n\t"
- "crorc 6,6,6\n\t"
"sc\n\t" /* getpid() */
"stw 3,0(28)\n\t" /* result -> block[0] */
"ld 4,0(28)\n\t" /* set %r4 = buf */
"ld 5,8(28)\n\t" /* set %r5 = n */
+ "crorc 6,6,6\n\t"
".long 0x48000005\n\t" /* bl .+4 */
"mflr 29\n\t"
- "addi 29,29,20\n\t"
+ "addi 29,29,16\n\t"
"mtlr 29\n\t"
- "crorc 6,6,6\n\t"
"sc\n\t" /* write() */
"std 3,0(28)\n\t" /* result */
"ld 2,0(28)\n\t" /* set %r2 = __NR_getpid */
+ "crorc 6,6,6\n\t"
".long 0x48000005\n\t" /* bl .+4 */
"mflr 29\n\t"
- "addi 29,29,20\n\t"
+ "addi 29,29,16\n\t"
"mtlr 29\n\t"
- "crorc 6,6,6\n\t"
"sc\n\t" /* getpid() */
"std 3,0(28)\n\t" /* result -> block[0] */
"lwz 9, 28(28)\n\t"
"lwz 10, 32(28)\n\t"
+ // set bit 3 of CR1 otherwise AIX 5.1 returns to the
+ // wrong address after the sc instruction
+ "crorc 6,6,6\n\t"
+
// set up LR to point just after the sc insn
".long 0x48000005\n\t" // "bl here+4" -- lr := & next insn
"mflr 29\n\t"
- "addi 29,29,20\n\t"
+ "addi 29,29,16\n\t"
"mtlr 29\n\t"
- // set bit 3 of CR1 otherwise AIX 5.1 returns to the
- // wrong address after the sc instruction
- "crorc 6,6,6\n\t"
-
// do it!
"sc\n\t"
"ld 9, 56(28)\n\t"
"ld 10, 64(28)\n\t"
+ // set bit 3 of CR1 otherwise AIX 5.1 returns to the
+ // wrong address after the sc instruction
+ "crorc 6,6,6\n\t"
+
// set up LR to point just after the sc insn
".long 0x48000005\n\t" // "bl here+4" -- lr := & next insn
"mflr 29\n\t"
- "addi 29,29,20\n\t"
+ "addi 29,29,16\n\t"
"mtlr 29\n\t"
- // set bit 3 of CR1 otherwise AIX 5.1 returns to the
- // wrong address after the sc instruction
- "crorc 6,6,6\n\t"
-
// do it!
"sc\n\t"
mr 6,7 /* nsigwords -- needed on AIX ? */
/* actually do the sigprocmask */
+ crorc 6,6,6
.long 0x48000005 /* bl here+4 */
mflr 26
addi 26,26,16
lwz 10,OFFSET_ppc32_GPR10(30)
mr 2,31 /* syscall number */
+ crorc 6,6,6
.long 0x48000005 /* bl here+4 */
mflr 26
addi 26,26,16
mr 6,28 /* nsigwords -- needed on AIX ? */
/* actually do the sigprocmask */
+ crorc 6,6,6
.long 0x48000005 /* bl here+4 */
mflr 26
addi 26,26,16
mr 6,7 /* nsigwords -- needed on AIX ? */
/* actually do the sigprocmask */
+ crorc 6,6,6
.long 0x48000005 /* bl here+4 */
mflr 26
addi 26,26,16
ld 10,OFFSET_ppc64_GPR10(30)
mr 2,31 /* syscall number */
+ crorc 6,6,6
.long 0x48000005 /* bl here+4 */
mflr 26
addi 26,26,16
mr 6,28 /* nsigwords -- needed on AIX ? */
/* actually do the sigprocmask */
+ crorc 6,6,6
.long 0x48000005 /* bl here+4 */
mflr 26
addi 26,26,16
"mr 2,23\n\t" /* r2 = __NR_exit */
"mr 3,22\n\t" /* set r3 = tst->os_state.exitcode */
/* set up for syscall */
+ "crorc 6,6,6\n\t"
".long 0x48000005\n\t" /* "bl here+4" */
"mflr 29\n\t"
"addi 29,29,16\n\t"
"mr 2,23\n\t" /* r2 = __NR_exit */
"mr 3,22\n\t" /* set r3 = tst->os_state.exitcode */
/* set up for syscall */
+ "crorc 6,6,6\n\t"
".long 0x48000005\n\t" /* "bl here+4" */
"mflr 29\n\t"
"addi 29,29,16\n\t"
Copyright (C) 2000-2006 Julian Seward
jseward@acm.org
-
+ Copyright (C) 2006-2006 OpenWorks LLP
+ info@open-works.co.uk
+
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
lwz 2,0(3) /* r2 = __NR___loadx */
lwz 5,20(3) /* r5 = off_preloadcorename */
add 6,3,5 /* r6 = preloadcorename */
+ addis 1,1,-4
bl do___loadx
+ addis 1,1,4
cmpwi 0,3,0
beq .Lfailed
cmpwi 0,5,0 /* skip tool preload if */
beq .Ltry_preload /* name not present */
add 6,3,5 /* r6 = preloadtoolname */
+ addis 1,1,-4
bl do___loadx
+ addis 1,1,4
cmpwi 0,3,0
beq .Lfailed
cmpwi 0,5,0 /* skip ld_preload if */
beq .Lstart_client /* name not present */
add 6,3,5 /* r6 = ld_preloadname */
+ addis 1,1,-4
bl do___loadx
+ addis 1,1,4
cmpwi 0,3,0
beq .Lfailed
/* On entry: r2 = __NR___loadx, r6 = name of module */
li 3,1
slwi 3,3,24 /* r3 = 0x1000000 = VKI_DL_LOAD */
- li 4,0
- li 5,0
+ mr 4,1
+ lis 5,3
li 7,0
li 8,0
li 9,0
li 10,0
do_syscall:
+ crorc 6,6,6
sc
+ trap
/* sc continues at 'lr', hence this
constitutes an automatic return */
li 9,0
li 10,0
do_syscall:
+ crorc 6,6,6
sc
/* sc continues at 'lr', hence this
constitutes an automatic return */