Skip to content

Commit 1aec417

Browse files
committed
Generic readmeta
1 parent 95522d7 commit 1aec417

File tree

1 file changed

+153
-18
lines changed

1 file changed

+153
-18
lines changed

src/ObjFileBase.jl

Lines changed: 153 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module ObjFileBase
22

33
export ObjectHandle, SectionRef, SymbolRef
44

5-
import Base: read, seek, readbytes, position
5+
import Base: read, seek, readbytes, position, show
66

77
########## ObjFileBase.jl - Basic shared functionality for all object files ####
88
#
@@ -106,19 +106,23 @@ abstract Section{T<:ObjectHandle}
106106
abstract SymbolRef{T<:ObjectHandle}
107107
abstract SymtabEntry{T<:ObjectHandle}
108108

109+
handleT{T}(::Union(Type{SectionRef{T}}, Type{Section{T}}, Type{SymbolRef{T}},
110+
Type{SymtabEntry{T}})) = T
111+
109112
################################# Utilities ####################################
110113

111114
typealias SectionOrRef{T} Union(Section{T},SectionRef{T})
112115

113116
sectionsize(sect::SectionRef) = sectionsize(deref(sect))
114117
sectionoffset(sect::SectionRef) = sectionoffset(deref(sect))
115118

116-
seek{T<:ObjectHandle}(oh::T, section::Section{T}) =
117-
seek(oh,sectionoffset(section))
119+
seek{T<:ObjectHandle,S}(oh::T, section::Section{S}) =
120+
(@assert T <: S; seek(oh,sectionoffset(section)))
118121

119122
seek(section::SectionRef) = seek(handle(section), deref(section))
120123

121-
function readbytes{T<:ObjectHandle}(oh::T,sec::Section{T})
124+
function readbytes{T<:ObjectHandle,S}(oh::T,sec::Section{S})
125+
@assert T <: S
122126
seek(oh, sec)
123127
readbytes(oh, sectionsize(sec))
124128
end
@@ -134,9 +138,8 @@ readbytes(sec::SectionRef) = readbytes(handle(sec),deref(sec))
134138

135139
using DWARF
136140

137-
@mustimplement debugsections(oh::ObjectHandle)
138-
139-
function read{T<:ObjectHandle}(oh::T,sec::Section{T},::Type{DWARF.ARTable})
141+
function read{T<:ObjectHandle,S}(oh::T,sec::Section{S},::Type{DWARF.ARTable})
142+
@assert T <: S
140143
seek(oh, sec)
141144
ret = DWARF.ARTable(Array(DWARF.ARTableSet,0))
142145
while position(oh) < sectionoffset(sec) + sectionsize(sec)
@@ -145,7 +148,8 @@ function read{T<:ObjectHandle}(oh::T,sec::Section{T},::Type{DWARF.ARTable})
145148
ret
146149
end
147150

148-
function read{T<:ObjectHandle}(oh::T,sec::Section{T},::Type{DWARF.PUBTable})
151+
function read{T<:ObjectHandle,S}(oh::T,sec::Section{S},::Type{DWARF.PUBTable})
152+
@assert T <: S
149153
seek(oh, sec)
150154
ret = DWARF.PUBTable(Array(DWARF.PUBTableSet,0))
151155
while position(oh) < sectionoffset(sec) + sectionsize(sec)
@@ -154,36 +158,167 @@ function read{T<:ObjectHandle}(oh::T,sec::Section{T},::Type{DWARF.PUBTable})
154158
ret
155159
end
156160

157-
function read{T<:ObjectHandle}(oh::T, sec::Section{T},
161+
function read{T<:ObjectHandle,S}(oh::T, sec::Section{S},
158162
::Type{DWARF.AbbrevTableSet})
163+
@assert T <: S
159164
seek(oh, sec)
160165
read(oh, AbbrevTableSet, endianness(oh))
161166
end
162167

163-
function read{T<:ObjectHandle}(oh::T,sec::Section{T},
168+
function read{T<:ObjectHandle,S}(oh::T,debug_info::Section{S},
164169
s::DWARF.PUBTableSet,::Type{DWARF.DWARFCUHeader})
165-
166-
seek(oh,sectionoffsect(debug_info)+s.header.debug_info_offset)
170+
@assert T <: S
171+
seek(oh,sectionoffset(debug_info)+s.header.debug_info_offset)
167172
read(oh,DWARF.DWARFCUHeader, endianness(oh))
168173
end
169174

170-
function read{T<:ObjectHandle}(oh::T, sec::Section{T}, s::DWARF.DWARFCUHeader,
175+
function read{T<:ObjectHandle,S}(oh::T, debug_info::Section{S}, s::DWARF.DWARFCUHeader,
171176
::Type{DWARF.AbbrevTableSet})
172-
173-
seek(oh,sectionoffsect(debug_info)+s.debug_abbrev_offset)
177+
@assert T <: S
178+
seek(oh,sectionoffset(debug_info)+s.debug_abbrev_offset)
174179
read(oh,DWARF.AbbrevTableSet, endianness(oh))
175180
end
176181

177-
function read{T<:ObjectHandle}(oh::T,
178-
debug_info::Section{T}, debug_abbrev::Section{T},
182+
function read{T<:ObjectHandle,S}(oh::T,
183+
debug_info::Section{S}, debug_abbrev::Section{S},
179184
s::DWARF.PUBTableSet, e::DWARF.PUBTableEntry,
180185
header::DWARF.DWARFCUHeader, ::Type{DWARF.DIETree})
181186

187+
@assert T <: S
182188
ats = read(oh,debug_abbrev,header,DWARF.AbbrevTableSet)
183-
seek(oh,sectionoffset(offset)+s.header.debug_info_offset+e.offset)
189+
seek(oh,sectionoffset(debug_info)+s.header.debug_info_offset+e.offset)
184190
ret = DWARF.DIETree(Array(DWARF.DIETreeNode,0))
185191
read(oh,header,ats,ret,DWARF.DIETreeNode,:LittleEndian)
186192
ret
187193
end
188194

195+
typealias Maybe{T} Union(T,Nothing)
196+
197+
# # # Higher level debug info support
198+
immutable DebugSections{T<:ObjectHandle, Sect}
199+
oh::T
200+
debug_abbrev::Maybe{Sect}
201+
debug_aranges::Maybe{Sect}
202+
debug_frame::Maybe{Sect}
203+
debug_info::Maybe{Sect}
204+
debug_line::Maybe{Sect}
205+
debug_loc::Maybe{Sect}
206+
debug_macinfo::Maybe{Sect}
207+
debug_pubnames::Maybe{Sect}
208+
debug_ranges::Maybe{Sect}
209+
debug_str::Maybe{Sect}
210+
debug_types::Maybe{Sect}
211+
212+
end
213+
214+
function DebugSections{T}(oh::T; debug_abbrev = nothing, debug_aranges = nothing,
215+
debug_frame = nothing, debug_info = nothing, debug_line = nothing,
216+
debug_macinfo = nothing, debug_pubnames = nothing, debug_loc= nothing,
217+
debug_ranges = nothing, debug_str = nothing, debug_types = nothing)
218+
DebugSections(oh, debug_abbrev, debug_aranges, debug_frame, debug_info,
219+
debug_line, debug_loc, debug_macinfo, debug_pubnames, debug_ranges,
220+
debug_pubnames, debug_ranges)
221+
end
222+
223+
function DebugSections{T<:ObjectHandle}(oh::T, sections::Dict)
224+
DebugSections(oh,
225+
debug_abbrev = get(sections, "debug_abbrev", nothing),
226+
debug_aranges = get(sections, "debug_aranges", nothing),
227+
debug_frame = get(sections, "debug_frame", nothing),
228+
debug_info = get(sections, "debug_info", nothing),
229+
debug_line = get(sections, "debug_line", nothing),
230+
debug_loc = get(sections, "debug_loc", nothing),
231+
debug_macinfo = get(sections, "debug_macinfo", nothing),
232+
debug_pubnames = get(sections, "debug_pubnames", nothing),
233+
debug_ranges = get(sections, "debug_ranges", nothing),
234+
debug_str = get(sections, "debug_str", nothing),
235+
debug_types = get(sections, "debug_types", nothing))
236+
end
237+
238+
function show(io::IO, dsect::DebugSections)
239+
println(io, "Debug Sections for $(dsect.oh)")
240+
println(io,"========================= debug_abbrev =========================")
241+
println(io,dsect.debug_abbrev)
242+
println(io,"======================== debug_aranges =========================")
243+
println(io,dsect.debug_aranges)
244+
println(io,"========================= debug_frame ==========================")
245+
println(io,dsect.debug_frame)
246+
println(io,"========================= debug_info ===========================")
247+
println(io,dsect.debug_info)
248+
println(io,"========================= debug_line ===========================")
249+
println(io,dsect.debug_line)
250+
println(io,"========================== debug_loc ===========================")
251+
println(io,dsect.debug_loc)
252+
println(io,"======================== debug_macinfo =========================")
253+
println(io,dsect.debug_macinfo)
254+
println(io,"======================= debug_pubnames =========================")
255+
println(io,dsect.debug_pubnames)
256+
println(io,"======================== debug_ranges ==========================")
257+
println(io,dsect.debug_ranges)
258+
println(io,"=========================== debug_str ==========================")
259+
println(io,dsect.debug_str)
260+
println(io,"========================= debug_types ==========================")
261+
println(io,dsect.debug_types)
262+
end
263+
264+
@mustimplement debugsections(oh::ObjectHandle)
265+
266+
export findindexbyname, findcubyname
267+
268+
function findindexbyname(x::DebugSections,name;
269+
pubtable=read(x.oh, deref(x.debug_pubnames), DWARF.PUBTable))
270+
symbols = map(y->map(x->x.name,y.entries),pubtable.sets)
271+
for i = 1:length(symbols)
272+
ind = findfirst(symbols[i],name)
273+
if ind != 0
274+
return (i,ind)
275+
end
276+
end
277+
return (0,0)
278+
end
279+
280+
function findcubyname(x::DebugSections, name;
281+
pubtable = read(x.oh, deref(x.debug_pubnames), DWARF.PUBTable))
282+
(si,ei) = findindexbyname(x, name; pubtable = pubtable)
283+
if si == ei == 0
284+
error("Not Found")
285+
end
286+
read(x.oh,deref(x.debug_info),pubtable.sets[si],DWARF.DWARFCUHeader)
287+
end
288+
289+
function finddietreebyname(x::DebugSections, name;
290+
pubtable = read(x.oh, deref(x.debug_pubnames), DWARF.PUBTable))
291+
(si,ei) = findindexbyname(x, name; pubtable = pubtable)
292+
if si == ei == 0
293+
error("Not Found")
294+
end
295+
pubset = pubtable.sets[si]
296+
pubentry = pubset.entries[ei]
297+
cu = read(x.oh,deref(x.debug_info),pubset,DWARF.DWARFCUHeader)
298+
d = read(x.oh,deref(x.debug_info),deref(x.debug_abbrev),pubset,pubentry,
299+
cu,DWARF.DIETree)
300+
end
301+
302+
303+
# User facing interfaces
304+
305+
function readmeta(io::IO)
306+
ts = subtypes(ObjFileBase.ObjectHandle)
307+
for T in ts
308+
try
309+
return readmeta(io, T)
310+
catch
311+
end
312+
end
313+
error("""
314+
Object file is not any of $(join(ts, ", "))!
315+
To force one object file use readmeta(io,T).
316+
If the format you want is not listed, make sure
317+
the appropriate pacakge is loaded before calling
318+
this function.
319+
""")
320+
end
321+
322+
readmeta(file::String) = readmeta(open(file,"r"))
323+
189324
end # module

0 commit comments

Comments
 (0)