I'm trying to compile an executable (ELF file) that does not use a dynamic loader. I built a cross compiler that compiles mips from linux to be used on a simulator I made. I asserted the flag -static-libgcc on compilation of my hello.cpp file (hello world program). Apparently this is not enough though. Because there is still a segment in my executable which contains the name/path of the dynamic loader. What flags do I use to generate an executable which contains EVERYTHING needed to be run? Do I need to rebuild my cross compiler?
Asked
Active
Viewed 5.1k times
2 Answers
121
Use the following flags for linking
-static -static-libgcc -static-libstdc++
Use these three flags to link against the static versions of all dependencies (assuming gcc). Note, that in certain situation you don't necessarily need all three flags, but they don't "hurt" either. Therefore just turn on all three.
Check if it actually worked
Make sure that there is really no dynamic linkage
ldd yourexecutable
should return "not a dynamic executable" or something equivalent.
Make sure that there are no unresolved symbols left
nm yourexecutable | grep " U "
The list should be empty or should contain only some special kernel-space symbols like
U __tls_get_addr
Finally, check if you can actually execute your executable

Bernhard Kausler
- 5,119
- 3
- 32
- 36
26
Try using the -static
flag?

sigjuice
- 28,661
- 12
- 68
- 93
-
Is there a good resource describing the exact result of each of the gcc flags? I'm not 100% sure whether I'm actually disabling dynamic loading or not. When I use -static I still have the name of a dynamic loader placed into my .interp section of the elf file. – Dan Snyder Jul 19 '10 at 16:47
-
http://gcc.gnu.org/onlinedocs/gcc/Option-Index.html I used to write an operating system which loads elf executables and I can confirm that the -static flag works, just ignore the ld-related stuff and jump directly to the executable's entry point – Tomaka17 Jul 19 '10 at 17:13
-
I read something about using some configure option "-disable-shared". Is this not necessary to compile a standalone executable? – Dan Snyder Jul 19 '10 at 18:22
-
--disable-shared is an option when configuring GCC (see http://gcc.gnu.org/install/configure.html) but GCC will always build a static version of all the standard libraries ; --enable-shared tells it to build a shared version of them in addition to the static version – Tomaka17 Jul 19 '10 at 18:56
-
1I see, so one way or another --disable-shared doesn't effect my resulting executable? If static is used (just so I can confirm that I understand) then my executable will be considerably larger because everything needed to run the binary will already be loaded into the elf file? I can then just set my program counter to the entry location and everything else should work out? – Dan Snyder Jul 19 '10 at 19:04
-
Try running the "file" command on your executable. It should tell you what type of executable you have. – sigjuice Jul 19 '10 at 19:25
-
Hmm, when I do this the following is outputted: "hello: ELF 32-bit MSB MIPS-I executable, MIPS, version 1 (SYSV), for GNU/Linux 2.4.18, dynamically linked (uses shared libs), not stripped." Unfortunately the file is dynamically linked. I want to disable all dynamic linking as well as loading. Is there a way to do this? – Dan Snyder Jul 19 '10 at 19:51
-
The -static flag should work (I just tried it) ; make sure you are not accidentally linking your program with a .so because of a link script or whatever, you can check this using the "ldd" command – Tomaka17 Jul 19 '10 at 20:38
-
I don't think ldd would tell anything here. ldd basically runs the executable to figure out the dependencies, which will fail unless the host system is MIPS as well. – sigjuice Jul 19 '10 at 20:43
-
@Dan. Do you have a static version of libgcc at all? – sigjuice Jul 19 '10 at 20:44
-
Didn't know that ldd executes the program ; however I think that GCC would at least issue a warning if he uses the -static flag while an internal library doesn't have a static version – Tomaka17 Jul 19 '10 at 20:50
-
Hmm, well, when I run "ldd hello" I'm told that hello is not a dynamic executable. Is this a default result or can I trust this outcome? – Dan Snyder Jul 19 '10 at 20:54
-
I'm not sure if I have a static version of libgcc. I basically just built my cross-compiler with crosstools (mostly unmodified). Is there any good way to verify that I do have one? – Dan Snyder Jul 19 '10 at 20:55
-
~like a filename to search for or something. – Dan Snyder Jul 19 '10 at 21:08
-
@Dan. ldd says that if it does not recognize the file format e.g. ldd /etc/passwd or ldd mips.a.out – sigjuice Jul 20 '10 at 03:35
-
@Tomaka17, ldd is simply a shell script that runs the program with LD_TRACE_LOADED_OBJECTS set. The output of "ldd /bin/ls" and "LD_TRACE_LOADED_OBJECTS=1 /bin/ls" are equivalent. – sigjuice Jul 20 '10 at 03:41
-
If you installed your cross-compiler without any prefix, you may find libgcc.a somewhere in /usr/local/mips-elf-linux/lib (if your target was mips-elf-linux of course) – Tomaka17 Jul 20 '10 at 07:54
-
@Dan. "your-gcc --print-file-name=libgcc.a" should output the full path of libgcc.a if it exists. – sigjuice Jul 20 '10 at 15:52