From e93e13089753a14a13b21982b2b2ee4b71a7ca86 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Wed, 5 Apr 2023 15:08:56 +0200 Subject: [PATCH] Rework readmeta to always return a collection of handles. --- src/COFF/COFFHandle.jl | 4 ++-- src/ELF/ELFHandle.jl | 4 ++-- src/MachO/MachOFat.jl | 2 +- src/MachO/MachOHandle.jl | 2 +- test/runtests.jl | 44 +++++++++++++++++++++++----------------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/COFF/COFFHandle.jl b/src/COFF/COFFHandle.jl index 4fde81b..ac28f26 100644 --- a/src/COFF/COFFHandle.jl +++ b/src/COFF/COFFHandle.jl @@ -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 @@ -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 diff --git a/src/ELF/ELFHandle.jl b/src/ELF/ELFHandle.jl index a4f0141..afcfbea 100644 --- a/src/ELF/ELFHandle.jl +++ b/src/ELF/ELFHandle.jl @@ -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 @@ -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 diff --git a/src/MachO/MachOFat.jl b/src/MachO/MachOFat.jl index 6d2546b..638f11d 100644 --- a/src/MachO/MachOFat.jl +++ b/src/MachO/MachOFat.jl @@ -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) diff --git a/src/MachO/MachOHandle.jl b/src/MachO/MachOHandle.jl index 823797f..648a2dc 100644 --- a/src/MachO/MachOHandle.jl +++ b/src/MachO/MachOHandle.jl @@ -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: diff --git a/test/runtests.jl b/test/runtests.jl index 4e30253..c9b0039 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,7 +6,7 @@ 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 @@ -14,8 +14,8 @@ 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)) @@ -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 @@ -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) @@ -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 @@ -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