1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Write LSDAs to `.gcc_except_table`.
//!
//! ## API Structure
//!
//! This module works by building up a representation of the LSDAs in memory
//! with [`GccExceptTable`] and [`Lsda`], and then writing them all at once to
//! a [`Writer`].
//!
//! * An [`Lsda`] holds the call-site table ([`CallSite`]), the action table
//! ([`Action`]), the type table, and the exception specifications
//! ([`ExceptionSpec`]). Entries refer to each other through ids, which are
//! indices into those tables; the writer computes the encoded offsets.
//!
//! * Addresses are [`Address`] values: either constants, which are encoded
//! relative to the bases in [`BaseAddresses`](crate::BaseAddresses), or
//! symbols, which require a writer that records relocations (see
//! [`RelocateWriter`]).
//!
//! * With the `read` feature, [`GccExceptTable::from_read`] converts parsed
//! tables so they can be modified and written again.
//!
//! ## Example Usage
//!
//! ```rust
//! use lsda::write::{Action, Address, CallSite, EndianVec, Filter, GccExceptTable, Lsda};
//! use lsda::{BaseAddresses, Encoding, Format, LittleEndian};
//!
//! # fn example() -> lsda::write::Result<()> {
//! // try { g(); } catch (int) { ... }
//! let mut lsda = Lsda::new();
//! lsda.ttype_encoding = Encoding::INDIRECT_PCREL_SDATA4;
//! let int = lsda.add_type(Some(Address::Constant(0x2000))); // DW.ref._ZTIi
//! let catch_int = lsda.add_action(Action {
//! filter: Filter::Catch(int),
//! next: None,
//! });
//! lsda.call_sites.push(CallSite::new(0x10, 0x08, 0x40, Some(catch_int)));
//!
//! let mut table = GccExceptTable::new(Format::new(8));
//! table.add_lsda(lsda);
//!
//! let mut section = EndianVec::new(LittleEndian);
//! let bases = BaseAddresses::default().set_section(0x1000);
//! table.write(&mut section, &bases)?;
//! assert_eq!(
//! section.slice(),
//! [
//! 0xff, 0x9b, 0x0d, 0x01, 0x04, // header
//! 0x10, 0x08, 0x40, 0x01, // call site
//! 0x01, 0x00, // action
//! 0x00, // padding
//! 0xf4, 0x0f, 0x00, 0x00, // type 1
//! ]
//! );
//! # Ok(())
//! # }
//! # example().unwrap();
//! ```
pub use *;
pub use Writer;
pub use *;
pub use *;
pub use *;
pub use *;
/// An address.