-
Notifications
You must be signed in to change notification settings - Fork 0
/
binarycode.vala
220 lines (191 loc) · 5.6 KB
/
binarycode.vala
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/* binarycode.vala
*
* Copyright (C) 2010 Luca Bruno
*
* This file is part of Mipsdis.
*
* Mipsdis is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Mipsdis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Mipsdis. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Luca Bruno <lethalman88@gmail.com>
*/
namespace Mips
{
public class BinaryCode
{
public AddressMapping address_mapping;
public SymbolTable symbol_table;
public StringTable string_table;
public TextSection text_section;
public StringTable readonly_data;
public PltTable plt_table;
}
public abstract class BinaryReference
{
public virtual string to_string () { return "(unnamed reference)"; }
}
public class AddressMapping
{
private ProgramHeader[] headers;
public void add_header (ProgramHeader header)
requires (header.type == ProgramHeader.Type.LOAD)
{
headers += header;
}
public bool has_physical_address (uint virtual_address)
{
foreach (var header in headers)
{
if (virtual_address >= header.virtual_addr && virtual_address <= (header.virtual_addr + header.file_size))
return true;
}
return false;
}
public uint get_physical_address (uint virtual_address)
{
foreach (var header in headers)
{
if (virtual_address >= header.virtual_addr && virtual_address <= (header.virtual_addr + header.file_size))
return virtual_address - header.virtual_addr + header.offset;
}
warning ("Unable to resolve virtual address to physical address: %p", (void*)(long)virtual_address);
return virtual_address;
}
public uint get_virtual_base_address (uint virtual_address)
{
foreach (var header in headers)
{
if (virtual_address >= header.virtual_addr && virtual_address <= (header.virtual_addr + header.file_size))
return header.virtual_addr;
}
warning ("Unable to resolve virtual address to physical address: %p", (void*)(long)virtual_address);
return virtual_address;
}
public uint get_last_address ()
{
ProgramHeader last_header = headers[0];
for (int i=1; i < headers.length; i++)
{
if (headers[i].offset > last_header.offset)
last_header = headers[i];
}
return last_header.offset + last_header.file_size;
}
}
public class TextSection
{
public uint file_offset;
public uint virtual_address;
public BinaryInstruction[] binary_instructions;
private int binary_instructions_size;
public TextSection (uint file_offset, uint virtual_address)
{
this.file_offset = file_offset;
this.virtual_address = virtual_address;
}
public void set_instructions (int n)
{
binary_instructions = new BinaryInstruction[n];
binary_instructions_size = 0;
}
public void add_instruction (BinaryInstruction inst)
{
binary_instructions[binary_instructions_size++] = inst;
}
public BinaryInstruction? instruction_at_address (uint virtual_address)
{
if (virtual_address < this.virtual_address)
return null;
var index = (virtual_address - this.virtual_address) / 4;
if (index > binary_instructions.length)
return null;
return binary_instructions[index];
}
}
public class BinaryObject : BinaryReference
{
public string name;
public BinaryObject (string name)
{
this.name = name;
}
public override string to_string ()
{
return name;
}
}
public class BinaryInstruction : BinaryReference
{
public Instruction instruction;
public uint file_offset;
public uint file_value;
public uint virtual_address;
public string label;
public bool is_func_start;
public BinaryInstruction (Instruction instruction, uint file_offset, uint file_value, uint virtual_address)
{
this.instruction = instruction;
this.file_offset = file_offset;
this.file_value = file_value;
this.virtual_address = virtual_address;
}
public override string to_string ()
{
if (label != null)
{
if (is_func_start)
return @"<$(label)>";
else
return label;
}
else
return base.to_string ();
}
}
public class BinaryString : BinaryReference
{
public uint file_offset;
public string str;
public BinaryString (uint file_offset, string str)
{
this.file_offset = file_offset;
this.str = str;
}
public override string to_string ()
{
return "%p: '%s'".printf ((void*)(long)file_offset, str);
}
}
public class BinaryAddress : BinaryReference
{
public uint address;
public BinaryAddress (uint address)
{
this.address = address;
}
public override string to_string ()
{
return "%p".printf ((void*)(long)address);
}
}
public class BinaryPltInitial : BinaryAddress
{
public BinaryPltInitial (uint address)
{
base (address);
}
public override string to_string ()
{
return "Initial: %p".printf ((void*)(long)address);
}
}
}