22
33#include < iomanip>
44#include < iostream>
5- #include < type_traits>
6- #include < variant>
75
86namespace safe {
97
@@ -22,32 +20,23 @@ const char* handler_kind_to_string_local(HandlerType kind)
2220 }
2321 return " Unknown" ;
2422}
23+ // we just call symbol_address.
24+ // std::uint64_t
25+ // symbol_address(const symbol_s& s)
26+ // {
27+ // return s.value;
28+ // }
2529
26- // Turn a symbol_s into a plain address so we can compare RTTI entries between
27- // Validator and LSDA.
28- std::uint64_t symbol_address (const symbol_s& s)
29- {
30- return std::visit (
31- [](auto && v) -> std::uint64_t {
32- using T = std::decay_t <decltype (v)>;
33- if constexpr (std::is_pointer_v<T>) {
34- return reinterpret_cast <std::uint64_t >(v);
35- } else {
36- return static_cast <std::uint64_t >(v);
37- }
38- },
39- s.value );
40- }
4130
42- } // namespace
31+ }
4332
4433const char * CatchValidator::handler_kind_to_string (HandlerType kind)
4534{
4635 return handler_kind_to_string_local (kind);
4736}
4837
4938CatchValidator::CatchValidator (const LsdaParser& parser)
50- : m_lsda(parser)
39+ // : m_lsda(parser)
5140{
5241 m_records.clear ();
5342 const auto & scopes = parser.get_scopes ();
@@ -72,124 +61,124 @@ CatchValidator::CatchValidator(const LsdaParser& parser)
7261 }
7362}
7463
75- CatchValidator::CorrelateResult CatchValidator::correlate_with_throws (
76- Validator& throw_validator,
77- std::string_view func_name) const
78- {
79- // ask the throw side Validator which RTTI objects this function throws.
80- auto thrown_opt = throw_validator.find_typeinfo (func_name);
81- if (!thrown_opt.has_value ()) {
82- // Either the function isn't known to Validator, or it couldn't compute
83- // typeinfo for it.
84- return std::unexpected (CorrelateError::NoTypeinfoForFunction);
85- }
86-
87- const auto & thrown_vec = *thrown_opt;
88- if (thrown_vec.empty ()) {
89- return std::unexpected (CorrelateError::NoThrownTypes);
90- }
91-
92- if (m_records.empty ()) {
93- return std::unexpected (CorrelateError::NoCatchRecords);
94- }
95-
96- std::vector<ThrowCatchMatch> result;
97- result.reserve (thrown_vec.size ());
98-
99- // for each thrown type, find matching LSDA catch records.
100- for (const auto & t : thrown_vec) {
101- ThrowCatchMatch rel{ t, {} };
102- const std::uint64_t thrown_addr = symbol_address (t);
103-
104- for (const auto & rec : m_records) {
105- // skip cleanups / filters / invalid indices.
106- if (rec.kind != HandlerType::Catch || rec.type_index <= 0 ) {
107- continue ;
108- }
109-
110- auto handler_addr_opt = m_lsda.resolve_type (rec.type_index );
111- if (!handler_addr_opt.has_value ()) {
112- // LSDA type table looks inconsistent; surface this as an error.
113- return std::unexpected (CorrelateError::TypeResolveFailed);
114- }
115-
116- if (*handler_addr_opt == thrown_addr) {
117- rel.handlers .push_back (&rec);
118- }
119- }
120-
121- result.push_back (std::move (rel));
122- }
123-
124- // if none of the thrown types mapped to any handlers at all, signal to
125- // callers.
126- bool any_handlers = false ;
127- for (const auto & m : result) {
128- if (!m.handlers .empty ()) {
129- any_handlers = true ;
130- break ;
131- }
132- }
133- if (!any_handlers) {
134- return std::unexpected (CorrelateError::NoCatchRecords);
135- }
136-
137- return result;
138- }
139-
140- void CatchValidator::print_throw_catch_report (Validator& throw_validator,
141- std::string_view func_name) const
142- {
143- auto matches_or_err = correlate_with_throws (throw_validator, func_name);
144-
145- std::cout << " [SAFE] throw/catch correlation for function " << func_name
146- << " :\n " ;
147-
148- if (!matches_or_err.has_value ()) {
149- switch (matches_or_err.error ()) {
150- case CorrelateError::NoTypeinfoForFunction:
151- std::cout
152- << " (no typeinfo found for this function in Validator)\n " ;
153- break ;
154- case CorrelateError::NoThrownTypes:
155- std::cout << " (function has no recorded throw types)\n " ;
156- break ;
157- case CorrelateError::NoCatchRecords:
158- std::cout
159- << " (no LSDA catch records matched any thrown type)\n " ;
160- break ;
161- case CorrelateError::TypeResolveFailed:
162- std::cout
163- << " (failed to resolve at least one LSDA type index)\n " ;
164- break ;
165- }
166- return ;
167- }
168-
169- const auto & matches = matches_or_err.value ();
170-
171- for (const auto & mc : matches) {
172- const auto addr = symbol_address (mc.thrown );
173-
174- std::cout << " Thrown RTTI symbol: " << mc.thrown .name << " @ 0x"
175- << std::hex << addr << std::dec << " \n " ;
176-
177- if (mc.handlers .empty ()) {
178- std::cout << " ❌ no matching catch handlers in LSDA\n " ;
179- } else {
180- std::cout << " ✅ handled by " << mc.handlers .size ()
181- << " catch handler(s):\n " ;
182- for (const auto * rec : mc.handlers ) {
183- std::cout << " - " << rec->scope_id << " ("
184- << handler_kind_to_string (rec->kind ) << " ) "
185- << " range 0x" << std::hex << rec->range_begin << " -0x"
186- << rec->range_end << " , landing_pad 0x"
187- << rec->landing_pad << std::dec << " , type_index "
188- << rec->type_index << " \n " ;
189- }
190- }
191- }
192- }
64+ // CatchValidator::CorrelateResult CatchValidator::correlate_with_throws(
65+ // Validator& throw_validator,
66+ // std::string_view func_name) const
67+ // {
68+ // // ask the throw side Validator which RTTI objects this function throws.
69+ // auto thrown_opt = throw_validator.find_typeinfo(func_name);
70+ // if (!thrown_opt.has_value()) {
71+ // // Either the function isn't known to Validator, or it couldn't compute
72+ // // typeinfo for it.
73+ // return std::unexpected(CorrelateError::NoTypeinfoForFunction);
74+ // }
75+
76+ // const auto& thrown_vec = *thrown_opt;
77+ // if (thrown_vec.empty()) {
78+ // return std::unexpected(CorrelateError::NoThrownTypes);
79+ // }
80+
81+ // if (m_records.empty()) {
82+ // return std::unexpected(CorrelateError::NoCatchRecords);
83+ // }
84+
85+ // std::vector<ThrowCatchMatch> result;
86+ // result.reserve(thrown_vec.size());
87+
88+ // // for each thrown type, find matching LSDA catch records.
89+ // for (const auto& t : thrown_vec) {
90+ // ThrowCatchMatch rel{ t, {} };
91+ // const std::uint64_t thrown_addr = symbol_address(t);
92+
93+ // for (const auto& rec : m_records) {
94+ // // skip cleanups / filters / invalid indices.
95+ // if (rec.kind != HandlerType::Catch || rec.type_index <= 0) {
96+ // continue;
97+ // }
98+
99+ // auto handler_addr_opt = m_lsda.resolve_type(rec.type_index);
100+ // if (!handler_addr_opt.has_value()) {
101+ // // LSDA type table looks inconsistent; surface this as an error.
102+ // return std::unexpected(CorrelateError::TypeResolveFailed);
103+ // }
104+
105+ // if (*handler_addr_opt == thrown_addr) {
106+ // rel.handlers.push_back(&rec);
107+ // }
108+ // }
109+
110+ // result.push_back(std::move(rel));
111+ // }
112+
113+ // // if none of the thrown types mapped to any handlers at all, signal to
114+ // // callers.
115+ // bool any_handlers = false;
116+ // for (const auto& m : result) {
117+ // if (!m.handlers.empty()) {
118+ // any_handlers = true;
119+ // break;
120+ // }
121+ // }
122+ // if (!any_handlers) {
123+ // return std::unexpected(CorrelateError::NoCatchRecords);
124+ // }
125+
126+ // return result;
127+ // }
128+
129+ // void CatchValidator::print_throw_catch_report(Validator& throw_validator,
130+ // std::string_view func_name) const
131+ // {
132+ // auto matches_or_err = correlate_with_throws(throw_validator, func_name);
133+
134+ // std::cout << "[SAFE] throw/catch correlation for function " << func_name
135+ // << ":\n";
136+
137+ // if (!matches_or_err.has_value()) {
138+ // switch (matches_or_err.error()) {
139+ // case CorrelateError::NoTypeinfoForFunction:
140+ // std::cout
141+ // << " (no typeinfo found for this function in Validator)\n";
142+ // break;
143+ // case CorrelateError::NoThrownTypes:
144+ // std::cout << " (function has no recorded throw types)\n";
145+ // break;
146+ // case CorrelateError::NoCatchRecords:
147+ // std::cout
148+ // << " (no LSDA catch records matched any thrown type)\n";
149+ // break;
150+ // case CorrelateError::TypeResolveFailed:
151+ // std::cout
152+ // << " (failed to resolve at least one LSDA type index)\n";
153+ // break;
154+ // }
155+ // return;
156+ // }
157+
158+ // const auto& matches = matches_or_err.value();
159+
160+ // for (const auto& mc : matches) {
161+ // const auto addr = symbol_address(mc.thrown);
162+
163+ // std::cout << " Thrown RTTI symbol: " << mc.thrown.name << " @ 0x"
164+ // << std::hex << addr << std::dec << "\n";
165+
166+ // if (mc.handlers.empty()) {
167+ // std::cout << " ❌ no matching catch handlers in LSDA\n";
168+ // } else {
169+ // std::cout << " ✅ handled by " << mc.handlers.size()
170+ // << " catch handler(s):\n";
171+ // for (const auto* rec : mc.handlers) {
172+ // std::cout << " - " << rec->scope_id << " ("
173+ // << handler_kind_to_string(rec->kind) << ") "
174+ // << "range 0x" << std::hex << rec->range_begin << "-0x"
175+ // << rec->range_end << ", landing_pad 0x"
176+ // << rec->landing_pad << std::dec << ", type_index "
177+ // << rec->type_index << "\n";
178+ // }
179+ // }
180+ // }
181+ // }
193182
194183void CatchValidator::print_records () const
195184{
0 commit comments