Skip to content

Commit

Permalink
Rollup merge of #101738 - dpaoliello:linkname, r=petrochenkov
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Dylan-DPC authored Sep 16, 2022
2 parents b763cd5 + 3c184db commit 61126d3
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 4 deletions.
7 changes: 3 additions & 4 deletions compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,14 +560,13 @@ impl<'tcx> Collector<'tcx> {
}
};

let import_name_type = self
.tcx
.codegen_fn_attrs(item.id.def_id)
let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.def_id);
let import_name_type = codegen_fn_attrs
.link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));

DllImport {
name: item.ident.name,
name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name),
import_name_type,
calling_convention,
span: item.span,
Expand Down
15 changes: 15 additions & 0 deletions src/test/run-make/raw-dylib-alt-calling-convention/extern.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ __declspec(dllexport) void __stdcall stdcall_fn_9(uint8_t x, double y) {
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) {
printf("fastcall_fn_1(%d)\n", i);
fflush(stdout);
Expand Down Expand Up @@ -122,6 +127,11 @@ __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
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
#ifdef _MSC_VER
__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
Expand Down Expand Up @@ -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);
fflush(stdout);
}

__declspec(dllexport) void __vectorcall vectorcall_fn_10(int i) {
printf("vectorcall_fn_10(%d)\n", i);
fflush(stdout);
}
#endif
9 changes: 9 additions & 0 deletions src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ extern "stdcall" {
fn stdcall_fn_7(a: S2, b: i32);
fn stdcall_fn_8(a: S3, b: S3);
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")]
Expand All @@ -45,6 +47,8 @@ extern "fastcall" {
fn fastcall_fn_7(a: S2, b: i32);
fn fastcall_fn_8(a: S3, b: S3);
fn fastcall_fn_9(x: u8, y: f64);
#[link_name = "fastcall_fn_10"]
fn fastcall_fn_10_renamed(i: i32);
}

#[cfg(target_env = "msvc")]
Expand All @@ -59,6 +63,8 @@ extern "vectorcall" {
fn vectorcall_fn_7(a: S2, b: i32);
fn vectorcall_fn_8(a: S3, b: S3);
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) {
Expand All @@ -73,6 +79,7 @@ pub fn library_function(run_msvc_only: bool) {
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_9(1, 3.0);
stdcall_fn_10_renamed(19);

fastcall_fn_1(14);
fastcall_fn_2(16, 3.5);
Expand All @@ -81,6 +88,7 @@ pub fn library_function(run_msvc_only: bool) {
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_9(1, 3.0);
fastcall_fn_10_renamed(19);
} else {
// FIXME: 91167
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
Expand All @@ -100,6 +108,7 @@ pub fn library_function(run_msvc_only: bool) {
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_9(1, 3.0);
vectorcall_fn_10_renamed(19);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ vectorcall_fn_6(S { x: 10, y: 12 })
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_9(1, 3.0)
vectorcall_fn_10(19)
2 changes: 2 additions & 0 deletions src/test/run-make/raw-dylib-alt-calling-convention/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ stdcall_fn_6(S { x: 10, y: 12 })
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_9(1, 3.0)
stdcall_fn_10(19)
fastcall_fn_1(14)
fastcall_fn_2(16, 3.5)
fastcall_fn_3(3.5)
fastcall_fn_4(1, 2, 3.0)
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_9(1, 3.0)
fastcall_fn_10(19)
5 changes: 5 additions & 0 deletions src/test/run-make/raw-dylib-c/extern_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ __declspec(dllexport) void extern_fn_with_long_name() {
printf("extern_fn_with_long_name; got the rename\n");
fflush(stdout);
}

__declspec(dllexport) void extern_fn_4() {
printf("extern_fn_4\n");
fflush(stdout);
}
3 changes: 3 additions & 0 deletions src/test/run-make/raw-dylib-c/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ pub fn library_function() {
fn extern_fn_2();
fn print_extern_variable();
static mut extern_variable: i32;
#[link_name = "extern_fn_4"]
fn extern_fn_4_renamed();
}

unsafe {
extern_fn_1();
extern_fn_2();
extern_fn_3();
extern_fn_4_renamed();
extern_variable = 42;
print_extern_variable();
extern_variable = -42;
Expand Down
1 change: 1 addition & 0 deletions src/test/run-make/raw-dylib-c/output.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
extern_fn_1
extern_fn_2; didn't get the rename
extern_fn_3
extern_fn_4
extern_variable value: 42
extern_variable value: -42
46 changes: 46 additions & 0 deletions src/test/run-make/raw-dylib-import-name-type/driver.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#![feature(raw_dylib)]
#![feature(abi_vectorcall)]

#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "C" {
fn cdecl_fn_undecorated(i: i32);
#[link_name = "cdecl_fn_undecorated2"]
fn cdecl_fn_undecorated_renamed(i: i32);
static mut extern_variable_undecorated: i32;
}

Expand All @@ -21,6 +24,8 @@ extern "C" {
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "stdcall" {
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")]
Expand All @@ -36,6 +41,8 @@ extern "stdcall" {
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "fastcall" {
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")]
Expand All @@ -48,6 +55,26 @@ extern "fastcall" {
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")]
extern {
fn print_extern_variable_undecorated();
Expand All @@ -58,14 +85,17 @@ extern {
pub fn main() {
unsafe {
cdecl_fn_undecorated(1);
cdecl_fn_undecorated_renamed(10);
cdecl_fn_noprefix(2);
cdecl_fn_decorated(3);

stdcall_fn_undecorated(4);
stdcall_fn_undecorated_renamed(14);
stdcall_fn_noprefix(5);
stdcall_fn_decorated(6);

fastcall_fn_undecorated(7);
fastcall_fn_undecorated_renamed(17);
fastcall_fn_noprefix(8);
fastcall_fn_decorated(9);

Expand All @@ -75,5 +105,21 @@ pub fn main() {
print_extern_variable_noprefix();
extern_variable_decorated = 44;
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)");
}
}
}
38 changes: 38 additions & 0 deletions src/test/run-make/raw-dylib-import-name-type/extern.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ void _cdecl cdecl_fn_undecorated(int i) {
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) {
printf("cdecl_fn_noprefix(%d)\n", i);
fflush(stdout);
Expand All @@ -21,6 +26,11 @@ void __stdcall stdcall_fn_undecorated(int i) {
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) {
printf("stdcall_fn_noprefix(%d)\n", i);
fflush(stdout);
Expand All @@ -36,6 +46,11 @@ void __fastcall fastcall_fn_undecorated(int i) {
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) {
printf("fastcall_fn_noprefix(%d)\n", i);
fflush(stdout);
Expand Down Expand Up @@ -63,3 +78,26 @@ __declspec(dllexport) void print_extern_variable_decorated() {
printf("extern_variable_decorated value: %d\n", extern_variable_decorated);
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
3 changes: 3 additions & 0 deletions src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
LIBRARY extern
EXPORTS
cdecl_fn_undecorated
cdecl_fn_undecorated2
cdecl_fn_noprefix
cdecl_fn_decorated
stdcall_fn_undecorated
stdcall_fn_undecorated2
stdcall_fn_noprefix@4
fastcall_fn_undecorated
fastcall_fn_undecorated2
@fastcall_fn_decorated@4

;ld doesn't handle fully-decorated stdcall, or no-prefix fastcall
Expand Down
7 changes: 7 additions & 0 deletions src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
LIBRARY extern
EXPORTS
cdecl_fn_undecorated
cdecl_fn_undecorated2
cdecl_fn_noprefix
cdecl_fn_decorated
stdcall_fn_undecorated
stdcall_fn_undecorated2
_stdcall_fn_decorated@4
fastcall_fn_undecorated
fastcall_fn_undecorated2
@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.
stdcall_fn_noprefix@4=_stdcall_fn_noprefix@4
Expand Down
7 changes: 7 additions & 0 deletions src/test/run-make/raw-dylib-import-name-type/output.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
cdecl_fn_undecorated(1)
cdecl_fn_undecorated2(10)
cdecl_fn_noprefix(2)
cdecl_fn_decorated(3)
stdcall_fn_undecorated(4)
stdcall_fn_undecorated2(14)
stdcall_fn_noprefix(5)
stdcall_fn_decorated(6)
fastcall_fn_undecorated(7)
fastcall_fn_undecorated2(17)
fastcall_fn_noprefix(8)
fastcall_fn_decorated(9)
extern_variable_undecorated value: 42
extern_variable_noprefix value: 43
extern_variable_decorated value: 44
vectorcall_fn_undecorated(10)
vectorcall_fn_undecorated2(20)
vectorcall_fn_noprefix(11)
vectorcall_fn_decorated(12)

0 comments on commit 61126d3

Please sign in to comment.