Skip to content

Commit 95522d7

Browse files
committed
Initial Functionality
1 parent 7247f44 commit 95522d7

File tree

1 file changed

+185
-1
lines changed

1 file changed

+185
-1
lines changed

src/ObjFileBase.jl

Lines changed: 185 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,189 @@
11
module ObjFileBase
22

3-
# package code goes here
3+
export ObjectHandle, SectionRef, SymbolRef
4+
5+
import Base: read, seek, readbytes, position
6+
7+
########## ObjFileBase.jl - Basic shared functionality for all object files ####
8+
#
9+
# This package provides basic functionality that is shared among object files.
10+
# It was written with ELF/MachO/COFF in mind, but should be easily adaptable
11+
# to other object files as well.
12+
#
13+
# The family of Object file implementations have a somewhat different focus than
14+
# a lot of other ones. While certainly usable to write a linker or compiler,
15+
# they are more intended for interactive exploration and verification and some
16+
# of the design choices reflect this. Nevertheless, this does not mean that
17+
# performance should be unnecessarily compromised.
18+
#
19+
# # # Basic Concepts
20+
#
21+
# # ObjectHandle
22+
#
23+
# Provides an abstraction over a specific instance of the object file.
24+
# Currently many implementations put the IO object to be read from in this
25+
# handle, which has proven convenient for interactive usage.
26+
#
27+
# # SectionIterator, SymbolIterator, etc.
28+
#
29+
# Provides support for iterating over Symbols, Sections, Relocations, etc.
30+
# These should have a reference to the original ObjectHandle and read the
31+
# desired information on demand. Rather than returning the read datastructure
32+
# directly, it should return in in an appropriate *Ref object.
33+
#
34+
# # SetionRef, SymbolRef
35+
#
36+
# Convenience objects (mostly for interactive usage) that contain a reference
37+
# to the original object handle as well as any information that may be needed
38+
# to get further information about the Referenced object that is not
39+
# explicitly encoded in the data structure itself. Examples may include:
40+
#
41+
# - Offset in the file (especially for variable length records
42+
# where only the header is part of the datastructure)
43+
# - Symbol/Section index
44+
# - Etc.
45+
#
46+
################################################################################
47+
48+
# # # Tools
49+
50+
macro mustimplement(sig)
51+
fname = sig.args[1]
52+
arg1 = sig.args[2]
53+
if isa(arg1,Expr)
54+
arg1 = arg1.args[1]
55+
end
56+
:($(esc(sig)) = error(typeof($(esc(arg1))),
57+
" must implement ", $(Expr(:quote,fname))))
58+
end
59+
60+
################################# Interfaces ###################################
61+
62+
# # # ObjectHandle
63+
64+
abstract ObjectHandle
65+
66+
# External facing interface
67+
readmeta{T<:ObjectHandle}(io::IO, ::Type{T}) =
68+
error("$T must register a readmeta method")
69+
70+
@mustimplement readheader(oh::ObjectHandle)
71+
72+
# Querying general properties
73+
@mustimplement endianness(oh::ObjectHandle)
74+
75+
# ObjectHandle IO interface
76+
@mustimplement seek(oh::ObjectHandle, args...)
77+
@mustimplement position(oh::ObjectHandle)
78+
79+
##
80+
# These are parameterized on the type of Object Handle. An imaginary Foo
81+
# fileformat might declare:
82+
#
83+
# module Foo
84+
# immutable FooHandle; ... end
85+
# immutable Section <: ObjFileBase.Section{FooHandle}
86+
# ...; end
87+
# end
88+
##
89+
90+
abstract SectionRef{T<:ObjectHandle}
91+
abstract Section{T<:ObjectHandle}
92+
93+
# The size of the actual data contained in the section. This should exclude any
94+
# padding mandated by the file format e.g. due to alignment rules
95+
@mustimplement sectionsize(section::Section)
96+
97+
# The offset of the section in the file
98+
@mustimplement sectionoffset(section::Section)
99+
100+
# Retrieving the actual section datastructure
101+
@mustimplement deref(section::SectionRef)
102+
103+
# Retrieving the object handle
104+
@mustimplement handle(section::SectionRef)
105+
106+
abstract SymbolRef{T<:ObjectHandle}
107+
abstract SymtabEntry{T<:ObjectHandle}
108+
109+
################################# Utilities ####################################
110+
111+
typealias SectionOrRef{T} Union(Section{T},SectionRef{T})
112+
113+
sectionsize(sect::SectionRef) = sectionsize(deref(sect))
114+
sectionoffset(sect::SectionRef) = sectionoffset(deref(sect))
115+
116+
seek{T<:ObjectHandle}(oh::T, section::Section{T}) =
117+
seek(oh,sectionoffset(section))
118+
119+
seek(section::SectionRef) = seek(handle(section), deref(section))
120+
121+
function readbytes{T<:ObjectHandle}(oh::T,sec::Section{T})
122+
seek(oh, sec)
123+
readbytes(oh, sectionsize(sec))
124+
end
125+
readbytes(sec::SectionRef) = readbytes(handle(sec),deref(sec))
126+
127+
# # # DWARF support
128+
#
129+
# Whether or not this is the right place to put this is up for debate, but
130+
# this way, DWARF does not need to be concerned with the specific notion of
131+
# being embedded in an object file.
132+
#
133+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
134+
135+
using DWARF
136+
137+
@mustimplement debugsections(oh::ObjectHandle)
138+
139+
function read{T<:ObjectHandle}(oh::T,sec::Section{T},::Type{DWARF.ARTable})
140+
seek(oh, sec)
141+
ret = DWARF.ARTable(Array(DWARF.ARTableSet,0))
142+
while position(oh) < sectionoffset(sec) + sectionsize(sec)
143+
push!(ret.sets, read(oh, DWARF.ARTableSet, endianness(oh)))
144+
end
145+
ret
146+
end
147+
148+
function read{T<:ObjectHandle}(oh::T,sec::Section{T},::Type{DWARF.PUBTable})
149+
seek(oh, sec)
150+
ret = DWARF.PUBTable(Array(DWARF.PUBTableSet,0))
151+
while position(oh) < sectionoffset(sec) + sectionsize(sec)
152+
push!(ret.sets,read(oh,DWARF.PUBTableSet, endianness(oh)))
153+
end
154+
ret
155+
end
156+
157+
function read{T<:ObjectHandle}(oh::T, sec::Section{T},
158+
::Type{DWARF.AbbrevTableSet})
159+
seek(oh, sec)
160+
read(oh, AbbrevTableSet, endianness(oh))
161+
end
162+
163+
function read{T<:ObjectHandle}(oh::T,sec::Section{T},
164+
s::DWARF.PUBTableSet,::Type{DWARF.DWARFCUHeader})
165+
166+
seek(oh,sectionoffsect(debug_info)+s.header.debug_info_offset)
167+
read(oh,DWARF.DWARFCUHeader, endianness(oh))
168+
end
169+
170+
function read{T<:ObjectHandle}(oh::T, sec::Section{T}, s::DWARF.DWARFCUHeader,
171+
::Type{DWARF.AbbrevTableSet})
172+
173+
seek(oh,sectionoffsect(debug_info)+s.debug_abbrev_offset)
174+
read(oh,DWARF.AbbrevTableSet, endianness(oh))
175+
end
176+
177+
function read{T<:ObjectHandle}(oh::T,
178+
debug_info::Section{T}, debug_abbrev::Section{T},
179+
s::DWARF.PUBTableSet, e::DWARF.PUBTableEntry,
180+
header::DWARF.DWARFCUHeader, ::Type{DWARF.DIETree})
181+
182+
ats = read(oh,debug_abbrev,header,DWARF.AbbrevTableSet)
183+
seek(oh,sectionoffset(offset)+s.header.debug_info_offset+e.offset)
184+
ret = DWARF.DIETree(Array(DWARF.DIETreeNode,0))
185+
read(oh,header,ats,ret,DWARF.DIETreeNode,:LittleEndian)
186+
ret
187+
end
4188

5189
end # module

0 commit comments

Comments
 (0)