Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.
Closed
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
115 changes: 115 additions & 0 deletions src/core/sys/dragonflybsd/dlfcn.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* D header file for DragonFlyBSD
*
* Copyright: Copyright Martin Nowak 2012.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)
* Copied: From core/sys/freebsd/sys
*/
module core.sys.dragonflybsd.dlfcn;

public import core.sys.posix.dlfcn;

version (DragonFlyBSD):

extern (C) nothrow @nogc:

enum __BSD_VISIBLE = true;

/*
* Modes and flags for dlopen().
*/
static assert(RTLD_LAZY == 1);
static assert(RTLD_NOW == 2);
enum RTLD_MODEMASK = 0x3;
static assert(RTLD_GLOBAL == 0x100);
static assert(RTLD_LOCAL == 0);
enum RTLD_TRACE = 0x200;
enum RTLD_NODELETE = 0x01000;
enum RTLD_NOLOAD = 0x02000;

/*
* Request arguments for dlinfo().
*/
enum RTLD_DI_LINKMAP = 2; /* Obtain link map. */
enum RTLD_DI_SERINFO = 4; /* Obtain search path info. */
enum RTLD_DI_SERINFOSIZE = 5; /* ... query for required space. */
enum RTLD_DI_ORIGIN = 6; /* Obtain object origin */
enum RTLD_DI_MAX = RTLD_DI_ORIGIN;

/*
* Special handle arguments for dlsym()/dlinfo().
*/
enum RTLD_NEXT = cast(void *)-1; /* Search subsequent objects. */
enum RTLD_DEFAULT = cast(void *)-2; /* Use default search algorithm. */
enum RTLD_SELF = cast(void *)-3; /* Search the caller itself. */

static if (__BSD_VISIBLE)
{
/*
* Structure filled in by dladdr().
*/
struct Dl_info {
const(char) *dli_fname; /* Pathname of shared object. */
void *dli_fbase; /* Base address of shared object. */
const(char) *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Address of nearest symbol. */
};


/*
* Structures, returned by the RTLD_DI_SERINFO dlinfo() request.
*/
struct Dl_serpath {
char * dls_name; /* single search path entry */
uint dls_flags; /* path information */
};

struct Dl_serinfo {
size_t dls_size; /* total buffer size */
uint dls_cnt; /* number of path entries */
Dl_serpath[1] dls_serpath; /* there may be more than one */
};

/*-
* The actual type declared by this typedef is immaterial, provided that
* it is a function pointer. Its purpose is to provide a return type for
* dlfunc() which can be cast to a function pointer type without depending
* on behavior undefined by the C standard, which might trigger a compiler
* diagnostic. We intentionally declare a unique type signature to force
* a diagnostic should the application not cast the return value of dlfunc()
* appropriately.
*/
struct __dlfunc_arg {
int __dlfunc_dummy;
};

alias dlfunc_t = void function(__dlfunc_arg);
}

private template __externC(RT, P...)
{
alias __externC = extern(C) RT function(P) nothrow @nogc;
}

/* XSI functions first. */
static assert(is(typeof(&dlclose) == __externC!(int, void*)));
static assert(is(typeof(&dlerror) == __externC!(char*)));
static assert(is(typeof(&dlopen) == __externC!(void*, const char*, int)));
static assert(is(typeof(&dlsym) == __externC!(void*, void*, const char*)));

static if (__BSD_VISIBLE)
{
void* fdlopen(int, int);
int dladdr(const(void)*, Dl_info*);
dlfunc_t dlfunc(void*, const(char)*);
int dlinfo(void*, int, void*);
/*void dllockinit(void* _context,
void* function(void* _context) _lock_create,
void function(void* _lock) _rlock_acquire,
void function(void* _lock) _wlock_acquire,
void function(void* _lock) _lock_release,
void function(void* _lock) _lock_destroy,
void function(void* _context) _context_destroy);*/
void* dlvsym(void*, const(char)*, const(char)*);
}
133 changes: 133 additions & 0 deletions src/core/sys/dragonflybsd/execinfo.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**
* DragonFlyBSD implementation of glibc's $(LINK2 http://www.gnu.org/software/libc/manual/html_node/Backtraces.html backtrace) facility.
*
* Copyright: Copyright Martin Nowak 2012.
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)
* Copied: From core/sys/freebsd/sys
*/
module core.sys.dragonflybsd.execinfo;

version (DragonFlyBSD):

extern (C) nothrow:

import core.sys.dragonflybsd.dlfcn;

// Use extern (D) so that these functions don't collide with libexecinfo.

extern (D) int backtrace(void** buffer, int size)
{
import core.thread : thread_stackBottom;

void** p, pend=cast(void**)thread_stackBottom();
version (D_InlineAsm_X86)
asm nothrow @trusted { mov p[EBP], EBP; }
else version (D_InlineAsm_X86_64)
asm nothrow @trusted { mov p[RBP], RBP; }
else
static assert(false, "Architecture not supported.");

int i;
for (; i < size && p < pend; ++i)
{
buffer[i] = *(p + 1);
auto pnext = cast(void**)*p;
if (pnext <= p) break;
p = pnext;
}
return i;
}


extern (D) char** backtrace_symbols(const(void*)* buffer, int size)
{
static void* realloc(void* p, size_t len) nothrow
{
static import cstdlib=core.stdc.stdlib;
auto res = cstdlib.realloc(p, len);
if (res is null) cstdlib.free(p);
return res;
}

if (size <= 0) return null;

size_t pos = size * (char*).sizeof;
char** p = cast(char**)realloc(null, pos);
if (p is null) return null;

Dl_info info;
foreach (i, addr; buffer[0 .. size])
{
if (dladdr(addr, &info) == 0)
(cast(ubyte*)&info)[0 .. info.sizeof] = 0;
fixupDLInfo(addr, info);

immutable len = formatStackFrame(null, 0, addr, info);
assert(len > 0);

p = cast(char**)realloc(p, pos + len);
if (p is null) return null;

formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);

p[i] = cast(char*)pos;
pos += len;
}
foreach (i; 0 .. size)
{
pos = cast(size_t)p[i];
p[i] = cast(char*)p + pos;
}
return p;
}


extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)
{
import core.sys.posix.unistd : write;
import core.stdc.stdlib : alloca;

if (size <= 0) return;

Dl_info info;
foreach (i, addr; buffer[0 .. size])
{
if (dladdr(addr, &info) == 0)
(cast(ubyte*)&info)[0 .. info.sizeof] = 0;
fixupDLInfo(addr, info);

enum maxAlloca = 1024;
enum min = (size_t a, size_t b) => a <= b ? a : b;
immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);
assert(len > 0);

auto p = cast(char*)alloca(len);
if (p is null) return;

formatStackFrame(p, len, addr, info) >= len || assert(0);
p[len - 1] = '\n';
write(fd, p, len);
}
}


private void fixupDLInfo(const(void)* addr, ref Dl_info info)
{
if (info.dli_fname is null) info.dli_fname = "???";
if (info.dli_fbase is null) info.dli_fbase = null;
if (info.dli_sname is null) info.dli_sname = "???";
if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr;
}


private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)
{
import core.stdc.stdio : snprintf;

immutable off = addr - info.dli_saddr;
immutable len = snprintf(p, plen, "%p <%s+%zd> at %s",
addr, info.dli_sname, off, info.dli_fname);
assert(len > 0);
return cast(size_t)len + 1; // + '\0'
}
16 changes: 16 additions & 0 deletions src/core/sys/dragonflybsd/sys/cdefs.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* D header file for DragonFlyBSD
*
* Authors: Martin Nowak,Diederik de Groot(port:DragonFlyBSD)
* Copied: From core/sys/freebsd/sys
*/
module core.sys.dragonflybsd.sys.cdefs;

version (DragonFlyBSD):

public import core.sys.posix.config;

enum __POSIX_VISIBLE = 200112;
enum __XSI_VISIBLE = 700;
enum __BSD_VISIBLE = true;
enum __ISO_C_VISIBLE = 1999;
12 changes: 12 additions & 0 deletions src/core/sys/dragonflybsd/sys/elf.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* D header file for DragonFlyBSD.
*
* Authors: Diederik de Groot(port:DragonFlyBSD)
* Copied: From core/sys/freebsd/sys
*/
module core.sys.dragonflybsd.sys.elf;

version (DragonFlyBSD):

public import core.sys.dragonflybsd.sys.elf32;
public import core.sys.dragonflybsd.sys.elf64;
Loading