Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit function declarations for functions with #[linkage="extern_weak"] #138349

Merged
merged 1 commit into from
Mar 17, 2025

Conversation

1c3t3a
Copy link
Member

@1c3t3a 1c3t3a commented Mar 11, 2025

Currently, when declaring an extern weak function in Rust, we use the following syntax:

unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}

This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static as an i8, and a pointer that is initialized with the value of the global i8 and represents the nullabilty e.g.

@FOO = extern_weak global i8
@_rust_extern_with_linkage_FOO = internal global ptr @FOO

This approach does not work well with CFI, where we need to attach CFI metadata to a concrete function declaration, which was pointed out in #115199.

This change switches to emitting a proper function declaration instead of a global i8. This allows CFI to work for extern_weak functions. Example:

@_rust_extern_with_linkage_FOO = internal global ptr @FOO
...
declare !type !61 !type !62 !type !63 !type !64 extern_weak void @FOO(double) unnamed_addr #6

We keep initializing the Rust internal symbol with the function declaration, which preserves the correct behavior for runtime checking the Option.

r? @rcvalle

cc @jakos-sec

try-job: test-various

@rustbot rustbot added PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 11, 2025
@rustbot
Copy link
Collaborator

rustbot commented Mar 11, 2025

Some changes occurred in tests/codegen/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

@compiler-errors
Copy link
Member

Squash the last two commits into the first, since there's no reason for the commit history to record all of the fixing lol

@1c3t3a
Copy link
Member Author

1c3t3a commented Mar 11, 2025

Ah, I was told that this is the workflow and that there is an avoidance of force-pushes. I am happy to squash anything.

@1c3t3a 1c3t3a force-pushed the external-weak-cfi branch from 4ee7222 to fb32abe Compare March 11, 2025 13:40
@rustbot
Copy link
Collaborator

rustbot commented Mar 11, 2025

rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead.

cc @rust-lang/rust-analyzer

@1c3t3a 1c3t3a force-pushed the external-weak-cfi branch 2 times, most recently from d630c28 to 55ed3be Compare March 11, 2025 13:49
@1c3t3a 1c3t3a force-pushed the external-weak-cfi branch from 55ed3be to 86492fa Compare March 13, 2025 10:22
@rcvalle
Copy link
Member

rcvalle commented Mar 14, 2025

Thank you for your time and work on this, @1c3t3a and @jakos-sec, and for reviewing it, @bjorn3 and @compiler-errors! Much appreciated. Hopefully, with this we can soon remove all the previously added no_sanitize to core and stdlib such as in #115200 and #138002.

@rcvalle
Copy link
Member

rcvalle commented Mar 14, 2025

@bors r+

@bors
Copy link
Contributor

bors commented Mar 14, 2025

📌 Commit 86492fa has been approved by rcvalle

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 14, 2025
fmease added a commit to fmease/rust that referenced this pull request Mar 14, 2025
Emit function declarations for functions with `#[linkage="extern_weak"]`

Currently, when declaring an extern weak function in Rust, we use the following syntax:
```rust
unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}
```
This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static as an i8, and a pointer that is initialized with the value of the global i8 and represents the nullabilty e.g.
```
`@FOO` = extern_weak global i8
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
```

This approach does not work well with CFI, where we need to attach CFI metadata to a concrete function declaration, which was pointed out in rust-lang#115199.

This change switches to emitting a proper function declaration instead of a global i8. This allows CFI to work for extern_weak functions. Example:
```
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
...
declare !type !61 !type !62 !type !63 !type !64 extern_weak void `@FOO(double)` unnamed_addr #6
```

We keep initializing the Rust internal symbol with the function declaration, which preserves the correct behavior for runtime checking the Option.

r? `@rcvalle`

cc `@jakos-sec`
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 14, 2025
Rollup of 8 pull requests

Successful merges:

 - rust-lang#138056 (rustc_target: Add target features for LoongArch v1.1)
 - rust-lang#138349 (Emit function declarations for functions with `#[linkage="extern_weak"]`)
 - rust-lang#138451 (Build GCC on CI with GCC, not Clang)
 - rust-lang#138454 (Improve post-merge workflow)
 - rust-lang#138460 (Pass struct field HirId when check_expr_struct_fields)
 - rust-lang#138482 (Fix HIR printing of parameters)
 - rust-lang#138507 (Mirror NetBSD sources)
 - rust-lang#138511 (Make `Parser::parse_expr_cond` public)

r? `@ghost`
`@rustbot` modify labels: rollup
@fmease
Copy link
Member

fmease commented Mar 14, 2025

Failed in rollup: #138516 (comment)
@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 14, 2025
Currently, when declaring an extern weak function in Rust, we use the
following syntax:
```rust
unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}
```
This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static
as an i8, and a pointer that is initialized with the value of the global
i8 and represents the nullabilty e.g.
```
@foo = extern_weak global i8
@_rust_extern_with_linkage_FOO = internal global ptr @foo
```

This approach does not work well with CFI, where we need to attach CFI
metadata to a concrete function declaration, which was pointed out in
rust-lang#115199.

This change switches to emitting a proper function declaration instead
of a global i8. This allows CFI to work for extern_weak functions.

We keep initializing the Rust internal symbol with the function
declaration, which preserves the correct behavior for runtime checking
the Option.

Co-authored-by: Jakob Koschel <jakobkoschel@google.com>
@1c3t3a 1c3t3a force-pushed the external-weak-cfi branch from 86492fa to b30cf11 Compare March 17, 2025 08:28
@1c3t3a
Copy link
Member Author

1c3t3a commented Mar 17, 2025

I added the mentioned flag to fix the issue (and a bunch of other tests in this directory have it). Is there any way to trigger this test again? Or does it only happen during rollup?

@fmease
Copy link
Member

fmease commented Mar 17, 2025

I'll do a try build.

@bors try

@bors
Copy link
Contributor

bors commented Mar 17, 2025

⌛ Trying commit b30cf11 with merge c29cad1...

bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 17, 2025
Emit function declarations for functions with `#[linkage="extern_weak"]`

Currently, when declaring an extern weak function in Rust, we use the following syntax:
```rust
unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}
```
This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static as an i8, and a pointer that is initialized with the value of the global i8 and represents the nullabilty e.g.
```
`@FOO` = extern_weak global i8
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
```

This approach does not work well with CFI, where we need to attach CFI metadata to a concrete function declaration, which was pointed out in rust-lang#115199.

This change switches to emitting a proper function declaration instead of a global i8. This allows CFI to work for extern_weak functions. Example:
```
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
...
declare !type !61 !type !62 !type !63 !type !64 extern_weak void `@FOO(double)` unnamed_addr rust-lang#6
```

We keep initializing the Rust internal symbol with the function declaration, which preserves the correct behavior for runtime checking the Option.

r? `@rcvalle`

cc `@jakos-sec`

try-job: test-various
@1c3t3a
Copy link
Member Author

1c3t3a commented Mar 17, 2025

Not sure I can do that but it'd be helpful to not rollup this patch.

@bors rollup=never

@bors
Copy link
Contributor

bors commented Mar 17, 2025

@1c3t3a: 🔑 Insufficient privileges: not in try users

@bors
Copy link
Contributor

bors commented Mar 17, 2025

☀️ Try build successful - checks-actions
Build commit: c29cad1 (c29cad1f56daa7fd1a315c02c28ac415a132c381)

@1c3t3a
Copy link
Member Author

1c3t3a commented Mar 17, 2025

Nice! Should we try to submit it again? :)

@fmease
Copy link
Member

fmease commented Mar 17, 2025

@bors r=rcvalle

@bors
Copy link
Contributor

bors commented Mar 17, 2025

📌 Commit b30cf11 has been approved by rcvalle

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 17, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 17, 2025
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#133870 (Stabilize `asm_goto` feature gate)
 - rust-lang#137449 (Denote `ControlFlow` as `#[must_use]`)
 - rust-lang#137465 (mir_build: Avoid some useless work when visiting "primary" bindings)
 - rust-lang#138349 (Emit function declarations for functions with `#[linkage="extern_weak"]`)
 - rust-lang#138412 (Install licenses into `share/doc/rust/licenses`)
 - rust-lang#138577 (rustdoc-json: Don't also include `#[deprecated]` in `Item::attrs`)
 - rust-lang#138588 (Avoid double lowering of idents)

Failed merges:

 - rust-lang#138321 ([bootstrap] Distribute split debuginfo if present)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 8f5c09b into rust-lang:master Mar 17, 2025
7 checks passed
@rustbot rustbot added this to the 1.87.0 milestone Mar 17, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 17, 2025
Rollup merge of rust-lang#138349 - 1c3t3a:external-weak-cfi, r=rcvalle

Emit function declarations for functions with `#[linkage="extern_weak"]`

Currently, when declaring an extern weak function in Rust, we use the following syntax:
```rust
unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}
```
This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static as an i8, and a pointer that is initialized with the value of the global i8 and represents the nullabilty e.g.
```
`@FOO` = extern_weak global i8
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
```

This approach does not work well with CFI, where we need to attach CFI metadata to a concrete function declaration, which was pointed out in rust-lang#115199.

This change switches to emitting a proper function declaration instead of a global i8. This allows CFI to work for extern_weak functions. Example:
```
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
...
declare !type !61 !type !62 !type !63 !type !64 extern_weak void `@FOO(double)` unnamed_addr rust-lang#6
```

We keep initializing the Rust internal symbol with the function declaration, which preserves the correct behavior for runtime checking the Option.

r? `@rcvalle`

cc `@jakos-sec`

try-job: test-various
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants