mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
103 lines
5.7 KiB
Markdown
103 lines
5.7 KiB
Markdown
|
|
[← Home](../../../README.md) · [Reverse Engineering](../../README.md) · [Static Analysis](../README.md)
|
|||
|
|
|
|||
|
|
# Per-Compiler Reverse Engineering — Binary Field Manuals
|
|||
|
|
|
|||
|
|
## Overview
|
|||
|
|
|
|||
|
|
This section provides **compiler-specific reverse engineering field manuals**. Each article answers one question: *"I have a binary produced by this compiler — what does it look like in IDA/Ghidra, and how do I read it?"* Rather than discussing compiler usage (see [13_toolchain](../../../13_toolchain/README.md) for that), these articles focus exclusively on **binary output**: hunk naming conventions, prologue/epilogue patterns, stack frame layouts, string addressing modes, startup code, optimization patterns, and debug info formats.
|
|||
|
|
|
|||
|
|
Every article includes the **same C function compiled by each compiler** — a side-by-side comparison that reveals exactly how `for` loops, `switch` statements, struct access, and AmigaOS library calls differ at the assembly level.
|
|||
|
|
|
|||
|
|
## Compiler Identification Decision Flowchart
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph TD
|
|||
|
|
BIN["m68k binary loaded in disassembler"]
|
|||
|
|
HUNK{"Hunk names?"}
|
|||
|
|
L_A5{"LINK A5 present?"}
|
|||
|
|
L_A6{"LINK A6 present?"}
|
|||
|
|
STR_ABS{"String addressing?"}
|
|||
|
|
REG_SAVE{"MOVEM.L save set size?"}
|
|||
|
|
FP_DEFAULT{"Default frame pointer?"}
|
|||
|
|
|
|||
|
|
BIN --> HUNK
|
|||
|
|
HUNK -->|"CODE/DATA/BSS"| L_A5
|
|||
|
|
HUNK -->|".text/.data/.bss"| L_A6
|
|||
|
|
HUNK -->|"CODE/DATA + __MERGED"| VBCC["→ VBCC"]
|
|||
|
|
HUNK -->|"Custom prefix"| STORMC["→ StormC"]
|
|||
|
|
|
|||
|
|
L_A5 -->|"Yes"| STR_ABS
|
|||
|
|
L_A5 -->|"No, LINK absent"| FP_DEFAULT
|
|||
|
|
STR_ABS -->|"Absolute (MOVE.L #str,Dn)"| SASC["→ SAS/C"]
|
|||
|
|
STR_ABS -->|"PC-relative (LEA str(PC))"| DICE["→ DICE C"]
|
|||
|
|
|
|||
|
|
L_A6 -->|"Yes"| GCC["→ GCC 2.95.x"]
|
|||
|
|
L_A6 -->|"No, LINK absent"| VBCC2["→ VBCC"]
|
|||
|
|
|
|||
|
|
FP_DEFAULT -->|"None (only used regs saved)"| VBCC3["→ VBCC"]
|
|||
|
|
FP_DEFAULT -->|"A5 frame pointer"| AZTEC["→ Aztec C / Lattice C"]
|
|||
|
|
|
|||
|
|
REG_SAVE -->|"D2-D7/A2-A4 (9 regs)"| SASC2["→ SAS/C"]
|
|||
|
|
REG_SAVE -->|"D3-D7 (5 regs)"| AZTEC2["→ Aztec C"]
|
|||
|
|
REG_SAVE -->|"D2-D7/A2-A6 (11 regs)"| GENSASC["→ SAS/C __saveds"]
|
|||
|
|
REG_SAVE -->|"Minimal, per-function"| VBCC4["→ VBCC"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Quick Identification Matrix
|
|||
|
|
|
|||
|
|
| Criterion | SAS/C 6.x | GCC 2.95.x | VBCC | StormC | Aztec C | Lattice C | DICE C |
|
|||
|
|
|---|---|---|---|---|---|---|---|
|
|||
|
|
| **Hunk names** | `CODE`, `DATA`, `BSS` | `.text`, `.data`, `.bss` | `CODE`, `DATA`, `BSS` + `__MERGED` | `CODE`, `DATA` (Amiga standard) | `CODE`, `DATA`, `BSS` | `CODE`, `DATA`, `BSS` | `CODE`, `DATA`, `BSS` |
|
|||
|
|
| **Frame pointer** | A5 (`LINK A5, #-N`) | A6 (or none with `-fomit-frame-pointer`) | None (rarely A5) | A5 (`LINK A5, #-N`) | A5 (`LINK A5, #-N`) | A5 (`LINK A5, #-N`) | None typically |
|
|||
|
|
| **String addressing** | Absolute + relocated | PC-relative | PC-relative | Absolute | Absolute | Absolute | PC-relative |
|
|||
|
|
| **Register save set** | D2-D7/A2-A4 (9 regs) | D2-D3/A2 (per-function) | Only used regs | D2-D7/A2-A4 (9 regs) | D3-D7 (5 regs) | D2-D5/A2-A3 | Per-function |
|
|||
|
|
| **Startup entry** | `_start` / `c.o` | `_start` / `libnix` | `_start` / `startup.o` | `_STORM_` prefix | `_start` / `aztec.o` | `_start` / `lc.o` | `_mainCRTStartup` |
|
|||
|
|
| **Library call style** | `JSR -$XXX(A6)` after loading global | `JSR -$XXX(A6)` with tighter code | `JSR -$XXX(A6)` via `__reg()` | `JSR -$XXX(A6)` SAS/C-like | `JSR -$XXX(A6)` | `JSR -$XXX(A6)` | `JSR -$XXX(A6)` |
|
|||
|
|
| **Era** | 1988–1996 | 1995–present | 1995–present | 1996–2000 | 1985–1992 | 1985–1989 | 1992–1995 |
|
|||
|
|
| **RE article** | [sasc.md](sasc.md) | [gcc.md](gcc.md) | [vbcc.md](vbcc.md) | [stormc.md](stormc.md) | [aztec_c.md](aztec_c.md) | [lattice_c.md](lattice_c.md) | [dice_c.md](dice_c.md) |
|
|||
|
|
|
|||
|
|
## Articles
|
|||
|
|
|
|||
|
|
| File | Compiler | Key RE Distinguishing Feature |
|
|||
|
|
|---|---|---|
|
|||
|
|
| [sasc.md](sasc.md) | SAS/C 5.x/6.x | `LINK A5` + 9-register MOVEM.L save — the most common Amiga C prologue |
|
|||
|
|
| [gcc.md](gcc.md) | GCC 2.95.x | `LINK A6` (or no frame pointer) + PC-relative strings + `__CTOR_LIST__`/`__DTOR_LIST__` arrays |
|
|||
|
|
| [vbcc.md](vbcc.md) | VBCC | No frame pointer + per-function register save + `__reg()` calling convention + `__MERGED` hunks |
|
|||
|
|
| [stormc.md](stormc.md) | StormC / StormC++ | A5 frame pointer + C++ vtable differences from GCC + integrated debug info |
|
|||
|
|
| [aztec_c.md](aztec_c.md) | Manx Aztec C | `LINK A5` + D3-D7 only (5 regs) — distinct from SAS/C 9-reg save |
|
|||
|
|
| [lattice_c.md](lattice_c.md) | Lattice C 3.x/4.x | Predecessor to SAS/C; less aggressive optimization, different startup stub |
|
|||
|
|
| [dice_c.md](dice_c.md) | DICE C | No frame pointer + PC-relative strings + extremely fast compilation marker patterns |
|
|||
|
|
|
|||
|
|
## Cross-Compiler Comparison — Same C Function
|
|||
|
|
|
|||
|
|
Every per-compiler article includes this reference function compiled by that compiler:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
/* Reference function used in all compiler comparison tables */
|
|||
|
|
ULONG CountWords(CONST_STRPTR str) {
|
|||
|
|
ULONG count = 0;
|
|||
|
|
BOOL in_word = FALSE;
|
|||
|
|
|
|||
|
|
while (*str) {
|
|||
|
|
if (*str == ' ' || *str == '\t' || *str == '\n') {
|
|||
|
|
in_word = FALSE;
|
|||
|
|
} else if (!in_word) {
|
|||
|
|
count++;
|
|||
|
|
in_word = TRUE;
|
|||
|
|
}
|
|||
|
|
str++;
|
|||
|
|
}
|
|||
|
|
return count;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Each article shows the full assembly output, annotated with which patterns are compiler-specific and which are universal m68k idioms.
|
|||
|
|
|
|||
|
|
## See Also
|
|||
|
|
|
|||
|
|
- [compiler_fingerprints.md](../../compiler_fingerprints.md) — Quick compiler identification guide
|
|||
|
|
- [ansi_c_reversing.md](../ansi_c_reversing.md) — General C reverse engineering methodology
|
|||
|
|
- [m68k_codegen_patterns.md](../m68k_codegen_patterns.md) — m68k code generation idiom catalog
|
|||
|
|
- [startup_code.md](../../../04_linking_and_libraries/startup_code.md) — CLI vs WB startup internals
|
|||
|
|
- [13_toolchain/](../../../13_toolchain/README.md) — Compiler usage and configuration (not RE)
|