Skip to content

Commit 343db55

Browse files
authored
made demo to show throws being found and checking if they are caught (#70)
* made demo to show throws being found and checking if they are caught * updated readme * added repo link to readme
1 parent aa5aff7 commit 343db55

5 files changed

Lines changed: 135 additions & 35 deletions

File tree

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,81 @@
11
# SAFE: Static Analyzer For Exceptions
2+
23
Exceptions binary analysis tool (for Itanum ARM ABI)
4+
5+
## Code Repository
6+
7+
https://github.com/libhal/exception-insights
8+
9+
## Code Structure
10+
11+
exception-insight
12+
├── CMakeLists.txt
13+
├── CMakeUserPresets.json
14+
├── LICENSE
15+
├── README.md
16+
├── build
17+
│ ├── Debug
18+
│ │ ├── CMakeCache.txt
19+
│ │ ├── CMakeFiles
20+
│ │ ├── Makefile
21+
│ │ ├── cmake_install.cmake
22+
│ │ ├── compile_commands.json
23+
│ │ ├── generators
24+
│ │ ├── metadata
25+
│ │ ├── safe
26+
│ │ └── unit_test
27+
│ └── logs
28+
│ ├── RTTI_typeinfo.txt
29+
│ └── function_binary.txt
30+
├── compile_commands.json
31+
├── conanfile.py
32+
├── docs
33+
│ ├── Doxyfile
34+
│ ├── html
35+
│ │ └── search
36+
│ └── latex
37+
│ └── Makefile
38+
├── include
39+
│ ├── abi_parse.hpp
40+
│ ├── elf_parser.hpp
41+
│ ├── gcc_parse.hpp
42+
│ └── validator.hpp
43+
├── src
44+
│ ├── abi_parse.cpp
45+
│ ├── elf_parser.cpp
46+
│ ├── gcc_parse.cpp
47+
│ ├── main.cpp
48+
│ ├── throw.cpp
49+
│ └── validator.cpp
50+
├── testing_programs
51+
│ ├── build
52+
│ │ ├── demo_class
53+
│ │ ├── elf_test
54+
│ │ ├── multi_tu.whole-program
55+
│ │ └── simple
56+
│ ├── demo.cpp
57+
│ ├── demo_class.cpp
58+
│ ├── demo_two.cpp
59+
│ ├── demo_two.h
60+
│ ├── elf_test.cpp
61+
│ ├── gcc_parse.py
62+
│ ├── generate_and_build.ps1
63+
│ ├── generate_and_build.sh
64+
│ ├── shell.nix
65+
│ ├── simple.cpp
66+
│ ├── single_tu.cpp
67+
│ └── test.c
68+
└── tests
69+
├── abi_parser.test.cpp
70+
├── elf_parser.test.cpp
71+
├── gcc_callgraph.test.cpp
72+
├── main.test.cpp
73+
├── testing.test.cpp
74+
├── validator.test.cpp
75+
└── validator_catch.test.cpp
76+
77+
# Build instructions
78+
79+
1. Build Command: `rm -r build && conan build . `
80+
2. Run Command: `./build/Debug/safe <target ELF file> `
81+
- Run with test file command: `./build/Debug/safe testing_programs/build/simple `

include/validator.hpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222
#include "gelf.h"
2323

2424
namespace safe {
25+
26+
enum class CorrelateError
27+
{
28+
NoTypeinfoForFunction, // Validator has no typeinfo for this function
29+
NoThrownTypes, // Function exists, but no throws recorded
30+
NoCatchRecords, // No LSDA catch records matched any thrown type
31+
TypeResolveFailed, // LSDA::resolve_type() failed for some index
32+
NoLsdaLoaded, // load_lsda() never called
33+
};
34+
2535
struct CatchRecord
2636
{
2737
std::string scope_id; // example: "scope[0]"
@@ -58,15 +68,6 @@ class Validator
5868
bool check_thrown_functions(std::string_view func_name);
5969
std::vector<symbol_s> find_thrown_functions();
6070

61-
enum class CorrelateError
62-
{
63-
NoTypeinfoForFunction, // Validator has no typeinfo for this function
64-
NoThrownTypes, // Function exists, but no throws recorded
65-
NoCatchRecords, // No LSDA catch records matched any thrown type
66-
TypeResolveFailed, // LSDA::resolve_type() failed for some index
67-
NoLsdaLoaded, // load_lsda() never called
68-
};
69-
7071
using Result = std::expected<std::vector<ThrowCatchMatch>, CorrelateError>;
7172

7273
void load_lsda(const LsdaParser& lsda);

src/abi_parse.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,11 @@ void LsdaParser::parse_actions_tail(size_t table_start, size_t limit_end)
425425
// truncate chain when target is outside known entries
426426
// techdebt: handle cross LSDA/shared-tail action chains when we
427427
// parse full .gcc_except_table sections instead of single LSDAs.
428-
std::cerr << "[AbiParser] warning: next_offset from entry_offset="
429-
<< a.entry_offset
430-
<< " points to unknown target_offset=" << target_offset
431-
<< " – truncating action chain\n";
428+
// temporary comment out for demo!
429+
// std::cerr << "[AbiParser] warning: next_offset from entry_offset="
430+
// << a.entry_offset
431+
// << " points to unknown target_offset=" << target_offset
432+
// << " – truncating action chain\n";
432433
a.next_index = -1;
433434
continue;
434435
}

src/main.cpp

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010
*/
1111
#include <expected>
1212
#include <filesystem>
13+
#include <iostream>
1314
#include <print>
1415
#include <span>
1516
#include <string>
1617
#include <string_view>
1718
#include <tuple>
18-
#include <vector>
1919
#include <unordered_set>
20-
#include <iostream>
21-
#include <string>
20+
#include <vector>
2221

2322
#include "abi_parse.hpp"
2423
#include "elf_parser.hpp"
@@ -122,24 +121,42 @@ int main(int argc, char* argv[])
122121
// Load LSDA catch table into Validator
123122
val.load_lsda(lsda);
124123

125-
auto res = val.analyze_exceptions("_Z3fooi");
126-
if (!res.has_value()) {
127-
std::print("analyze_exceptions failed\n");
128-
return EXIT_FAILURE;
129-
}
130-
131-
for (const auto& f : val.find_thrown_functions()) {
132-
std::println("throws: {}",
133-
val.demangle(f.name.c_str()).value_or(f.name));
124+
std::println("=======================================");
125+
std::println("Function that can throw: ");
126+
std::println("=======================================");
127+
std::vector<symbol_s> callsite_function = val.find_thrown_functions();
128+
for (const auto& func : callsite_function) {
129+
std::println(" {}",
130+
val.demangle(func.name.c_str()).value_or(func.name));
134131
}
135132

133+
std::println("=======================================");
134+
std::println("Catch Sites: ");
135+
std::println("=======================================");
136136
// we print it but we canremove this
137-
for (const auto& m : res.value()) {
138-
auto dn = val.demangle(m.thrown.name.c_str()).value_or(m.thrown.name);
139-
std::print("Thrown: {}\n", dn);
140-
for (auto* h : m.handlers) {
141-
std::print(" caught by {} type_index={}\n", h->scope_id, h->type_index);
137+
for (const auto& func : callsite_function) {
138+
std::println("Function: {}", func.name);
139+
140+
auto caught_throws = val.analyze_exceptions(func.name);
141+
if (!caught_throws.has_value()) {
142+
std::print("analyze_exceptions failed\n");
143+
return EXIT_FAILURE;
144+
}
145+
146+
for (auto& caught_throw : caught_throws.value()) {
147+
symbol_s caught_throw_obj = caught_throw.thrown;
148+
std::string caught_throw_name
149+
= val.demangle(caught_throw_obj.name.c_str())
150+
.value_or(caught_throw_obj.name);
151+
std::println("\tThrows: {}", caught_throw_name);
152+
auto callsite_handlers = caught_throw.handlers;
153+
for (auto& handler : callsite_handlers) {
154+
std::print("\t\t* caught by {}\n\t\t* type_index={}\n",
155+
handler->scope_id,
156+
handler->type_index);
157+
}
142158
}
159+
std::println("---------------------------------------");
143160
}
144161

145162
return 0;

testing_programs/simple.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ void foo(int i) {
55
throw std::invalid_argument("arg error");
66
} else if(i == 1){
77
throw 67;
8-
} else if(i == 0){
9-
throw std::runtime_error("error");
108
} else if(i == 2){
119
throw "error";
1210
} else if (i == 3){
13-
throw 6.7;
11+
throw 6;
1412
}
1513
}
1614

@@ -23,7 +21,11 @@ void baa() {
2321
int main(){
2422
try{
2523
baa();
26-
} catch (...) {
24+
} catch (int& i) {
2725

28-
};
26+
} catch (std::string& s) {
27+
28+
} catch (std::invalid_argument& e) {
29+
30+
}
2931
}

0 commit comments

Comments
 (0)