Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20171002105033.GK15263@port70.net>
Date: Mon, 2 Oct 2017 12:50:33 +0200
From: Szabolcs Nagy <nsz@...t70.net>
To: musl@...ts.openwall.com
Subject: Re: C++ program with no dependencies except musl

* Paul Kaletta <pk@...lkaletta.org> [2017-10-02 12:05:33 +0200]:
> I'm just getting started with musl, and have two questions.
> 
> On Arch Linux I installed the packages for musl (vesion 1.1.16-2), and
> gcc (version 7.2.0-2).
> 
> I have this program:
> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main(void)
> {
>     printf("Hello!\n");
>     exit(0);
> }
> 
> I have stored it in justmain.c, and justmain.cpp.
> 
> I can easily compile it with:
> 
> $ musl-gcc -o justmain_static_c justmain.c -static
> 

musl-gcc is a hack to wrap the system gcc to make it use musl
instead of the system c library and drop the system -I and -L paths.

so your gcc is most likely configured against glibc not against
musl which can cause various issues:
- system libatomics.so may fail to load (it uses a gnu
extension that is only supported by the glibc dynamic loader.
matters if atomics are not inlined e.g. 16byte atomics is used)
- there may be symbol versioning issues (musl loader does not
support glibc compatible symbol versions, it affects libgcc_s.so
which is needed for c++ code for the unwinder)
- broken gthread which incorrectly detects single-threadedness
in case of static linking with libstdc++.
- different __*INT*_TYPE macro definitions than in libc headers
(most code should work fine, but some things might fail:
e.g. gfortran ffi calls into c functions using uint_fast16_t)
- many other details i dont remember now..

the recommended use of musl on a non-musl system is via a cross
toolchain that is built against musl (e.g.
https://github.com/richfelker/musl-cross-make
can build you one)

> However, when I do not want a dynamically linked library, I get an
> error:
> 
> $ musl-gcc -o justmain_dynamic_c justmain.c
> /usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/crtbegin.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
> /usr/bin/ld: final link failed: Nonrepresentable section on output
> collect2: error: ld returned 1 exit status
> 
> The error goes away when I append the -pie, or -no-pie linker option
> to the build command line.  What is happening here, and why do both
> options work?
> 

the host gcc most likely defaults to pie, the musl-gcc wrapper
assumes traditional non-default-pie gcc (since that was the only
way to build gcc when musl-gcc was written).

i don't know if the musl-gcc specs file can be updated to support
both cases (the specs file does not know the default, only what
the user specified explicitly).

> For a little project of mine I would like to use C++ language
> features, but leave out the default C++ standard library.  I was also
> thinking about using musl together with tinystl
> (https://github.com/mendsley/tinystl), which is header-only.
> 
> I found some good sources (http://www.avabodh.com/cxxin/nostdlib.html,
> http://wiki.osdev.org/C%2B%2B,
> http://wiki.osdev.org/Calling_Global_Constructors), but I'm still
> figuring out how to apply the information to my use case.
> 
> I have a hard time with the basics already.  I can take the program
> from above and compile it as C++.
> 
> $ musl-gcc -std=c++11 -g -nostdlib -fno-exceptions -fno-rtti justmain.cpp -o justmain_cpp --entry main -L /usr/lib/musl/lib/ -lc
> 
> The resulting binary works.  When I add -static, I can compile
> succesfully, but the resulting binary gives me a segmentation fault.
> 
> $ musl-gcc -std=c++11 -g -nostdlib -fno-exceptions -fno-rtti justmain.cpp -o justmain_static_cpp --entry main -L /usr/lib/musl/lib/ -lc -static
> $ ./justmain_static_cpp 
> Segmentation fault (core dumped)
> 

if you use -nostdlib you have to be careful how you link,
since you jump directly to main without initializing the
libc things will break (crt*.o files are there for a reason..)

> Program received signal SIGSEGV, Segmentation fault.
> 0x00000000004002c1 in __overflow ()
> (gdb)
> 
> I'm not sure what exactly is happening, but I suspect that some global
> init function for musl was not called, which results in the observed
> behavior.
> 

you need to add the appropriate crt files (and specify
pie/no-pie)

> My goal is a minimal example of a C++ program that depends on musl and
> nothing else.  It would be nice if it could be linked both statically
> and dynamically.  I realize that some C++ language features will need
> some infrastructure that is normally provided by the C++ runtime
> library.  But as a first step: what is required to get the above
> program to compile (with a C++ compiler) to a statically linked binary
> that actually works?
> 
> Can I use the musl-gcc wrapper with -std=c++11 for my purpose, or do I
> need a more sophisticated approach?
> 

use a cross toolchain, with that, arbitrary c++11 code should
compile with both static and dynamic linking.

> Best regards,
> Paul

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.