File tree Expand file tree Collapse file tree 4 files changed +81
-0
lines changed Expand file tree Collapse file tree 4 files changed +81
-0
lines changed Original file line number Diff line number Diff line change @@ -30,6 +30,7 @@ include("ELFSegment.jl")
30
30
include (" ELFSymbol.jl" )
31
31
include (" ELFDynEntry.jl" )
32
32
include (" ELFDynamicLink.jl" )
33
+ include (" ELFVersion.jl" )
33
34
34
35
# Holdovers from ObjFileBase that I haven't cleaned up yet
35
36
# 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 162
162
# Run COFF tests
163
163
test_libfoo_and_fooifier (" ./win32/fooifier.exe" , " ./win32/libfoo.dll" )
164
164
test_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