Commit 70add834 authored by A. Wilcox's avatar A. Wilcox 🦊
Browse files

Merge branch 'patch-4' into 'master'

New kernel compatibility; obstack; pthread_getname_np

The gcompat loader compiled as a static binary doesn't work on Linux since [a4ff8e8620d3f4](https://github.com/torvalds/linux/commit/a4ff8e8620d3f4f50ac4b41e8067b7d395056843), failing with an error like:
```
[349055.473655] 13325 (cmake): Uhuuh, elf segment at 0000000000400000 requested but the memory is mapped already
```
This is because the actual binary we want to run is also loaded at 0x400000. While it's actually okay to overlap the binary, since we're going to call `execve` again, the kernel doesn't allow the overlap anymore. Fix that by compiling the loader as static PIE, so it can be put at a different address.

Also add `pthread_getname_np` and the option to link `obstack`.

See merge request !4
parents e97935b9 d186323a
......@@ -11,6 +11,17 @@
0.4.0 (201?-??-??)
==================
Build system
------------
* Allow building against libobstack.
* Fix compatibility with Linux 4.17 and newer.
pthread
-------
* Add pthread_getname_np.
wchar
-----
......
LIBGCOMPAT_INCLUDE = \
libgcompat/alias.h
libgcompat/alias.h \
libgcompat/internal.h
LIBGCOMPAT_SRC = \
libgcompat/ctype.c \
libgcompat/cxx_thread.c \
......@@ -43,36 +44,50 @@ LOADER_OBJ = ${LOADER_SRC:.c=.o}
LOADER_NAME = ld-linux.so.2
LOADER_PATH = /lib/${LOADER_NAME}
ifdef WITH_LIBUCONTEXT
PKG_CONFIG ?= pkg-config
LIBUCONTEXT_LIBS = -Wl,--no-as-needed -lucontext
ifdef WITH_LIBUCONTEXT
LIBUCONTEXT_CFLAGS = -DWITH_LIBUCONTEXT
LIBUCONTEXT_LIBS = -lucontext
endif
ifndef WITH_OBSTACK
WITH_OBSTACK = $(shell \
for pkg in obstack obstack-standalone; do \
${PKG_CONFIG} --exists "$$pkg" && { echo "$$pkg"; exit 0; } \
done; echo "no")
endif
ifneq (${WITH_OBSTACK},no)
OBSTACK_CFLAGS = $(shell ${PKG_CONFIG} --cflags ${WITH_OBSTACK}) -DWITH_OBSTACK
OBSTACK_LIBS = $(shell ${PKG_CONFIG} --libs ${WITH_OBSTACK})
endif
all: ${LIBGCOMPAT_NAME} ${LOADER_NAME}
${LIBGCOMPAT_NAME}: ${LIBGCOMPAT_OBJ}
$(CC) -o ${LIBGCOMPAT_NAME} -Wl,-soname,${LIBGCOMPAT_NAME} \
-shared ${LIBGCOMPAT_OBJ} ${LIBUCONTEXT_LIBS}
${CC} ${CFLAGS} ${LDFLAGS} -shared -Wl,-soname,${LIBGCOMPAT_NAME} \
-o ${LIBGCOMPAT_NAME} ${LIBGCOMPAT_OBJ} \
-Wl,--no-as-needed ${LIBUCONTEXT_LIBS} ${OBSTACK_LIBS}
${LIBGCOMPAT_OBJ}: ${LIBGCOMPAT_INCLUDE}
${LOADER_NAME}: ${LOADER_OBJ}
$(CC) -o ${LOADER_NAME} -fPIE -static ${LOADER_OBJ}
${CC} ${CFLAGS} ${LDFLAGS} -static-pie -o ${LOADER_NAME} ${LOADER_OBJ}
.c.o:
$(CC) -c -D_BSD_SOURCE -DLIBGCOMPAT=\"${LIBGCOMPAT_PATH}\" \
-DLINKER=\"${LINKER_PATH}\" -DLOADER=\"${LOADER_NAME}\" \
-Ilibgcompat ${LIBUCONTEXT_CFLAGS} \
-fPIC -std=c99 -Wall -Wextra -Wno-frame-address \
-Wno-unused-parameter ${CFLAGS} ${CPPFLAGS} -o $@ $<
${CC} ${CPPFLAGS} ${CFLAGS} -c -D_BSD_SOURCE \
-DLIBGCOMPAT='"${LIBGCOMPAT_PATH}"' \
-DLINKER='"${LINKER_PATH}"' -DLOADER='"${LOADER_NAME}"' \
-fPIC -Ilibgcompat -std=c99 \
-Wall -Wextra -Wno-frame-address -Wno-unused-parameter \
${LIBUCONTEXT_CFLAGS} ${OBSTACK_CFLAGS} -o $@ $<
clean:
rm -f libgcompat/*.o loader/*.o ${LIBGCOMPAT_NAME} ${LOADER_NAME}
format:
clang-format -i ${LIBGCOMPAT_SRC} ${LOADER_SRC}
clang-format -i ${LIBGCOMPAT_INCLUDE} ${LIBGCOMPAT_SRC} ${LOADER_SRC}
install: all
install -D -m755 ${LIBGCOMPAT_NAME} ${DESTDIR}/${LIBGCOMPAT_PATH}
......
#ifndef _ALIAS_H_
#define _ALIAS_H_
#define alias(old, new) \
#define alias(old, new) \
extern __typeof(old) new __attribute__((__alias__(#old)))
#define weak_alias(old, new) \
#define weak_alias(old, new) \
extern __typeof(old) new __attribute__((weak, __alias__(#old)))
#endif /* _ALIAS_H_ */
......@@ -3,12 +3,11 @@
void GCOMPAT__panic(const char *fmt, ...) __attribute__((noreturn));
#define GCOMPAT__assert_with_reason(chk, ...) \
do { \
if (!(chk)) { \
GCOMPAT__panic(__VA_ARGS__); \
} \
} \
while(0);
#define GCOMPAT__assert_with_reason(chk, ...) \
do { \
if (!(chk)) { \
GCOMPAT__panic(__VA_ARGS__); \
} \
} while (0);
#endif
#include <pthread.h>
#define _GNU_SOURCE
#include <errno.h> /* errno */
#include <fcntl.h> /* O_CLOEXEC, O_RDONLY */
#include <pthread.h> /* pthread_atfork */
#include <unistd.h> /* open, read */
#include "alias.h" /* weak_alias */
......@@ -27,3 +31,22 @@ int __register_atfork(void (*prepare)(void), void (*parent)(void),
return pthread_atfork(prepare, parent, child);
}
weak_alias(__register_atfork, register_atfork);
/**
* Get the name of a thread.
*/
int pthread_getname_np(pthread_t thread, char *name, size_t len)
{
int fd = open("/proc/thread-self/comm", O_RDONLY | O_CLOEXEC);
char dummy;
if (fd < 0)
return errno;
if (read(fd, name, len) < 0)
return errno;
/* If there's more to read, the buffer was too small. */
if (read(fd, &dummy, 1) > 0)
return ERANGE;
return 0;
}
......@@ -45,7 +45,7 @@ int __vswprintf_chk(wchar_t *s, size_t n, int flag, size_t slen,
* LSB 5.0: LSB-Core-generic/baselib---wcstol-internal-1.html
*/
long int __wcstol_internal(const wchar_t *nptr, wchar_t **endptr, int base,
int group)
int group)
{
assert(group == 0);
return wcstol(nptr, endptr, base);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment