Author Topic: G5 qemu attempts.  (Read 59148 times)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #80 on: October 16, 2018, 08:10:00 AM »
Ok I'm game, but you'll have to walk me through what I need to do, as so far I only understand some of what we are doing.

Ok, consider the following code (that's the beginning of bcopy):

Code: [Select]
0x20FB4C      cmplwi  cr7, r5, 0x20
0x20FB50      cmplw   cr6, r4, r3
0x20FB54      mr.     r0, r5
0x20FB58      bgt     cr7, 0x20FB70
0x20FB5C      beq     cr7, 0x20FBC4
0x20FB60      blt     cr6, 0x20FC74
0x20FB64      add     r3, r3, r5
0x20FB68      add     r4, r4, r5
0x20FB6C      b       0x20FC08

The first two instructions are unsigned comparisons, cr7 is the condition field that will be set according with the comparison result, we're going to compare r5 (copy length) with 0x20:

Code: [Select]
cr7.eq = r5 - 0x20
cr7.lt = r5 - 0x20
cr7.gt = r5 - 0x20

where "eq" denotes equality, "lt" - lower then, "gt" - greater than. In other words, if r5 == 0x20, the "eq" flag of CR7 will be set, otherwise cleared; if r5 < 0x20, "lt" is set, otherwise cleared an so on.

You'd basically start the trace on G4 at 0x203ce8 and proceed by executing every single instruction using "stepi". Then you write down updated register values, for example "add r3, r3, r5" will update $r3 so you need to write that new value down.

Regarding conditional branches: beq (branch if equal), blt (branch if lower) an so on - you'll only need to write down if a particular branch is taken or not (I'm using "+" for taken and "-" for not taken).

The PowerPC instruction reference will be very useful here...

Then you take that list and compares the results with the trace on G5. It's tedious, yes, but this way you should be able to spot the failing instruction...

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #81 on: October 16, 2018, 09:15:33 AM »
You completely lost me :-\

I need to set the break point to  0x203ce8, then I'm not sure what command to use to trace, before I use stepi?

I know it's painful, but once I understand the first one, thing should go a little quicker. 8)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #82 on: October 16, 2018, 09:29:56 AM »
You completely lost me :-\

I need to set the break point to  0x203ce8, then I'm not sure what command to use to trace, before I use stepi?

You don't need anything else than "stepi". Just set the breakpoint, then trace with stepi.

Code: [Select]
(gdb) break *0x203ce8
(gdb) cont
(gdb) display/i $pc
(gdb) stepi (this will excute b 0x20fe70)
(gdb) stepi (this will execute b 0x20fb4c)
(gdb) stepi (this will execute cmplwi cr7, r5, 0x20)
(gdb) stepi (this will execute cmplw cr6, r4, r3)
(gdb) stepi (this will execute mr. r0, r5 after it r0 = r5, no need to track it)
(gdb) stepi (execute bgt cr7, 0x20FB70 --> conditional branch, mark it with "+" if it jumps to 0x20fb70, otherwise mark it with "-")
(gdb) stepi (beq cr7, 0x20FBC4 --> another cond branch, proceed as above)
(gdb) stepi (blt cr6, 0x20FC74 --> yet another cond branch, proceed as above)
(gdb) stepi (add  r3, r3, r5 --> changes $r3, so...)
(gdb) p/x $r3 (write down new $r3 value)

an so on...

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #83 on: October 16, 2018, 10:01:49 AM »
Still lost:

Code: [Select]
Breakpoint 1, 0x0000000000203ce8 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x203ce8: bl      0x20fe70
(gdb) stepi
0x000000000020fe70 in ?? ()
1: x/i $pc
=> 0x20fe70: b       0x20fb4c
(gdb) stepi
0x000000000020fb4c in ?? ()
1: x/i $pc
=> 0x20fb4c: cmplwi  cr7,r5,32
(gdb) stepi
0x000000000020fb50 in ?? ()
1: x/i $pc
=> 0x20fb50: cmplw   cr6,r4,r3
(gdb) stepi
0x000000000020fb54 in ?? ()
1: x/i $pc
=> 0x20fb54: mr.     r0,r5
(gdb) stepi
0x000000000020fb58 in ?? ()
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70
(gdb) stepi
0x000000000020fb70 in ?? ()
1: x/i $pc
=> 0x20fb70: beqlr   cr6
(gdb) stepi
0x000000000020fb74 in ?? ()
1: x/i $pc
=> 0x20fb74: bltlr   
(gdb) stepi
0x000000000020fb78 in ?? ()
1: x/i $pc
=> 0x20fb78: mflr    r12
(gdb) stepi
0x000000000020fb7c in ?? ()
1: x/i $pc
=> 0x20fb7c: bge     cr6,0x20fba0
(gdb) stepi
0x000000000020fba0 in ?? ()
1: x/i $pc
=> 0x20fba0: add     r3,r3,r5
(gdb) p/x $r3
$1 = 0x3fee5038
(gdb)

Code: [Select]
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70

conditional branch, but I don't understand what is being compared to what, or what is being done?

If what is greater than?


Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #84 on: October 16, 2018, 01:44:09 PM »
Code: [Select]
cmplwi  cr7,r5,32This compares r5 to 32 and sets condition register 7 (cr7) to the result.
Code: [Select]
bgt cr7, 0x20fb70This checks if the 'gt' flag in cr7 is set, and will branch to 0x20fb70 if that is the case.

Code: [Select]
mr.     r0,r5This moves r5 to r0. The modifier '.' can be placed at the end of quite a few instructions. It means that the result will be compared with zero and cr0 will be set with the result.

There are 8 condition register, cr0-cr7. Instructions that begin with 'cmp' typically let you set any one of them.

For more info on PowerPC conditional stuff, check out https://www.ibm.com/developerworks/library/l-powasm3/index.html

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #85 on: October 16, 2018, 02:05:38 PM »
Code: [Select]
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70

conditional branch, but I don't understand what is being compared to what, or what is being done?

If what is greater than?

Yes, these cryptic PowerPC conditions... It works similar to x86 architecture: comparison instructions provide flags and branches (jumps in Intel's jargon) consume them. The only difference is that x86 has only one flags register but PowerPC has 8 labeled cr0...cr7 (strictly speaking, PowerPC has ONE condition register with 8 fields but, for simplicity, let's assume it has 8 condition registers).

PowerPC instructions usually looks like that: OPCODE  DST, OP1, OP2. The first operand is usually the destination, i.e. it receives the result.

Code: [Select]
cmplwi cr7, r5, 0x20
is read as "compare unsigned value in $r5 with 32 and set eq, lt and gt flags of the condition register CR7 accordingly". The corresponding branch instruction bgt cr7,0x20fb70 does examine the specified condition in CR7 and takes one of the two actions: if the condition is true, it jumps to the destination address 0x20fb70, otherwise - the next instruction right after the branch will be executed.

In our precise example, the comparison will update three flags simultaneously but the branch will only consume the single condition: gt (greater than). So the final comparison and its corresponding branch can be collapsed to the following pseudo-C code:

Code: [Select]
if (r5 > 0x20) goto 0x20fb70

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #86 on: October 16, 2018, 02:12:28 PM »
There are 8 condition register, cr0-cr7. Instructions that begin with 'cmp' typically let you set any one of them.

Thank you, Daniel, for your great explanation. It looks like we got our answers crossed.

PowerPC can also omit the destination condition register: cmpwi r3, 0
In that case, CR0 is always assumed. Motorola docs call this "simplified mnemonics"...

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #87 on: October 16, 2018, 02:56:16 PM »
Code: [Select]
cmplwi  cr7,r5,32This compares r5 to 32 and sets condition register 7 (cr7) to the result.

So it's either 32 true or false? <>=?

So cr7 could have three values  < > or = to?

Quote
Code: [Select]
bgt cr7, 0x20fb70This checks if the 'gt' flag in cr7 is set, and will branch to 0x20fb70 if that is the case.

Still don't understand.

Quote
Code: [Select]
mr.     r0,r5This moves r5 to r0. The modifier '.' can be placed at the end of quite a few instructions. It means that the result will be compared with zero and cr0 will be set with the result.

You mean the value in r5 is copied to r0?

What's a modifier?

« Last Edit: October 16, 2018, 03:23:25 PM by darthnVader »

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #88 on: October 16, 2018, 03:27:19 PM »
Sorry. I guess my explanation only makes sense if you already understand it.

Each condition field has 4 bit flags: lt, gt, eq, so. A compare instruction will assign values to all four of those flags for the condition field specified. This provides enough information to allow ==, !=, >, <, >=, <=...etc. The 'bgt' instruction only looks at the gt flag of the specified field and ignores the rest.

Here's an example:
Code: [Select]
cmplwi cr6,r1,4
blt cr6,some_address
beq cr6,another_address
bgt cr6, yet_another_address
cr6 will be set with the results of the comparison. The four bit flags will indicate the relationship between the 2 numbers compared. The code will end up at 'some_address', 'another_address', or 'yet_another_address' depending on whether r1 is <, ==, or > 4.

Yes, the 'mr. r0, r5' copies r5 to r0. r0 will likely not actually be used. The main purpose is to do a quick compare with zero. I call it a modifier because it is a controllable feature of most instructions. 'mr.' is a 'mr' instruction that also compares the destination with zero. 'add.', 'rlwinm.', and 'xor.' have have this same relation to 'add', 'rlwinm', and 'xor'.

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #89 on: October 16, 2018, 04:31:36 PM »
Sorry. I guess my explanation only makes sense if you already understand it.

Each condition field has 4 bit flags: lt, gt, eq, so. A compare instruction will assign values to all four of those flags for the condition field specified. This provides enough information to allow ==, !=, >, <, >=, <=...etc. The 'bgt' instruction only looks at the gt flag of the specified field and ignores the rest.

Here's an example:
Code: [Select]
cmplwi cr6,r1,4
blt cr6,some_address
beq cr6,another_address
bgt cr6, yet_another_address
cr6 will be set with the results of the comparison. The four bit flags will indicate the relationship between the 2 numbers compared. The code will end up at 'some_address', 'another_address', or 'yet_another_address' depending on whether r1 is <, ==, or > 4.

Yes, the 'mr. r0, r5' copies r5 to r0. r0 will likely not actually be used. The main purpose is to do a quick compare with zero. I call it a modifier because it is a controllable feature of most instructions. 'mr.' is a 'mr' instruction that also compares the destination with zero. 'add.', 'rlwinm.', and 'xor.' have have this same relation to 'add', 'rlwinm', and 'xor'.

Still struggling to understand the first part:

cmplwi cr6,r1,4

cr6 is set to what if the value of r1 is equal to 4?


Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #90 on: October 16, 2018, 04:35:03 PM »
Still struggling to understand the first part:

cmplwi cr6,r1,4

cr6 is set to what if the value of r1 is equal to 4?

Code: [Select]
cr6.eq = 1 if r1 == 4
cr6.lt = 1 if r1 < 4
cr6.gt = 1 if r1 > 4

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #91 on: October 16, 2018, 04:45:30 PM »
Still struggling to understand the first part:

cmplwi cr6,r1,4

cr6 is set to what if the value of r1 is equal to 4?

Code: [Select]
cr6.eq = 1 if r1 == 4
cr6.lt = 1 if r1 < 4
cr6.gt = 1 if r1 > 4

ok, I understand there are 8 condition registers cr0-cr7, but I don't understand cr6.??

If r1 = 4

cr6.eq =1 (true)
cr6.lt = 0? (false)
cr6.gt = 0? (false)




Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #92 on: October 16, 2018, 04:51:27 PM »
ok, I understand there are 8 condition registers cr0-cr7, but I don't understand cr6.??

If r1 = 4

cr6.eq =1 (true)
cr6.lt = 0? (false)
cr6.gt = 0? (false)

Yes.

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #93 on: October 16, 2018, 04:53:27 PM »
ok, I understand there are 8 condition registers cr0-cr7, but I don't understand cr6.??

If r1 = 4

cr6.eq =1 (true)
cr6.lt = 0? (false)
cr6.gt = 0? (false)





Yes.

The condition registers are a 3 bit register, or they have three one bit registers?

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #94 on: October 16, 2018, 05:11:49 PM »
Sorry. I guess my explanation only makes sense if you already understand it.

Each condition field has 4 bit flags: lt, gt, eq, so. A compare instruction will assign values to all four of those flags for the condition field specified. This provides enough information to allow ==, !=, >, <, >=, <=...etc. The 'bgt' instruction only looks at the gt flag of the specified field and ignores the rest.

Here's an example:
Code: [Select]
cmplwi cr6,r1,4
blt cr6,some_address
beq cr6,another_address
bgt cr6, yet_another_address
cr6 will be set with the results of the comparison. The four bit flags will indicate the relationship between the 2 numbers compared. The code will end up at 'some_address', 'another_address', or 'yet_another_address' depending on whether r1 is <, ==, or > 4.

Yes, the 'mr. r0, r5' copies r5 to r0. r0 will likely not actually be used. The main purpose is to do a quick compare with zero. I call it a modifier because it is a controllable feature of most instructions. 'mr.' is a 'mr' instruction that also compares the destination with zero. 'add.', 'rlwinm.', and 'xor.' have have this same relation to 'add', 'rlwinm', and 'xor'.

Code: [Select]
1: x/i $pc
=> 0x20fb4c: cmplwi  cr7,r5,32
(gdb) stepi
0x000000000020fb50 in ?? ()
1: x/i $pc
=> 0x20fb50: cmplw   cr6,r4,r3
(gdb) stepi
0x000000000020fb54 in ?? ()
1: x/i $pc
=> 0x20fb54: mr.     r0,r5
(gdb) stepi
0x000000000020fb58 in ?? ()
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70

If the value of r5 is greater than 32 cr7.gt = 1 then brach to the address 0x20fb70?


Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #95 on: October 16, 2018, 05:19:11 PM »
Yes. Branch if r5 > 32.

The condition register is a 32-bit register split up into 8 sections (cr0-cr7) of 4 bits each (I really have no idea what the 'so' bits are used for, but 'lt', 'eq', and 'gt' are pretty clear). All the mnemonics like blt are essentially macros that expand into a more general branch instruction that takes a bit index into the cr as a whole. The compare instructions are still required to operate on cr0-cr7.


Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #96 on: October 16, 2018, 05:25:46 PM »
Yes. Branch if r5 > 32.

The condition register is a 32-bit register split up into 8 sections (cr0-cr7) of 4 bits each (I really have no idea what the 'so' bits are used for, but 'lt', 'eq', and 'gt' are pretty clear). All the mnemonics like blt are essentially macros that expand into a more general branch instruction that takes a bit index into the cr as a whole. The compare instructions are still required to operate on cr0-cr7.

Ok, I'm starting to understand, let's see if I can apply it to what I need to do.

Code: [Select]
(gdb) stepi (execute bgt cr7, 0x20FB70 --> conditional branch, mark it with "+" if it jumps to 0x20fb70, otherwise mark it with "-")
(gdb) stepi (beq cr7, 0x20FBC4 --> another cond branch, proceed as above)
(gdb) stepi (blt cr6, 0x20FC74 --> yet another cond branch, proceed as above)

How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #97 on: October 16, 2018, 05:30:34 PM »
I really have no idea what the 'so' bits are used for

SO - summary overflow. Used for implementing really big numbers...

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #98 on: October 16, 2018, 05:34:04 PM »
Yes. Branch if r5 > 32.

The condition register is a 32-bit register split up into 8 sections (cr0-cr7) of 4 bits each (I really have no idea what the 'so' bits are used for, but 'lt', 'eq', and 'gt' are pretty clear). All the mnemonics like blt are essentially macros that expand into a more general branch instruction that takes a bit index into the cr as a whole. The compare instructions are still required to operate on cr0-cr7.

Ok, I'm starting to understand, let's see if I can apply it to what I need to do.

Code: [Select]
(gdb) stepi (execute bgt cr7, 0x20FB70 --> conditional branch, mark it with "+" if it jumps to 0x20fb70, otherwise mark it with "-")
(gdb) stepi (beq cr7, 0x20FBC4 --> another cond branch, proceed as above)
(gdb) stepi (blt cr6, 0x20FC74 --> yet another cond branch, proceed as above)

How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?
An easy way to check it is to see what address gdb reported the program counter to be at.
Code: [Select]
0x000000000020fb58 in ?? ()
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70
(gdb) stepi
0x000000000020fb70 in ?? ()
1: x/i $pc
=> 0x20fb70: beqlr   cr6
It appears to have made the jump. The PC is 0x000000000020fb70 in the instruction immediately following the branch. Also, there might be some register dump command like '%cr' or something. I am not familiar with gdb, so I am not sure.

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #99 on: October 16, 2018, 05:34:59 PM »
How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?

Don't bother with them at all! We don't need to decompile this function - that's already done. Just record which code instructions are executed and concentrate yourself on everything that changes general purpose registers (r0...r31).