From 3e9e202e117d3c815e1ec95dffe043ca9131199e Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Fri, 5 Oct 2018 02:49:05 +0200 Subject: [PATCH 1/2] rt.sections_elf_shared: Tiny refactoring --- src/rt/sections_elf_shared.d | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/rt/sections_elf_shared.d b/src/rt/sections_elf_shared.d index 49c5939037..439a72d548 100644 --- a/src/rt/sections_elf_shared.d +++ b/src/rt/sections_elf_shared.d @@ -122,6 +122,12 @@ private: Array!(DSO*) _deps; // D libraries needed by this DSO void* _handle; // corresponding handle } + + // get the TLS range for the executing thread + void[] tlsRange() const nothrow @nogc + { + return getTLSRange(_tlsMod, _tlsSize); + } } /**** @@ -302,7 +308,7 @@ version (Shared) // update the _tlsRange for the executing thread void updateTLSRange() nothrow @nogc { - _tlsRange = getTLSRange(_pdso._tlsMod, _pdso._tlsSize); + _tlsRange = _pdso.tlsRange(); } } Array!(ThreadDSO) _loadedDSOs; @@ -404,15 +410,14 @@ extern(C) void _d_dso_registry(CompilerDSOData* data) * thread with a refCnt of 1 and call the TlsCtors. */ immutable ushort refCnt = 1, addCnt = 0; - auto tlsRng = getTLSRange(pdso._tlsMod, pdso._tlsSize); - _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, tlsRng)); + _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, pdso.tlsRange())); } } else { foreach (p; _loadedDSOs) assert(p !is pdso); _loadedDSOs.insertBack(pdso); - _tlsRanges.insertBack(getTLSRange(pdso._tlsMod, pdso._tlsSize)); + _tlsRanges.insertBack(pdso.tlsRange()); } // don't initialize modules before rt_init was called (see Bugzilla 11378) @@ -509,8 +514,7 @@ version (Shared) foreach (dep; pdso._deps) incThreadRef(dep, false); immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0; - auto tlsRng = getTLSRange(pdso._tlsMod, pdso._tlsSize); - _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, tlsRng)); + _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, pdso.tlsRange())); pdso._moduleGroup.runTlsCtors(); } } @@ -623,14 +627,14 @@ void freeDSO(DSO* pdso) nothrow @nogc version (Shared) { @nogc nothrow: - link_map* linkMapForHandle(void* handle) nothrow @nogc + link_map* linkMapForHandle(void* handle) { link_map* map; dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0 || assert(0); return map; } - link_map* exeLinkMap(link_map* map) nothrow @nogc + link_map* exeLinkMap(link_map* map) { assert(map); while (map.l_prev !is null) @@ -638,7 +642,7 @@ version (Shared) return map; } - DSO* dsoForHandle(void* handle) nothrow @nogc + DSO* dsoForHandle(void* handle) { DSO* pdso; !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); @@ -648,7 +652,7 @@ version (Shared) return pdso; } - void setDSOForHandle(DSO* pdso, void* handle) nothrow @nogc + void setDSOForHandle(DSO* pdso, void* handle) { !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); assert(handle !in _handleToDSO); @@ -656,7 +660,7 @@ version (Shared) !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); } - void unsetDSOForHandle(DSO* pdso, void* handle) nothrow @nogc + void unsetDSOForHandle(DSO* pdso, void* handle) { !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); assert(_handleToDSO[handle] == pdso); @@ -664,7 +668,7 @@ version (Shared) !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); } - void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps) nothrow @nogc + void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps) { // get the entries of the .dynamic section ElfW!"Dyn"[] dyns; @@ -716,7 +720,7 @@ version (Shared) } } - void* handleForName(const char* name) nothrow @nogc + void* handleForName(const char* name) { auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY); if (handle !is null) .dlclose(handle); // drop reference count From 90e6976a53d35e3f870897873f33486b0eb190c7 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Fri, 5 Oct 2018 03:01:00 +0200 Subject: [PATCH 2/2] rt.sections_elf_shared: Refactor findDSOInfoForAddr() --- src/rt/sections_elf_shared.d | 70 ++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/src/rt/sections_elf_shared.d b/src/rt/sections_elf_shared.d index 439a72d548..f168ba60ff 100644 --- a/src/rt/sections_elf_shared.d +++ b/src/rt/sections_elf_shared.d @@ -774,59 +774,51 @@ void scanSegments(in ref dl_phdr_info info, DSO* pdso) nothrow @nogc /************************** * Input: - * result where the output is to be written; dl_phdr_info is a Linux struct + * result where the output is to be written; dl_phdr_info is an OS struct * Returns: * true if found, and *result is filled in * References: * http://linux.die.net/man/3/dl_iterate_phdr */ -version (linux) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc +bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc { - static struct DG { const(void)* addr; dl_phdr_info* result; } + version (linux) enum IterateManually = true; + else version (NetBSD) enum IterateManually = true; + else enum IterateManually = false; - extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc + static if (IterateManually) { - auto p = cast(DG*)arg; - if (findSegmentForAddr(*info, p.addr)) + static struct DG { const(void)* addr; dl_phdr_info* result; } + + extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc { - if (p.result !is null) *p.result = *info; - return 1; // break; + auto p = cast(DG*)arg; + if (findSegmentForAddr(*info, p.addr)) + { + if (p.result !is null) *p.result = *info; + return 1; // break; + } + return 0; // continue iteration } - return 0; // continue iteration - } - - auto dg = DG(addr, result); - /* Linux function that walks through the list of an application's shared objects and - * calls 'callback' once for each object, until either all shared objects - * have been processed or 'callback' returns a nonzero value. - */ - return dl_iterate_phdr(&callback, &dg) != 0; -} -else version (FreeBSD) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc -{ - return !!_rtld_addr_phdr(addr, result); -} -else version (NetBSD) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc -{ - static struct DG { const(void)* addr; dl_phdr_info* result; } + auto dg = DG(addr, result); - extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc + /* OS function that walks through the list of an application's shared objects and + * calls 'callback' once for each object, until either all shared objects + * have been processed or 'callback' returns a nonzero value. + */ + return dl_iterate_phdr(&callback, &dg) != 0; + } + else version (FreeBSD) { - auto p = cast(DG*)arg; - if (findSegmentForAddr(*info, p.addr)) - { - if (p.result !is null) *p.result = *info; - return 1; // break; - } - return 0; // continue iteration + return !!_rtld_addr_phdr(addr, result); } - auto dg = DG(addr, result); - return dl_iterate_phdr(&callback, &dg) != 0; -} -else version (DragonFlyBSD) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc -{ - return !!_rtld_addr_phdr(addr, result); + else version (DragonFlyBSD) + { + return !!_rtld_addr_phdr(addr, result); + } + else + static assert(0, "unimplemented"); } /*********************************