rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.13k stars 12.69k forks source link

`-C link-arg=-nostartfiles` does not work on musl target #91578

Open AsafFisher opened 2 years ago

AsafFisher commented 2 years ago

I tried this code:

#![no_std]
#![no_main]

// use libcore::run;
const hello: &str = "hello_world";
// Move main to core, and make hal a lib if shellcode - use hal::shellcode etc
extern "C" fn pr(a: usize, b: usize, c: u8) -> u64 // Address is printed
{
    //println!("hello {:?} {:?} {:?}", a, b, c);
    return 4;
}

#[no_mangle]
pub extern "C" fn _start() -> !{
    //println!("func: {:p}", pr as extern "C" fn(usize, usize, u8) -> _);
    //println!("Const: {:p}", hello);
    panic!();
}
#[panic_handler]
fn panic(_panic_info: &core::panic::PanicInfo) -> ! {

    loop {
        unsafe {
        }
    }
}
musl_x86 = "x86_64-unknown-linux-musl"
os.environ['RUSTFLAGS'] = '-C link-arg=-nostartfiles'
os.system(f'cargo +nightly build -Zbuild-std=std,panic_abort --release --verbose --target {musl_x86}')

I expected to see this happen: A static+pie binary with no main.

Instead, this happened:

Backtrace

Meta

rustc --version --verbose:

rustc 1.59.0-nightly (efec54529 2021-12-04)
binary: rustc
commit-hash: efec545293b9263be9edfb283a7aa66350b3acbf
commit-date: 2021-12-04
host: x86_64-unknown-linux-gnu
release: 1.59.0-nightly
LLVM version: 13.0.0
Backtrace

``` note: /usr/bin/ld: /workspace/dbg/target/x86_64-unknown-linux-musl/release/deps/standard_linuxgdb-b39958c4e33e1b5c.standard_linuxgdb.a819e94f-cgu.0.rcgu.o: in function `_start': standard_linuxgdb.a819e94f-cgu.0:(.text._start+0x0): multiple definition of `_start'; /home/gitpod/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/rcrt1.o:rcrt1.c:(.text+0x0): first defined here /usr/bin/ld: /home/gitpod/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/rcrt1.o: in function `__dls2': /build/musl-cross-make/build/local/x86_64-linux-musl/obj_musl/../src_musl/crt/rcrt1.c:13: undefined reference to `main' /usr/bin/ld: /build/musl-cross-make/build/local/x86_64-linux-musl/obj_musl/../src_musl/crt/rcrt1.c:13: undefined reference to `__libc_start_main' collect2: error: ld returned 1 exit status ```

hkratz commented 2 years ago

@rustbot label A-linkage O-musl O-linux

bjorn3 commented 2 years ago

I believe this happens because rustc explicitly passes the crt object files to the linker rather than letting the linker select them. The later option would cause the glibc crt object files to be used on glibc based systems. I'm not sure this can be fixed without letting rustc parse -nostartfiles, but doing so will likely go wrong in edge cases.