mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
fix: calculate windows dll symbols from prebuilt shared library
This commit is contained in:
parent
b92d0ef315
commit
720ed2a457
5 changed files with 46 additions and 45 deletions
|
@ -15,9 +15,10 @@ use std::{
|
|||
io::{BufReader, BufWriter},
|
||||
mem,
|
||||
path::Path,
|
||||
time::{Duration, Instant},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use crate::util::{is_roc_definition, is_roc_undefined, report_timing};
|
||||
use crate::{
|
||||
align_by_constraint, align_to_offset_by_constraint, load_struct_inplace,
|
||||
load_struct_inplace_mut, load_structs_inplace_mut, open_mmap, open_mmap_mut,
|
||||
|
@ -103,26 +104,6 @@ impl Metadata {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_timing(label: &str, duration: Duration) {
|
||||
println!("\t{:9.3} ms {}", duration.as_secs_f64() * 1000.0, label,);
|
||||
}
|
||||
|
||||
fn is_roc_symbol(sym: &object::Symbol) -> bool {
|
||||
if let Ok(name) = sym.name() {
|
||||
name.trim_start_matches('_').starts_with("roc_")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_roc_definition(sym: &object::Symbol) -> bool {
|
||||
sym.is_definition() && is_roc_symbol(sym)
|
||||
}
|
||||
|
||||
fn is_roc_undefined(sym: &object::Symbol) -> bool {
|
||||
sym.is_undefined() && is_roc_symbol(sym)
|
||||
}
|
||||
|
||||
fn collect_roc_definitions<'a>(object: &object::File<'a, &'a [u8]>) -> MutMap<String, u64> {
|
||||
let mut vaddresses = MutMap::default();
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ use std::path::{Path, PathBuf};
|
|||
mod elf;
|
||||
mod macho;
|
||||
mod pe;
|
||||
mod util;
|
||||
|
||||
mod generate_dylib;
|
||||
|
||||
|
@ -380,7 +381,6 @@ pub fn preprocess_host(
|
|||
&metadata_path,
|
||||
preprocessed_path.as_path(),
|
||||
dylib_path,
|
||||
&[],
|
||||
verbose,
|
||||
time,
|
||||
)
|
||||
|
@ -394,7 +394,6 @@ fn preprocess(
|
|||
metadata_path: &Path,
|
||||
preprocessed_path: &Path,
|
||||
shared_lib: &Path,
|
||||
stub_dll_symbols: &[String],
|
||||
verbose: bool,
|
||||
time: bool,
|
||||
) {
|
||||
|
@ -430,7 +429,7 @@ fn preprocess(
|
|||
host_exe_path,
|
||||
metadata_path,
|
||||
preprocessed_path,
|
||||
stub_dll_symbols,
|
||||
shared_lib,
|
||||
verbose,
|
||||
time,
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ use object::{
|
|||
ImageSectionHeader, ImageThunkData64,
|
||||
},
|
||||
read::pe::ImportTable,
|
||||
LittleEndian as LE, Object, RelocationTarget, SectionIndex,
|
||||
LittleEndian as LE, Object, ObjectSection, ObjectSymbol, RelocationTarget, SectionIndex,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -19,8 +19,10 @@ use roc_collections::{MutMap, VecMap};
|
|||
use roc_error_macros::internal_error;
|
||||
|
||||
use crate::{
|
||||
generate_dylib::APP_DLL, load_struct_inplace, load_struct_inplace_mut,
|
||||
load_structs_inplace_mut, open_mmap, open_mmap_mut,
|
||||
generate_dylib::APP_DLL,
|
||||
load_struct_inplace, load_struct_inplace_mut, load_structs_inplace_mut, open_mmap,
|
||||
open_mmap_mut,
|
||||
util::is_roc_definition,
|
||||
};
|
||||
|
||||
/// The metadata stores information about/from the host .exe because
|
||||
|
@ -95,8 +97,6 @@ impl PeMetadata {
|
|||
}
|
||||
|
||||
fn from_preprocessed_host(preprocessed_data: &[u8], new_sections: &[[u8; 8]]) -> Self {
|
||||
use object::ObjectSection;
|
||||
|
||||
let dynhost_obj = object::read::pe::PeFile64::parse(preprocessed_data)
|
||||
.unwrap_or_else(|err| internal_error!("Failed to parse executable file: {}", err));
|
||||
|
||||
|
@ -183,17 +183,26 @@ pub(crate) fn preprocess_windows(
|
|||
host_exe_filename: &Path,
|
||||
metadata_filename: &Path,
|
||||
preprocessed_filename: &Path,
|
||||
dummy_dll_symbols: &[String],
|
||||
shared_lib: &Path,
|
||||
_verbose: bool,
|
||||
_time: bool,
|
||||
) -> object::read::Result<()> {
|
||||
let data = open_mmap(host_exe_filename);
|
||||
let exec_data = open_mmap(host_exe_filename);
|
||||
let shared_lib_data = &*open_mmap(shared_lib);
|
||||
let shared_lib_obj = match object::File::parse(shared_lib_data) {
|
||||
Ok(obj) => obj,
|
||||
Err(e) => internal_error!("Failed to parse shared library file: {e}"),
|
||||
};
|
||||
let dummy_dll_symbols = shared_lib_obj
|
||||
.dynamic_symbols()
|
||||
.filter(is_roc_definition)
|
||||
.count();
|
||||
|
||||
let new_sections = [*b".text\0\0\0", *b".rdata\0\0"];
|
||||
let mut preprocessed = Preprocessor::preprocess(
|
||||
preprocessed_filename,
|
||||
&data,
|
||||
dummy_dll_symbols.len(),
|
||||
&exec_data,
|
||||
dummy_dll_symbols,
|
||||
&new_sections,
|
||||
);
|
||||
|
||||
|
@ -1164,8 +1173,6 @@ fn process_internal_relocations(
|
|||
|
||||
impl<'a> AppSections<'a> {
|
||||
fn from_data(data: &'a [u8]) -> Self {
|
||||
use object::ObjectSection;
|
||||
|
||||
let file = object::File::parse(data).unwrap();
|
||||
|
||||
let mut sections = Vec::new();
|
||||
|
@ -1193,8 +1200,6 @@ impl<'a> AppSections<'a> {
|
|||
for (offset_in_section, relocation) in section.relocations() {
|
||||
match relocation.target() {
|
||||
RelocationTarget::Symbol(symbol_index) => {
|
||||
use object::ObjectSymbol;
|
||||
|
||||
let symbol = file.symbol_by_index(symbol_index);
|
||||
|
||||
let address = symbol.as_ref().map(|s| s.address()).unwrap_or_default();
|
||||
|
@ -1252,8 +1257,6 @@ impl<'a> AppSections<'a> {
|
|||
let mut other_symbols = Vec::new();
|
||||
|
||||
for symbol in file.symbols() {
|
||||
use object::ObjectSymbol;
|
||||
|
||||
if symbol.name_bytes().unwrap_or_default().starts_with(b"roc") {
|
||||
if let object::SymbolSection::Section(index) = symbol.section() {
|
||||
let (kind, offset_in_host_section) = section_starts[&index];
|
||||
|
@ -1801,7 +1804,7 @@ mod test {
|
|||
&dir.join("host.exe"),
|
||||
&dir.join("metadata"),
|
||||
&preprocessed_host_filename,
|
||||
&names,
|
||||
&dir.join("libapp.dll"),
|
||||
false,
|
||||
false,
|
||||
)
|
||||
|
|
23
crates/linker/src/util.rs
Normal file
23
crates/linker/src/util.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use object::ObjectSymbol;
|
||||
|
||||
pub(crate) fn report_timing(label: &str, duration: Duration) {
|
||||
println!("\t{:9.3} ms {}", duration.as_secs_f64() * 1000.0, label,);
|
||||
}
|
||||
|
||||
fn is_roc_symbol(sym: &object::Symbol) -> bool {
|
||||
if let Ok(name) = sym.name() {
|
||||
name.trim_start_matches('_').starts_with("roc_")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_roc_definition(sym: &object::Symbol) -> bool {
|
||||
sym.is_definition() && is_roc_symbol(sym)
|
||||
}
|
||||
|
||||
pub(crate) fn is_roc_undefined(sym: &object::Symbol) -> bool {
|
||||
sym.is_undefined() && is_roc_symbol(sym)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue