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

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #40 on: October 12, 2018, 05:47:07 AM »
That didn't work, gdb-multiarch must be the wrong debugger, I'll see if I can figure how to setup PPC gdb.

Did you try to invoke qemu-system-ppc64 with the "-g" option? Quoting https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-arm-mips-elf-with-qemu-toolchain

Quote
In order to debug the binary with GDB, you need to launch qemu-mips so that it exposes a GDB stub, and connect from GDB.

Here another similar post: http://tinkering-is-fun.blogspot.com/2009/12/debugging-non-native-programs-with-qemu.html

The -g argument is reserved for the graphics mode on the mac99 machine in qemu-system-ppc.

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #41 on: October 12, 2018, 07:04:40 AM »
I don't know if I'm doing this correct, if if I have the debugger setup correct, however:

It seem the closest point in the trampoline I can find a breakpoint for, before we get to the  memory overlap is a breakpoint 0x20dccc

Code: [Select]
Breakpoint 2, 0x000000000020dccc in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x20dccc: stwu    r1,-80(r1)
(gdb) stepi
0x000000000020dcd0 in ?? ()
1: x/i $pc
=> 0x20dcd0: stw     r6,116(r1)
(gdb)
0x000000000020dcd4 in ?? ()
1: x/i $pc
=> 0x20dcd4: stw     r7,120(r1)
(gdb)
0x000000000020dcd8 in ?? ()
1: x/i $pc
=> 0x20dcd8: stw     r8,124(r1)
(gdb)
0x000000000020dcdc in ?? ()
1: x/i $pc
=> 0x20dcdc: stw     r9,128(r1)
(gdb)
0x000000000020dce0 in ?? ()
1: x/i $pc
=> 0x20dce0: stw     r10,132(r1)
(gdb)
0x000000000020dce4 in ?? ()
1: x/i $pc
=> 0x20dce4: lwz     r30,-12(r2)
(gdb)
0x000000000020dce8 in ?? ()
1: x/i $pc
=> 0x20dce8: mr      r29,r5
(gdb)
0x000000000020dcec in ?? ()
1: x/i $pc
=> 0x20dcec: addi    r6,r2,26808
(gdb)
0x000000000020dcf0 in ?? ()
1: x/i $pc
=> 0x20dcf0: addi    r8,r29,2
(gdb)
0x000000000020dcf4 in ?? ()
1: x/i $pc
=> 0x20dcf4: stw     r6,0(r30)
(gdb)
0x000000000020dcf8 in ?? ()
1: x/i $pc
=> 0x20dcf8: cmpwi   r29,0
(gdb)
0x000000000020dcfc in ?? ()
1: x/i $pc
=> 0x20dcfc: stw     r8,4(r30)
(gdb)
0x000000000020dd00 in ?? ()
1: x/i $pc
=> 0x20dd00: addi    r31,r1,120
(gdb)
0x000000000020dd04 in ?? ()
1: x/i $pc
=> 0x20dd04: lwz     r9,116(r1)
(gdb)
0x000000000020dd08 in ?? ()
1: x/i $pc
=> 0x20dd08: addi    r7,r30,20
(gdb)
0x000000000020dd0c in ?? ()
1: x/i $pc
=> 0x20dd0c: addi    r9,r9,1
(gdb)
0x000000000020dd10 in ?? ()
1: x/i $pc
=> 0x20dd10: stw     r9,8(r30)
(gdb)
0x000000000020dd14 in ?? ()
1: x/i $pc
=> 0x20dd14: stw     r3,12(r30)
(gdb)
0x000000000020dd18 in ?? ()
1: x/i $pc
=> 0x20dd18: stw     r4,16(r30)
(gdb)
0x000000000020dd1c in ?? ()
1: x/i $pc

That maybe just gibberish, I don't know PPC assembly and I've only used gdb a few times to step though some C code, and never tried to debug a running target in Qemu.

Let me know if I'm barking up the wrong tree here?

The trampoline seem to hit that address a few times, so it breaks @ 0x20dccc a few times before it gets to this point:

 
Code: [Select]
Hardware info:
Dumping 192 bytes @ 0x3FEE4000
3FEE4000: 00C00000 6400000C 64048084 00003000
3FEE4010: 3FEDD000 3FEDF000 80040000 00000000
3FEE4020: 00000000 00000000 00000000 00000000
3FEE4030: 00000000 00000000 00000000 00001400
3FEE4040: 00000000 00000000 00000000 00000000
3FEE4050: 00000000 00000000 00000000 00000000
3FEE4060: 00000000 00000000 00000000 00000000
3FEE4070: 486E666F 00403035 00250024 08000800
3FEE4080: 00190000 08000800 00400000 00000000
3FEE4090: 00000000 00000004 00000000 00410000
3FEE40A0: 1A05D66A 00000000 3FEDE000 00000000
3FEE40B0: 00000000 00000000 00000000 00000000

HardwareInit info:
Dumping 32 bytes @ 0x3FEE7000
3FEE7000: 3FEE5000 3FEE6000 00000000 3FEE4000
3FEE7010: 00000000 00000080 00F10000 80012000

Cascade Info:
Dumping 516 bytes @ 0x00117818
00117818: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF
00117828: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117838: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117848: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117858: FFFFFFFF 01040404 04040402 04020402
00117868: 02000000 00000000 00000000 00000000
00117878: 00000000 00000000 00000000 00000000
00117888: 00000000 00000000 00000000 00000000
00117898: 00000000 00000000 00000000 00000000
001178A8: 00000000 00000000 00000000 00000000
001178B8: 00000000 00000000 00000000 00000000
001178C8: 00000000 00000000 00000000 00000000
001178D8: 00000000 00000000 00000000 00000000
001178E8: 00000000 00000000 00000000 00000000
001178F8: 00000000 00000000 00000000 00000000
00117908: 00000000 00000000 00000000 00000000
00117918: 00000000 00000000 00000000 00000000
00117928: 00000000 00000000 00000000 00000000
00117938: 00000000 00000000 00000000 00000000
00117948: 00000000 00000000 00000000 00000000
00117958: 00000000 00000000 00000000 00000000
00117968: 00000000 00000000 00000000 00000000
00117978: 00000000 00000000 00000000 00000000
00117988: 00000000 00000000 00000000 00000000
00117998: 00000000 00000000 00000000 00000000
001179A8: 00000000 00000000 00000000 00000000
001179B8: 00000000 00000000 00000000 00000000
001179C8: 00000000 00000000 00000000 00000000
001179D8: 00000000 00000000 00000000 00000000
001179E8: 00000000 00000000 00000000 00000000
001179F8: 00000000 00000000 00000000 00000000
00117A08: 00000000 00000000 00000000 00000000
00117A18: 00000000

The next continue gives:

Code: [Select]
IsKeyDown: no keys held down
Overlap in AddMemoryRelocationEntry().
    - dst = 0x00003000, dstLength = 0x0000052C, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
    - dst = 0x00003F80, dstLength = 0x00000080, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
    - dst = 0x00003F40, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
    - dst = 0x00003CFC, dstLength = 0x00000204, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
    - dst = 0x00003F00, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x00048298.



Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #42 on: October 12, 2018, 07:42:32 AM »
I don't know if I'm doing this correct, if if I have the debugger setup correct [snip]

Congrats! It looks like you got the QEMU+GDB toolchain set up correctly. Memory addresses are big-endian now (0x000000000020dccc instead of x86's 0x20dccc0000000000) and stepping works as well.

Would you mind posting a step-by-step instructions on how to setup that toolchain? Just for the case if someone want to step in and help us out...

It seem the closest point in the trampoline I can find a breakpoint for, before we get to the  memory overlap is a breakpoint 0x20dccc

I don't understand that. What command was used to set that breakpoint? Any other address doesn't work?

That maybe just gibberish, I don't know PPC assembly and I've only used gdb a few times to step though some C code, and never tried to debug a running target in Qemu.

The code looks right. 0x20dccc belongs to CallMethod() function inside the Trampoline. The function itself starts @0x20dcc0.

To be done next:

  • run a disassembler on the target code and obtain a good disassembly listing
  • PM me your GitLab account name. If you don't own any GitLab account, set up one first at gitlab.org. I'll grant you an access to my C source code for the Trampoline
  • obtain docs on the OF client interface (google for 1275-1994.pdf)

Then having the assembly listing on the left hand side and the C code on the right hand side, you'd trace the target code and compare its behavior with the expected one. This will be a lot of fun and you'll learn the PPC assembly very quickly ;D
« Last Edit: October 12, 2018, 06:13:56 PM by powermax »

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #43 on: October 12, 2018, 11:45:07 AM »
To build gdb-powerpc-linux on Linux, you'll need normal build tools such as gcc installed, I'll assume people know how to install that stuff with apt or their other package manager. Anything you don't have you need installed to build, it will likely let you know when you try to configure.

Download the GDB source code, I had trouble with the latest release, so likely people will want to use v7.9.

http://ftp.gnu.org/gnu/gdb/gdb-7.9.tar.gz

Unpack it and cd into the dir, then just:

Code: [Select]
./configure -target=powerpc-linux --enable-sim-powerpc
make && sudo make install

After that, all you need to do is launch qemu-system-ppc(64) with -s and -S, it will pause and listen on port 1234 for GDB.

Then in another terminal launch gdb:

Code: [Select]
gdb-powerpc-linux
target remote localhost:1234
continue

You'll likely want to set prom-env "auto-boot?=false" --nographic for Qemu.

Set your breakpoint in GDB, I.E.

Code: [Select]
break *0x20dccc

Then type boot in the Qemu terminal.

.



Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #44 on: October 13, 2018, 01:04:01 AM »
I don't know if I'm doing this correct, if if I have the debugger setup correct [snip]

Congrats! It looks like you got the QEMU+GDB toolchain set up correctly. Memory addresses are big-endian now (0x000000000020dccc instead of x86's 0x20dccc0000000000) and stepping works as well.

Would you mind posting a step-by-step instructions on how to setup that toolchain? Just for the case if someone want to step in and help us out...

It seem the closest point in the trampoline I can find a breakpoint for, before we get to the  memory overlap is a breakpoint 0x20dccc

I don't understand that. What command was used to set that breakpoint? Any other address doesn't work?



I was just trying to find a breakpoint nearest to the code that is causing the memory overlap. CallMethod() seems to be executed a few times, once just before we get our overlap, so hopefully that will help us find the exact code that needs work.

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #45 on: October 13, 2018, 02:54:15 AM »
I was just trying to find a breakpoint nearest to the code that is causing the memory overlap. CallMethod() seems to be executed a few times, once just before we get our overlap, so hopefully that will help us find the exact code that needs work.

I see. The problem is that CallMethod() is completely unrelated to our issue. You need to track calls to AddMemoryRelocationEntry() located @0x201DB4. This function has the following prototype:

Code: [Select]
int AddMemoryRelocationEntry(uint32_t src, uint32_t srcLength, uint32_t dst,
                             uint32_t dstLength, uint32_t flags);

The PowerPC ABI prescribes that the first 7 parameters will be always passed in registers starting with R3, i.e. R3 = src, R4 = srcLength, R5 = dst, R6 = dstLength, R7 = flags. Return values will be placed in R3. For further details, see reloc.c, line 75 in my code.

The destination address "dst" will be set to NULL somewhere causing AddMemoryRelocationEntry to reserve a big block of memory @0x00000000. That's wrong and the task is to determine why that actually happens.

I suppose that the faulty call to AddMemoryRelocationEntry is located in main at 0x2059f4. "dst"(R5) will probably contain NULL. This address is also calculated there based on the value in NKSystemInfo.PhysicalMemorySize that should contain zero in your precise case.

The task is also to verify if the above mentioned conditions hold true and when they do, try to find out which code sets NKSystemInfo.PhysicalMemorySize to zero.
« Last Edit: October 13, 2018, 05:33:23 AM by powermax »

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #46 on: October 13, 2018, 04:34:55 AM »
I was just trying to find a breakpoint nearest to the code that is causing the memory overlap. CallMethod() seems to be executed a few times, once just before we get our overlap, so hopefully that will help us find the exact code that needs work.

I see. The problem is that CallMethod() is completely unrelated to our issue. You need to track calls to AddMemoryRelocationEntry() located @0x201DB4. This function has the following prototype:

Code: [Select]
int AddMemoryRelocationEntry(uint32_t src, uint32_t srcLength, uint32_t dst,
                             uint32_t dstLength, uint32_t flags);

The Power ABI prescribes that the first 7 parameters will be always passed in registers starting with R3, i.e. R3 = src, R4 = srcLength, R5 = dst, R6 = dstLength, R7 = flags. Return values will be placed in R3. For further details, see reloc.c, line 75 in my code.

The destination address "dst" will be set to NULL somewhere causing AddMemoryRelocationEntry to reserve a big block of memory @0x00000000. That's wrong and the task is to determine why that actually happens.

I suppose that the faulty call to AddMemoryRelocationEntry is located in main at 0x2059f4. "dst"(R5) will probably contain NULL. This address is also calculated there based on the value in NKSystemInfo.PhysicalMemorySize that should contain zero in your precise case.

The task is also to verify if the above mentioned conditions hold true and when they do, try to find out which code sets NKSystemInfo.PhysicalMemorySize to zero.

Thanks, I understand some of that, I'll look into it, and see if I can figure some sort of work around. I'll just have to see what goes on in Qemu with the G4 CPU and maybe that will tell me what goes wrong with the G5.

I'm sure I'll have lots of question. ;D

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #47 on: October 13, 2018, 05:21:25 AM »
Thanks, I understand some of that, I'll look into it, and see if I can figure some sort of work around.

Let's spot the issue first by answering the following questions:

  • does the call to AddMemoryRelocationEntry in the basic block at 0x2059f4 pass zero in R5? (yes/no)
  • if 1. is true, does R3 at 0x2059fc contain zero as well? (yes/no)
  • please dump the memory pointed to by R23 at 0x2059fc and post it here. The size of the dump is 320 bytes (i.e. sizeof(NKSystemInfo))

I'm sure I'll have lots of question. ;D
Don't hesitate to ask here :D

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #48 on: October 14, 2018, 03:51:51 AM »
OK, I've successfully pulled the repo. It wasn't really what I was expecting, not that I'm complaining, but I was thinking it had the code to decompile the trampoline, and maybe patch and recompile it.

Like I say, not a complaint, I'm just not real sure how to use this code to patch the trampoline.

Anywho, the recol.c seems to contain the code we are tripping over:

Code: [Select]
int AddMemoryRelocationEntry(uint32_t src, uint32_t srcLength, uint32_t dst,
                             uint32_t dstLength, uint32_t flags)
{
    int i;
    uint32_t size;
    MemRelocEntry *pEntry;
    MemRelocList  *pNewList;

    if (gMemRelocList == 0) {
        gMemRelocList = ClaimMem(sizeof(MemRelocList), 2);
        if ((int)gMemRelocList == -1)
            return 0;

        gMemRelocList->cnt.nUsedEntries = 0;
        gMemRelocList->cnt.nFreeEntries = 64;
    }

    for (i = 0; i < gMemRelocList->cnt.nUsedEntries; i++) {
        pEntry = &gMemRelocList->entries[i];
        if ((dst + dstLength) > pEntry->dst && (pEntry->dst + pEntry->dst_len) > dst) {
            printf("Overlap in AddMemoryRelocationEntry().\r");
            printf("    - dst = 0x%08X, dstLength = 0x%08X,"
                   " entry->dst = 0x%08X, entry->dst_len = 0x%08X.\r",
                   dst, dstLength, pEntry->dst, pEntry->dst_len);
            gFatalErr = 1;
            return 1;
        }
    }

    for (i = 0; i < gMemRelocList->cnt.nUsedEntries; i++) {
        pEntry = &gMemRelocList->entries[i];
        if ((src + srcLength) > pEntry->src && (pEntry->src + pEntry->src_len) > src) {
            printf("Overlap in AddMemoryRelocationEntry().\r");
            printf("    - src = 0x%08X, srcLength = 0x%08X,"
                   " entry->src = 0x%08X, entry->src_len = 0x%08X.\r",
                   src, srcLength, pEntry->src, pEntry->src_len);
            gFatalErr = 1;
            return 1;
        }
    }

I'm not real sure exactly why we are failing here, or how to insert some code here to help with debugging?

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #49 on: October 14, 2018, 04:00:15 AM »
Thanks, I understand some of that, I'll look into it, and see if I can figure some sort of work around.

Let's spot the issue first by answering the following questions:

  • does the call to AddMemoryRelocationEntry in the basic block at 0x2059f4 pass zero in R5? (yes/no)
  • if 1. is true, does R3 at 0x2059fc contain zero as well? (yes/no)
  • please dump the memory pointed to by R23 at 0x2059fc and post it here. The size of the dump is 320 bytes (i.e. sizeof(NKSystemInfo))

I'm sure I'll have lots of question. ;D
Don't hesitate to ask here :D

I'm not real sure how to do 1, 2 , or 3, I'll need some exact examples, as well as a basic overview of the process.

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #50 on: October 14, 2018, 04:11:18 AM »
Code: [Select]

Breakpoint 1, 0x00000000002059f4 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x2059f4: lwz     r23,0(r26)
(gdb) stepi
0x00000000002059f8 in ?? ()
1: x/i $pc
=> 0x2059f8: addi    r6,r28,3
(gdb) stepi
0x00000000002059fc in ?? ()
1: x/i $pc
=> 0x2059fc: lwz     r3,0(r23)
(gdb)

« Last Edit: October 14, 2018, 04:24:46 AM by darthnVader »

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #51 on: October 14, 2018, 05:19:23 AM »
I'm not real sure how to do 1, 2 , or 3, I'll need some exact examples, as well as a basic overview of the process.

Well, as I already said before, you need to obtain a disassembling list for the code you're trying to debug. For that purpose, you need a disassembler. Fortunately, you have several choices: IDA Pro freeware, Hopper, Radare2...

Below the snippet of interest:

Code: [Select]
002059F4    lwz     r23, 0(r26)
002059F8    addi    r6, r28, 3
002059FC    lwz     r3, 0(r23)
00205A00    mr      r4, r28       # srcLength
00205A04    li      r7, 1         # flags
00205A08    divwu   r5, r3, r16
00205A0C    lwz     r3, 724(r1)   # src
00205A10    slwi    r5, r5, 1
00205A14    addis   r5, r5, 0x10
00205A18    clrrwi  r6, r6, 2     # dstLength
00205A1C    addi    r5, r5, -1
00205A20    clrrwi  r5, r5, 20    # dst
00205A24    bl      AddMemoryRelocationEntry

Then you set a breakpoint at 0x2059f4 and executes your target until it hits that breakpoint. To obtain a memory dump, you use GDB's "x" command:

Code: [Select]
(gdb) break *0x2059f4
(gdb) cont
...
Breakpoint 1, 0x00000000002059f4 in ?? ()
(gdb) display/i $pc
(gdb) stepi
(gdb) x/80w $r23

The last command will dump 320 bytes of memory starting with $r23, formatted as 80 big-endian double words.

The next example shows how to read the value of R5 at 0x205a20 (that's the "dst" param passed to AddMemoryRelocationEntry, see the snippet above):

Code: [Select]
(gdb) break *0x205a24
(gdb) cont
(gdb) info registers

I set a breakpoint past the instruction of interest to ensure it has been executed (that's why I set a breakpoint at 0x205a20+4). Then I dump the CPU register file with "info registers" to examine the value of R3.

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #52 on: October 14, 2018, 06:12:43 AM »
OK, I've successfully pulled the repo. It wasn't really what I was expecting, not that I'm complaining, but I was thinking it had the code to decompile the trampoline, and maybe patch and recompile it.

You expected to find the source code for a full-blown PPC decompiler there?

I wonder how you interpret the term "decompilation".

Mapping some binary code to a list of processor mnemonics (i.e. disassembly) is relatively easy. That's what a tool called "disassembler" is capable of performing automatically. Well, near automatically.

Reconstructing a high-level source code for a compiled executable program (in other words, "decompilation" as the inverse of "compilation") is, in contrast, an enormously hard task. No tool doing that ever existed and will likely never exist.

Decompilation is mostly carried out by humans using various program analysis tools. For further details, please refer to this thread: http://macos9lives.com/smforum/index.php/topic,3953.0.html

I'm just not real sure how to use this code to patch the trampoline.

My code is a translation from PPC Asm to C. You find a bug on the binary level, fix it in the C source and then recompile the whole Trampoline using a PowerPC C compiler (gcc, MPW's MrC, whatsoever). Then you bundle this new version in a custom "Mac OS ROM" file using CDG5 tools (https://github.com/elliotnunn/newworld-rom) and replace the ROM file shipped with Mac OS with your "fixed" version.

That's how it supposed to work. I call it "high-level hacking". The reality is a bit different: the decompiled code must be complete and compilable. That's what I'm currently working on.

I'm not real sure exactly why we are failing here, or how to insert some code here to help with debugging?

Until I complete Trampoline's decompilation, you'll have to resort to the "low-level hacking", that is, working on the binary/Asm level. The decompiled code should help to understand how the binary program works, which data it uses and how this data is laid out in memory. The missing mapping between the C source and its compiled form must be done in our brains. ???

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #53 on: October 14, 2018, 06:13:31 AM »
Code: [Select]
Breakpoint 1, 0x00000000002059f4 in ?? ()
1: x/i $pc
=> 0x2059f4: lwz     r23,0(r26)
(gdb) display/i $pc
2: x/i $pc
=> 0x2059f4: lwz     r23,0(r26)
(gdb) stepi
0x00000000002059f8 in ?? ()
2: x/i $pc
=> 0x2059f8: addi    r6,r28,3
1: x/i $pc
=> 0x2059f8: addi    r6,r28,3
(gdb)  x/80w $r23
0x3fec0000: 0 0 0 0
0x3fec0010: 0 0 0 0
0x3fec0020: 0 0 0 0
0x3fec0030: 0 12582912 15040512 684032
0x3fec0040: 16777216 -16777216 0 0
0x3fec0050: 0 0 0 0
0x3fec0060: 0 0 0 0
0x3fec0070: 0 0 0 0
0x3fec0080: 0 0 0 0
0x3fec0090: 0 0 0 0
0x3fec00a0: 0 0 0 0
0x3fec00b0: 0 0 0 0
0x3fec00c0: 0 0 0 0
0x3fec00d0: 0 0 0 0
0x3fec00e0: 0 0 0 0
0x3fec00f0: 0 0 0 0
0x3fec0100: -2147221504 0 0 0
0x3fec0110: 0 0 0 0
0x3fec0120: 0 0 53 -805306368
0x3fec0130: 0 0 0 0
(gdb) break *0x205a24
Breakpoint 2 at 0x205a24
(gdb) cont
Continuing.

Breakpoint 2, 0x0000000000205a24 in ?? ()
2: x/i $pc
=> 0x205a24: bl      0x201db4
1: x/i $pc
=> 0x205a24: bl      0x201db4
(gdb) info register
r0             0x2059ec 2120172
r1             0x116a28 1141288
r2             0x1001e8 1049064
r3             0x3f280000 1059586048
r4             0x48498 296088
r5             0x0 0
r6             0x48498 296088
r7             0x1 1
r8             0x0 0
r9             0x11669c 1140380
r10            0x106e84 1076868
r11            0x106e8b 1076875
r12            0x1198b8 1153208
r13            0x0 0
r14            0x100698 1050264
r15            0xa 10
r16            0x3 3
r17            0x3fee1000 1072566272
r18            0x3fee1000 1072566272
r19            0x106e48 1076808
r20            0x3fee1000 1072566272
r21            0x8 8
r22            0x117818 1144856
---Type <return> to continue, or q <return> to quit---
r23            0x3fec0000 1072431104
r24            0x8 8
r25            0x816116f9 2170623737
r26            0x117080 1142912
r27            0x1170ac 1142956
r28            0x48498 296088
r29            0x106b34 1076020
r30            0x117088 1142920
r31            0x117084 1142916
pc             0x205a24 0x205a24
msr            0x3030 12336
cr             0x22400244 574620228
lr             0x2059ec 0x2059ec
ctr            0xfff025d0 4293928400
xer            0x0 0
(gdb)

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #54 on: October 14, 2018, 06:26:22 AM »
OK, I've successfully pulled the repo. It wasn't really what I was expecting, not that I'm complaining, but I was thinking it had the code to decompile the trampoline, and maybe patch and recompile it.

You expected to find the source code for a full-blown PPC decompiler there?

I wonder how you interpret the term "decompilation".

Mapping some binary code to a list of processor mnemonics (i.e. disassembly) is relatively easy. That's what a tool called "disassembler" is capable of performing automatically. Well, near automatically.

Reconstructing a high-level source code for a compiled executable program (in other words, "decompilation" as the inverse of "compilation") is, in contrast, an enormously hard task. No tool doing that ever existed and will likely never exist.

Decompilation is mostly carried out by humans using various program analysis tools. For further details, please refer to this thread: http://macos9lives.com/smforum/index.php/topic,3953.0.html

I'm just not real sure how to use this code to patch the trampoline.

My code is a translation from PPC Asm to C. You find a bug on the binary level, fix it in the C source and then recompile the whole Trampoline using a PowerPC C compiler (gcc, MPW's MrC, whatsoever). Then you bundle this new version in a custom "Mac OS ROM" file using CDG5 tools (https://github.com/elliotnunn/newworld-rom) and replace the ROM file shipped with Mac OS with your "fixed" version.

That's how it supposed to work. I call it "high-level hacking". The reality is a bit different: the decompiled code must be complete and compilable. That's what I'm currently working on.

I'm not real sure exactly why we are failing here, or how to insert some code here to help with debugging?

Until I complete Trampoline's decompilation, you'll have to resort to the "low-level hacking", that is, working on the binary/Asm level. The decompiled code should help to understand how the binary program works, which data it uses and how this data is laid out in memory. The missing mapping between the C source and its compiled form must be done in our brains. ???

OK, I see, I realize how hard it must have been to get the source files you have in the repo, as I've made attempts at reverse engineering binary data before. Normally I just revert to binary hacks in a hex editor, tho in this case I'm going to have to get my hands dirty and learn some new tricks. ;D

I was just kind of hoping things would be a little easer, but it's ok. I was really just hoping for a makefile and some instructions on how to build in WPM or something, but I can see it's move involved  than that, as the trampoline is just one part of the Mac OS ROM.

A lot of these things are beyond my understanding, at this point, so forgive my ignorance.   

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #55 on: October 14, 2018, 06:56:25 AM »
Code: [Select]
Breakpoint 1, 0x00000000002059f4 in ?? ()
1: x/i $pc
=> 0x2059f4: lwz     r23,0(r26)
(gdb) display/i $pc
2: x/i $pc
=> 0x2059f4: lwz     r23,0(r26)
(gdb) stepi
0x00000000002059f8 in ?? ()
2: x/i $pc
=> 0x2059f8: addi    r6,r28,3
1: x/i $pc
=> 0x2059f8: addi    r6,r28,3
(gdb)  x/80w $r23
0x3fec0000: 0 0 0 0
0x3fec0010: 0 0 0 0
0x3fec0020: 0 0 0 0
0x3fec0030: 0 12582912 15040512 684032
0x3fec0040: 16777216 -16777216 0 0
0x3fec0050: 0 0 0 0
0x3fec0060: 0 0 0 0
0x3fec0070: 0 0 0 0
0x3fec0080: 0 0 0 0
0x3fec0090: 0 0 0 0
0x3fec00a0: 0 0 0 0
0x3fec00b0: 0 0 0 0
0x3fec00c0: 0 0 0 0
0x3fec00d0: 0 0 0 0
0x3fec00e0: 0 0 0 0
0x3fec00f0: 0 0 0 0
0x3fec0100: -2147221504 0 0 0
0x3fec0110: 0 0 0 0
0x3fec0120: 0 0 53 -805306368
0x3fec0130: 0 0 0 0
(gdb) break *0x205a24
Breakpoint 2 at 0x205a24
(gdb) cont
Continuing.

Breakpoint 2, 0x0000000000205a24 in ?? ()
2: x/i $pc
=> 0x205a24: bl      0x201db4
1: x/i $pc
=> 0x205a24: bl      0x201db4
(gdb) info register
r0             0x2059ec 2120172
r1             0x116a28 1141288
r2             0x1001e8 1049064
r3             0x3f280000 1059586048
r4             0x48498 296088
r5             0x0 0
r6             0x48498 296088
r7             0x1 1
r8             0x0 0
r9             0x11669c 1140380
r10            0x106e84 1076868
r11            0x106e8b 1076875
r12            0x1198b8 1153208
r13            0x0 0
r14            0x100698 1050264
r15            0xa 10
r16            0x3 3
r17            0x3fee1000 1072566272
r18            0x3fee1000 1072566272
r19            0x106e48 1076808
r20            0x3fee1000 1072566272
r21            0x8 8
r22            0x117818 1144856
---Type <return> to continue, or q <return> to quit---
r23            0x3fec0000 1072431104
r24            0x8 8
r25            0x816116f9 2170623737
r26            0x117080 1142912
r27            0x1170ac 1142956
r28            0x48498 296088
r29            0x106b34 1076020
r30            0x117088 1142920
r31            0x117084 1142916
pc             0x205a24 0x205a24
msr            0x3030 12336
cr             0x22400244 574620228
lr             0x2059ec 0x2059ec
ctr            0xfff025d0 4293928400
xer            0x0 0
(gdb)

Thanks. That dumps have answered all three questions of mine. AddMemoryRelocationEntry is called with dst=0 which usually shouldn't happen. The value of dst is calculated using the following C statement:

Code: [Select]
dst = (NKSystemInfo.PhysicalMemorySize / 3 * 2 + 0xFFFFF) & 0xFFF00000;
In other words, it takes 2/3 of the available physical memory and align that amount to the 1MB boundary. This will be the physical destination address for the flattened device tree.

In your precise case, that destination address is 0x00000000 because NKSystemInfo.PhysicalMemorySize contains zero. That's the reason why the consequent calls to AddMemoryRelocationEntry fail.

Would you kindly verify which calls to AddMemoryRelocationEntry report overlapping? To achieve that, you need to set the following breakpoints (each one past a blr AddMemoryRelocationEntry):

0x205A28 (shouldn't report any error)
0x205A58
0x205A88
0x205AC8
0x205B08
0x205B48

Everytime each of these breakpoints is reached and NO error appears in the QEMU console, mark the corresponding call as "false". Otherwise, mark it as "true".

Moreover, I'd appreciate a memory dump at "src", i.e.

Code: [Select]
break *0x205A24
cont
x/32xb $r3

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #56 on: October 14, 2018, 07:38:20 AM »
Code: [Select]
0x205A28 (shouldn't report any error)
0x205A58 false
0x205A88 true
0x205AC8 true
0x205B08 true
0x205B48 true

Code: [Select]
(gdb) break *0x205A24
Note: breakpoint 7 also set at pc 0x205a24.
Breakpoint 8 at 0x205a24
(gdb) cont
Continuing.

Breakpoint 7, 0x0000000000205a24 in ?? ()
(gdb) x/32xb $r3
0x3fad8000: 0x50 0x4d 0x52 0x26 0x42 0x47 0x73 0x54
0x3fad8008: 0x72 0x65 0x65 0x00 0x00 0x00 0x00 0x00
0x3fad8010: 0x00 0x00 0x00 0x0c 0x00 0x02 0xef 0x70
0x3fad8018: 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00
(gdb)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #57 on: October 14, 2018, 09:57:23 AM »
Code: [Select]
0x205A28 (shouldn't report any error)
0x205A58 false
0x205A88 true
0x205AC8 true
0x205B08 true
0x205B48 true

According to the error log reported earlier, 0x205A58 is expected to fail as well. Can you recheck?

Code: [Select]
0x3fad8000: 0x50 0x4d 0x52 0x26 0x42 0x47 0x73 0x54
0x3fad8008: 0x72 0x65 0x65 0x00 0x00 0x00 0x00 0x00
0x3fad8010: 0x00 0x00 0x00 0x0c 0x00 0x02 0xef 0x70
0x3fad8018: 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00
(gdb)

Yes, that's the beginning of the flattened device tree. ;D

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #58 on: October 14, 2018, 10:13:42 AM »
Code: [Select]
0x205A28 (shouldn't report any error)
0x205A58 false
0x205A88 true
0x205AC8 true
0x205B08 true
0x205B48 true

According to the error log reported earlier, 0x205A58 is expected to fail as well. Can you recheck?

Code: [Select]
0x3fad8000: 0x50 0x4d 0x52 0x26 0x42 0x47 0x73 0x54
0x3fad8008: 0x72 0x65 0x65 0x00 0x00 0x00 0x00 0x00
0x3fad8010: 0x00 0x00 0x00 0x0c 0x00 0x02 0xef 0x70
0x3fad8018: 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00
(gdb)

Yes, that's the beginning of the flattened device tree. ;D

0x20a58 does fail.

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #59 on: October 14, 2018, 10:18:26 AM »
It's worth trying to set R5 before AddMemoryRelocationEntry to the correct value to see if it fixes that fatal error.

Code: [Select]
(gdb) break *0x205A24
(gdb) cont
(gdb) set $r5=0x2AB00000
(gdb) cont

0x2AB00000 is calculated from the assigned physical memory, i.e. ((1024*1024*1024) / 3 * 2 + 0xFFFFF) & 0xFFF0000 = 0x2AB00000.

I'm curious what happens then...