Skip to content

Commit

Permalink
Rework readmeta to always return a collection of handles.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Apr 5, 2023
1 parent 7397b6d commit e93e130
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/COFF/COFFHandle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct COFFHandle{T<:IO} <: ObjectHandle

# The parsed-out header of the COFF object
header::COFFHeader

# The location of the header (because of MZ confusion, we must store this)
header_offset::UInt32

Expand Down Expand Up @@ -63,7 +63,7 @@ function readmeta(io::IO, ::Type{H}) where {H <: COFFHandle}
opt_header = read(io, COFFOptionalHeader)

# Construct our COFFHandle, pilfering the filename from the IOStream
return COFFHandle(io, Int64(start), header, header_offset, opt_header, path(io))
return [COFFHandle(io, Int64(start), header, header_offset, opt_header, path(io))]
end


Expand Down
4 changes: 2 additions & 2 deletions src/ELF/ELFHandle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function readmeta(io::IO, ::Type{H}) where {H <: ELFHandle}
start = position(io)

# Check for magic bytes
magic = [read(io, UInt8) for idx in 1:4]
magic = [read(io, UInt8) for idx in 1:4]
if any(magic .!= elven_magic)
msg = """
Magic Number 0x$(join(string.(magic, base=16),"")) does not match expected ELF
Expand All @@ -56,7 +56,7 @@ function readmeta(io::IO, ::Type{H}) where {H <: ELFHandle}
seek(io, start)

# Construct our ELFHandle, pilfering the filename from the IOStream
return ELFHandle(io, Int64(start), ei, header, path(io))
return [ELFHandle(io, Int64(start), ei, header, path(io))]
end


Expand Down
2 changes: 1 addition & 1 deletion src/MachO/MachOFat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ length(h::FatMachOHandle) = length(h.header.archs)
eltype(::Type{S}) where {S <: FatMachOHandle} = MachOLoadCmdRef
function getindex(h::FatMachOHandle, idx)
seek(h.io, h.start + h.header.archs[idx].offset)
readmeta(h.io, MachOHandle)
only(readmeta(h.io, MachOHandle))
end

function show(io::IO, oh::FatMachOHandle)
Expand Down
2 changes: 1 addition & 1 deletion src/MachO/MachOHandle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function readmeta(io::IO,::Type{MachOHandle})

# Unpack the header
header = unpack(io, header_type, endianness)
return MachOHandle(io, Int64(start), header, path(io))
return [MachOHandle(io, Int64(start), header, path(io))]
end

## IOStream-like operations:
Expand Down
44 changes: 25 additions & 19 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ using Test
mktempdir() do dir
fpath = joinpath(dir, "empty")
touch(fpath)
@test_throws MagicMismatch readmeta(fpath) do oh
@test_throws MagicMismatch readmeta(fpath) do ohs
@test false
end
end
end

function test_libfoo_and_fooifier(fooifier_path, libfoo_path)
# Actually read it in
oh_exe = readmeta(open(fooifier_path, "r"))
oh_lib = readmeta(open(libfoo_path, "r"))
oh_exe = only(readmeta(open(fooifier_path, "r")))
oh_lib = only(readmeta(open(libfoo_path, "r")))

# Tease out some information from the containing folder name
dir_path = basename(dirname(libfoo_path))
Expand Down Expand Up @@ -158,28 +158,31 @@ function test_libfoo_and_fooifier(fooifier_path, libfoo_path)
end

function test_fat_libfoo(file)
oh = readmeta(open(file, "r"))
@test isa(oh, FatMachOHandle)
local (ntotal, n64) = (0, 0)
for coh in oh
ohs = readmeta(open(file, "r"))
@test isa(ohs, FatMachOHandle)
@test length(ohs) == 2
ntotal, n64 = 0, 0
for oh in ohs
ntotal += 1
n64 += is64bit(coh)
n64 += is64bit(oh)
end
@test ntotal == 2
@test n64 == 1
end

function test_metal(file)
oh = readmeta(open(file, "r"))
@test isa(oh, FatMachOHandle)
@test length(oh) == 2
ohs = readmeta(open(file, "r"))
@test isa(ohs, FatMachOHandle)
@test length(ohs) == 2

arch = oh[1]
@test arch.header isa MachO.MachOHeader64
@test findfirst(Sections(arch), "__TEXT,__compute") !== nothing
let oh = ohs[1]
@test oh.header isa MachO.MachOHeader64
@test findfirst(Sections(oh), "__TEXT,__compute") !== nothing
end

arch = oh[2]
@test arch.header isa MachO.MetallibHeader
let oh = ohs[2]
@test oh.header isa MachO.MetallibHeader
end
end

# Run ELF tests
Expand All @@ -202,7 +205,8 @@ test_libfoo_and_fooifier("./win64/fooifier.exe", "./win64/libfoo.dll")

# Extract all pieces of `.gnu.version_d` from libstdc++.so, find the `GLIBCXX_*`
# symbols, and use the maximum version of that to find the GLIBCXX ABI version number
version_symbols = readmeta(libstdcxx_path) do oh
version_symbols = readmeta(libstdcxx_path) do ohs
oh = only(ohs)
unique(vcat((x -> x.names).(ObjectFile.ELF.ELFVersionData(oh))...))
end
version_symbols = filter(x -> startswith(x, "GLIBCXX_"), version_symbols)
Expand All @@ -216,7 +220,8 @@ end
# Test that 6a66694a8dd5ca85bd96fe6236f21d5b183e7de6 fix worked
libmsobj_path = "./win32/msobj140.dll"

dynamic_links = readmeta(libmsobj_path) do oh
dynamic_links = readmeta(libmsobj_path) do ohs
oh = only(ohs)
path.(DynamicLinks(oh))
end

Expand All @@ -226,7 +231,8 @@ end
@test "api-ms-win-crt-runtime-l1-1-0.dll" in dynamic_links

whouses_exe = "./win32/WhoUses.exe"
dynamic_links = readmeta(whouses_exe) do oh
dynamic_links = readmeta(whouses_exe) do ohs
oh = only(ohs)
path.(DynamicLinks(oh))
end

Expand Down

0 comments on commit e93e130

Please sign in to comment.