Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: courgette/disassembler_win32_x86.cc

Issue 1543643002: Switch to standard integer types in courgette/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/disassembler_win32_x86.h ('k') | courgette/disassembler_win32_x86_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "courgette/disassembler_win32_x86.h" 5 #include "courgette/disassembler_win32_x86.h"
6 6
7 #include <stddef.h>
8 #include <stdint.h>
9
7 #include <algorithm> 10 #include <algorithm>
8 #include <string> 11 #include <string>
9 #include <vector> 12 #include <vector>
10 13
11 #include "base/basictypes.h"
12 #include "base/logging.h" 14 #include "base/logging.h"
13 15
14 #include "courgette/assembly_program.h" 16 #include "courgette/assembly_program.h"
15 #include "courgette/courgette.h" 17 #include "courgette/courgette.h"
16 #include "courgette/encoded_program.h" 18 #include "courgette/encoded_program.h"
17 #include "courgette/rel32_finder_win32_x86.h" 19 #include "courgette/rel32_finder_win32_x86.h"
18 20
19 namespace courgette { 21 namespace courgette {
20 22
21 DisassemblerWin32X86::DisassemblerWin32X86(const void* start, size_t length) 23 DisassemblerWin32X86::DisassemblerWin32X86(const void* start, size_t length)
(...skipping 26 matching lines...) Expand all
48 // 50 //
49 bool DisassemblerWin32X86::ParseHeader() { 51 bool DisassemblerWin32X86::ParseHeader() {
50 if (length() < kOffsetOfFileAddressOfNewExeHeader + 4 /*size*/) 52 if (length() < kOffsetOfFileAddressOfNewExeHeader + 4 /*size*/)
51 return Bad("Too small"); 53 return Bad("Too small");
52 54
53 // Have 'MZ' magic for a DOS header? 55 // Have 'MZ' magic for a DOS header?
54 if (start()[0] != 'M' || start()[1] != 'Z') 56 if (start()[0] != 'M' || start()[1] != 'Z')
55 return Bad("Not MZ"); 57 return Bad("Not MZ");
56 58
57 // offset from DOS header to PE header is stored in DOS header. 59 // offset from DOS header to PE header is stored in DOS header.
58 uint32 offset = ReadU32(start(), 60 uint32_t offset = ReadU32(start(), kOffsetOfFileAddressOfNewExeHeader);
59 kOffsetOfFileAddressOfNewExeHeader);
60 61
61 if (offset >= length()) 62 if (offset >= length())
62 return Bad("Bad offset to PE header"); 63 return Bad("Bad offset to PE header");
63 64
64 const uint8* const pe_header = OffsetToPointer(offset); 65 const uint8_t* const pe_header = OffsetToPointer(offset);
65 const size_t kMinPEHeaderSize = 4 /*signature*/ + kSizeOfCoffHeader; 66 const size_t kMinPEHeaderSize = 4 /*signature*/ + kSizeOfCoffHeader;
66 if (pe_header <= start() || 67 if (pe_header <= start() ||
67 pe_header >= end() - kMinPEHeaderSize) 68 pe_header >= end() - kMinPEHeaderSize)
68 return Bad("Bad offset to PE header"); 69 return Bad("Bad offset to PE header");
69 70
70 if (offset % 8 != 0) 71 if (offset % 8 != 0)
71 return Bad("Misaligned PE header"); 72 return Bad("Misaligned PE header");
72 73
73 // The 'PE' header is an IMAGE_NT_HEADERS structure as defined in WINNT.H. 74 // The 'PE' header is an IMAGE_NT_HEADERS structure as defined in WINNT.H.
74 // See http://msdn.microsoft.com/en-us/library/ms680336(VS.85).aspx 75 // See http://msdn.microsoft.com/en-us/library/ms680336(VS.85).aspx
75 // 76 //
76 // The first field of the IMAGE_NT_HEADERS is the signature. 77 // The first field of the IMAGE_NT_HEADERS is the signature.
77 if (!(pe_header[0] == 'P' && 78 if (!(pe_header[0] == 'P' &&
78 pe_header[1] == 'E' && 79 pe_header[1] == 'E' &&
79 pe_header[2] == 0 && 80 pe_header[2] == 0 &&
80 pe_header[3] == 0)) 81 pe_header[3] == 0))
81 return Bad("no PE signature"); 82 return Bad("no PE signature");
82 83
83 // The second field of the IMAGE_NT_HEADERS is the COFF header. 84 // The second field of the IMAGE_NT_HEADERS is the COFF header.
84 // The COFF header is also called an IMAGE_FILE_HEADER 85 // The COFF header is also called an IMAGE_FILE_HEADER
85 // http://msdn.microsoft.com/en-us/library/ms680313(VS.85).aspx 86 // http://msdn.microsoft.com/en-us/library/ms680313(VS.85).aspx
86 const uint8* const coff_header = pe_header + 4; 87 const uint8_t* const coff_header = pe_header + 4;
87 machine_type_ = ReadU16(coff_header, 0); 88 machine_type_ = ReadU16(coff_header, 0);
88 number_of_sections_ = ReadU16(coff_header, 2); 89 number_of_sections_ = ReadU16(coff_header, 2);
89 size_of_optional_header_ = ReadU16(coff_header, 16); 90 size_of_optional_header_ = ReadU16(coff_header, 16);
90 91
91 // The rest of the IMAGE_NT_HEADERS is the IMAGE_OPTIONAL_HEADER(32|64) 92 // The rest of the IMAGE_NT_HEADERS is the IMAGE_OPTIONAL_HEADER(32|64)
92 const uint8* const optional_header = coff_header + kSizeOfCoffHeader; 93 const uint8_t* const optional_header = coff_header + kSizeOfCoffHeader;
93 optional_header_ = optional_header; 94 optional_header_ = optional_header;
94 95
95 if (optional_header + size_of_optional_header_ >= end()) 96 if (optional_header + size_of_optional_header_ >= end())
96 return Bad("optional header past end of file"); 97 return Bad("optional header past end of file");
97 98
98 // Check we can read the magic. 99 // Check we can read the magic.
99 if (size_of_optional_header_ < 2) 100 if (size_of_optional_header_ < 2)
100 return Bad("optional header no magic"); 101 return Bad("optional header no magic");
101 102
102 uint16 magic = ReadU16(optional_header, 0); 103 uint16_t magic = ReadU16(optional_header, 0);
103 104
104 if (magic == kImageNtOptionalHdr32Magic) { 105 if (magic == kImageNtOptionalHdr32Magic) {
105 is_PE32_plus_ = false; 106 is_PE32_plus_ = false;
106 offset_of_data_directories_ = 107 offset_of_data_directories_ =
107 kOffsetOfDataDirectoryFromImageOptionalHeader32; 108 kOffsetOfDataDirectoryFromImageOptionalHeader32;
108 } else if (magic == kImageNtOptionalHdr64Magic) { 109 } else if (magic == kImageNtOptionalHdr64Magic) {
109 is_PE32_plus_ = true; 110 is_PE32_plus_ = true;
110 offset_of_data_directories_ = 111 offset_of_data_directories_ =
111 kOffsetOfDataDirectoryFromImageOptionalHeader64; 112 kOffsetOfDataDirectoryFromImageOptionalHeader64;
112 } else { 113 } else {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 size_t detected_length = 0; 170 size_t detected_length = 0;
170 171
171 for (int i = 0; i < number_of_sections_; ++i) { 172 for (int i = 0; i < number_of_sections_; ++i) {
172 const Section* section = &sections_[i]; 173 const Section* section = &sections_[i];
173 174
174 // TODO(sra): consider using the 'characteristics' field of the section 175 // TODO(sra): consider using the 'characteristics' field of the section
175 // header to see if the section contains instructions. 176 // header to see if the section contains instructions.
176 if (memcmp(section->name, ".text", 6) == 0) 177 if (memcmp(section->name, ".text", 6) == 0)
177 has_text_section_ = true; 178 has_text_section_ = true;
178 179
179 uint32 section_end = 180 uint32_t section_end =
180 section->file_offset_of_raw_data + section->size_of_raw_data; 181 section->file_offset_of_raw_data + section->size_of_raw_data;
181 if (section_end > detected_length) 182 if (section_end > detected_length)
182 detected_length = section_end; 183 detected_length = section_end;
183 } 184 }
184 185
185 // Pretend our in-memory copy is only as long as our detected length. 186 // Pretend our in-memory copy is only as long as our detected length.
186 ReduceLength(detected_length); 187 ReduceLength(detected_length);
187 188
188 if (!is_32bit()) { 189 if (!is_32bit()) {
189 return Bad("64 bit executables are not supported by this disassembler"); 190 return Bad("64 bit executables are not supported by this disassembler");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 223
223 size_t relocs_size = base_relocation_table_.size_; 224 size_t relocs_size = base_relocation_table_.size_;
224 if (relocs_size == 0) 225 if (relocs_size == 0)
225 return true; 226 return true;
226 227
227 // The format of the base relocation table is a sequence of variable sized 228 // The format of the base relocation table is a sequence of variable sized
228 // IMAGE_BASE_RELOCATION blocks. Search for 229 // IMAGE_BASE_RELOCATION blocks. Search for
229 // "The format of the base relocation data is somewhat quirky" 230 // "The format of the base relocation data is somewhat quirky"
230 // at http://msdn.microsoft.com/en-us/library/ms809762.aspx 231 // at http://msdn.microsoft.com/en-us/library/ms809762.aspx
231 232
232 const uint8* relocs_start = RVAToPointer(base_relocation_table_.address_); 233 const uint8_t* relocs_start = RVAToPointer(base_relocation_table_.address_);
233 const uint8* relocs_end = relocs_start + relocs_size; 234 const uint8_t* relocs_end = relocs_start + relocs_size;
234 235
235 // Make sure entire base relocation table is within the buffer. 236 // Make sure entire base relocation table is within the buffer.
236 if (relocs_start < start() || 237 if (relocs_start < start() ||
237 relocs_start >= end() || 238 relocs_start >= end() ||
238 relocs_end <= start() || 239 relocs_end <= start() ||
239 relocs_end > end()) { 240 relocs_end > end()) {
240 return Bad(".relocs outside image"); 241 return Bad(".relocs outside image");
241 } 242 }
242 243
243 const uint8* block = relocs_start; 244 const uint8_t* block = relocs_start;
244 245
245 // Walk the variable sized blocks. 246 // Walk the variable sized blocks.
246 while (block + 8 < relocs_end) { 247 while (block + 8 < relocs_end) {
247 RVA page_rva = ReadU32(block, 0); 248 RVA page_rva = ReadU32(block, 0);
248 uint32 size = ReadU32(block, 4); 249 uint32_t size = ReadU32(block, 4);
249 if (size < 8 || // Size includes header ... 250 if (size < 8 || // Size includes header ...
250 size % 4 != 0) // ... and is word aligned. 251 size % 4 != 0) // ... and is word aligned.
251 return Bad("unreasonable relocs block"); 252 return Bad("unreasonable relocs block");
252 253
253 const uint8* end_entries = block + size; 254 const uint8_t* end_entries = block + size;
254 255
255 if (end_entries <= block || 256 if (end_entries <= block ||
256 end_entries <= start() || 257 end_entries <= start() ||
257 end_entries > end()) 258 end_entries > end())
258 return Bad(".relocs block outside image"); 259 return Bad(".relocs block outside image");
259 260
260 // Walk through the two-byte entries. 261 // Walk through the two-byte entries.
261 for (const uint8* p = block + 8; p < end_entries; p += 2) { 262 for (const uint8_t* p = block + 8; p < end_entries; p += 2) {
262 uint16 entry = ReadU16(p, 0); 263 uint16_t entry = ReadU16(p, 0);
263 int type = entry >> 12; 264 int type = entry >> 12;
264 int offset = entry & 0xFFF; 265 int offset = entry & 0xFFF;
265 266
266 RVA rva = page_rva + offset; 267 RVA rva = page_rva + offset;
267 // Skip the relocs that live outside of the image. It might be the case 268 // Skip the relocs that live outside of the image. It might be the case
268 // if a reloc is relative to a register, e.g.: 269 // if a reloc is relative to a register, e.g.:
269 // mov ecx,dword ptr [eax+044D5888h] 270 // mov ecx,dword ptr [eax+044D5888h]
270 uint32 target_address = Read32LittleEndian(RVAToPointer(rva)); 271 uint32_t target_address = Read32LittleEndian(RVAToPointer(rva));
271 if (target_address < image_base_ || 272 if (target_address < image_base_ ||
272 target_address > (image_base_ + size_of_image_)) { 273 target_address > (image_base_ + size_of_image_)) {
273 continue; 274 continue;
274 } 275 }
275 if (type == 3) { // IMAGE_REL_BASED_HIGHLOW 276 if (type == 3) { // IMAGE_REL_BASED_HIGHLOW
276 relocs->push_back(rva); 277 relocs->push_back(rva);
277 } else if (type == 0) { // IMAGE_REL_BASED_ABSOLUTE 278 } else if (type == 0) { // IMAGE_REL_BASED_ABSOLUTE
278 // Ignore, used as padding. 279 // Ignore, used as padding.
279 } else { 280 } else {
280 // Does not occur in Windows x86 executables. 281 // Does not occur in Windows x86 executables.
281 return Bad("unknown type of reloc"); 282 return Bad("unknown type of reloc");
282 } 283 }
283 } 284 }
284 285
285 block += size; 286 block += size;
286 } 287 }
287 288
288 std::sort(relocs->begin(), relocs->end()); 289 std::sort(relocs->begin(), relocs->end());
289 290
290 return true; 291 return true;
291 } 292 }
292 293
293 const Section* DisassemblerWin32X86::RVAToSection(RVA rva) const { 294 const Section* DisassemblerWin32X86::RVAToSection(RVA rva) const {
294 for (int i = 0; i < number_of_sections_; i++) { 295 for (int i = 0; i < number_of_sections_; i++) {
295 const Section* section = &sections_[i]; 296 const Section* section = &sections_[i];
296 uint32 offset = rva - section->virtual_address; 297 uint32_t offset = rva - section->virtual_address;
297 if (offset < section->virtual_size) { 298 if (offset < section->virtual_size) {
298 return section; 299 return section;
299 } 300 }
300 } 301 }
301 return NULL; 302 return NULL;
302 } 303 }
303 304
304 int DisassemblerWin32X86::RVAToFileOffset(RVA rva) const { 305 int DisassemblerWin32X86::RVAToFileOffset(RVA rva) const {
305 const Section* section = RVAToSection(rva); 306 const Section* section = RVAToSection(rva);
306 if (section) { 307 if (section) {
307 uint32 offset = rva - section->virtual_address; 308 uint32_t offset = rva - section->virtual_address;
308 if (offset < section->size_of_raw_data) { 309 if (offset < section->size_of_raw_data) {
309 return section->file_offset_of_raw_data + offset; 310 return section->file_offset_of_raw_data + offset;
310 } else { 311 } else {
311 return kNoOffset; // In section but not in file (e.g. uninit data). 312 return kNoOffset; // In section but not in file (e.g. uninit data).
312 } 313 }
313 } 314 }
314 315
315 // Small RVA values point into the file header in the loaded image. 316 // Small RVA values point into the file header in the loaded image.
316 // RVA 0 is the module load address which Windows uses as the module handle. 317 // RVA 0 is the module load address which Windows uses as the module handle.
317 // RVA 2 sometimes occurs, I'm not sure what it is, but it would map into the 318 // RVA 2 sometimes occurs, I'm not sure what it is, but it would map into the
318 // DOS header. 319 // DOS header.
319 if (rva == 0 || rva == 2) 320 if (rva == 0 || rva == 2)
320 return rva; 321 return rva;
321 322
322 NOTREACHED(); 323 NOTREACHED();
323 return kNoOffset; 324 return kNoOffset;
324 } 325 }
325 326
326 const uint8* DisassemblerWin32X86::RVAToPointer(RVA rva) const { 327 const uint8_t* DisassemblerWin32X86::RVAToPointer(RVA rva) const {
327 int file_offset = RVAToFileOffset(rva); 328 int file_offset = RVAToFileOffset(rva);
328 if (file_offset == kNoOffset) 329 if (file_offset == kNoOffset)
329 return NULL; 330 return NULL;
330 else 331 else
331 return OffsetToPointer(file_offset); 332 return OffsetToPointer(file_offset);
332 } 333 }
333 334
334 std::string DisassemblerWin32X86::SectionName(const Section* section) { 335 std::string DisassemblerWin32X86::SectionName(const Section* section) {
335 if (section == NULL) 336 if (section == NULL)
336 return "<none>"; 337 return "<none>";
337 char name[9]; 338 char name[9];
338 memcpy(name, section->name, 8); 339 memcpy(name, section->name, 8);
339 name[8] = '\0'; // Ensure termination. 340 name[8] = '\0'; // Ensure termination.
340 return name; 341 return name;
341 } 342 }
342 343
343 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { 344 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) {
344 // Walk all the bytes in the file, whether or not in a section. 345 // Walk all the bytes in the file, whether or not in a section.
345 uint32 file_offset = 0; 346 uint32_t file_offset = 0;
346 while (file_offset < length()) { 347 while (file_offset < length()) {
347 const Section* section = FindNextSection(file_offset); 348 const Section* section = FindNextSection(file_offset);
348 if (section == NULL) { 349 if (section == NULL) {
349 // No more sections. There should not be extra stuff following last 350 // No more sections. There should not be extra stuff following last
350 // section. 351 // section.
351 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program); 352 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program);
352 break; 353 break;
353 } 354 }
354 if (file_offset < section->file_offset_of_raw_data) { 355 if (file_offset < section->file_offset_of_raw_data) {
355 uint32 section_start_offset = section->file_offset_of_raw_data; 356 uint32_t section_start_offset = section->file_offset_of_raw_data;
356 if(!ParseNonSectionFileRegion(file_offset, section_start_offset, 357 if(!ParseNonSectionFileRegion(file_offset, section_start_offset,
357 program)) 358 program))
358 return false; 359 return false;
359 360
360 file_offset = section_start_offset; 361 file_offset = section_start_offset;
361 } 362 }
362 uint32 end = file_offset + section->size_of_raw_data; 363 uint32_t end = file_offset + section->size_of_raw_data;
363 if (!ParseFileRegion(section, file_offset, end, program)) 364 if (!ParseFileRegion(section, file_offset, end, program))
364 return false; 365 return false;
365 file_offset = end; 366 file_offset = end;
366 } 367 }
367 368
368 #if COURGETTE_HISTOGRAM_TARGETS 369 #if COURGETTE_HISTOGRAM_TARGETS
369 HistogramTargets("abs32 relocs", abs32_target_rvas_); 370 HistogramTargets("abs32 relocs", abs32_target_rvas_);
370 HistogramTargets("rel32 relocs", rel32_target_rvas_); 371 HistogramTargets("rel32 relocs", rel32_target_rvas_);
371 #endif 372 #endif
372 373
373 return true; 374 return true;
374 } 375 }
375 376
376 bool DisassemblerWin32X86::ParseAbs32Relocs() { 377 bool DisassemblerWin32X86::ParseAbs32Relocs() {
377 abs32_locations_.clear(); 378 abs32_locations_.clear();
378 if (!ParseRelocs(&abs32_locations_)) 379 if (!ParseRelocs(&abs32_locations_))
379 return false; 380 return false;
380 381
381 #if COURGETTE_HISTOGRAM_TARGETS 382 #if COURGETTE_HISTOGRAM_TARGETS
382 for (size_t i = 0; i < abs32_locations_.size(); ++i) { 383 for (size_t i = 0; i < abs32_locations_.size(); ++i) {
383 RVA rva = abs32_locations_[i]; 384 RVA rva = abs32_locations_[i];
384 // The 4 bytes at the relocation are a reference to some address. 385 // The 4 bytes at the relocation are a reference to some address.
385 uint32 target_address = Read32LittleEndian(RVAToPointer(rva)); 386 uint32_t target_address = Read32LittleEndian(RVAToPointer(rva));
386 ++abs32_target_rvas_[target_address - image_base()]; 387 ++abs32_target_rvas_[target_address - image_base()];
387 } 388 }
388 #endif 389 #endif
389 return true; 390 return true;
390 } 391 }
391 392
392 void DisassemblerWin32X86::ParseRel32RelocsFromSections() { 393 void DisassemblerWin32X86::ParseRel32RelocsFromSections() {
393 uint32 file_offset = 0; 394 uint32_t file_offset = 0;
394 while (file_offset < length()) { 395 while (file_offset < length()) {
395 const Section* section = FindNextSection(file_offset); 396 const Section* section = FindNextSection(file_offset);
396 if (section == NULL) 397 if (section == NULL)
397 break; 398 break;
398 if (file_offset < section->file_offset_of_raw_data) 399 if (file_offset < section->file_offset_of_raw_data)
399 file_offset = section->file_offset_of_raw_data; 400 file_offset = section->file_offset_of_raw_data;
400 ParseRel32RelocsFromSection(section); 401 ParseRel32RelocsFromSection(section);
401 file_offset += section->size_of_raw_data; 402 file_offset += section->size_of_raw_data;
402 } 403 }
403 std::sort(rel32_locations_.begin(), rel32_locations_.end()); 404 std::sort(rel32_locations_.begin(), rel32_locations_.end());
(...skipping 22 matching lines...) Expand all
426 VLOG(1) << "common " << common; 427 VLOG(1) << "common " << common;
427 #endif 428 #endif
428 } 429 }
429 430
430 void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) { 431 void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) {
431 // TODO(sra): use characteristic. 432 // TODO(sra): use characteristic.
432 bool isCode = strcmp(section->name, ".text") == 0; 433 bool isCode = strcmp(section->name, ".text") == 0;
433 if (!isCode) 434 if (!isCode)
434 return; 435 return;
435 436
436 uint32 start_file_offset = section->file_offset_of_raw_data; 437 uint32_t start_file_offset = section->file_offset_of_raw_data;
437 uint32 end_file_offset = start_file_offset + section->size_of_raw_data; 438 uint32_t end_file_offset = start_file_offset + section->size_of_raw_data;
438 439
439 const uint8* start_pointer = OffsetToPointer(start_file_offset); 440 const uint8_t* start_pointer = OffsetToPointer(start_file_offset);
440 const uint8* end_pointer = OffsetToPointer(end_file_offset); 441 const uint8_t* end_pointer = OffsetToPointer(end_file_offset);
441 442
442 RVA start_rva = FileOffsetToRVA(start_file_offset); 443 RVA start_rva = FileOffsetToRVA(start_file_offset);
443 RVA end_rva = start_rva + section->virtual_size; 444 RVA end_rva = start_rva + section->virtual_size;
444 445
445 Rel32FinderWin32X86_Basic finder( 446 Rel32FinderWin32X86_Basic finder(
446 base_relocation_table().address_, 447 base_relocation_table().address_,
447 base_relocation_table().address_ + base_relocation_table().size_, 448 base_relocation_table().address_ + base_relocation_table().size_,
448 size_of_image_); 449 size_of_image_);
449 finder.Find(start_pointer, end_pointer, start_rva, end_rva, abs32_locations_); 450 finder.Find(start_pointer, end_pointer, start_rva, end_rva, abs32_locations_);
450 finder.SwapRel32Locations(&rel32_locations_); 451 finder.SwapRel32Locations(&rel32_locations_);
451 452
452 #if COURGETTE_HISTOGRAM_TARGETS 453 #if COURGETTE_HISTOGRAM_TARGETS
453 DCHECK(rel32_target_rvas_.empty()); 454 DCHECK(rel32_target_rvas_.empty());
454 finder.SwapRel32TargetRVAs(&rel32_target_rvas_); 455 finder.SwapRel32TargetRVAs(&rel32_target_rvas_);
455 #endif 456 #endif
456 } 457 }
457 458
458 CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion( 459 CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion(
459 uint32 start_file_offset, 460 uint32_t start_file_offset,
460 uint32 end_file_offset, 461 uint32_t end_file_offset,
461 AssemblyProgram* program) { 462 AssemblyProgram* program) {
462 if (incomplete_disassembly_) 463 if (incomplete_disassembly_)
463 return true; 464 return true;
464 465
465 if (end_file_offset > start_file_offset) { 466 if (end_file_offset > start_file_offset) {
466 if (!program->EmitBytesInstruction(OffsetToPointer(start_file_offset), 467 if (!program->EmitBytesInstruction(OffsetToPointer(start_file_offset),
467 end_file_offset - start_file_offset)) { 468 end_file_offset - start_file_offset)) {
468 return false; 469 return false;
469 } 470 }
470 } 471 }
471 472
472 return true; 473 return true;
473 } 474 }
474 475
475 CheckBool DisassemblerWin32X86::ParseFileRegion( 476 CheckBool DisassemblerWin32X86::ParseFileRegion(const Section* section,
476 const Section* section, 477 uint32_t start_file_offset,
477 uint32 start_file_offset, uint32 end_file_offset, 478 uint32_t end_file_offset,
478 AssemblyProgram* program) { 479 AssemblyProgram* program) {
479 RVA relocs_start_rva = base_relocation_table().address_; 480 RVA relocs_start_rva = base_relocation_table().address_;
480 481
481 const uint8* start_pointer = OffsetToPointer(start_file_offset); 482 const uint8_t* start_pointer = OffsetToPointer(start_file_offset);
482 const uint8* end_pointer = OffsetToPointer(end_file_offset); 483 const uint8_t* end_pointer = OffsetToPointer(end_file_offset);
483 484
484 RVA start_rva = FileOffsetToRVA(start_file_offset); 485 RVA start_rva = FileOffsetToRVA(start_file_offset);
485 RVA end_rva = start_rva + section->virtual_size; 486 RVA end_rva = start_rva + section->virtual_size;
486 487
487 // Quick way to convert from Pointer to RVA within a single Section is to 488 // Quick way to convert from Pointer to RVA within a single Section is to
488 // subtract 'pointer_to_rva'. 489 // subtract 'pointer_to_rva'.
489 const uint8* const adjust_pointer_to_rva = start_pointer - start_rva; 490 const uint8_t* const adjust_pointer_to_rva = start_pointer - start_rva;
490 491
491 std::vector<RVA>::iterator rel32_pos = rel32_locations_.begin(); 492 std::vector<RVA>::iterator rel32_pos = rel32_locations_.begin();
492 std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin(); 493 std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin();
493 494
494 if (!program->EmitOriginInstruction(start_rva)) 495 if (!program->EmitOriginInstruction(start_rva))
495 return false; 496 return false;
496 497
497 const uint8* p = start_pointer; 498 const uint8_t* p = start_pointer;
498 499
499 while (p < end_pointer) { 500 while (p < end_pointer) {
500 RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); 501 RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva);
501 502
502 // The base relocation table is usually in the .relocs section, but it could 503 // The base relocation table is usually in the .relocs section, but it could
503 // actually be anywhere. Make sure we skip it because we will regenerate it 504 // actually be anywhere. Make sure we skip it because we will regenerate it
504 // during assembly. 505 // during assembly.
505 if (current_rva == relocs_start_rva) { 506 if (current_rva == relocs_start_rva) {
506 if (!program->EmitPeRelocsInstruction()) 507 if (!program->EmitPeRelocsInstruction())
507 return false; 508 return false;
508 uint32 relocs_size = base_relocation_table().size_; 509 uint32_t relocs_size = base_relocation_table().size_;
509 if (relocs_size) { 510 if (relocs_size) {
510 p += relocs_size; 511 p += relocs_size;
511 continue; 512 continue;
512 } 513 }
513 } 514 }
514 515
515 while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) 516 while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva)
516 ++abs32_pos; 517 ++abs32_pos;
517 518
518 if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) { 519 if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) {
519 uint32 target_address = Read32LittleEndian(p); 520 uint32_t target_address = Read32LittleEndian(p);
520 RVA target_rva = target_address - image_base(); 521 RVA target_rva = target_address - image_base();
521 // TODO(sra): target could be Label+offset. It is not clear how to guess 522 // TODO(sra): target could be Label+offset. It is not clear how to guess
522 // which it might be. We assume offset==0. 523 // which it might be. We assume offset==0.
523 if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva))) 524 if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva)))
524 return false; 525 return false;
525 p += 4; 526 p += 4;
526 continue; 527 continue;
527 } 528 }
528 529
529 while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva) 530 while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 s << std::hex << rva; 612 s << std::hex << rva;
612 if (section) { 613 if (section) {
613 s << " ("; 614 s << " (";
614 s << SectionName(section) << "+" 615 s << SectionName(section) << "+"
615 << std::hex << (rva - section->virtual_address) 616 << std::hex << (rva - section->virtual_address)
616 << ")"; 617 << ")";
617 } 618 }
618 return s.str(); 619 return s.str();
619 } 620 }
620 621
621 const Section* DisassemblerWin32X86::FindNextSection(uint32 fileOffset) const { 622 const Section* DisassemblerWin32X86::FindNextSection(
623 uint32_t fileOffset) const {
622 const Section* best = 0; 624 const Section* best = 0;
623 for (int i = 0; i < number_of_sections_; i++) { 625 for (int i = 0; i < number_of_sections_; i++) {
624 const Section* section = &sections_[i]; 626 const Section* section = &sections_[i];
625 if (section->size_of_raw_data > 0) { // i.e. has data in file. 627 if (section->size_of_raw_data > 0) { // i.e. has data in file.
626 if (fileOffset <= section->file_offset_of_raw_data) { 628 if (fileOffset <= section->file_offset_of_raw_data) {
627 if (best == 0 || 629 if (best == 0 ||
628 section->file_offset_of_raw_data < best->file_offset_of_raw_data) { 630 section->file_offset_of_raw_data < best->file_offset_of_raw_data) {
629 best = section; 631 best = section;
630 } 632 }
631 } 633 }
632 } 634 }
633 } 635 }
634 return best; 636 return best;
635 } 637 }
636 638
637 RVA DisassemblerWin32X86::FileOffsetToRVA(uint32 file_offset) const { 639 RVA DisassemblerWin32X86::FileOffsetToRVA(uint32_t file_offset) const {
638 for (int i = 0; i < number_of_sections_; i++) { 640 for (int i = 0; i < number_of_sections_; i++) {
639 const Section* section = &sections_[i]; 641 const Section* section = &sections_[i];
640 uint32 offset = file_offset - section->file_offset_of_raw_data; 642 uint32_t offset = file_offset - section->file_offset_of_raw_data;
641 if (offset < section->size_of_raw_data) { 643 if (offset < section->size_of_raw_data) {
642 return section->virtual_address + offset; 644 return section->virtual_address + offset;
643 } 645 }
644 } 646 }
645 return 0; 647 return 0;
646 } 648 }
647 649
648 bool DisassemblerWin32X86::ReadDataDirectory( 650 bool DisassemblerWin32X86::ReadDataDirectory(
649 int index, 651 int index,
650 ImageDataDirectory* directory) { 652 ImageDataDirectory* directory) {
651 653
652 if (index < number_of_data_directories_) { 654 if (index < number_of_data_directories_) {
653 size_t offset = index * 8 + offset_of_data_directories_; 655 size_t offset = index * 8 + offset_of_data_directories_;
654 if (offset >= size_of_optional_header_) 656 if (offset >= size_of_optional_header_)
655 return Bad("number of data directories inconsistent"); 657 return Bad("number of data directories inconsistent");
656 const uint8* data_directory = optional_header_ + offset; 658 const uint8_t* data_directory = optional_header_ + offset;
657 if (data_directory < start() || 659 if (data_directory < start() ||
658 data_directory + 8 >= end()) 660 data_directory + 8 >= end())
659 return Bad("data directory outside image"); 661 return Bad("data directory outside image");
660 RVA rva = ReadU32(data_directory, 0); 662 RVA rva = ReadU32(data_directory, 0);
661 size_t size = ReadU32(data_directory, 4); 663 size_t size = ReadU32(data_directory, 4);
662 if (size > size_of_image_) 664 if (size > size_of_image_)
663 return Bad("data directory size too big"); 665 return Bad("data directory size too big");
664 666
665 // TODO(sra): validate RVA. 667 // TODO(sra): validate RVA.
666 directory->address_ = rva; 668 directory->address_ = rva;
667 directory->size_ = static_cast<uint32>(size); 669 directory->size_ = static_cast<uint32_t>(size);
668 return true; 670 return true;
669 } else { 671 } else {
670 directory->address_ = 0; 672 directory->address_ = 0;
671 directory->size_ = 0; 673 directory->size_ = 0;
672 return true; 674 return true;
673 } 675 }
674 } 676 }
675 677
676 } // namespace courgette 678 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/disassembler_win32_x86.h ('k') | courgette/disassembler_win32_x86_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698