File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -30,6 +30,7 @@ include("ELFSegment.jl")
3030include (" ELFSymbol.jl" )
3131include (" ELFDynEntry.jl" )
3232include (" ELFDynamicLink.jl" )
33+ include (" ELFVersion.jl" )
3334
3435# Holdovers from ObjFileBase that I haven't cleaned up yet
3536# include("ELFRelocation.jl")
Original file line number Diff line number Diff line change 1+ export ELFVersionData
2+
3+ # Special ELF version data structures
4+ @io struct ELFVerDef{H <: ELFHandle }
5+ vd_version:: UInt16
6+ vd_flags:: UInt16
7+ vd_ndx:: UInt16
8+ vd_cnt:: UInt16
9+ vd_hash:: UInt32
10+ vd_aux:: UInt32
11+ vd_next:: UInt32
12+ end
13+
14+ @io struct ELFVerdAux{H <: ELFHandle }
15+ vda_name:: UInt32
16+ vda_next:: UInt32
17+ end
18+
19+ @io struct ELFVerNeed{H <: ELFHandle }
20+ vn_version:: UInt16
21+ vn_cnt:: UInt16
22+ vn_file:: UInt16
23+ vn_aux:: UInt32
24+ vn_next:: UInt32
25+ end
26+
27+ struct ELFVersionEntry{H <: ELFHandle }
28+ ver_def:: ELFVerDef{H}
29+ names:: Vector{String}
30+ end
31+
32+ function ELFVersionData (oh:: H ) where {H <: ELFHandle }
33+ s = findfirst (Sections (oh), " .gnu.version_d" )
34+ strtab = StrTab (findfirst (Sections (oh), " .dynstr" ))
35+
36+ # Queue oh up to the beginning of this section
37+ seek (oh, section_offset (s))
38+
39+ # Read out ALL OF THE version definitions
40+ version_defs = ELFVersionEntry[]
41+ while true
42+ vd_pos = position (oh)
43+ vd = unpack (oh, ELFVerDef{H})
44+
45+ # Find aux names and resolve immediately to strings
46+ auxes = String[]
47+ aux_offset = 0
48+ for aux_idx in 1 : vd. vd_cnt
49+ seek (oh, vd_pos + vd. vd_aux + aux_offset)
50+ aux = unpack (oh, ELFVerdAux{H})
51+ name = strtab_lookup (strtab, aux. vda_name)
52+ push! (auxes, name)
53+ aux_offset += aux. vda_next
54+ end
55+
56+ push! (version_defs, ELFVersionEntry (vd, auxes))
57+
58+ if vd. vd_next == 0
59+ break
60+ end
61+ seek (oh, vd_pos + vd. vd_next)
62+ end
63+
64+ return version_defs
65+ end
Original file line number Diff line number Diff line change 162162# Run COFF tests
163163test_libfoo_and_fooifier (" ./win32/fooifier.exe" , " ./win32/libfoo.dll" )
164164test_libfoo_and_fooifier (" ./win64/fooifier.exe" , " ./win64/libfoo.dll" )
165+
166+
167+ # Ensure that ELF version stuff works
168+ @testset " ELF Version Info Parsing" begin
169+ libstdcxx_path = " ./linux64/libstdc++.so.6"
170+
171+ # Extract all pieces of `.gnu.version_d` from libstdc++.so, find the `GLIBCXX_*`
172+ # symbols, and use the maximum version of that to find the GLIBCXX ABI version number
173+ version_symbols = readmeta (libstdcxx_path) do oh
174+ unique (vcat ((x -> x. names). (ObjectFile. ELF. ELFVersionData (oh)). .. ))
175+ end
176+ version_symbols = filter (x -> startswith (x, " GLIBCXX_" ), version_symbols)
177+ max_version = maximum ([VersionNumber (split (v, " _" )[2 ]) for v in version_symbols])
178+ @test max_version == v " 3.4.25"
179+ end
You can’t perform that action at this time.
0 commit comments