Skip to content

Building in release mode with LTO breaks RPM build process for some code #78445

Open
@gavrie

Description

@gavrie

When building a dynamic library from my Rust code with LTO enabled, the resulting binary includes a seemingly invalid slash-terminated directory table entry, which in turn prevents building an RPM from the library on RHEL (details follow below).

The Rust code (reduced to the minimal code that reproduces the issue) in src/lib.rs:

#[no_mangle]
pub extern "C" fn on_load() {
    let _ = std::panic::take_hook();
}

The Cargo.toml:

[package]
name = "lto-bug"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]
name = "lto_bug"

[profile.release]
lto = true

The build command:

cargo build --release

I expected to see this happen: Get a valid binary for the dynamic library.

Instead, this happened:

The resulting binary includes a directory table entry that ends with a slash, which in turn breaks the RPM build process.

The output of objdump -g target/release/liblto_bug.so includes:

 The Directory Table (offset 0x19d4c):
  1     /cargo/registry/src/github.com-1ecc6299db9ec823/rustc-demangle-0.1.16/src
  2     /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src
  3     /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/slice
  4     /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/
  5     /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/ops
...

Entry 4 ends with a slash, which wreaks havoc with RPM's debugedit utility that is run while building an RPM.

Reproducing this:

$ /usr/lib/rpm/debugedit -b / -d / target/release/liblto_bug.so
/usr/lib/rpm/debugedit: canonicalization unexpectedly shrank by one character

See this Red Hat bug report that describes the problem.
It could be considered a bug in debugedit, but it's very longstanding and would be great if Rust didn't do this.

It seems to be some an unintentional side effect that the directory /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/ is added to the directory table, certainly with the terminating slash.

I tried to see if I could work around this by using --remap-path-prefix, but that seems to have no effect at all on this path.

Meta

rustc --version --verbose:

rustc 1.47.0 (18bf6b4f0 2020-10-07)
binary: rustc
commit-hash: 18bf6b4f01a6feaf7259ba7cdae58031af1b7b39
commit-date: 2020-10-07
host: x86_64-unknown-linux-gnu
release: 1.47.0
LLVM version: 11.0

Also happens with nightly:

rustc 1.49.0-nightly (ffa2e7ae8 2020-10-24)
binary: rustc
commit-hash: ffa2e7ae8fbf9badc035740db949b9dae271c29f
commit-date: 2020-10-24
host: x86_64-unknown-linux-gnu
release: 1.49.0-nightly
LLVM version: 11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LTOArea: Link-time optimization (LTO)A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions