Skip to content

Commit d710f8b

Browse files
committed
Moar comments.
1 parent 9a71c5c commit d710f8b

File tree

7 files changed

+59
-30
lines changed

7 files changed

+59
-30
lines changed

src/librustc_back/target/windows_base.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ pub fn opts() -> TargetOptions {
6565
"-nostdlib".to_string(),
6666
),
6767
pre_link_objects_exe: vec!(
68-
"crt2.o".to_string(),
69-
"rsbegin.o".to_string(),
68+
"crt2.o".to_string(), // mingw C runtime initialization for executables
69+
"rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs
7070
),
7171
pre_link_objects_dll: vec!(
72-
"dllcrt2.o".to_string(),
72+
"dllcrt2.o".to_string(), // mingw C runtime initialization for dlls
7373
"rsbegin.o".to_string(),
7474
),
7575
late_link_args: vec!(

src/libstd/lib.rs

-9
Original file line numberDiff line numberDiff line change
@@ -400,15 +400,6 @@ pub mod __rand {
400400
pub use rand::{thread_rng, ThreadRng, Rng};
401401
}
402402

403-
// Rust runtime's startup objects depend on these symbols, so they must be public.
404-
// Since sys_common isn't public, we have to re-export them here explicitly.
405-
#[doc(hidden)]
406-
#[unstable(feature = "eh_frame_registry", issue = "0")]
407-
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
408-
pub mod __frame_registry {
409-
pub use sys_common::unwind::imp::eh_frame_registry::*;
410-
}
411-
412403
// Include a number of private modules that exist solely to provide
413404
// the rustdoc documentation for primitive types. Using `include!`
414405
// because rustdoc only looks for these modules at the crate level.

src/libstd/rt.rs

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ use thread::{self, Thread};
3232
// Reexport some of our utilities which are expected by other crates.
3333
pub use sys_common::unwind::{begin_unwind, begin_unwind_fmt};
3434

35+
// Rust runtime's startup objects depend on these symbols, so they must be public.
36+
// Since sys_common isn't public, we have to re-export them here.
37+
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
38+
pub use sys_common::unwind::imp::eh_frame_registry::*;
39+
3540
#[cfg(not(test))]
3641
#[lang = "start"]
3742
fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {

src/libstd/sys/common/unwind/gcc.rs

+5
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ pub mod eabi {
232232
}
233233
}
234234

235+
// See docs in the `unwind` module.
235236
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu", not(test)))]
236237
#[lang = "eh_unwind_resume"]
237238
#[unwind]
@@ -241,6 +242,10 @@ unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
241242

242243
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
243244
pub mod eh_frame_registry {
245+
// The implementation of stack unwinding is (for now) deferred to libgcc_eh, however Rust
246+
// crates use these Rust-specific entry points to avoid potential clashes with GCC runtime.
247+
// See also: rtbegin.rs, `unwind` module.
248+
244249
#[link(name = "gcc_eh")]
245250
extern {
246251
fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);

src/libstd/sys/common/unwind/mod.rs

+24-17
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,35 @@
3434
//! object being thrown, and to decide whether it should be caught at that stack
3535
//! frame. Once the handler frame has been identified, cleanup phase begins.
3636
//!
37-
//! In the cleanup phase, personality routines invoke cleanup code associated
38-
//! with their stack frames (i.e. destructors). Once stack has been unwound down
39-
//! to the handler frame level, unwinding stops and the last personality routine
40-
//! transfers control to its catch block.
37+
//! In the cleanup phase, the unwinder invokes each personality routine again.
38+
//! This time it decides which (if any) cleanup code needs to be run for
39+
//! the current stack frame. If so, the control is transferred to a special branch
40+
//! in the function body, the "landing pad", which invokes destructors, frees memory,
41+
//! etc. At the end of the landing pad, control is transferred back to the unwinder
42+
//! and unwinding resumes.
4143
//!
42-
//! ## Frame unwind info registration
44+
//! Once stack has been unwound down to the handler frame level, unwinding stops
45+
//! and the last personality routine transfers control to the catch block.
4346
//!
44-
//! Each module has its own frame unwind info section (usually ".eh_frame"), and
45-
//! unwinder needs to know about all of them in order for unwinding to be able to
46-
//! cross module boundaries.
47+
//! ## `eh_personality` and `eh_unwind_resume`
4748
//!
48-
//! On some platforms, like Linux, this is achieved by dynamically enumerating
49-
//! currently loaded modules via the dl_iterate_phdr() API and finding all
50-
//! .eh_frame sections.
49+
//! These language items are used by the compiler when generating unwind info.
50+
//! The first one is the personality routine described above. The second one
51+
//! allows compilation target to customize the process of resuming unwind at the
52+
//! end of the landing pads. `eh_unwind_resume` is used only if `custom_unwind_resume`
53+
//! flag in the target options is set.
5154
//!
52-
//! Others, like Windows, require modules to actively register their unwind info
53-
//! sections by calling __register_frame_info() API at startup. In the latter
54-
//! case it is essential that there is only one copy of the unwinder runtime in
55-
//! the process. This is usually achieved by linking to the dynamic version of
56-
//! the unwind runtime.
55+
//! ## Frame unwind info registration
5756
//!
58-
//! Currently Rust uses unwind runtime provided by libgcc.
57+
//! Each module's image contains a frame unwind info section (usually ".eh_frame").
58+
//! When a module is loaded/unloaded into the process, the unwinder must be informed
59+
//! about the location of this section in memory. The methods of achieving that vary
60+
//! by the platform.
61+
//! On some (e.g. Linux), the unwinder can discover unwind info sections on its own
62+
//! (by dynamically enumerating currently loaded modules via the dl_iterate_phdr() API
63+
//! and finding their ".eh_frame" sections);
64+
//! Others, like Windows, require modules to actively register their unwind info
65+
//! sections via unwinder API (see `rust_eh_register_frames`/`rust_eh_unregister_frames`).
5966
6067
#![allow(dead_code)]
6168
#![allow(unused_imports)]

src/rtstartup/rsbegin.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,21 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// rsbegin.o and rsend.o are the so called "compiler runtime startup objects".
12+
// They contain code needed to correctly initialize the compiler runtime.
13+
//
14+
// When an executable or dylib image is linked, all user code and libraries are
15+
// "sandwiched" between these two object files, so code or data from rsbegin.o
16+
// become first in the respective sections of the image, whereas code and data
17+
// from rsend.o become the last ones. This effect can be used to place symbols
18+
// at the beginning or at the end of a section, as well as to insert any required
19+
// headers or footers.
20+
//
21+
// Note that the actual module entry point is located in the C runtime startup
22+
// object (usually called `crtX.o), which then invokes initialization callbacks
23+
// of other runtime components (registered via yet another special image section).
24+
1125
#![feature(no_std)]
12-
#![feature(linkage)]
1326

1427
#![crate_type="rlib"]
1528
#![no_std]
@@ -20,27 +33,33 @@ pub mod eh_frames
2033
{
2134
#[no_mangle]
2235
#[link_section = ".eh_frame"]
36+
// Marks beginning of the stack frame unwind info section
2337
pub static __EH_FRAME_BEGIN__: [u8; 0] = [];
2438

2539
// Scratch space for unwinder's internal book-keeping.
2640
// This is defined as `struct object` in $GCC/libgcc/unwind-dw2-fde.h.
2741
static mut obj: [isize; 6] = [0; 6];
2842

43+
// Unwind info registration/deregistration routines.
44+
// See the docs of `unwind` module in libstd.
2945
extern {
3046
fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8);
3147
fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8);
3248
}
3349

3450
unsafe fn init() {
51+
// register unwind info on module startup
3552
rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8,
3653
&mut obj as *mut _ as *mut u8);
3754
}
3855

3956
unsafe fn uninit() {
57+
// unregister on shutdown
4058
rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8,
4159
&mut obj as *mut _ as *mut u8);
4260
}
4361

62+
// MSVC-specific init/uninit routine registration
4463
pub mod ms_init
4564
{
4665
// .CRT$X?? sections are roughly analogous to ELF's .init_array and .fini_array,

src/rtstartup/rsend.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// See rsbegin.rs for details.
12+
1113
#![feature(no_std)]
1214

1315
#![crate_type="rlib"]

0 commit comments

Comments
 (0)