Skip to content

options/glibc: implement backtrace #1385

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

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
28 changes: 14 additions & 14 deletions ci/bootstrap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ packages:
- '--buildtype=debugoptimized'
- "-Dc_args=['-Wno-error=maybe-uninitialized', '-Wno-unknown-warning-option']"
- "-Dcpp_args=['-Wno-error=maybe-uninitialized', '-Wno-unknown-warning-option']"
- "-Dlibgcc_dependency=false"
# - "-Dlibgcc_dependency=false"
- "-Duse_freestnd_hdrs=enabled"
- "-Dbuild_tests=true"
- "-Db_sanitize=undefined"
Expand All @@ -51,7 +51,7 @@ packages:
environ:
CFLAGS: '-Wno-error=maybe-uninitialized'
CXXFLAGS: '-Wno-error=maybe-uninitialized'
LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
# LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
build:
- args: ['ninja']
- args: ['ninja', 'install']
Expand All @@ -74,7 +74,7 @@ packages:
- '--buildtype=debugoptimized'
- "-Dc_args=['-Wno-error=maybe-uninitialized']"
- "-Dcpp_args=['-Wno-error=maybe-uninitialized']"
- "-Dlibgcc_dependency=false"
# - "-Dlibgcc_dependency=false"
- "-Duse_freestnd_hdrs=enabled"
- "-Dbuild_tests=true"
- "-Db_sanitize=undefined"
Expand All @@ -83,8 +83,8 @@ packages:
- '-Dlinux_kernel_headers=@BUILD_ROOT@/packages/linux-headers/usr/include'
- "--cross-file=@THIS_SOURCE_DIR@/ci/linux-@OPTION:arch@-@OPTION:compiler@.cross-file"
- '@THIS_SOURCE_DIR@'
environ:
LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
# environ:
# LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
build:
- args: ['ninja']
- args: ['ninja', 'install']
Expand All @@ -106,7 +106,7 @@ packages:
- '--buildtype=debugoptimized'
- "-Dc_args=['-Wno-error=maybe-uninitialized']"
- "-Dcpp_args=['-Wno-error=maybe-uninitialized']"
- "-Dlibgcc_dependency=false"
# - "-Dlibgcc_dependency=false"
- "-Duse_freestnd_hdrs=enabled"
- "-Dbuild_tests=true"
- "-Db_sanitize=undefined"
Expand All @@ -115,8 +115,8 @@ packages:
- '-Dlinux_kernel_headers=@BUILD_ROOT@/packages/linux-headers/usr/include'
- "--cross-file=@THIS_SOURCE_DIR@/ci/linux-@OPTION:arch@-@OPTION:compiler@.cross-file"
- '@THIS_SOURCE_DIR@'
environ:
LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
# environ:
# LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
build:
- args: ['ninja']
- args: ['ninja', 'install']
Expand All @@ -139,7 +139,7 @@ packages:
- '--buildtype=debugoptimized'
- "-Dc_args=['-Wno-error=maybe-uninitialized']"
- "-Dcpp_args=['-Wno-error=maybe-uninitialized']"
- "-Dlibgcc_dependency=false"
# - "-Dlibgcc_dependency=false"
- "-Duse_freestnd_hdrs=enabled"
- "-Dbuild_tests=true"
- "-Db_sanitize=undefined"
Expand All @@ -152,8 +152,8 @@ packages:
- '-Dlinux_kernel_headers=@BUILD_ROOT@/packages/linux-headers/usr/include'
- "--cross-file=@THIS_SOURCE_DIR@/ci/linux-@OPTION:arch@-@OPTION:compiler@.cross-file"
- '@THIS_SOURCE_DIR@'
environ:
LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
# environ:
# LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
build:
- args: ['ninja']
- args: ['ninja', 'install']
Expand All @@ -176,16 +176,16 @@ packages:
- '--buildtype=debugoptimized'
- "-Dc_args=['-Wno-error=maybe-uninitialized']"
- "-Dcpp_args=['-Wno-error=maybe-uninitialized']"
- "-Dlibgcc_dependency=false"
# - "-Dlibgcc_dependency=false"
- "-Duse_freestnd_hdrs=enabled"
- "-Db_sanitize=undefined"
- "-Dwerror=true"
- "-Dheaders_only=true"
- '-Dlinux_kernel_headers=@BUILD_ROOT@/packages/linux-headers/usr/include'
- "--cross-file=@THIS_SOURCE_DIR@/ci/linux-@OPTION:arch@-@OPTION:compiler@.cross-file"
- '@THIS_SOURCE_DIR@'
environ:
LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
# environ:
# LDFLAGS: '-Wl,/tmp/libgcc-@OPTION:arch@.a'
build:
- args: ['ninja']
- args: ['ninja', 'install']
Expand Down
5 changes: 5 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ rtlib_deps = []

if not headers_only
if libgcc_dependency
libgcc_eh = meson.get_compiler('c').find_library('gcc_eh', required: false)
libgcc = meson.get_compiler('c').find_library('gcc', required: false)

compiler_rt_name = 'libclang_rt.builtins-' + host_machine.cpu_family()
Expand All @@ -462,6 +463,10 @@ if not headers_only
compiler_rt = meson.get_compiler('c').find_library(compiler_rt_name, required: false)
endif

if libgcc_eh.found()
libc_deps += libgcc_eh
endif

if libgcc.found()
rtlib_deps += libgcc
elif compiler_rt.found()
Expand Down
4 changes: 3 additions & 1 deletion options/elf/include/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,9 @@ enum {
DT_VERDEF = 0x6ffffffc,
DT_VERDEFNUM = 0x6ffffffd,
DT_VERNEED = 0x6ffffffe,
DT_VERNEEDNUM = 0x6fffffff
DT_VERNEEDNUM = 0x6fffffff,
DT_LOPROC = 0x70000000,
DT_HIPROC = 0x7fffffff
};

enum {
Expand Down
70 changes: 64 additions & 6 deletions options/glibc/generic/execinfo.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,77 @@
#include <dlfcn.h>
#include <execinfo.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#include <unwind.h>

#include <bits/ensure.h>
#include <mlibc/debug.hpp>

int backtrace(void **, int) {
mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog;
return 0;
namespace {

struct UnwindState {
void **frames;
int count;
int current_frame = 0;
};

_Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) {
uintptr_t ip = _Unwind_GetIP(context);

if (ip) {
#if defined(__x86_64__) || defined(__i386__)
ip--;
#elif defined(__aarch64__) || defined(__loongarch64)
ip -= 4;
#elif defined(__riscv) || defined(__m68k__)
ip -= 2;
#else
#warning "Missing support for architecture"
ip--;
#endif
}

UnwindState *state = static_cast<UnwindState *>(arg);
state->frames[state->current_frame++] = reinterpret_cast<void *>(ip);
return (state->current_frame >= state->count) ? _URC_END_OF_STACK : _URC_NO_REASON;
}

} // namespace

int backtrace(void **buffer, int size) {
if (size <= 0)
return 0;

UnwindState state{buffer, size};
_Unwind_Backtrace(trace, &state);
return state.current_frame;
}

char **backtrace_symbols(void *const *, int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

void backtrace_symbols_fd(void *const *, int, int) {
__ensure(!"Not implemented");
__builtin_unreachable();
void backtrace_symbols_fd(void *const *buffer, int size, int fd) {
if (size <= 0 || fd < 0)
return;

for (int frame_num = 0; frame_num < size; frame_num++) {
Dl_info info;
if (dladdr(buffer[frame_num], &info) != 0) {
if (info.dli_fname != nullptr)
write(fd, info.dli_fname, strlen(info.dli_fname));

if (info.dli_sname != nullptr)
dprintf(fd, "(%s+0x%" PRIxPTR ") ", info.dli_sname,
reinterpret_cast<uintptr_t>(buffer[frame_num]) - reinterpret_cast<uintptr_t>(info.dli_saddr));
else if(info.dli_saddr)
dprintf(fd, "(+%p) ", info.dli_saddr);
else
dprintf(fd, "() ");
}

dprintf(fd, "[%p]\n", buffer[frame_num]);
}
}
15 changes: 15 additions & 0 deletions options/internal/include/mlibc-asm/helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#if !defined(__ASSEMBLER__)
#error "This file can only be used by assembly files."
#endif

#define PROC_START(name) \
.global name; \
.type name, @function; \
.cfi_startproc; \
name:

#define PROC_END(name) \
.cfi_endproc; \
.size name, . - name
5 changes: 5 additions & 0 deletions options/posix/generic/dlfcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ extern "C" void *__dlapi_open(const char *, int, void *);
extern "C" void *__dlapi_resolve(void *, const char *, void *, const char *);
extern "C" int __dlapi_reverse(const void *, __dlapi_symbol *);
extern "C" int __dlapi_close(void *);
extern "C" int __dlapi_find_object(void *__address, dl_find_object *__result);

int dlclose(void *handle) {
return __dlapi_close(handle);
Expand Down Expand Up @@ -91,4 +92,8 @@ int dlinfo(void *__restrict, int, void *__restrict) {
__builtin_unreachable();
}

int _dl_find_object(void *address, struct dl_find_object *result) {
return __dlapi_find_object(address, result);
}

#endif // __MLIBC_GLIBC_OPTION
13 changes: 13 additions & 0 deletions options/posix/generic/sys-uio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ ssize_t writev(int fd, const struct iovec *iovs, int iovc) {
__ensure(iovc);

ssize_t written = 0;

auto sysdep = mlibc::sys_writev;
if(sysdep) {
int e = sysdep(fd, iovs, iovc, &written);
if(e) {
errno = e;
return -1;
}
return written;
}

// TODO: this implementation is not safe to use in signal contexts
mlibc::infoLogger() << "mlibc: falling back to signal-unsafe writev implementation!" << frg::endlog;
size_t bytes = 0;
for(int i = 0; i < iovc; i++) {
if(SSIZE_MAX - bytes < iovs[i].iov_len) {
Expand Down
1 change: 1 addition & 0 deletions options/posix/include/mlibc/posix-sysdeps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read);
[[gnu::weak]] int sys_readv(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_read);

int sys_write(int fd, const void *buf, size_t count, ssize_t *bytes_written);
[[gnu::weak]] int sys_writev(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_written);
[[gnu::weak]] int sys_pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read);
[[gnu::weak]] int sys_pwrite(int fd, const void *buf, size_t n, off_t off, ssize_t *bytes_read);

Expand Down
6 changes: 4 additions & 2 deletions options/rtld/aarch64/entry.S
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "mlibc-asm/helpers.h"

.global _start
_start:
PROC_START(_start)
bl relocateSelf

mov x0, sp
bl interpreterMain

br x0
PROC_END(_start)

.section .note.GNU-stack,"",%progbits

Loading
Loading