Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to static link libc?

Tags:

gcc

linker

I've seen a bunch of questions here and on other forums where the suggestion is to use -static or sometimes even -static -static-libgcc along with the compile arguments. This never works on Alpine, but woks fine on Ubuntu and Fedora.

I wrote a simple hello-world program in C, then had is compiled as gcc -static test.c. And the resulting binary still lights up ldd. See,

$ gcc -s test.c -static
$ ldd ./a.out
    /lib/ld-musl-x86_64.so.1 (0x7f043eae8000)

$ file ./a.out
./a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, stripped

Running the same on Ubuntu shows:

$ gcc -s test.c -static                   
$ file ./a.out 
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=bf6bfa1c78c541ae4e81586bcd050923bca9e34a, stripped

What is the correct and consistent way to static link libc itself on any platform? Is this something to do with the way GCC itself is compiled?

like image 499
Unmanned Player Avatar asked Dec 24 '19 01:12

Unmanned Player


People also ask

Can you statically link libc?

Statically linking libc is it's own minefield. It can and is done but even if you statically link everything else you should almost always dynamically link against your platform's libc. Statically linking libc is harder than dynamically linking it, but certainly easier than rewriting it.

Is libc static or dynamic?

libc is the C Standard library which is also linked dynamically. Let us now try to link the standard libraries statically so that our new executable a1. out does not have any runtime dependencies.

Is libc statically linked or dynamically linked?

However libc has not been linked in statically, only dynamically, so it is another failed attempt.

What is static library libc A?

A static library is usually identified by a . a (for "archive") suffix (e.g. libc. a). The library contains the modules you want to include in your program and is formatted as a collection of ELF object modules that the linker can then extract (as required by your program) and bind with your program at link time.


Video Answer


2 Answers

I'm answering my own question here for those who naively came here searching on keywords like static link libc or something.

If this is for MSVC, your only option is /MT or /MTd. But if you came here looking for GCC, welcome to the position independent code rabbit hole.

There are several variations of GCC floating around that are patched for specific targets or patched just because they can be. So if you have, say GCC version 6.0 and expect your command line arguments to generate same behaviour, you could be a victim of some bad patch work.

Some versions of GCC as in this question enforce position independent executable (-fPIE -pie) and silently ignore the -static option as seen in this example. I wonder if this should be reported as a bug to Alpine maintainers. To force it to ignore PIE, pass -no-pie to your GCC.

$  gcc -no-pie -static test.c

And if you do

$ file ./a.out
/lib/ld-musl-x86_64.so.1: ./a.out: Not a valid dynamic program

For details of how fPIE and static read these slides from OpenBSD.

like image 141
Unmanned Player Avatar answered Oct 07 '22 04:10

Unmanned Player


Your Ubuntu binary isn't PIE-enabled. If you pass -no-pie to GCC on Alpine, its binary will similarly not be PIE-enabled, but then it will be statically linked as you want.

like image 31
Joseph Sible-Reinstate Monica Avatar answered Oct 07 '22 05:10

Joseph Sible-Reinstate Monica