mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Workaround for private global symbol issue
This commit is contained in:
parent
e69336efe0
commit
67e746cc68
@ -83,7 +83,20 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
|||||||
let llfn = if tcx.sess.target.arch == "x86" &&
|
let llfn = if tcx.sess.target.arch == "x86" &&
|
||||||
let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym)
|
let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym)
|
||||||
{
|
{
|
||||||
cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi)
|
// Fix for https://github.com/rust-lang/rust/issues/104453
|
||||||
|
// On x86 Windows, LLVM uses 'L' as the prefix for any private
|
||||||
|
// global symbols, so when we create an undecorated function symbol
|
||||||
|
// that begins with an 'L' LLVM misinterprets that as a private
|
||||||
|
// global symbol that it created and so fails the compilation at a
|
||||||
|
// later stage since such a symbol must have a definition.
|
||||||
|
//
|
||||||
|
// To avoid this, we set the Storage Class to "DllImport" so that
|
||||||
|
// LLVM will prefix the name with `__imp_`. Ideally, we'd like the
|
||||||
|
// existing logic below to set the Storage Class, but it has an
|
||||||
|
// exemption for MinGW for backwards compatability.
|
||||||
|
let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi);
|
||||||
|
unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); }
|
||||||
|
llfn
|
||||||
} else {
|
} else {
|
||||||
cx.declare_fn(sym, fn_abi)
|
cx.declare_fn(sym, fn_abi)
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#[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 LooksLikeAPrivateGlobal(i: i32);
|
||||||
fn cdecl_fn_undecorated(i: i32);
|
fn cdecl_fn_undecorated(i: i32);
|
||||||
#[link_name = "cdecl_fn_undecorated2"]
|
#[link_name = "cdecl_fn_undecorated2"]
|
||||||
fn cdecl_fn_undecorated_renamed(i: i32);
|
fn cdecl_fn_undecorated_renamed(i: i32);
|
||||||
@ -84,6 +85,13 @@ extern {
|
|||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Regression test for #104453
|
||||||
|
// On x86 LLVM uses 'L' as the prefix for private globals (PrivateGlobalPrefix), which
|
||||||
|
// causes it to believe that undecorated functions starting with 'L' are actually temporary
|
||||||
|
// symbols that it generated, which causes a later check to fail as the symbols we are
|
||||||
|
// creating don't have definitions (whereas all temporary symbols do).
|
||||||
|
LooksLikeAPrivateGlobal(13);
|
||||||
|
|
||||||
cdecl_fn_undecorated(1);
|
cdecl_fn_undecorated(1);
|
||||||
cdecl_fn_undecorated_renamed(10);
|
cdecl_fn_undecorated_renamed(10);
|
||||||
cdecl_fn_noprefix(2);
|
cdecl_fn_noprefix(2);
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void _cdecl LooksLikeAPrivateGlobal(int i) {
|
||||||
|
printf("LooksLikeAPrivateGlobal(%d)\n", i);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
void _cdecl cdecl_fn_undecorated(int i) {
|
void _cdecl cdecl_fn_undecorated(int i) {
|
||||||
printf("cdecl_fn_undecorated(%d)\n", i);
|
printf("cdecl_fn_undecorated(%d)\n", i);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
LIBRARY extern
|
LIBRARY extern
|
||||||
EXPORTS
|
EXPORTS
|
||||||
|
LooksLikeAPrivateGlobal
|
||||||
cdecl_fn_undecorated
|
cdecl_fn_undecorated
|
||||||
cdecl_fn_undecorated2
|
cdecl_fn_undecorated2
|
||||||
cdecl_fn_noprefix
|
cdecl_fn_noprefix
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
LIBRARY extern
|
LIBRARY extern
|
||||||
EXPORTS
|
EXPORTS
|
||||||
|
LooksLikeAPrivateGlobal
|
||||||
cdecl_fn_undecorated
|
cdecl_fn_undecorated
|
||||||
cdecl_fn_undecorated2
|
cdecl_fn_undecorated2
|
||||||
cdecl_fn_noprefix
|
cdecl_fn_noprefix
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
LooksLikeAPrivateGlobal(13)
|
||||||
cdecl_fn_undecorated(1)
|
cdecl_fn_undecorated(1)
|
||||||
cdecl_fn_undecorated2(10)
|
cdecl_fn_undecorated2(10)
|
||||||
cdecl_fn_noprefix(2)
|
cdecl_fn_noprefix(2)
|
||||||
|
Loading…
Reference in New Issue
Block a user