| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_elf_32.h" | 5 #include "courgette/disassembler_elf_32.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 #include "base/memory/scoped_vector.h" | 15 #include "base/memory/scoped_vector.h" |
| 14 | 16 |
| 15 #include "courgette/assembly_program.h" | 17 #include "courgette/assembly_program.h" |
| 16 #include "courgette/courgette.h" | 18 #include "courgette/courgette.h" |
| 17 #include "courgette/encoded_program.h" | 19 #include "courgette/encoded_program.h" |
| 18 | 20 |
| 19 namespace courgette { | 21 namespace courgette { |
| 20 | 22 |
| 21 DisassemblerElf32::DisassemblerElf32(const void* start, size_t length) | 23 DisassemblerElf32::DisassemblerElf32(const void* start, size_t length) |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 177 } |
| 176 } | 178 } |
| 177 } | 179 } |
| 178 | 180 |
| 179 return false; | 181 return false; |
| 180 } | 182 } |
| 181 | 183 |
| 182 RVA DisassemblerElf32::FileOffsetToRVA(size_t offset) const { | 184 RVA DisassemblerElf32::FileOffsetToRVA(size_t offset) const { |
| 183 // File offsets can be 64 bit values, but we are dealing with 32 | 185 // File offsets can be 64 bit values, but we are dealing with 32 |
| 184 // bit executables and so only need to support 32bit file sizes. | 186 // bit executables and so only need to support 32bit file sizes. |
| 185 uint32 offset32 = (uint32)offset; | 187 uint32_t offset32 = (uint32_t)offset; |
| 186 | 188 |
| 187 for (int i = 0; i < SectionHeaderCount(); i++) { | 189 for (int i = 0; i < SectionHeaderCount(); i++) { |
| 188 | 190 |
| 189 const Elf32_Shdr *section_header = SectionHeader(i); | 191 const Elf32_Shdr *section_header = SectionHeader(i); |
| 190 | 192 |
| 191 // These can appear to have a size in the file, but don't. | 193 // These can appear to have a size in the file, but don't. |
| 192 if (section_header->sh_type == SHT_NOBITS) | 194 if (section_header->sh_type == SHT_NOBITS) |
| 193 continue; | 195 continue; |
| 194 | 196 |
| 195 Elf32_Off section_begin = section_header->sh_offset; | 197 Elf32_Off section_begin = section_header->sh_offset; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 return false; | 235 return false; |
| 234 | 236 |
| 235 (*rva)->set_offset(offset); | 237 (*rva)->set_offset(offset); |
| 236 } | 238 } |
| 237 | 239 |
| 238 return true; | 240 return true; |
| 239 } | 241 } |
| 240 | 242 |
| 241 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) { | 243 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) { |
| 242 // Walk all the bytes in the file, whether or not in a section. | 244 // Walk all the bytes in the file, whether or not in a section. |
| 243 uint32 file_offset = 0; | 245 uint32_t file_offset = 0; |
| 244 | 246 |
| 245 std::vector<size_t> abs_offsets; | 247 std::vector<size_t> abs_offsets; |
| 246 | 248 |
| 247 if (!RVAsToOffsets(&abs32_locations_, &abs_offsets)) | 249 if (!RVAsToOffsets(&abs32_locations_, &abs_offsets)) |
| 248 return false; | 250 return false; |
| 249 | 251 |
| 250 if (!RVAsToOffsets(&rel32_locations_)) | 252 if (!RVAsToOffsets(&rel32_locations_)) |
| 251 return false; | 253 return false; |
| 252 | 254 |
| 253 std::vector<size_t>::iterator current_abs_offset = abs_offsets.begin(); | 255 std::vector<size_t>::iterator current_abs_offset = abs_offsets.begin(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 if (next_relocation > file_offset) { | 365 if (next_relocation > file_offset) { |
| 364 if (!ParseSimpleRegion(file_offset, next_relocation, program)) | 366 if (!ParseSimpleRegion(file_offset, next_relocation, program)) |
| 365 return false; | 367 return false; |
| 366 | 368 |
| 367 file_offset = next_relocation; | 369 file_offset = next_relocation; |
| 368 continue; | 370 continue; |
| 369 } | 371 } |
| 370 | 372 |
| 371 if (*current_abs_offset != end_abs_offset && | 373 if (*current_abs_offset != end_abs_offset && |
| 372 file_offset == **current_abs_offset) { | 374 file_offset == **current_abs_offset) { |
| 373 | 375 const uint8_t* p = OffsetToPointer(file_offset); |
| 374 const uint8* p = OffsetToPointer(file_offset); | |
| 375 RVA target_rva = Read32LittleEndian(p); | 376 RVA target_rva = Read32LittleEndian(p); |
| 376 | 377 |
| 377 if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva))) | 378 if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva))) |
| 378 return false; | 379 return false; |
| 379 file_offset += sizeof(RVA); | 380 file_offset += sizeof(RVA); |
| 380 (*current_abs_offset)++; | 381 (*current_abs_offset)++; |
| 381 continue; | 382 continue; |
| 382 } | 383 } |
| 383 | 384 |
| 384 if (*current_rel != end_rel && | 385 if (*current_rel != end_rel && |
| 385 file_offset == (**current_rel)->get_offset()) { | 386 file_offset == (**current_rel)->get_offset()) { |
| 386 | 387 uint32_t relative_target = (**current_rel)->relative_target(); |
| 387 uint32 relative_target = (**current_rel)->relative_target(); | |
| 388 // This cast is for 64 bit systems, and is only safe because we | 388 // This cast is for 64 bit systems, and is only safe because we |
| 389 // are working on 32 bit executables. | 389 // are working on 32 bit executables. |
| 390 RVA target_rva = (RVA)(origin + (file_offset - origin_offset) + | 390 RVA target_rva = (RVA)(origin + (file_offset - origin_offset) + |
| 391 relative_target); | 391 relative_target); |
| 392 | 392 |
| 393 if (! (**current_rel)->EmitInstruction(program, target_rva)) | 393 if (! (**current_rel)->EmitInstruction(program, target_rva)) |
| 394 return false; | 394 return false; |
| 395 file_offset += (**current_rel)->op_size(); | 395 file_offset += (**current_rel)->op_size(); |
| 396 (*current_rel)++; | 396 (*current_rel)++; |
| 397 continue; | 397 continue; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 return false; | 494 return false; |
| 495 } | 495 } |
| 496 | 496 |
| 497 std::sort(rel32_locations_.begin(), | 497 std::sort(rel32_locations_.begin(), |
| 498 rel32_locations_.end(), | 498 rel32_locations_.end(), |
| 499 TypedRVA::IsLessThan); | 499 TypedRVA::IsLessThan); |
| 500 return true; | 500 return true; |
| 501 } | 501 } |
| 502 | 502 |
| 503 } // namespace courgette | 503 } // namespace courgette |
| OLD | NEW |