Rollup merge of #101738 - dpaoliello:linkname, r=petrochenkov

Fix `#[link kind="raw-dylib"]` to respect `#[link_name]`

Issue Details:
When using `#[link kind="raw-dylib"]` (#58713), the Rust compiler ignored any `#[link_name]` attributes when generating the import library and so the resulting binary would fail to link due to missing symbols.

Fix Details:
Use the name from `#[link_name]` if present when generating the `raw-dylib` import library, otherwise default back to the actual symbol name.
This commit is contained in:
Dylan DPC 2022-09-16 11:17:00 +05:30 committed by GitHub
commit 61126d3611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 140 additions and 4 deletions

View File

@ -560,14 +560,13 @@ impl<'tcx> Collector<'tcx> {
} }
}; };
let import_name_type = self let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.def_id);
.tcx let import_name_type = codegen_fn_attrs
.codegen_fn_attrs(item.id.def_id)
.link_ordinal .link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord))); .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
DllImport { DllImport {
name: item.ident.name, name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name),
import_name_type, import_name_type,
calling_convention, calling_convention,
span: item.span, span: item.span,

View File

@ -70,6 +70,11 @@ __declspec(dllexport) void __stdcall stdcall_fn_9(uint8_t x, double y) {
fflush(stdout); fflush(stdout);
} }
__declspec(dllexport) void __stdcall stdcall_fn_10(int i) {
printf("stdcall_fn_10(%d)\n", i);
fflush(stdout);
}
__declspec(dllexport) void __fastcall fastcall_fn_1(int i) { __declspec(dllexport) void __fastcall fastcall_fn_1(int i) {
printf("fastcall_fn_1(%d)\n", i); printf("fastcall_fn_1(%d)\n", i);
fflush(stdout); fflush(stdout);
@ -122,6 +127,11 @@ __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
fflush(stdout); fflush(stdout);
} }
__declspec(dllexport) void __fastcall fastcall_fn_10(int i) {
printf("fastcall_fn_10(%d)\n", i);
fflush(stdout);
}
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485 // GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
#ifdef _MSC_VER #ifdef _MSC_VER
__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) { __declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
@ -175,4 +185,9 @@ __declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) {
printf("vectorcall_fn_9(%d, %.1f)\n", x, y); printf("vectorcall_fn_9(%d, %.1f)\n", x, y);
fflush(stdout); fflush(stdout);
} }
__declspec(dllexport) void __vectorcall vectorcall_fn_10(int i) {
printf("vectorcall_fn_10(%d)\n", i);
fflush(stdout);
}
#endif #endif

View File

@ -32,6 +32,8 @@ extern "stdcall" {
fn stdcall_fn_7(a: S2, b: i32); fn stdcall_fn_7(a: S2, b: i32);
fn stdcall_fn_8(a: S3, b: S3); fn stdcall_fn_8(a: S3, b: S3);
fn stdcall_fn_9(x: u8, y: f64); fn stdcall_fn_9(x: u8, y: f64);
#[link_name = "stdcall_fn_10"]
fn stdcall_fn_10_renamed(i: i32);
} }
#[link(name = "extern", kind = "raw-dylib")] #[link(name = "extern", kind = "raw-dylib")]
@ -45,6 +47,8 @@ extern "fastcall" {
fn fastcall_fn_7(a: S2, b: i32); fn fastcall_fn_7(a: S2, b: i32);
fn fastcall_fn_8(a: S3, b: S3); fn fastcall_fn_8(a: S3, b: S3);
fn fastcall_fn_9(x: u8, y: f64); fn fastcall_fn_9(x: u8, y: f64);
#[link_name = "fastcall_fn_10"]
fn fastcall_fn_10_renamed(i: i32);
} }
#[cfg(target_env = "msvc")] #[cfg(target_env = "msvc")]
@ -59,6 +63,8 @@ extern "vectorcall" {
fn vectorcall_fn_7(a: S2, b: i32); fn vectorcall_fn_7(a: S2, b: i32);
fn vectorcall_fn_8(a: S3, b: S3); fn vectorcall_fn_8(a: S3, b: S3);
fn vectorcall_fn_9(x: u8, y: f64); fn vectorcall_fn_9(x: u8, y: f64);
#[link_name = "vectorcall_fn_10"]
fn vectorcall_fn_10_renamed(i: i32);
} }
pub fn library_function(run_msvc_only: bool) { pub fn library_function(run_msvc_only: bool) {
@ -73,6 +79,7 @@ pub fn library_function(run_msvc_only: bool) {
stdcall_fn_7(S2 { x: 15, y: 16 }, 3); stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] }); stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
stdcall_fn_9(1, 3.0); stdcall_fn_9(1, 3.0);
stdcall_fn_10_renamed(19);
fastcall_fn_1(14); fastcall_fn_1(14);
fastcall_fn_2(16, 3.5); fastcall_fn_2(16, 3.5);
@ -81,6 +88,7 @@ pub fn library_function(run_msvc_only: bool) {
fastcall_fn_6(Some(&S { x: 10, y: 12 })); fastcall_fn_6(Some(&S { x: 10, y: 12 }));
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] }); fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
fastcall_fn_9(1, 3.0); fastcall_fn_9(1, 3.0);
fastcall_fn_10_renamed(19);
} else { } else {
// FIXME: 91167 // FIXME: 91167
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7 // rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
@ -100,6 +108,7 @@ pub fn library_function(run_msvc_only: bool) {
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3); vectorcall_fn_7(S2 { x: 15, y: 16 }, 3);
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] }); vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
vectorcall_fn_9(1, 3.0); vectorcall_fn_9(1, 3.0);
vectorcall_fn_10_renamed(19);
} }
} }
} }

View File

@ -9,3 +9,4 @@ vectorcall_fn_6(S { x: 10, y: 12 })
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3) vectorcall_fn_7(S2 { x: 15, y: 16 }, 3)
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] }) vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
vectorcall_fn_9(1, 3.0) vectorcall_fn_9(1, 3.0)
vectorcall_fn_10(19)

View File

@ -7,6 +7,7 @@ stdcall_fn_6(S { x: 10, y: 12 })
stdcall_fn_7(S2 { x: 15, y: 16 }, 3) stdcall_fn_7(S2 { x: 15, y: 16 }, 3)
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] }) stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
stdcall_fn_9(1, 3.0) stdcall_fn_9(1, 3.0)
stdcall_fn_10(19)
fastcall_fn_1(14) fastcall_fn_1(14)
fastcall_fn_2(16, 3.5) fastcall_fn_2(16, 3.5)
fastcall_fn_3(3.5) fastcall_fn_3(3.5)
@ -14,3 +15,4 @@ fastcall_fn_4(1, 2, 3.0)
fastcall_fn_6(S { x: 10, y: 12 }) fastcall_fn_6(S { x: 10, y: 12 })
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] }) fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
fastcall_fn_9(1, 3.0) fastcall_fn_9(1, 3.0)
fastcall_fn_10(19)

View File

@ -21,3 +21,8 @@ __declspec(dllexport) void extern_fn_with_long_name() {
printf("extern_fn_with_long_name; got the rename\n"); printf("extern_fn_with_long_name; got the rename\n");
fflush(stdout); fflush(stdout);
} }
__declspec(dllexport) void extern_fn_4() {
printf("extern_fn_4\n");
fflush(stdout);
}

View File

@ -16,12 +16,15 @@ pub fn library_function() {
fn extern_fn_2(); fn extern_fn_2();
fn print_extern_variable(); fn print_extern_variable();
static mut extern_variable: i32; static mut extern_variable: i32;
#[link_name = "extern_fn_4"]
fn extern_fn_4_renamed();
} }
unsafe { unsafe {
extern_fn_1(); extern_fn_1();
extern_fn_2(); extern_fn_2();
extern_fn_3(); extern_fn_3();
extern_fn_4_renamed();
extern_variable = 42; extern_variable = 42;
print_extern_variable(); print_extern_variable();
extern_variable = -42; extern_variable = -42;

View File

@ -1,5 +1,6 @@
extern_fn_1 extern_fn_1
extern_fn_2; didn't get the rename extern_fn_2; didn't get the rename
extern_fn_3 extern_fn_3
extern_fn_4
extern_variable value: 42 extern_variable value: 42
extern_variable value: -42 extern_variable value: -42

View File

@ -1,8 +1,11 @@
#![feature(raw_dylib)] #![feature(raw_dylib)]
#![feature(abi_vectorcall)]
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")] #[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "C" { extern "C" {
fn cdecl_fn_undecorated(i: i32); fn cdecl_fn_undecorated(i: i32);
#[link_name = "cdecl_fn_undecorated2"]
fn cdecl_fn_undecorated_renamed(i: i32);
static mut extern_variable_undecorated: i32; static mut extern_variable_undecorated: i32;
} }
@ -21,6 +24,8 @@ extern "C" {
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")] #[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "stdcall" { extern "stdcall" {
fn stdcall_fn_undecorated(i: i32); fn stdcall_fn_undecorated(i: i32);
#[link_name = "stdcall_fn_undecorated2"]
fn stdcall_fn_undecorated_renamed(i: i32);
} }
#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")] #[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
@ -36,6 +41,8 @@ extern "stdcall" {
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")] #[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "fastcall" { extern "fastcall" {
fn fastcall_fn_undecorated(i: i32); fn fastcall_fn_undecorated(i: i32);
#[link_name = "fastcall_fn_undecorated2"]
fn fastcall_fn_undecorated_renamed(i: i32);
} }
#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")] #[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
@ -48,6 +55,26 @@ extern "fastcall" {
fn fastcall_fn_decorated(i: i32); fn fastcall_fn_decorated(i: i32);
} }
#[cfg(target_env = "msvc")]
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "vectorcall" {
fn vectorcall_fn_undecorated(i: i32);
#[link_name = "vectorcall_fn_undecorated2"]
fn vectorcall_fn_undecorated_renamed(i: i32);
}
#[cfg(target_env = "msvc")]
#[link(name = "extern", kind = "raw-dylib", import_name_type = "noprefix")]
extern "vectorcall" {
fn vectorcall_fn_noprefix(i: i32);
}
#[cfg(target_env = "msvc")]
#[link(name = "extern", kind = "raw-dylib", import_name_type = "decorated")]
extern "vectorcall" {
fn vectorcall_fn_decorated(i: i32);
}
#[link(name = "extern", kind = "raw-dylib")] #[link(name = "extern", kind = "raw-dylib")]
extern { extern {
fn print_extern_variable_undecorated(); fn print_extern_variable_undecorated();
@ -58,14 +85,17 @@ extern {
pub fn main() { pub fn main() {
unsafe { unsafe {
cdecl_fn_undecorated(1); cdecl_fn_undecorated(1);
cdecl_fn_undecorated_renamed(10);
cdecl_fn_noprefix(2); cdecl_fn_noprefix(2);
cdecl_fn_decorated(3); cdecl_fn_decorated(3);
stdcall_fn_undecorated(4); stdcall_fn_undecorated(4);
stdcall_fn_undecorated_renamed(14);
stdcall_fn_noprefix(5); stdcall_fn_noprefix(5);
stdcall_fn_decorated(6); stdcall_fn_decorated(6);
fastcall_fn_undecorated(7); fastcall_fn_undecorated(7);
fastcall_fn_undecorated_renamed(17);
fastcall_fn_noprefix(8); fastcall_fn_noprefix(8);
fastcall_fn_decorated(9); fastcall_fn_decorated(9);
@ -75,5 +105,21 @@ pub fn main() {
print_extern_variable_noprefix(); print_extern_variable_noprefix();
extern_variable_decorated = 44; extern_variable_decorated = 44;
print_extern_variable_decorated(); print_extern_variable_decorated();
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
#[cfg(target_env = "msvc")]
{
vectorcall_fn_undecorated(10);
vectorcall_fn_undecorated_renamed(20);
vectorcall_fn_noprefix(11);
vectorcall_fn_decorated(12);
}
#[cfg(not(target_env = "msvc"))]
{
println!("vectorcall_fn_undecorated(10)");
println!("vectorcall_fn_undecorated2(20)");
println!("vectorcall_fn_noprefix(11)");
println!("vectorcall_fn_decorated(12)");
}
} }
} }

View File

@ -6,6 +6,11 @@ void _cdecl cdecl_fn_undecorated(int i) {
fflush(stdout); fflush(stdout);
} }
void _cdecl cdecl_fn_undecorated2(int i) {
printf("cdecl_fn_undecorated2(%d)\n", i);
fflush(stdout);
}
void _cdecl cdecl_fn_noprefix(int i) { void _cdecl cdecl_fn_noprefix(int i) {
printf("cdecl_fn_noprefix(%d)\n", i); printf("cdecl_fn_noprefix(%d)\n", i);
fflush(stdout); fflush(stdout);
@ -21,6 +26,11 @@ void __stdcall stdcall_fn_undecorated(int i) {
fflush(stdout); fflush(stdout);
} }
void __stdcall stdcall_fn_undecorated2(int i) {
printf("stdcall_fn_undecorated2(%d)\n", i);
fflush(stdout);
}
void __stdcall stdcall_fn_noprefix(int i) { void __stdcall stdcall_fn_noprefix(int i) {
printf("stdcall_fn_noprefix(%d)\n", i); printf("stdcall_fn_noprefix(%d)\n", i);
fflush(stdout); fflush(stdout);
@ -36,6 +46,11 @@ void __fastcall fastcall_fn_undecorated(int i) {
fflush(stdout); fflush(stdout);
} }
void __fastcall fastcall_fn_undecorated2(int i) {
printf("fastcall_fn_undecorated2(%d)\n", i);
fflush(stdout);
}
void __fastcall fastcall_fn_noprefix(int i) { void __fastcall fastcall_fn_noprefix(int i) {
printf("fastcall_fn_noprefix(%d)\n", i); printf("fastcall_fn_noprefix(%d)\n", i);
fflush(stdout); fflush(stdout);
@ -63,3 +78,26 @@ __declspec(dllexport) void print_extern_variable_decorated() {
printf("extern_variable_decorated value: %d\n", extern_variable_decorated); printf("extern_variable_decorated value: %d\n", extern_variable_decorated);
fflush(stdout); fflush(stdout);
} }
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
#ifdef _MSC_VER
void __vectorcall vectorcall_fn_undecorated(int i) {
printf("vectorcall_fn_undecorated(%d)\n", i);
fflush(stdout);
}
void __vectorcall vectorcall_fn_undecorated2(int i) {
printf("vectorcall_fn_undecorated2(%d)\n", i);
fflush(stdout);
}
void __vectorcall vectorcall_fn_noprefix(int i) {
printf("vectorcall_fn_noprefix(%d)\n", i);
fflush(stdout);
}
void __vectorcall vectorcall_fn_decorated(int i) {
printf("vectorcall_fn_decorated(%d)\n", i);
fflush(stdout);
}
#endif

View File

@ -1,11 +1,14 @@
LIBRARY extern LIBRARY extern
EXPORTS EXPORTS
cdecl_fn_undecorated cdecl_fn_undecorated
cdecl_fn_undecorated2
cdecl_fn_noprefix cdecl_fn_noprefix
cdecl_fn_decorated cdecl_fn_decorated
stdcall_fn_undecorated stdcall_fn_undecorated
stdcall_fn_undecorated2
stdcall_fn_noprefix@4 stdcall_fn_noprefix@4
fastcall_fn_undecorated fastcall_fn_undecorated
fastcall_fn_undecorated2
@fastcall_fn_decorated@4 @fastcall_fn_decorated@4
;ld doesn't handle fully-decorated stdcall, or no-prefix fastcall ;ld doesn't handle fully-decorated stdcall, or no-prefix fastcall

View File

@ -1,12 +1,19 @@
LIBRARY extern LIBRARY extern
EXPORTS EXPORTS
cdecl_fn_undecorated cdecl_fn_undecorated
cdecl_fn_undecorated2
cdecl_fn_noprefix cdecl_fn_noprefix
cdecl_fn_decorated cdecl_fn_decorated
stdcall_fn_undecorated stdcall_fn_undecorated
stdcall_fn_undecorated2
_stdcall_fn_decorated@4 _stdcall_fn_decorated@4
fastcall_fn_undecorated fastcall_fn_undecorated
fastcall_fn_undecorated2
@fastcall_fn_decorated@4 @fastcall_fn_decorated@4
vectorcall_fn_undecorated
vectorcall_fn_undecorated2
vectorcall_fn_decorated@@4
vectorcall_fn_noprefix@@4
;MSVC doesn't seem to recognize the "no prefix" syntax. ;MSVC doesn't seem to recognize the "no prefix" syntax.
stdcall_fn_noprefix@4=_stdcall_fn_noprefix@4 stdcall_fn_noprefix@4=_stdcall_fn_noprefix@4

View File

@ -1,12 +1,19 @@
cdecl_fn_undecorated(1) cdecl_fn_undecorated(1)
cdecl_fn_undecorated2(10)
cdecl_fn_noprefix(2) cdecl_fn_noprefix(2)
cdecl_fn_decorated(3) cdecl_fn_decorated(3)
stdcall_fn_undecorated(4) stdcall_fn_undecorated(4)
stdcall_fn_undecorated2(14)
stdcall_fn_noprefix(5) stdcall_fn_noprefix(5)
stdcall_fn_decorated(6) stdcall_fn_decorated(6)
fastcall_fn_undecorated(7) fastcall_fn_undecorated(7)
fastcall_fn_undecorated2(17)
fastcall_fn_noprefix(8) fastcall_fn_noprefix(8)
fastcall_fn_decorated(9) fastcall_fn_decorated(9)
extern_variable_undecorated value: 42 extern_variable_undecorated value: 42
extern_variable_noprefix value: 43 extern_variable_noprefix value: 43
extern_variable_decorated value: 44 extern_variable_decorated value: 44
vectorcall_fn_undecorated(10)
vectorcall_fn_undecorated2(20)
vectorcall_fn_noprefix(11)
vectorcall_fn_decorated(12)