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

program without libc (without std lib) leads to cryptic error #17346

Open
phil-opp opened this issue Sep 17, 2014 · 19 comments
Open

program without libc (without std lib) leads to cryptic error #17346

phil-opp opened this issue Sep 17, 2014 · 19 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@phil-opp
Copy link
Contributor

The code at http://doc.rust-lang.org/guide-unsafe.html#avoiding-the-standard-library requires libc. It isn't possible to remove this line or to replace it with the platform independent rlibc. The following error occurs (playpen: http://is.gd/GWl8YT):

error: linking with `cc` failed: exit code: 1
note: cc '-m64' '-L' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib' '-o' 'out' 'out.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-nodefaultlibs' '-Wl,--gc-sections' '-pie' '-Wl,--as-needed' '-Wl,-O1' '-L' '/home/rust/.rust' '-L' '/home/rust' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-lcompiler-rt'
note: /usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../lib/Scrt1.o: In function `_start':
(.text 0x12): undefined reference to `__libc_csu_fini'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../lib/Scrt1.o: In function `_start':
(.text 0x19): undefined reference to `__libc_csu_init'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/../../../../lib/Scrt1.o: In function `_start':
(.text 0x25): undefined reference to `__libc_start_main'
collect2: error: ld returned 1 exit status

error: aborting due to previous error

I want to use libcore, that doesn't require libc (http://doc.rust-lang.org/core/). The libcore code example in the guide (http://doc.rust-lang.org/guide-unsafe.html#using-libcore) has no libc dependency, but the playpen link in the top right of the code example reinserts it and removing it leads to the same error as above (http://is.gd/sxVAr0).

@Virtlink
Copy link

Virtlink commented Nov 4, 2014

I also encountered this error in Rust 0.13 nightly, and it prevents me from continuing.

@thestinger
Copy link
Contributor

The rlibc library provides a low quality implementation of a few primitives required by LLVM for the freestanding use case. It is not going to replace the platform's standard C library in a hosted environment. This is a documentation issue, not a bug in the compiler or libraries.

It's not likely that Rust will support running in a hosted environment without the platform's usual entry point. It does support freestanding usage, but in that environment the programmer is responsible for providing the entry code.

@Virtlink
Copy link

Virtlink commented Nov 5, 2014

So, if I understand correctly, extern crate libc removes the errors but the resulting binary won't be freestanding. If I want a freestanding binary, how would I go about providing the missing functions __libc_csu_fini, __libc_csu_init and __libc_start_main (and others)?

@thestinger
Copy link
Contributor

Those functions are provided by the C runtime and it's not trivial to replicate all of the functionality yourself. You need to handle differences between Linux kernel versions and set up stuff like the vdso yourself. It would be a much better idea to use a C standard library implementation like musl... I can't see an advantage to reinventing this wheel.

@thestinger
Copy link
Contributor

Anyway, you really don't want to be calling the raw system calls yourself. For example, the setuid system call really only changes the uid of the thread rather than the process and you need to set up a bunch of real-time signal magic to interrupt the other threads and set it globally. That's just a small example of the obstacles you're going to face if for some reason you decide to build everything from the ground up. It's certainly not necessary to get a binary without any external library dependencies.

@phil-opp
Copy link
Contributor Author

phil-opp commented Nov 5, 2014

If you want to write an OS Kernel or something like that compile your crate as a staticlib and link it manually with some entry code (that provides a stack and sets the stack limit in fs:XY). Not sure if there's a better way to do this but at least it works :)

@Virtlink
Copy link

Virtlink commented Nov 5, 2014

Thanks, I indeed intended to try my hand at writing an operating system kernel, which is why I was looking at freestanding Rust. I'll look into staticlib.

@steveklabnik
Copy link
Member

This doesn't seem to be an actual bug, then.

@carlpaten
Copy link

@steveklabnik maybe the real bug is how cryptic the error is?

@steveklabnik
Copy link
Member

@LilRed this issue was opened a very long time ago, does the same thing happen today? I've been doing osdev and I haven't run into it.

@carlpaten
Copy link

carlpaten commented Dec 28, 2015

apparently yes

@phil-opp
Copy link
Contributor Author

Just a quick brain dump since I'm on mobile right now:

I think I ran into this error back then when I tried to build a no_std executable. The solution was to build it as a staticlib instead and link it manually.

I think the main problem is that an executable isn't well defined without an operating system and libc. But the docs were/are very sparse on this topic, so I think we should at least improve them.

The error message is so cryptic because it is an error from the linker. I'm not sure if it can be improved easily.

@steveklabnik
Copy link
Member

The error message is so cryptic because it is an error from the linker. I'm not sure if it can be improved easily.

Yes, this is my fear as well. Hrm.

@steveklabnik steveklabnik reopened this Dec 28, 2015
@steveklabnik
Copy link
Member

Re-opening just in case, and re-tagging diagnostics.

@steveklabnik steveklabnik added A-diagnostics Area: Messages for errors, warnings, and lints and removed A-book labels Dec 28, 2015
@steveklabnik steveklabnik added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@joshtriplett
Copy link
Member

This still happens today:

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/josh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/tmp/embedtest/target/release/deps/embedtest-b44225ae3dc56b70.0.o" "-o" "/tmp/embedtest/target/release/deps/embedtest-b44225ae3dc56b70" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs" "-L" "/tmp/embedtest/target/release/deps" "-L" "/home/josh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/josh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-d213300c6af4be27.rlib" "-Wl,-Bdynamic"
  = note: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
          (.text 0x12): undefined reference to `__libc_csu_fini'
          /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
          (.text 0x19): undefined reference to `__libc_csu_init'
          /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
          (.text 0x26): undefined reference to `__libc_start_main'
          collect2: error: ld returned 1 exit status

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 22, 2017
@zesterer
Copy link
Contributor

zesterer commented May 1, 2018

This is still a problem. @phil-opp suggested this was due to Rust not clearly defining what an executable is in a freestanding environment. This also seems to happen when invoking rustc with -g and --omit=obj,link in RUSTFLAGS. It seems like the compiler gets confused and infers that debugging flags require a hosted environment, so switches to the host architecture for its compilation target?

New working playpen: https://play.rust-lang.org/?gist=3291629081e07458e1dae21bf12660f7&version=nightly&mode=debug

@phil-opp
Copy link
Contributor Author

phil-opp commented May 1, 2018

It seems like the C runtime is always linked when compiling for the host OS, even without a libc dependency (at least on Linux). Passing -nostartfiles to the linker fixes this problem on Linux.

@joshtriplett
Copy link
Member

joshtriplett commented Jan 14, 2019

I did manage to get a Rust program to link with -nostdlib, which removed these errors, but got the following spurious warning:

warning: unused attribute
 --> src/main.rs:4:1
  |
4 | #[link_args="-nostdlib"]
  | ^^^^^^^^^^^^^^^^^^^^^^^^
  |

@shufps
Copy link

shufps commented Mar 23, 2021

I did manage to get a Rust program to link with -nostdlib, which removed these errors, but got the following spurious warning:

warning: unused attribute
 --> src/main.rs:4:1
  |
4 | #[link_args="-nostdlib"]
  | ^^^^^^^^^^^^^^^^^^^^^^^^
  |

Just figured out, you can avoid this warning by putting

[target.x86_64-unknown-linux-gnu]
rustflags = [
    "-C", "link-arg=-nostdlib"
]

[build]
target = "x86_64-unknown-linux-gnu"

into .cargo/config

lnicola pushed a commit to lnicola/rust that referenced this issue Jun 23, 2024
Changed package.json so vscode extension settings have submenus

There are a lot of options that are a part of rust-analyzer, sometimes it can be hard to find an option that you are looking for. To fix this I have put all configurations into categories based on their names. I have also changed the schema in `crates/rust-analyzer/src/config.rs` to reflect this.

Currently for each generated entry the title is redeclared, this does function but I am prepared to change this if it is a problem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants