From 82727b0c0f7973864c3990853447def2ab3059af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Sun, 8 Mar 2026 22:36:30 +0100 Subject: [PATCH 1/6] Refactor DllImport to better differentiate types --- .../src/back/link/raw_dylib.rs | 20 +++++++++++-------- compiler/rustc_codegen_ssa/src/common.rs | 8 ++++---- compiler/rustc_metadata/src/native_libs.rs | 18 +++++++++-------- compiler/rustc_session/src/cstore.rs | 10 ++++++++-- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 477c9478c3609..ec1c013205622 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_hashes::Hash128; use rustc_hir::attrs::NativeLibKind; use rustc_session::Session; -use rustc_session::cstore::DllImport; +use rustc_session::cstore::{DllImport, DllImportSymbolType}; use rustc_span::Symbol; use rustc_target::spec::Arch; @@ -95,14 +95,14 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>( true, ) }), - is_data: !import.is_fn, + is_data: import.symbol_type != DllImportSymbolType::Function, } } else { ImportLibraryItem { name: import.name.to_string(), ordinal: import.ordinal(), symbol_name: None, - is_data: !import.is_fn, + is_data: import.symbol_type != DllImportSymbolType::Function, } } }) @@ -271,10 +271,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] vers.push((version_name, dynstr)); id }; - syms.push((name, dynstr, Some(ver), symbol.is_fn)); + syms.push((name, dynstr, Some(ver), symbol.symbol_type)); } else { let dynstr = stub.add_dynamic_string(symbol_name.as_bytes()); - syms.push((symbol_name, dynstr, None, symbol.is_fn)); + syms.push((symbol_name, dynstr, None, symbol.symbol_type)); } } @@ -398,8 +398,12 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] // .dynsym stub.write_null_dynamic_symbol(); - for (_name, dynstr, _ver, is_fn) in syms.iter().copied() { - let sym_type = if is_fn { elf::STT_FUNC } else { elf::STT_NOTYPE }; + for (_name, dynstr, _ver, symbol_type) in syms.iter().copied() { + let sym_type = match symbol_type { + DllImportSymbolType::Function => elf::STT_FUNC, + DllImportSymbolType::Static => elf::STT_OBJECT, + DllImportSymbolType::ThreadLocal => elf::STT_TLS, + }; stub.write_dynamic_symbol(&write::Sym { name: Some(dynstr), st_info: (elf::STB_GLOBAL << 4) | sym_type, @@ -418,7 +422,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] if !vers.is_empty() { // .gnu_version stub.write_null_gnu_versym(); - for (_name, _dynstr, ver, _is_fn) in syms.iter().copied() { + for (_name, _dynstr, ver, _symbol_type) in syms.iter().copied() { stub.write_gnu_versym(if let Some(ver) = ver { assert!((2 + ver as u16) < elf::VERSYM_HIDDEN); elf::VERSYM_HIDDEN | (2 + ver as u16) diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 89a3f8061a8c1..a0f46a2d4f5ef 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -5,7 +5,7 @@ use rustc_hir::attrs::PeImportNameType; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; -use rustc_session::cstore::{DllCallingConvention, DllImport}; +use rustc_session::cstore::{DllCallingConvention, DllImport, DllImportSymbolType}; use rustc_span::Span; use rustc_target::spec::{Abi, Env, Os, Target}; @@ -199,7 +199,7 @@ pub fn i686_decorated_name( decorated_name.push('\x01'); } - let prefix = if add_prefix && dll_import.is_fn { + let prefix = if add_prefix && dll_import.symbol_type == DllImportSymbolType::Function { match dll_import.calling_convention { DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None, DllCallingConvention::Stdcall(_) => (!mingw @@ -207,7 +207,7 @@ pub fn i686_decorated_name( .then_some('_'), DllCallingConvention::Fastcall(_) => Some('@'), } - } else if !dll_import.is_fn && !mingw { + } else if dll_import.symbol_type != DllImportSymbolType::Function && !mingw { // For static variables, prefix with '_' on MSVC. Some('_') } else { @@ -219,7 +219,7 @@ pub fn i686_decorated_name( decorated_name.push_str(name); - if add_suffix && dll_import.is_fn { + if add_suffix && dll_import.symbol_type == DllImportSymbolType::Function { use std::fmt::Write; match dll_import.calling_convention { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 52b11615c76f0..1bd6a896b4e25 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -10,7 +10,9 @@ use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::config::CrateType; -use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, NativeLib}; +use rustc_session::cstore::{ + DllCallingConvention, DllImport, DllImportSymbolType, ForeignModule, NativeLib, +}; use rustc_session::search_paths::PathKind; use rustc_span::Symbol; use rustc_span::def_id::{DefId, LOCAL_CRATE}; @@ -451,12 +453,12 @@ impl<'tcx> Collector<'tcx> { } } - DllImport { - name, - import_name_type, - calling_convention, - span, - is_fn: self.tcx.def_kind(item).is_fn_like(), - } + let symbol_type = if self.tcx.def_kind(item).is_fn_like() { + DllImportSymbolType::Function + } else { + bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item)); + }; + + DllImport { name, import_name_type, calling_convention, span, symbol_type } } } diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 2f969aefda182..41e8dfbfcefbc 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -97,8 +97,14 @@ pub struct DllImport { pub calling_convention: DllCallingConvention, /// Span of import's "extern" declaration; used for diagnostics. pub span: Span, - /// Is this for a function (rather than a static variable). - pub is_fn: bool, + pub symbol_type: DllImportSymbolType, +} + +#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, PartialEq)] +pub enum DllImportSymbolType { + Function, + Static, + ThreadLocal, } impl DllImport { From 2fad36b93d0bd964f3b99af23e9abe0f2cc0a301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Sun, 8 Mar 2026 23:13:26 +0100 Subject: [PATCH 2/6] Extend raw-dylib to handle statics and TLS for ELF --- compiler/rustc_metadata/src/native_libs.rs | 11 ++++++++++- tests/run-make/raw-dylib-elf/library.c | 3 +++ tests/run-make/raw-dylib-elf/main.rs | 12 ++++++++++-- tests/run-make/raw-dylib-elf/output.txt | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 1bd6a896b4e25..a60c030b9c0b6 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -5,7 +5,9 @@ use rustc_abi::ExternAbi; use rustc_attr_parsing::eval_config_entry; use rustc_data_structures::fx::FxHashSet; use rustc_hir::attrs::{NativeLibKind, PeImportNameType}; +use rustc_hir::def::DefKind; use rustc_hir::find_attr; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_session::Session; @@ -453,8 +455,15 @@ impl<'tcx> Collector<'tcx> { } } - let symbol_type = if self.tcx.def_kind(item).is_fn_like() { + let def_kind = self.tcx.def_kind(item); + let symbol_type = if def_kind.is_fn_like() { DllImportSymbolType::Function + } else if matches!(def_kind, DefKind::Static { .. }) { + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { + DllImportSymbolType::ThreadLocal + } else { + DllImportSymbolType::Static + } } else { bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item)); }; diff --git a/tests/run-make/raw-dylib-elf/library.c b/tests/run-make/raw-dylib-elf/library.c index 2e3a95b7edeca..943a1382e3405 100644 --- a/tests/run-make/raw-dylib-elf/library.c +++ b/tests/run-make/raw-dylib-elf/library.c @@ -1,3 +1,6 @@ +int global_variable = 3; +__thread int tls_variable = 33; + int this_is_a_library_function() { return 42; } diff --git a/tests/run-make/raw-dylib-elf/main.rs b/tests/run-make/raw-dylib-elf/main.rs index 3be944d295148..ec8951da88f03 100644 --- a/tests/run-make/raw-dylib-elf/main.rs +++ b/tests/run-make/raw-dylib-elf/main.rs @@ -1,11 +1,19 @@ #![feature(raw_dylib_elf)] +#![feature(thread_local)] #![allow(incomplete_features)] +use std::ffi::c_int; + #[link(name = "library", kind = "raw-dylib")] unsafe extern "C" { - safe fn this_is_a_library_function() -> core::ffi::c_int; + safe fn this_is_a_library_function() -> c_int; + static mut global_variable: c_int; + #[thread_local] + static mut tls_variable: c_int; } fn main() { - println!("{}", this_is_a_library_function()) + unsafe { + println!("{} {} {}", this_is_a_library_function(), global_variable, tls_variable); + } } diff --git a/tests/run-make/raw-dylib-elf/output.txt b/tests/run-make/raw-dylib-elf/output.txt index d81cc0710eb6c..53383c3b86453 100644 --- a/tests/run-make/raw-dylib-elf/output.txt +++ b/tests/run-make/raw-dylib-elf/output.txt @@ -1 +1 @@ -42 +42 3 33 From f3654324e6da3fd388035418c9db1912a0d8c4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Mon, 9 Mar 2026 18:17:07 +0100 Subject: [PATCH 3/6] Set symbol size in raw-dylib for ELF --- .../rustc_codegen_ssa/src/back/link/raw_dylib.rs | 10 +++++----- compiler/rustc_metadata/src/native_libs.rs | 16 +++++++++++++++- compiler/rustc_session/src/cstore.rs | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index ec1c013205622..3017e5fc567d3 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -271,10 +271,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] vers.push((version_name, dynstr)); id }; - syms.push((name, dynstr, Some(ver), symbol.symbol_type)); + syms.push((name, dynstr, Some(ver), symbol.symbol_type, symbol.size)); } else { let dynstr = stub.add_dynamic_string(symbol_name.as_bytes()); - syms.push((symbol_name, dynstr, None, symbol.symbol_type)); + syms.push((symbol_name, dynstr, None, symbol.symbol_type, symbol.size)); } } @@ -398,7 +398,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] // .dynsym stub.write_null_dynamic_symbol(); - for (_name, dynstr, _ver, symbol_type) in syms.iter().copied() { + for (_name, dynstr, _ver, symbol_type, size) in syms.iter().copied() { let sym_type = match symbol_type { DllImportSymbolType::Function => elf::STT_FUNC, DllImportSymbolType::Static => elf::STT_OBJECT, @@ -411,7 +411,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] section: Some(text_section), st_shndx: 0, // ignored by object in favor of the `section` field st_value: 0, - st_size: 0, + st_size: size.bytes(), }); } @@ -422,7 +422,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] if !vers.is_empty() { // .gnu_version stub.write_null_gnu_versym(); - for (_name, _dynstr, ver, _symbol_type) in syms.iter().copied() { + for (_name, _dynstr, ver, _symbol_type, _size) in syms.iter().copied() { stub.write_gnu_versym(if let Some(ver) = ver { assert!((2 + ver as u16) < elf::VERSYM_HIDDEN); elf::VERSYM_HIDDEN | (2 + ver as u16) diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index a60c030b9c0b6..17b16b3cfe2d9 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::attrs::{NativeLibKind, PeImportNameType}; use rustc_hir::def::DefKind; use rustc_hir::find_attr; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, List, Ty, TyCtxt}; @@ -468,6 +469,19 @@ impl<'tcx> Collector<'tcx> { bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item)); }; - DllImport { name, import_name_type, calling_convention, span, symbol_type } + let size = match symbol_type { + // We cannot determine the size of a function at compile time, but it shouldn't matter anyway. + DllImportSymbolType::Function => rustc_abi::Size::ZERO, + DllImportSymbolType::Static | DllImportSymbolType::ThreadLocal => { + let ty = self.tcx.type_of(item).instantiate_identity(); + self.tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .ok() + .map(|layout| layout.size) + .unwrap_or_else(|| bug!("Non-function symbols must have a size")) + } + }; + + DllImport { name, import_name_type, calling_convention, span, symbol_type, size } } } diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 41e8dfbfcefbc..c186557ccaa49 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -98,6 +98,7 @@ pub struct DllImport { /// Span of import's "extern" declaration; used for diagnostics. pub span: Span, pub symbol_type: DllImportSymbolType, + pub size: rustc_abi::Size, } #[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, PartialEq)] From 36381555bb78f41f178032dbabbf9ebd602c3530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 13 Mar 2026 18:54:40 +0100 Subject: [PATCH 4/6] Put statics in .data section in raw-dylib for ELF This fixes issues with statics when using static relocation model and linking with GNU ld. Other linkers don't work yet. --- .../src/back/link/raw_dylib.rs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 3017e5fc567d3..06dd7e7eb2bdf 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -296,6 +296,8 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] stub.reserve_shstrtab_section_index(); let text_section_name = stub.add_section_name(".text".as_bytes()); let text_section = stub.reserve_section_index(); + let data_section_name = stub.add_section_name(".data".as_bytes()); + let data_section = stub.reserve_section_index(); stub.reserve_dynsym_section_index(); stub.reserve_dynstr_section_index(); if !vers.is_empty() { @@ -375,7 +377,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] // Section headers stub.write_null_section_header(); stub.write_shstrtab_section_header(); - // Create a dummy .text section for our dummy symbols. + // Create a dummy .text section for our dummy non-data symbols. stub.write_section_header(&write::SectionHeader { name: Some(text_section_name), sh_type: elf::SHT_PROGBITS, @@ -388,6 +390,19 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] sh_addralign: 1, sh_entsize: 0, }); + // And also a dummy .data section for our dummy data symbols. + stub.write_section_header(&write::SectionHeader { + name: Some(data_section_name), + sh_type: elf::SHT_PROGBITS, + sh_flags: (elf::SHF_WRITE | elf::SHF_ALLOC) as u64, + sh_addr: 0, + sh_offset: 0, + sh_size: 0, + sh_link: 0, + sh_info: 0, + sh_addralign: 16, + sh_entsize: 0, + }); stub.write_dynsym_section_header(0, 1); stub.write_dynstr_section_header(0); if !vers.is_empty() { @@ -404,11 +419,13 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] DllImportSymbolType::Static => elf::STT_OBJECT, DllImportSymbolType::ThreadLocal => elf::STT_TLS, }; + let section = + if symbol_type == DllImportSymbolType::Static { data_section } else { text_section }; stub.write_dynamic_symbol(&write::Sym { name: Some(dynstr), st_info: (elf::STB_GLOBAL << 4) | sym_type, st_other: elf::STV_DEFAULT, - section: Some(text_section), + section: Some(section), st_shndx: 0, // ignored by object in favor of the `section` field st_value: 0, st_size: size.bytes(), From ed4afa598928a239725a7862589145359dbf9b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 13 Mar 2026 19:46:32 +0100 Subject: [PATCH 5/6] Set symbols value in raw-dylib for ELF With this change LLD finally produces working binaries with static relocation model. --- compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 06dd7e7eb2bdf..ddc30ee9f3ac2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -387,7 +387,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] sh_size: 0, sh_link: 0, sh_info: 0, - sh_addralign: 1, + sh_addralign: 16, sh_entsize: 0, }); // And also a dummy .data section for our dummy data symbols. @@ -413,6 +413,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] // .dynsym stub.write_null_dynamic_symbol(); + // Linkers like LLD require at least somewhat reasonable symbol values rather than zero, + // otherwise all the symbols might get put at the same address. Thus we increment the value + // every time we write a symbol. + let mut st_value = 0; for (_name, dynstr, _ver, symbol_type, size) in syms.iter().copied() { let sym_type = match symbol_type { DllImportSymbolType::Function => elf::STT_FUNC, @@ -427,9 +431,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] st_other: elf::STV_DEFAULT, section: Some(section), st_shndx: 0, // ignored by object in favor of the `section` field - st_value: 0, + st_value, st_size: size.bytes(), }); + st_value += 8; } // .dynstr From 3531ed9c1d7e866cf2b2c238efaca7e5fc3f4b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Mon, 9 Mar 2026 18:17:07 +0100 Subject: [PATCH 6/6] Extend raw-dylib test for ELF with reloc models --- tests/run-make/raw-dylib-elf/library.c | 2 ++ tests/run-make/raw-dylib-elf/main.rs | 14 ++++++++++-- tests/run-make/raw-dylib-elf/output.txt | 2 +- tests/run-make/raw-dylib-elf/rmake.rs | 30 ++++++++++++++++--------- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/tests/run-make/raw-dylib-elf/library.c b/tests/run-make/raw-dylib-elf/library.c index 943a1382e3405..060cab6ee02f7 100644 --- a/tests/run-make/raw-dylib-elf/library.c +++ b/tests/run-make/raw-dylib-elf/library.c @@ -1,5 +1,7 @@ int global_variable = 3; __thread int tls_variable = 33; +const long const_array[] = {795, 906}; +const char *const_string = "sums of three cubes"; int this_is_a_library_function() { return 42; diff --git a/tests/run-make/raw-dylib-elf/main.rs b/tests/run-make/raw-dylib-elf/main.rs index ec8951da88f03..b55cde766a375 100644 --- a/tests/run-make/raw-dylib-elf/main.rs +++ b/tests/run-make/raw-dylib-elf/main.rs @@ -2,7 +2,7 @@ #![feature(thread_local)] #![allow(incomplete_features)] -use std::ffi::c_int; +use std::ffi::{CStr, c_char, c_int, c_long}; #[link(name = "library", kind = "raw-dylib")] unsafe extern "C" { @@ -10,10 +10,20 @@ unsafe extern "C" { static mut global_variable: c_int; #[thread_local] static mut tls_variable: c_int; + safe static const_array: [c_long; 2]; + safe static const_string: *const c_char; } fn main() { unsafe { - println!("{} {} {}", this_is_a_library_function(), global_variable, tls_variable); + println!( + "{} {} {} {} {} {}", + this_is_a_library_function(), + global_variable, + tls_variable, + const_array[0], + const_array[1], + CStr::from_ptr(const_string).to_str().unwrap(), + ); } } diff --git a/tests/run-make/raw-dylib-elf/output.txt b/tests/run-make/raw-dylib-elf/output.txt index 53383c3b86453..6a9770dcb39b4 100644 --- a/tests/run-make/raw-dylib-elf/output.txt +++ b/tests/run-make/raw-dylib-elf/output.txt @@ -1 +1 @@ -42 3 33 +42 3 33 795 906 sums of three cubes diff --git a/tests/run-make/raw-dylib-elf/rmake.rs b/tests/run-make/raw-dylib-elf/rmake.rs index 59f901ac1ed72..d8a10fcb7f838 100644 --- a/tests/run-make/raw-dylib-elf/rmake.rs +++ b/tests/run-make/raw-dylib-elf/rmake.rs @@ -11,19 +11,27 @@ use run_make_support::{build_native_dynamic_lib, cwd, diff, run, rustc}; fn main() { - // We compile the binary without having the library present. + // We compile the binaries without having the library present with different relocation + // models. // We also set the rpath to the current directory so we can pick up the library at runtime. - rustc() - .crate_type("bin") - .input("main.rs") - .arg(&format!("-Wl,-rpath={}", cwd().display())) - .run(); + let relocation_models = ["static", "pic", "pie"]; + for relocation_model in relocation_models { + rustc() + .crate_type("bin") + .input("main.rs") + .arg(&format!("-Wl,-rpath={}", cwd().display())) + .arg(&format!("-Crelocation-model={}", relocation_model)) + .output(&format!("main-{}", relocation_model)) + .run(); + } - // Now, *after* building the binary, we build the library... + // Now, *after* building the binaries, we build the library... build_native_dynamic_lib("library"); - // ... and run with this library, ensuring it was linked correctly at runtime. - let output = run("main").stdout_utf8(); - - diff().expected_file("output.txt").actual_text("actual", output).run(); + for relocation_model in relocation_models { + // ... and run with this library, ensuring it was linked correctly at runtime. + // The output here should be the same regardless of the relocation model. + let output = run(&format!("main-{}", relocation_model)).stdout_utf8(); + diff().expected_file("output.txt").actual_text("actual", output).run(); + } }