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

i#1973 musl: fix build on musl libc #7168

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

ziyao233
Copy link
Contributor

This pull request allows DynamoRIO and all the tests to be built on musl libc,

  • Introduce MUSL macro and detect for musl libc in CMakeLists.txt
  • Add necessary macro and typedefs in core/unix/include/siginfo.h
  • Fix compilation of vendored elfutils
  • Temporarily use STDOUT/STDERR_FILENO when we need the underlying fds of
    stdout/stderr and suppress warnings for musl's opaque FILE type
  • Adjust linux.signal* tests to stay compatible with musl's SIGRTMAX, which is
    actually a function call, instead of a constant value

Tested on Alpine Linux, half of the tests are passed and it's possible to run
some applications (busybox, mutt and telegram-desktop) and some simple clients
(bbsize).

Issue: #1973

This introduces the MUSL macro.
bits/wordsize.h is a glibc-specific header, on musl __WORD_SIZE is
defined as LONG_BIT. This is okay since Linux kernel assumes the size
of long is equal to a machine word.
The pre-defined config.h is adjusted to match musl's features. We also
to build and link lib/error.c to provide functions for error message
handling.
As DynamoRIO enables -Werror by default, such warnings will prevent a
warning-aware build. Since we also issue a warnings during start up,
Let's remove it.
GCC on Alpine Linux enables "-Wtrampolines" by default, breaking the
test. Since Alpine is the most widely-used musl-based distribution, it's
worth to work around this: let's defaults to -Wno-trampoline on musl
systems.
Some glibc-specific APIs are used in the test, we need to port them to
musl.
DynamoRIO defines REG_* macros for compatibility with old clients, which
conflict with signal.h on musl. Use of pragma push_macro/pop_macro to
avoid messing musl's header up.
@ziyao233
Copy link
Contributor Author

@derekbruening thanks for your review

@abhinav92003
Copy link
Contributor

@derekbruening thanks for your review

If this PR is ready for review, please add a reviewer from the "Reviewers" list on the top-right1.

@ziyao233
Copy link
Contributor Author

@derekbruening thanks for your review

If this PR is ready for review, please add a reviewer from the "Reviewers" list on the top-right1.

I have no write access to the repository, thus cannot require a reviewer :/
It's ready for review and I'll be thankful if you could give me a helpful hand.

CMakeLists.txt Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
if (NOT LDD)
message(STATUS "Unable to find ldd: assume glibc")
else ()
execute_process(COMMAND ${LDD}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the build host ldd on the path always correspond with the build toolchain in use and the target? Any cross-compilation concerns?

Copy link
Contributor Author

@ziyao233 ziyao233 Jan 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the build host ldd on the path always correspond with the build toolchain in use and the target?

Sure not.

Any cross-compilation concerns?

I don't know a better way to detect musl in cmake. but following strategy may be appropriate,

  1. When building natively, check ldd and examine whether it's musl libc.
  2. When cross compiling, always assume glibc.
  3. Provide an extra build argument to force a musl build.

Then native builds and cross ones targeting glibc will go smoothly, which covers most cases. Those who crosscompile for musl should know what they're doing (and read the doc).

What do you think of it?

suite/tests/CMakeLists.txt Outdated Show resolved Hide resolved
suite/tests/linux/signal-base.h Outdated Show resolved Hide resolved
suite/tests/linux/signal-base.h Outdated Show resolved Hide resolved
@@ -182,7 +168,28 @@ static void
}
#endif

default: assert(0);
default:
/* i#1973: SIGRTMAX is a macro over function call, rather a constant on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A function call into libc.so? While that may work in this test, that will break core DR where libdynamorio.so cannot import from libc. All core DR uses need to be replaced with something that does not need libc code at runtime. There is a build-time check for such imports: CMake_readelf.cmake check_deps. Is that check running in your build (maybe it gets disabled if it can't find readelf or sthg)? Does it pass?

Copy link
Contributor Author

@ziyao233 ziyao233 Jan 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A function call into libc.so? While that may work in this test, that will break core DR where libdynamorio.so cannot import from libc. All core DR uses need to be replaced with something that does not need libc code at runtime.

I understand dr cannot rely on any libc functions, but __SIGRTMAX seems unrelated to this: All results of git grep SIGRTMAX are in suite/tests/linux/signal-base.h, thus I think there's no reference to it in the core DR.

There is a build-time check for such imports: CMake_readelf.cmake check_deps. Is that check running in your build (maybe it gets disabled if it can't find readelf or sthg)? Does it pass?

Have checked my generated build.ninja, it did run and pass :)

CMakeLists.txt Show resolved Hide resolved
@@ -6418,7 +6418,6 @@ set_stdfile_fileno(stdfile_t **stdfile, file_t old_fd, file_t file_no)
(*stdfile)->STDFILE_FILENO = file_no;
# endif
#else
# warning stdfile_t is opaque; DynamoRIO will not set fds of libc FILEs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to separate the build system from the target runtime system: but here it seems they are tied together so a glibc build will fail when trying to use a musl libc library with a tool run on a musl system; and this musl build will fail on a glibc system even though the musl build would be able to work if it had dynamic discovery of the libc type. Add a XXX comment on that possibility? Likely not worth effort to implement at this point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of adding

XXX: Discover libc type at runtime and use appropriate stdfile_t variant

at top of set_stdfile_fileno()?

@ziyao233 ziyao233 changed the title I#1973: fix build on musl libc i#1973: fix build on musl libc Jan 11, 2025
@ziyao233 ziyao233 changed the title i#1973: fix build on musl libc i#1973 musl: fix build on musl libc Jan 11, 2025
@ziyao233
Copy link
Contributor Author

ziyao233 commented Jan 11, 2025

btw, may I have write access to the repository? I'm an intern of ISCAS and will continue working on riscv and musl port for DR, the access will help a lot (like adding an appropriate reviewer)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants