Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
make sections_elf_shared work with FreeBSD
Browse files Browse the repository at this point in the history
- use local symbol to get handle of druntime
- relocate elf stringtable entry
- dlopen(RTLD_NOLOAD) increfs on linux, but not on FBSD
- use getprogname instead of program_invocation_name
  • Loading branch information
MartinNowak committed Dec 27, 2014
1 parent bda15e6 commit 658b5a2
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 24 deletions.
8 changes: 5 additions & 3 deletions posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ OBJS= $(OBJDIR)/errno_c.o $(OBJDIR)/bss_section.o $(OBJDIR)/threadasm.o
# build with shared library support
SHARED=$(if $(findstring $(OS),linux freebsd),1,)

LINKDL=$(if $(findstring $(OS),linux),-L-ldl,)

######################## All of'em ##############################

ifneq (,$(SHARED))
Expand Down Expand Up @@ -169,7 +171,7 @@ $(DRUNTIMESO) $(DRUNTIMESOLIB) dll: DFLAGS+=-version=Shared
dll: $(DRUNTIMESOLIB)

$(DRUNTIMESO): $(OBJS) $(SRCS)
$(DMD) -shared -debuglib= -defaultlib= -of$(DRUNTIMESO) $(DFLAGS) $(SRCS) $(OBJS) -L-ldl
$(DMD) -shared -debuglib= -defaultlib= -of$(DRUNTIMESO) $(DFLAGS) $(SRCS) $(OBJS) $(LINKDL)

$(DRUNTIMESOLIB): $(OBJS) $(SRCS)
$(DMD) -c -fPIC -of$(DRUNTIMESOOBJ) $(DFLAGS) $(SRCS)
Expand Down Expand Up @@ -211,7 +213,7 @@ UT_DRUNTIME:=$(OBJDIR)/lib$(DRUNTIME_BASE)-ut$(DOTDLL)
$(UT_DRUNTIME): override PIC:=-fPIC
$(UT_DRUNTIME): UDFLAGS+=-version=Shared
$(UT_DRUNTIME): $(OBJS) $(SRCS)
$(DMD) $(UDFLAGS) -shared -unittest -of$@ $(SRCS) $(OBJS) -L-ldl -debuglib= -defaultlib=
$(DMD) $(UDFLAGS) -shared -unittest -of$@ $(SRCS) $(OBJS) $(LINKDL) -debuglib= -defaultlib=

$(OBJDIR)/test_runner: $(UT_DRUNTIME) src/test_runner.d
$(DMD) $(UDFLAGS) -of$@ src/test_runner.d -L$(UT_DRUNTIME) -debuglib= -defaultlib=
Expand All @@ -235,7 +237,7 @@ test/shared/.run: $(DRUNTIMESO)

test/%/.run: test/%/Makefile
$(QUIET)$(MAKE) -C test/$* MODEL=$(MODEL) OS=$(OS) DMD=$(abspath $(DMD)) \
DRUNTIME=$(abspath $(DRUNTIME)) DRUNTIMESO=$(abspath $(DRUNTIMESO)) QUIET=$(QUIET)
DRUNTIME=$(abspath $(DRUNTIME)) DRUNTIMESO=$(abspath $(DRUNTIMESO)) QUIET=$(QUIET) LINKDL=$(LINKDL)

detab:
detab $(MANIFEST)
Expand Down
4 changes: 3 additions & 1 deletion src/rt/bss_section.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
/* These symbols are defined in the linker script and bracket the
* .bss, .lbss, .lrodata and .ldata sections.
*/
#if __linux__
#if defined(__linux__) || defined(__FreeBSD__)
// Need to use weak linkage to workaround a bug in ld.bfd (Bugzilla 13025).
extern int __attribute__((weak)) __bss_start, _end;

__attribute__ ((visibility ("hidden"))) void* rt_get_bss_start();
__attribute__ ((visibility ("hidden"))) void* rt_get_end();
void* rt_get_bss_start() { return (void*)&__bss_start; }
void* rt_get_end() { return (void*)&_end; }
#endif
57 changes: 47 additions & 10 deletions src/rt/sections_elf_shared.d
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
/**
* Written in the D programming language.
* This module provides linux-specific support for sections.
* This module provides ELF-specific support for sections with shared libraries.
*
* Copyright: Copyright Martin Nowak 2012-2013.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Martin Nowak
* Source: $(DRUNTIMESRC src/rt/_sections_linux.d)
*/

module rt.sections_linux;
module rt.sections_elf_shared;

version (linux):
version (linux) enum SharedELF = true;
else version (FreeBSD) enum SharedELF = true;
else enum SharedELF = false;
static if (SharedELF):

// debug = PRINTF;
import core.memory;
import core.stdc.stdio;
import core.stdc.stdlib : calloc, exit, free, malloc, EXIT_FAILURE;
import core.stdc.string : strlen;
import core.sys.linux.dlfcn;
import core.sys.linux.elf;
import core.sys.linux.link;
version (linux)
{
import core.sys.linux.dlfcn;
import core.sys.linux.elf;
import core.sys.linux.link;
}
else version (FreeBSD)
{
import core.sys.freebsd.dlfcn;
import core.sys.freebsd.sys.elf;
import core.sys.freebsd.sys.link_elf;
}
else
{
static assert(0, "unimplemented");
}
import core.sys.posix.pthread;
import rt.deh;
import rt.dmain2;
Expand Down Expand Up @@ -221,6 +237,9 @@ else

private:

// start of linked list for ModuleInfo references
version (FreeBSD) deprecated extern (C) __gshared void* _Dmodule_ref;

version (Shared)
{
/*
Expand Down Expand Up @@ -328,7 +347,11 @@ extern(C) void _d_dso_registry(CompilerDSOData* data)
{
// the first loaded DSO is druntime itself
assert(!_loadedDSOs.empty ||
handleForAddr(&_d_dso_registry) == handleForAddr(data._slot));
/* We need a local symbol (rt_get_bss_start) or the function
* pointer might be a PLT address in the executable.
* data._slot is already local in the shared library
*/
handleForAddr(&rt_get_bss_start) == handleForAddr(data._slot));

getDependencies(info, pdso._deps);
pdso._handle = handleForAddr(data._slot);
Expand Down Expand Up @@ -603,7 +626,12 @@ version (Shared)
{
if (dyn.d_tag == DT_STRTAB)
{
strtab = cast(const(char)*)dyn.d_un.d_ptr;
version (linux)
strtab = cast(const(char)*)dyn.d_un.d_ptr;
else version (FreeBSD)
strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
else
static assert(0, "unimplemented");
break;
}
}
Expand Down Expand Up @@ -728,12 +756,21 @@ bool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!"Phdr"* re
return false;
}

version (linux) import core.sys.linux.errno : program_invocation_name;
// should be in core.sys.freebsd.stdlib
version (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc;

@property const(char)* progname() nothrow @nogc
{
version (linux) return program_invocation_name;
version (FreeBSD) return getprogname();
}

nothrow
const(char)[] dsoName(const char* dlpi_name)
{
import core.sys.linux.errno;
// the main executable doesn't have a name in its dlpi_name field
const char* p = dlpi_name[0] != 0 ? dlpi_name : program_invocation_name;
const char* p = dlpi_name[0] != 0 ? dlpi_name : progname;
return p[0 .. strlen(p)];
}

Expand Down
1 change: 1 addition & 0 deletions test/exceptions/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ DMD:=
DRUNTIME:=
DRUNTIMESO:=
QUIET:=
LINKDL:=

SRC:=src
ROOT:=./obj/$(OS)/$(MODEL)
Expand Down
1 change: 1 addition & 0 deletions test/init_fini/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ DMD:=
DRUNTIME:=
DRUNTIMESO:=
QUIET:=
LINKDL:=

SRC:=src
ROOT:=./obj/$(OS)/$(MODEL)
Expand Down
20 changes: 11 additions & 9 deletions test/shared/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ DMD:=
DRUNTIME:=
DRUNTIMESO:=
QUIET:=
LINKDL:= # -L-ldl
LDL:=$(subst -L,,$(LINKDL)) # -ldl

SRC:=src
ROOT:=./obj/$(OS)/$(MODEL)
Expand Down Expand Up @@ -34,31 +36,31 @@ $(ROOT)/link_linkdep: $(SRC)/link_linkdep.d $(ROOT)/lib.so $(ROOT)/liblinkdep.so
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKFLAGS) -L$(ROOT)/liblinkdep.so -L$(ROOT)/lib.so

$(ROOT)/load_linkdep: $(SRC)/load_linkdep.d $(ROOT)/lib.so $(ROOT)/liblinkdep.so $(DRUNTIMESO)
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKFLAGS) -L-ldl
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKFLAGS) $(LINKDL)

$(ROOT)/link_loaddep: $(SRC)/link_loaddep.d $(ROOT)/lib.so $(ROOT)/libloaddep.so $(DRUNTIMESO)
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKFLAGS) -L$(ROOT)/libloaddep.so

$(ROOT)/load_loaddep: $(SRC)/load_loaddep.d $(ROOT)/lib.so $(ROOT)/libloaddep.so $(DRUNTIMESO)
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKFLAGS) -L-ldl
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKFLAGS) $(LINKDL)

$(ROOT)/load $(ROOT)/finalize: $(ROOT)/%: $(SRC)/%.d $(ROOT)/lib.so $(DRUNTIMESO)
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< -L-ldl
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKDL)

$(ROOT)/load_13414: $(ROOT)/%: $(SRC)/%.d $(ROOT)/lib_13414.so $(DRUNTIMESO)
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< -L-ldl
$(QUIET)$(DMD) $(DFLAGS) -of$@ $< $(LINKDL)

$(ROOT)/linkD: $(SRC)/linkD.c $(ROOT)/lib.so $(DRUNTIMESO)
$(QUIET)$(CC) $(CFLAGS) -o $@ $< $(ROOT)/lib.so -ldl
$(QUIET)$(CC) $(CFLAGS) -o $@ $< $(ROOT)/lib.so $(LDL)

$(ROOT)/linkDR: $(SRC)/linkDR.c $(ROOT)/lib.so $(DRUNTIMESO)
$(QUIET)$(CC) $(CFLAGS) -o $@ $< $(DRUNTIMESO) -ldl
$(QUIET)$(CC) $(CFLAGS) -o $@ $< $(DRUNTIMESO) $(LDL)

$(ROOT)/loadDR: $(SRC)/loadDR.c $(ROOT)/lib.so $(DRUNTIMESO)
$(QUIET)$(CC) $(CFLAGS) -o $@ $< -ldl
$(QUIET)$(CC) $(CFLAGS) -o $@ $< $(LDL)

$(ROOT)/host: $(SRC)/host.c $(ROOT)/plugin1.so $(ROOT)/plugin2.so
$(QUIET)$(CC) $(CFLAGS) -o $@ $< -ldl
$(QUIET)$(CC) $(CFLAGS) -o $@ $< $(LDL)

$(ROOT)/liblinkdep.so: $(ROOT)/lib.so
$(ROOT)/liblinkdep.so: DFLAGS+=-L$(ROOT)/lib.so
Expand All @@ -67,7 +69,7 @@ $(ROOT)/plugin1.so $(ROOT)/plugin2.so: $(SRC)/plugin.d $(DRUNTIMESO)
$(QUIET)$(DMD) -fPIC -shared $(DFLAGS) -of$@ $<

$(ROOT)/%.so: $(SRC)/%.d $(DRUNTIMESO)
$(QUIET)$(DMD) -fPIC -shared $(DFLAGS) -of$@ $< -L-ldl
$(QUIET)$(DMD) -fPIC -shared $(DFLAGS) -of$@ $< $(LINKDL)

clean:
rm -rf obj
6 changes: 5 additions & 1 deletion test/shared/src/load.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import core.runtime, core.stdc.stdio, core.thread, core.sys.linux.dlfcn;
import core.runtime, core.stdc.stdio, core.thread;

version (linux) import core.sys.linux.dlfcn;
else version (FreeBSD) import core.sys.freebsd.dlfcn;
else static assert(0, "unimplemented");

void loadSym(T)(void* handle, ref T val, const char* mangle)
{
Expand Down

0 comments on commit 658b5a2

Please sign in to comment.