Skip to content

Commit

Permalink
Support loading and linking of .text.unlikely. sections (theseus-os…
Browse files Browse the repository at this point in the history
…#520)

* A recent change to Rust's usage of LLVM resulted in some sections in the compiled object files now being named `.text.unlikely.<name>`, which the module management (crate loading) code did not previously account for. 

* We now handle global `.text.unlikely` sections only, as those are the ones that need the proper name to be parsed in order to be added to the current namespace's symbol map. Moreover, other sections in foreign crates may depend on that symbol existing _without_ the `.unlikely.` prefix.
    * For example, this occurs in the `wasmtime_runtime` crate at the very least, and perhaps others as well.

* Note: I attempted to disable the hot-cold splitting of function sections that causes this by passing a variety of different `-C llvm-args=...` arguments to rustc, but none of them made a difference.
  • Loading branch information
kevinaboos authored May 13, 2022
1 parent 486df20 commit d0ea6c2
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion kernel/mod_mgmt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,7 @@ impl CrateNamespace {
let (mut rodata_offset, mut data_offset) = (0 , 0);

const TEXT_PREFIX: &'static str = ".text.";
const UNLIKELY_PREFIX: &'static str = "unlikely."; // the full section prefix is ".text.unlikely."
const RODATA_PREFIX: &'static str = ".rodata.";
const DATA_PREFIX: &'static str = ".data.";
const BSS_PREFIX: &'static str = ".bss.";
Expand Down Expand Up @@ -1235,7 +1236,20 @@ impl CrateNamespace {

// First, check for executable sections, which can only be .text sections.
if is_exec && !is_write {
let is_global = global_sections.contains(&shndx);
let name = try_get_symbol_name_after_prefix!(sec_name, TEXT_PREFIX);
// Handle cold sections, which have a section prefix of ".text.unlikely."
// Currently, we ignore the cold/hot designation in terms of placing a section in memory.
// Note: we only *truly* have to do this for global sections, because other crates
// might depend on their correct section name after the ".text.unlikely." prefix.
let name = if is_global && name.starts_with(UNLIKELY_PREFIX) {
name.get(UNLIKELY_PREFIX.len() ..).ok_or_else(|| {
error!("Failed to get the .text.unlikely. section's name: {:?}", sec_name);
"Failed to get the .text.unlikely. section's name after the prefix"
})?
} else {
name
};
let demangled = demangle(name).to_string();

// We already copied the content of all .text sections above,
Expand All @@ -1253,7 +1267,7 @@ impl CrateNamespace {
text_offset,
dest_vaddr,
sec_size,
global_sections.contains(&shndx),
is_global,
new_crate_weak_ref.clone(),
))
);
Expand Down

0 comments on commit d0ea6c2

Please sign in to comment.