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

Merged
merged 18 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,27 @@ if (APPLE)
set(OLDEST_OSX_SUPPPORTED "11.7")
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
elseif (UNIX)
set(LINUX 1)

# Identify whether building with (and targeting) musl libc with ldd. This
# assumes a native build. For cross compiling, a musl build could be forced
# by DR_TARGET_MUSL.
find_program(LDD ldd DOC "util for examing shared object dependency")
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
if (NOT LDD)
message(STATUS "Unable to find ldd: assume glibc")
else ()
execute_process(COMMAND ${LDD}
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
RESULT_VARIABLE ldd_result
ERROR_VARIABLE ldd_err
OUTPUT_VARIABLE ldd_out)
if (ldd_err MATCHES "^musl libc")
set(MUSL 1)
endif ()
endif ()

option(DR_TARGET_MUSL "Target musl libc" OFF)
if (DR_TARGET_MUSL)
set(MUSL 1)
endif ()
endif (APPLE)
if (WIN32)
set(WINDOWS 1)
Expand Down
6 changes: 6 additions & 0 deletions core/unix/include/siginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* undef them here.
*/
#include <signal.h>
#include <limits.h>

#ifdef MACOS
/* For now we just use the system header. */
Expand All @@ -33,6 +34,11 @@ typedef clock_t __clock_t;
# ifndef __WORDSIZE
# define __WORDSIZE 32
# endif
# elif !defined(__GLIBC__)
# define __WORDSIZE LONG_BIT
typedef uid_t __uid_t;
typedef pid_t __pid_t;
typedef clock_t __clock_t;
# else
# include <bits/wordsize.h>
# endif
Expand Down
3 changes: 2 additions & 1 deletion core/unix/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -6408,6 +6408,8 @@ cleanup_after_vfork_execve(dcontext_t *dcontext)
num_threads * sizeof(thread_record_t *) HEAPACCT(ACCT_THREAD_MGT));
}

/* XXX: Discover libc type at runtime and use appropriate stdfile_t variant
* instead of depending on build-time preprocessor defines */
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
static void
set_stdfile_fileno(stdfile_t **stdfile, file_t old_fd, file_t file_no)
{
Expand All @@ -6418,7 +6420,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.
ziyao233 marked this conversation as resolved.
Show resolved Hide resolved
/* i#1973: musl libc support (and potentially other non-glibcs) */
/* only called by handle_close_pre(), so warning is specific to that. */
SYSLOG_INTERNAL_WARNING_ONCE(
Expand Down
4 changes: 4 additions & 0 deletions ext/drsyms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ elseif (UNIX)
# libdw uses pthread_rwlock_* routines.
link_with_pthread(dw_pic)

if (MUSL)
target_sources(elf_pic PRIVATE "${elfutils_dir}/lib/error.c")
endif ()

include_directories("${elfutils_dir}/libelf")
include_directories("${elfutils_dir}/libdw")
set(srcs ${srcs} drsyms_dw.c drsyms_elf.c)
Expand Down
12 changes: 9 additions & 3 deletions ext/drsyms/elfutils/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@

/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#define HAVE_DCGETTEXT 1
#if !defined(__linux__) || defined(__GLIBC__)
# define HAVE_DCGETTEXT 1
#endif

/* Define to 1 if you have the declaration of `mempcpy', and to 0 if you
don't. */
Expand All @@ -49,7 +51,9 @@

/* Define to 1 if you have the declaration of `rawmemchr', and to 0 if you
don't. */
#define HAVE_DECL_RAWMEMCHR 1
#if !defined(__linux__) || defined(__GLIBC__)
# define HAVE_DECL_RAWMEMCHR 1
#endif

/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
don't. */
Expand All @@ -60,7 +64,9 @@
#define HAVE_DECL_STRERROR_R 1

/* Define to 1 if you have the <error.h> header file. */
#define HAVE_ERROR_H 1
#if !defined(__linux__) || defined(__GLIBC__)
# define HAVE_ERROR_H 1
#endif

/* Define to 1 if you have the <err.h> header file. */
#define HAVE_ERR_H 1
Expand Down
1 change: 1 addition & 0 deletions make/configure.cmake.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
/* Used a lot due to the different TLS. We thus provide a convenience define. */
# define MACOS64
#endif
#cmakedefine MUSL

/* host, when different */
#cmakedefine DR_HOST_X86
Expand Down
9 changes: 8 additions & 1 deletion suite/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ function (set_cflags source)
else ()
set(cflags "${ORIG_CMAKE_C_FLAGS}")
endif ()
# Alpine Linux enables "-Wtrampolines" by default, breaking
# security-linux/trampoline.c.
if (MUSL)
set(cflags "${cflags} -Wno-trampolines")
endif ()
if ("${source}" MATCHES ".cpp$")
# Our C files need -std=gnu99, but that's an invalid flag for C++.
# configure_DynamoRIO_global removes unfavorable options for clients,
Expand Down Expand Up @@ -2737,7 +2742,9 @@ else (UNIX)

tobuild_ci(client.winxfer client-interface/winxfer.c "" "" "")
endif (UNIX)
if (NOT APPLE OR NOT AARCH64) # TODO i#5383: Port to Mac M1.
# TODO i#5383: Port to Mac M1.
# TODO i#1973: Port to musl libc.
if (NOT APPLE OR NOT AARCH64 AND NOT MUSL)
tobuild_ci(client.file_io client-interface/file_io.c
"${CMAKE_CURRENT_SOURCE_DIR}/client-interface/file_io_data.txt" "" "")
endif ()
Expand Down
47 changes: 27 additions & 20 deletions suite/tests/linux/signal-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ static sigjmp_buf env;
# define ITERS 500000
#endif

/* i#1973: __SIGRTMAX isn't available on musl libc. */
#ifndef __SIGRTMAX
# define __SIGRTMAX SIGRTMAX
#endif

#ifdef AARCHXX
/* i#4719: Work around QEMU bugs where QEMU can't handle signals 63 or 64. */
# undef SIGRTMAX
Expand Down Expand Up @@ -151,25 +156,6 @@ static void
break;
}

#ifdef LINUX
case __SIGRTMAX: {
sigcontext_t *sc = SIGCXT_FROM_UCXT(ucxt);
void *pc = (void *)sc->SC_XIP;
/* SIGRTMAX has been 64 on Linux since kernel 2.1, from looking at glibc
* sources. */
# ifndef AARCHXX /* i#4719: Work around QEMU bugs handling signals 63,64. */
assert(__SIGRTMAX == 64);
# endif
assert(__SIGRTMAX == SIGRTMAX);
# if VERBOSE
print("Got SIGRTMAX @ 0x%08x\n", pc);
# else
print("Got SIGRTMAX\n");
# endif
break;
}
#endif

#if USE_TIMER
case SIGVTALRM: {
sigcontext_t *sc = SIGCXT_FROM_UCXT(ucxt);
Expand All @@ -182,7 +168,28 @@ static void
}
#endif

default: assert(0);
default:
/* i#1973: SIGRTMAX is a macro over function call, rather than a constant on
* musl libc. We use an if branch in default block to handle this. */
#ifdef LINUX
if (sig == __SIGRTMAX) {
sigcontext_t *sc = SIGCXT_FROM_UCXT(ucxt);
void *pc = (void *)sc->SC_XIP;
/* SIGRTMAX has been 64 on Linux since kernel 2.1, from looking at glibc
* sources. */
# ifndef AARCHXX /* i#4719: Work around QEMU bugs handling signals 63,64. */
assert(__SIGRTMAX == 64);
# endif
assert(__SIGRTMAX == SIGRTMAX);
# if VERBOSE
print("Got SIGRTMAX @ 0x%08x\n", pc);
# else
print("Got SIGRTMAX\n");
# endif
break;
}
#endif
assert(0);
}
}

Expand Down
3 changes: 3 additions & 0 deletions suite/tests/tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@ nolibc_print(const char *str)
3,
# if defined(MACOS) || defined(ANDROID)
stderr->_file,
/* TODO i#1973: handle opaque FILE * on musl libc */
Copy link
Contributor

Choose a reason for hiding this comment

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

See PR #7190: Android64 needs this too. Let's remove the ifdefs and use STDERR_FILENO everywhere, for tools.c anyway. Not sure whether #7190 should do that first and this one merge or vice versa: please coordinate: @jackgallagher-arm

Copy link
Member Author

@ziyao233 ziyao233 Jan 16, 2025

Choose a reason for hiding this comment

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

Oops, I didn't see the comment and got it merged.

Copy link
Contributor

Choose a reason for hiding this comment

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

No problem, #7190 can put in code simplication here.

# elif defined(MUSL)
STDERR_FILENO,
# else
stderr->_fileno,
# endif
Expand Down
55 changes: 55 additions & 0 deletions suite/tests/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,62 @@
# include <sys/mman.h>
# include <stdlib.h> /* abort */
# include <errno.h>
# ifdef MUSL
# pragma push_macro("REG_R8")
# pragma push_macro("REG_R9")
# pragma push_macro("REG_R10")
# pragma push_macro("REG_R11")
# pragma push_macro("REG_R12")
# pragma push_macro("REG_R13")
# pragma push_macro("REG_R14")
# pragma push_macro("REG_R15")
# pragma push_macro("REG_RDI")
# pragma push_macro("REG_RSI")
# pragma push_macro("REG_RBP")
# pragma push_macro("REG_RBX")
# pragma push_macro("REG_RDX")
# pragma push_macro("REG_RAX")
# pragma push_macro("REG_RCX")
# pragma push_macro("REG_RSP")
# pragma push_macro("REG_CR2")
# undef REG_R8
# undef REG_R9
# undef REG_R10
# undef REG_R11
# undef REG_R12
# undef REG_R13
# undef REG_R14
# undef REG_R15
# undef REG_RDI
# undef REG_RSI
# undef REG_RBP
# undef REG_RBX
# undef REG_RDX
# undef REG_RAX
# undef REG_RCX
# undef REG_RSP
# undef REG_CR2
# endif
# include <signal.h>
# ifdef MUSL
# pragma pop_macro("REG_R8")
# pragma pop_macro("REG_R9")
# pragma pop_macro("REG_R10")
# pragma pop_macro("REG_R11")
# pragma pop_macro("REG_R12")
# pragma pop_macro("REG_R13")
# pragma pop_macro("REG_R14")
# pragma pop_macro("REG_R15")
# pragma pop_macro("REG_RDI")
# pragma pop_macro("REG_RSI")
# pragma pop_macro("REG_RBP")
# pragma pop_macro("REG_RBX")
# pragma pop_macro("REG_RDX")
# pragma pop_macro("REG_RAX")
# pragma pop_macro("REG_RCX")
# pragma pop_macro("REG_RSP")
# pragma pop_macro("REG_CR2")
# endif
# ifdef MACOS
# define _XOPEN_SOURCE \
700 /* required to get POSIX, etc. defines out of ucontext.h */
Expand Down
Loading