diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index f1df0db77..caad15da8 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -131,9 +131,9 @@ TP_Type SimpleAtom::get_type(const TypeState& input, if (hint_kv != env.label_types().end()) { return TP_Type::make_from_ts(dts.parse_type_spec(hint_kv->second.type_name)); } - // throw std::runtime_error("IR_StaticAddress could not figure out the type: " + label.name); - lg::error("IR_StaticAddress does not know the type of {}", label.name); - return TP_Type::make_from_ts("object"); + // todo: should we take out this warning? + lg::warn("IR_StaticAddress does not know the type of {}", label.name); + return TP_Type::make_label_addr(); } case Kind::INVALID: default: diff --git a/decompiler/analysis/stack_spill.cpp b/decompiler/analysis/stack_spill.cpp index b54ace866..dfbf4a650 100644 --- a/decompiler/analysis/stack_spill.cpp +++ b/decompiler/analysis/stack_spill.cpp @@ -13,6 +13,16 @@ void StackSpillMap::add_access(const StackSpillSlot& access) { auto existing = m_slot_map.find(access.offset); if (existing != m_slot_map.end()) { if (access != existing->second) { + // the GOAL float -> GPR loads are just totally wrong. + if (existing->second.size == 16 && access.size == 4) { + existing->second.size = 4; + return; + } + + if (existing->second.size == 4 && access.size == 16) { + return; + } + throw std::runtime_error(fmt::format("Inconsistent stack access:\n{}\n{}\n", existing->second.print(), access.print())); } diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 1bcd91891..499a5edd8 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -18223,14 +18223,6 @@ ;; - Types -; (deftype fuel-cell (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; unrecognized get op: (set! v1 eco-collectable) parent was UNKNOWN -; ) - ;; - Symbols @@ -19426,17 +19418,6 @@ ;; Containing DGOs - ['GAME', 'ENGINE'] ;; Version - 3 -;; - Types - -; (deftype money (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) - - ;; - Symbols (define-extern task-control-reset function) @@ -19700,125 +19681,208 @@ ;; - Types -; (deftype ecovalve (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; unrecognized get op: (set! v1 process-drawable) parent was UNKNOWN -; ) +(deftype collectable (process-drawable) + ((pickup-type int32 :offset-assert 176) + (pickup-amount float :offset-assert 180) + (notify-parent basic :offset-assert 184) + (old-base vector :inline :offset-assert 192) + (base vector :inline :offset-assert 208) + (extra-trans vector :inline :offset-assert 224) + (jump-pos vector :inline :offset-assert 240) + (flags uint32 :offset-assert 256) + (birth-time uint64 :offset-assert 264) + (collect-timeout uint64 :offset-assert 272) + (fadeout-timeout uint64 :offset-assert 280) + (bob-offset uint64 :offset-assert 288) + (bob-amount float :offset-assert 296) + (pickup-handle handle :offset-assert 304) ;; not sure it's a handle + (actor-pause basic :offset-assert 312) + ) + + (:methods + (dummy-20 () none 20) + (dummy-21 () none 21) + ) + :heap-base #xd0 + + :method-count-assert 22 + :size-assert #x13c + :flag-assert #x1600d0013c -; (deftype eco-blue (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) + ) -; (deftype eco-red (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +;; L729 +(deftype eco-collectable (collectable) + ((eco-effect basic :offset-assert 316) + (collect-effect basic :offset-assert 320) + (collect-effect2 basic :offset-assert 324) + (collect-effect-time uint64 :offset-assert 328) + (respawn-delay uint64 :offset-assert 336) + (sound-name basic :offset-assert 344) + (target uint64 :offset-assert 352) + (suck-time uint64 :offset-assert 360) + (suck-y-offset float :offset-assert 368) + (speed vector :inline :offset-assert 384) + (movie-pos-index int32 :offset-assert 400) + ) + + (:methods + (dummy-22 () none 22) + (dummy-23 () none 23) + (dummy-24 () none 24) + (dummy-25 () none 25) + (dummy-26 () none 26) + (dummy-27 () none 27) + (dummy-28 () none 28) + (dummy-29 () none 29) + (dummy-30 () none 30) + ) + + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype eco-yellow (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +;; L729 +(deftype eco (eco-collectable) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype health (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +(deftype eco-yellow (eco) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype buzzer (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; unrecognized get op: (set! v1 eco-collectable) parent was UNKNOWN -; ) +(deftype eco-red (eco) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype eco-pill (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +(deftype eco-blue (eco) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype eco-collectable (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; unrecognized get op: (set! v1 collectable) parent was UNKNOWN -; ) +(deftype health (eco-collectable) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype vent (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; unrecognized get op: (set! v1 process-drawable) parent was UNKNOWN -; ) +(deftype eco-pill (eco-collectable) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype eco (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +(deftype money (eco-collectable) + () + :heap-base #x130 + :method-count-assert 31 + :size-assert #x194 + :flag-assert #x1f01300194 + ) -; (deftype collectable (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; unrecognized get op: (set! v1 process-drawable) parent was UNKNOWN -; ) +;; L730 +(deftype fuel-cell (eco-collectable) + ((victory-anim basic :offset-assert 404) + (state-object basic :offset-assert 408)) + :heap-base #x130 + :method-count-assert 31 + :size-assert #x19c + :flag-assert #x1f0130019c + ) -; (deftype ventyellow (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +;; L732 +(deftype buzzer (eco-collectable) + ((victory-anim basic :offset-assert 404)) + + :heap-base #x130 + :method-count-assert 31 + :size-assert #x198 + :flag-assert #x1f01300198 + ) -; (deftype ventred (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +;; L728 +(deftype ecovalve (process-drawable) + ((offset vector :inline :offset-assert 176) + (offset-target vector :inline :offset-assert 192) + (block-func basic :offset-assert 208)) + :heap-base #x70 + :method-count-assert 20 + :size-assert #xd4 + :flag-assert #x14007000d4 + ) -; (deftype ventblue (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +;; L731 +(deftype vent (process-drawable) + ((show-particles basic :offset-assert 176) + (collect-effect basic :offset-assert 180) + (collect-effect2 basic :offset-assert 184) + (collect-effect-time uint64 :offset-assert 192) + (blocker basic :offset-assert 200) + (block-func basic :offset-assert 204) + (pickup-handle handle :offset-assert 208)) ;; not sure handle + + (:methods + (dummy-20 () none 20) + ) + + :heap-base #x70 + :method-count-assert 21 + :size-assert #xd8 + :flag-assert #x15007000d8 + ) -; (deftype ecovent (UNKNOWN) -; () -; :method-count-assert 0 -; :size-assert #x0 -; :flag-assert #x0 -; ;; not enough basic ops -; ) +(deftype ventyellow (vent) + () + :heap-base #x70 + :method-count-assert 21 + :size-assert #xd8 + :flag-assert #x15007000d8 + ) + +(deftype ventred (vent) + () + :heap-base #x70 + :method-count-assert 21 + :size-assert #xd8 + :flag-assert #x15007000d8 + ) + +(deftype ventblue (vent) + () + :heap-base #x70 + :method-count-assert 21 + :size-assert #xd8 + :flag-assert #x15007000d8 + ) + +(deftype ecovent (vent) + () + :heap-base #x70 + :method-count-assert 21 + :size-assert #xd8 + :flag-assert #x15007000d8 + ) ;; - Symbols @@ -19841,17 +19905,17 @@ ;; - Unknowns -;;(define-extern vent-wait-for-touch object) ;; unknown type -;;(define-extern vent-pickup object) ;; unknown type -;;(define-extern vent-blocked object) ;; unknown type -;;(define-extern *ecovalve-sg* object) ;; unknown type -;;(define-extern ecovalve-idle object) ;; unknown type -;;(define-extern *eco-pill-count* object) ;; unknown type -;;(define-extern *buzzer-sg* object) ;; unknown type -;;(define-extern fuel-cell-clone-anim object) ;; unknown type -;;(define-extern *fuel-cell-tune-pos* object) ;; unknown type -;;(define-extern *fuel-cell-sg* object) ;; unknown type -;;(define-extern *money-sg* object) ;; unknown type +(define-extern vent-wait-for-touch state) ;; unknown type +(define-extern vent-pickup state) ;; unknown type +(define-extern vent-blocked state) ;; unknown type +(define-extern *ecovalve-sg* skeleton-group) ;; unknown type +(define-extern ecovalve-idle state) ;; unknown type +(define-extern *eco-pill-count* int) ;; unknown type +(define-extern *buzzer-sg* skeleton-group) ;; unknown type +(define-extern fuel-cell-clone-anim state) ;; unknown type +(define-extern *fuel-cell-tune-pos* vector) ;; unknown type +(define-extern *fuel-cell-sg* skeleton-group) ;; unknown type +(define-extern *money-sg* skeleton-group) ;; unknown type ;; ---------------------- diff --git a/decompiler/util/DecompilerTypeSystem.cpp b/decompiler/util/DecompilerTypeSystem.cpp index 592c62a40..b35dc1e6c 100644 --- a/decompiler/util/DecompilerTypeSystem.cpp +++ b/decompiler/util/DecompilerTypeSystem.cpp @@ -296,6 +296,10 @@ TP_Type DecompilerTypeSystem::tp_lca(const TP_Type& existing, return TP_Type::make_from_ts( ts.lowest_common_ancestor(existing.typespec(), add.typespec())); + case TP_Type::Kind::LABEL_ADDR: + *changed = false; + return existing; + case TP_Type::Kind::FALSE_AS_NULL: case TP_Type::Kind::UNINITIALIZED: case TP_Type::Kind::DYNAMIC_METHOD_ACCESS: diff --git a/decompiler/util/TP_Type.cpp b/decompiler/util/TP_Type.cpp index 6b9c176f0..5682efefb 100644 --- a/decompiler/util/TP_Type.cpp +++ b/decompiler/util/TP_Type.cpp @@ -67,6 +67,8 @@ std::string TP_Type::print() const { } case Kind::PCPYUD_BITFIELD: return fmt::format("", m_ts.print()); + case Kind::LABEL_ADDR: + return ""; case Kind::INVALID: default: assert(false); @@ -117,6 +119,8 @@ bool TP_Type::operator==(const TP_Type& other) const { return m_int == other.m_int && m_ts == other.m_ts && m_pcpyud == other.m_pcpyud; case Kind::PCPYUD_BITFIELD: return m_pcpyud == other.m_pcpyud && m_ts == other.m_ts; + case Kind::LABEL_ADDR: + return true; case Kind::INVALID: default: assert(false); @@ -173,6 +177,8 @@ TypeSpec TP_Type::typespec() const { return TypeSpec("int"); // ideally this is never used. case Kind::PCPYUD_BITFIELD: return TypeSpec("int"); + case Kind::LABEL_ADDR: + return TypeSpec("pointer"); // ? case Kind::INVALID: default: assert(false); diff --git a/decompiler/util/TP_Type.h b/decompiler/util/TP_Type.h index c80ac8736..faf6e3250 100644 --- a/decompiler/util/TP_Type.h +++ b/decompiler/util/TP_Type.h @@ -34,6 +34,7 @@ class TP_Type { NON_VIRTUAL_METHOD, PCPYUD_BITFIELD, LEFT_SHIFTED_BITFIELD, // (bitfield << some-constant) + LABEL_ADDR, INVALID } kind = Kind::UNINITIALIZED; TP_Type() = default; @@ -61,6 +62,7 @@ class TP_Type { case Kind::NON_VIRTUAL_METHOD: case Kind::LEFT_SHIFTED_BITFIELD: case Kind::PCPYUD_BITFIELD: + case Kind::LABEL_ADDR: return false; case Kind::UNINITIALIZED: case Kind::OBJECT_NEW_METHOD: @@ -238,6 +240,12 @@ class TP_Type { return result; } + static TP_Type make_label_addr() { + TP_Type result; + result.kind = Kind::LABEL_ADDR; + return result; + } + const TypeSpec& get_objects_typespec() const { assert(kind == Kind::TYPESPEC || kind == Kind::INTEGER_CONSTANT_PLUS_VAR); return m_ts;