Skip to content

Commit

Permalink
Libdl: better support for musl
Browse files Browse the repository at this point in the history
We previously claimed that:
"Skip over objects without a path (as they represent this own object)"
This was false on two levels:
 - On everything non-glibc the binary does have a path
 - On linux, there is also usually also at least one shim object that does not have a path

So instead, we filter these out explicitly at the end (and remove some duplicate code paths).
  • Loading branch information
vtjnash committed Mar 21, 2019
1 parent a9a681d commit 818c576
Showing 1 changed file with 12 additions and 46 deletions.
58 changes: 12 additions & 46 deletions stdlib/Libdl/src/Libdl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ File extension for dynamic libraries (e.g. dll, dylib, so) on the current platfo
"""
dlext

if Sys.islinux()
if (Sys.islinux() || Sys.isbsd()) && !Sys.isapple()
struct dl_phdr_info
# Base address of object
addr::Cuint
Expand All @@ -224,51 +224,18 @@ if Sys.islinux()
phnum::Cshort
end

# This callback function called by dl_iterate_phdr() on Linux
function dl_phdr_info_callback(di::dl_phdr_info, size::Csize_t, dynamic_libraries::Array{String,1})
# Skip over objects without a path (as they represent this own object)
name = unsafe_string(di.name)
if !isempty(name)
push!(dynamic_libraries, name)
end
return convert(Cint, 0)::Cint
end
end # linux-only

if Sys.isbsd() && !Sys.isapple()
# This callback function called by dl_iterate_phdr() on Linux and BSD's
# DL_ITERATE_PHDR(3) on freebsd
struct dl_phdr_info
# Base address of object
addr::Cuint

# Null-terminated name of object
name::Ptr{UInt8}

# Pointer to array of ELF program headers for this object
phdr::Ptr{Cvoid}

# Number of program headers for this object
phnum::Cshort
end

function dl_phdr_info_callback(di::dl_phdr_info, size::Csize_t, dy_libs::Vector{String})
function dl_phdr_info_callback(di::dl_phdr_info, size::Csize_t, dynamic_libraries::Array{String,1})
name = unsafe_string(di.name)
if !isempty(name)
push!(dy_libs, name)
end
return convert(Cint, 0)::Cint
push!(dynamic_libraries, name)
return Cint(0)
end
end # bsd family
end

function dllist()
dynamic_libraries = Vector{String}()

@static if Sys.islinux()
callback = @cfunction(dl_phdr_info_callback, Cint,
(Ref{dl_phdr_info}, Csize_t, Ref{Vector{String}}))
ccall(:dl_iterate_phdr, Cint, (Ptr{Cvoid}, Ref{Vector{String}}), callback, dynamic_libraries)
end

@static if Sys.isapple()
numImages = ccall(:_dyld_image_count, Cint, ())

Expand All @@ -277,17 +244,16 @@ function dllist()
name = unsafe_string(ccall(:_dyld_get_image_name, Cstring, (UInt32,), i))
push!(dynamic_libraries, name)
end
end

@static if Sys.iswindows()
ccall(:jl_dllist, Cint, (Any,), dynamic_libraries)
end

@static if Sys.isbsd() && !Sys.isapple()
elseif Sys.islinux() || Sys.isbsd()
callback = @cfunction(dl_phdr_info_callback, Cint,
(Ref{dl_phdr_info}, Csize_t, Ref{Vector{String}}))
ccall(:dl_iterate_phdr, Cint, (Ptr{Cvoid}, Ref{Vector{String}}), callback, dynamic_libraries)
popfirst!(dynamic_libraries)
filter!(!isempty, dynamic_libraries)
elseif Sys.iswindows()
ccall(:jl_dllist, Cint, (Any,), dynamic_libraries)
else
# unimplemented
end

return dynamic_libraries
Expand Down

0 comments on commit 818c576

Please sign in to comment.