Skip to content

Commit 2082aca

Browse files
bors[bot]adamgreig
andauthored
Merge #318
318: Use LTO instead of removing the panic handler manually. Closes #309 r=jonas-schievink a=adamgreig Co-authored-by: Adam Greig <[email protected]>
2 parents 6d75b14 + 4c624da commit 2082aca

16 files changed

+4
-96
lines changed

bin/thumbv6m-none-eabi-lto.a

-4.21 KB
Binary file not shown.

bin/thumbv6m-none-eabi.a

-2.67 KB
Binary file not shown.

bin/thumbv7em-none-eabi-lto.a

-4.19 KB
Binary file not shown.

bin/thumbv7em-none-eabi.a

-1.93 KB
Binary file not shown.

bin/thumbv7em-none-eabihf-lto.a

-4.13 KB
Binary file not shown.

bin/thumbv7em-none-eabihf.a

-1.73 KB
Binary file not shown.

bin/thumbv7m-none-eabi-lto.a

-4.01 KB
Binary file not shown.

bin/thumbv7m-none-eabi.a

-2.11 KB
Binary file not shown.

bin/thumbv8m.base-none-eabi-lto.a

-4.23 KB
Binary file not shown.

bin/thumbv8m.base-none-eabi.a

-1.96 KB
Binary file not shown.

bin/thumbv8m.main-none-eabi-lto.a

-4.14 KB
Binary file not shown.

bin/thumbv8m.main-none-eabi.a

-1 KB
Binary file not shown.

bin/thumbv8m.main-none-eabihf-lto.a

-4.01 KB
Binary file not shown.

bin/thumbv8m.main-none-eabihf.a

-812 Bytes
Binary file not shown.

xtask/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,3 @@ harness = false
1111

1212
[dependencies]
1313
ar = "0.8.0"
14-
15-
[dependencies.object]
16-
version = "0.22.0"
17-
features = ["write"]

xtask/src/lib.rs

Lines changed: 4 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
//!
55
//! Also see the docs in `asm.rs`.
66
7-
use object::read::{Object as _, ObjectSection as _};
8-
use object::write::{Object, Symbol, SymbolSection};
9-
use object::{ObjectSymbol, SymbolFlags};
107
use std::collections::BTreeMap;
118
use std::env::current_dir;
129
use std::fs::{self, File};
@@ -25,90 +22,6 @@ fn rustc() -> Command {
2522
cmd
2623
}
2724

28-
/// Patches an object file so that it doesn't contain a panic handler.
29-
///
30-
/// The panic handler defined in `asm/lib.rs` should never get linked to the final program.
31-
/// Unfortunately, Rust uses the same symbol for all panic handlers, and doesn't really like it if
32-
/// that ends up with multiple ones. It also demands that we define a panic handler for the inline
33-
/// assembly shim, even though none of that code should ever be able to panic. The result of this is
34-
/// that the supposedly unreachable panic handler does end up getting linked into the final program,
35-
/// unless it is built with optimizations enabled.
36-
///
37-
/// To fix that, we put the never-to-be-used panic handler into its own section via
38-
/// `#[link_section]`, and then use this function to delete that section.
39-
fn trim_panic_handler(obj_file: &str) {
40-
let objdata = fs::read(&obj_file).unwrap();
41-
let obj = object::File::parse(&objdata).unwrap();
42-
43-
let mut writer = Object::new(obj.format(), obj.architecture(), obj.endianness());
44-
writer.flags = obj.flags(); // Preserve flags of input file
45-
46-
for (sec_index, section) in obj.sections().enumerate() {
47-
assert_eq!(section.index().0, sec_index);
48-
49-
let name = section.name().unwrap();
50-
if name.starts_with(".ARM")
51-
|| name.starts_with(".rel.ARM")
52-
|| name.contains("asm_panic_handler")
53-
|| name == ".strtab"
54-
|| name == ".symtab"
55-
{
56-
// We drop the ARM exception handling tables since they refer back to the panic handler
57-
// symbol. They aren't used either way. We also drop `.strtab` and `.symtab` since they
58-
// otherwise end up having the wrong section type. The object crate should rebuild any
59-
// index tables when writing the file.
60-
continue;
61-
}
62-
63-
let segment = section
64-
.segment_name()
65-
.unwrap()
66-
.map(|s| s.as_bytes())
67-
.unwrap_or(&[]);
68-
let sec_id = writer.add_section(segment.to_vec(), name.as_bytes().to_vec(), section.kind());
69-
70-
let align = if section.align() == 0 {
71-
// Not sure why but `section.align()` can return 0.
72-
1
73-
} else {
74-
section.align()
75-
};
76-
writer.append_section_data(sec_id, section.data().unwrap(), align);
77-
78-
// Import all symbols from the section.
79-
for symbol in obj.symbols() {
80-
if symbol.section_index() == Some(section.index()) {
81-
writer.add_symbol(Symbol {
82-
name: symbol.name().unwrap_or("").as_bytes().to_vec(),
83-
value: symbol.address(),
84-
size: symbol.size(),
85-
kind: symbol.kind(),
86-
scope: symbol.scope(),
87-
weak: symbol.is_weak(),
88-
section: match symbol.section() {
89-
object::SymbolSection::Unknown => unimplemented!(),
90-
object::SymbolSection::None => SymbolSection::None,
91-
object::SymbolSection::Undefined => SymbolSection::Undefined,
92-
object::SymbolSection::Absolute => SymbolSection::Absolute,
93-
object::SymbolSection::Common => SymbolSection::Common,
94-
object::SymbolSection::Section(_) => SymbolSection::Section(sec_id),
95-
},
96-
flags: match symbol.flags() {
97-
SymbolFlags::None => SymbolFlags::None,
98-
SymbolFlags::Elf { st_info, st_other } => {
99-
SymbolFlags::Elf { st_info, st_other }
100-
}
101-
_ => unimplemented!(),
102-
},
103-
});
104-
}
105-
}
106-
}
107-
108-
let obj = writer.write().unwrap();
109-
fs::write(&obj_file, obj).unwrap();
110-
}
111-
11225
fn assemble_really(target: &str, cfgs: &[&str], plugin_lto: bool) {
11326
let mut cmd = rustc();
11427

@@ -122,6 +35,10 @@ fn assemble_really(target: &str, cfgs: &[&str], plugin_lto: bool) {
12235
// We always optimize the assembly shims. There's not really any reason not to.
12336
cmd.arg("-O");
12437

38+
// We use LTO on the archive to ensure the (unused) panic handler is removed, preventing
39+
// a linker error when the archives are linked into final crates with two panic handlers.
40+
cmd.arg("-Clto=yes");
41+
12542
// rustc will usually add frame pointers by default to aid with debugging, but that is a high
12643
// overhead for the tiny assembly routines.
12744
cmd.arg("-Cforce-frame-pointers=no");
@@ -158,11 +75,6 @@ fn assemble_really(target: &str, cfgs: &[&str], plugin_lto: bool) {
15875
let status = cmd.status().unwrap();
15976
assert!(status.success());
16077

161-
if !plugin_lto {
162-
// Post-process the object file.
163-
trim_panic_handler(&obj_file);
164-
}
165-
16678
// Archive `target.o` -> `bin/target.a`.
16779
let mut builder = ar::Builder::new(File::create(format!("bin/{}.a", file_stub)).unwrap());
16880

0 commit comments

Comments
 (0)