tidy up a bit
This commit is contained in:
parent
857c03df07
commit
5fc8f90a21
@ -1,54 +1,50 @@
|
|||||||
//! Handles dynamic library loading for proc macro
|
//! Handles dynamic library loading for proc macro
|
||||||
|
|
||||||
use crate::{proc_macro::bridge, rustc_server::TokenStream};
|
use crate::{proc_macro::bridge, rustc_server::TokenStream};
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use goblin::{mach::Mach, Object};
|
use goblin::{mach::Mach, Object};
|
||||||
use libloading::Library;
|
use libloading::Library;
|
||||||
use ra_proc_macro::ProcMacroKind;
|
use ra_proc_macro::ProcMacroKind;
|
||||||
|
|
||||||
static NEW_REGISTRAR_SYMBOL: &str = "__rustc_proc_macro_decls_";
|
static NEW_REGISTRAR_SYMBOL: &str = "_rustc_proc_macro_decls_";
|
||||||
static _OLD_REGISTRAR_SYMBOL: &str = "__rustc_derive_registrar_";
|
|
||||||
|
|
||||||
fn read_bytes(file: &Path) -> Option<Vec<u8>> {
|
|
||||||
let mut fd = File::open(file).ok()?;
|
|
||||||
let mut buffer = Vec::new();
|
|
||||||
fd.read_to_end(&mut buffer).ok()?;
|
|
||||||
|
|
||||||
Some(buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_symbols_from_lib(file: &Path) -> Option<Vec<String>> {
|
fn get_symbols_from_lib(file: &Path) -> Option<Vec<String>> {
|
||||||
let buffer = read_bytes(file)?;
|
let buffer = std::fs::read(file).ok()?;
|
||||||
let object = Object::parse(&buffer).ok()?;
|
let object = Object::parse(&buffer).ok()?;
|
||||||
|
|
||||||
return match object {
|
return match object {
|
||||||
Object::Elf(elf) => {
|
Object::Elf(elf) => {
|
||||||
let symbols = elf.dynstrtab.to_vec().ok()?;
|
let symbols = elf.dynstrtab.to_vec().ok()?;
|
||||||
let names = symbols.iter().map(|s| s.to_string()).collect();
|
let names = symbols.iter().map(|s| s.to_string()).collect();
|
||||||
|
|
||||||
Some(names)
|
Some(names)
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::PE(pe) => {
|
Object::PE(pe) => {
|
||||||
let symbol_names =
|
let symbol_names =
|
||||||
pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect();
|
pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect();
|
||||||
Some(symbol_names)
|
Some(symbol_names)
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Mach(mach) => match mach {
|
Object::Mach(mach) => match mach {
|
||||||
Mach::Binary(binary) => {
|
Mach::Binary(binary) => {
|
||||||
let exports = binary.exports().ok()?;
|
let exports = binary.exports().ok()?;
|
||||||
let names = exports.iter().map(|s| s.name.clone()).collect();
|
let names = exports
|
||||||
|
.iter()
|
||||||
|
.map(|s| {
|
||||||
|
// In macos doc:
|
||||||
|
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
|
||||||
|
// Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
|
||||||
|
// prepended with an underscore.
|
||||||
|
if s.name.starts_with("_") {
|
||||||
|
s.name[1..].to_string()
|
||||||
|
} else {
|
||||||
|
s.name.to_string()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
Some(names)
|
Some(names)
|
||||||
}
|
}
|
||||||
|
|
||||||
Mach::Fat(_) => None,
|
Mach::Fat(_) => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
Object::Archive(_) | Object::Unknown(_) => None,
|
Object::Archive(_) | Object::Unknown(_) => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -57,28 +53,10 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool {
|
|||||||
symbol.contains(NEW_REGISTRAR_SYMBOL)
|
symbol.contains(NEW_REGISTRAR_SYMBOL)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
|
||||||
fn adjust_symbol_name(name: &str) -> String {
|
|
||||||
name.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn adjust_symbol_name(s: &str) -> String {
|
|
||||||
// In macos doc:
|
|
||||||
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
|
|
||||||
// Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
|
|
||||||
// prepended with an underscore.
|
|
||||||
if s.starts_with("_") {
|
|
||||||
s[1..s.len()].to_string()
|
|
||||||
} else {
|
|
||||||
s.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_registrar_symbol(file: &Path) -> Option<String> {
|
fn find_registrar_symbol(file: &Path) -> Option<String> {
|
||||||
let symbols = get_symbols_from_lib(file)?;
|
let symbols = get_symbols_from_lib(file)?;
|
||||||
|
|
||||||
symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| adjust_symbol_name(&s))
|
symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads dynamic library in platform dependent manner.
|
/// Loads dynamic library in platform dependent manner.
|
||||||
@ -119,11 +97,9 @@ fn open(file: &Path) -> Result<Self, String> {
|
|||||||
.ok_or(format!("Cannot find registrar symbol in file {:?}", file))?;
|
.ok_or(format!("Cannot find registrar symbol in file {:?}", file))?;
|
||||||
|
|
||||||
let lib = load_library(file).map_err(|e| e.to_string())?;
|
let lib = load_library(file).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let exported_macros = {
|
let exported_macros = {
|
||||||
let macros: libloading::Symbol<&&[bridge::client::ProcMacro]> =
|
let macros: libloading::Symbol<&&[bridge::client::ProcMacro]> =
|
||||||
unsafe { lib.get(symbol_name.as_bytes()) }.map_err(|e| e.to_string())?;
|
unsafe { lib.get(symbol_name.as_bytes()) }.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
macros.to_vec()
|
macros.to_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -140,7 +116,6 @@ pub struct Expander {
|
|||||||
impl Expander {
|
impl Expander {
|
||||||
pub fn new<P: AsRef<Path>>(lib: &P) -> Result<Expander, String> {
|
pub fn new<P: AsRef<Path>>(lib: &P) -> Result<Expander, String> {
|
||||||
let mut libs = vec![];
|
let mut libs = vec![];
|
||||||
|
|
||||||
/* Some libraries for dynamic loading require canonicalized path (even when it is
|
/* Some libraries for dynamic loading require canonicalized path (even when it is
|
||||||
already absolute
|
already absolute
|
||||||
*/
|
*/
|
||||||
@ -177,20 +152,16 @@ pub fn expand(
|
|||||||
crate::rustc_server::Rustc::default(),
|
crate::rustc_server::Rustc::default(),
|
||||||
parsed_body,
|
parsed_body,
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.map(|it| it.subtree);
|
return res.map(|it| it.subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => {
|
bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => {
|
||||||
let res = client.run(
|
let res = client.run(
|
||||||
&crate::proc_macro::bridge::server::SameThread,
|
&crate::proc_macro::bridge::server::SameThread,
|
||||||
crate::rustc_server::Rustc::default(),
|
crate::rustc_server::Rustc::default(),
|
||||||
parsed_body,
|
parsed_body,
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.map(|it| it.subtree);
|
return res.map(|it| it.subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => {
|
bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => {
|
||||||
let res = client.run(
|
let res = client.run(
|
||||||
&crate::proc_macro::bridge::server::SameThread,
|
&crate::proc_macro::bridge::server::SameThread,
|
||||||
@ -201,10 +172,7 @@ pub fn expand(
|
|||||||
|
|
||||||
return res.map(|it| it.subtree);
|
return res.map(|it| it.subtree);
|
||||||
}
|
}
|
||||||
|
_ => continue,
|
||||||
_ => {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user