-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathELFSection.jl
122 lines (102 loc) · 3.3 KB
/
ELFSection.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
export ELFSections, ELFSection, ELFSection32, ELFSection64, ELFSectionRef
# Export certain extensions to the base API
export section_type
"""
ELFSections
ELF Section header table type, containing information about the number of
sections within the ELF object, the location of the section headers, etc...
"""
struct ELFSections{H <: ELFHandle} <: Sections{ELFHandle}
handle::H
end
Sections(oh::ELFHandle) = ELFSections(oh)
# Implement Sections API
handle(sections::ELFSections) = sections.handle
function lastindex(sections::ELFSections)
head = header(handle(sections))
head.e_shoff == 0 && return 0
if head.e_shnum == 0
# Large section extension. Number of sections is actually stored in the
# sh_size field of the undef section
seek(handle(sections), head.e_shoff)
return unpack(handle(sections), section_header_type(handle(sections))).sh_size - 1
end
# Exclude the SHT_NULL section
return head.e_shnum - 1
end
"""
ELFSection
ELF Section type, containing information about a `Section` within the ELF
object, such as the `Section`'s name, its size, etc...
"""
abstract type ELFSection{H <: ELFHandle} <: Section{H} end
@io struct ELFSection32{H <: ELFHandle} <: ELFSection{H}
sh_name::UInt32
sh_type::UInt32
sh_flags::UInt32
sh_addr::UInt32
sh_offset::UInt32
sh_size::UInt32
sh_link::UInt32
sh_info::UInt32
sh_addralign::UInt32
sh_entsize::UInt32
end
@io struct ELFSection64{H <: ELFHandle} <: ELFSection{H}
sh_name::UInt32
sh_type::UInt32
sh_flags::UInt64
sh_addr::UInt64
sh_offset::UInt64
sh_size::UInt64
sh_link::UInt32
sh_info::UInt32
sh_addralign::UInt64
sh_entsize::UInt64
end
# Implement Section API
function read(oh::ELFHandle, ::Type{ST}) where {ST <: ELFSection}
type_func = section_header_type
size_func = section_header_size
return read_struct(oh, type_func, size_func, "Section Header")
end
section_name(s::ELFSection) = string("strtab@", s.sh_name)
section_type(s::ELFSection) = s.sh_type
section_size(s::ELFSection) = s.sh_size
section_offset(s::ELFSection) = s.sh_offset
section_address(s::ELFSection) = s.sh_addr
"""
ELFSectionRef
ELF `SectionRef` type, containing an `ELFSection` and important metadata.
"""
struct ELFSectionRef{H<:ELFHandle} <: SectionRef{H}
sections::ELFSections{H}
section::ELFSection{H}
idx::UInt32
end
function SectionRef(sections::ELFSections, s::ELFSection, idx)
return ELFSectionRef(sections, s, UInt32(idx))
end
deref(s::ELFSectionRef) = s.section
sections(s::ELFSectionRef) = s.sections
handle(s::ELFSectionRef) = handle(sections(s))
section_number(s::ELFSectionRef) = s.idx
@derefmethod section_type(s::ELFSectionRef)
function section_name(section::ELFSectionRef)
# Actually do the strtab lookup to get the name of this guy
strtab = StrTab(handle(section))
return strtab_lookup(strtab, deref(section).sh_name)
end
"""
section_type_string(s::ELFSection)
Return the given `ELFSection`'s section type as a string.
"""
function section_type_string(s::ELFSection)
global SHT_TYPES
sh_type = section_type(s)
if haskey(SHT_TYPES, sh_type)
return SHT_TYPES[sh_type]
end
return string("Unknown Section Type (0x", string(sh_type, base=16), ")")
end
@derefmethod section_type_string(s::ELFSectionRef)