OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_x86.h" | 5 #include "courgette/disassembler_elf_32_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 | 19 |
18 namespace courgette { | 20 namespace courgette { |
19 | 21 |
20 DisassemblerElf32X86::DisassemblerElf32X86(const void* start, size_t length) | 22 DisassemblerElf32X86::DisassemblerElf32X86(const void* start, size_t length) |
21 : DisassemblerElf32(start, length) { | 23 : DisassemblerElf32(start, length) { |
22 } | 24 } |
23 | 25 |
24 // Convert an ELF relocation struction into an RVA | 26 // Convert an ELF relocation struction into an RVA |
25 CheckBool DisassemblerElf32X86::RelToRVA(Elf32_Rel rel, RVA* result) const { | 27 CheckBool DisassemblerElf32X86::RelToRVA(Elf32_Rel rel, RVA* result) const { |
26 | 28 |
27 // The rightmost byte of r_info is the type... | 29 // The rightmost byte of r_info is the type... |
28 elf32_rel_386_type_values type = | 30 elf32_rel_386_type_values type = |
29 (elf32_rel_386_type_values)(unsigned char)rel.r_info; | 31 (elf32_rel_386_type_values)(unsigned char)rel.r_info; |
30 | 32 |
31 // The other 3 bytes of r_info are the symbol | 33 // The other 3 bytes of r_info are the symbol |
32 uint32 symbol = rel.r_info >> 8; | 34 uint32_t symbol = rel.r_info >> 8; |
33 | 35 |
34 switch(type) | 36 switch(type) |
35 { | 37 { |
36 case R_386_NONE: | 38 case R_386_NONE: |
37 case R_386_32: | 39 case R_386_32: |
38 case R_386_PC32: | 40 case R_386_PC32: |
39 case R_386_GOT32: | 41 case R_386_GOT32: |
40 case R_386_PLT32: | 42 case R_386_PLT32: |
41 case R_386_COPY: | 43 case R_386_COPY: |
42 case R_386_GLOB_DAT: | 44 case R_386_GLOB_DAT: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 | 83 |
82 bool match = true; | 84 bool match = true; |
83 | 85 |
84 // Walk all the bytes in the section, matching relocation table or not | 86 // Walk all the bytes in the section, matching relocation table or not |
85 size_t file_offset = section_header->sh_offset; | 87 size_t file_offset = section_header->sh_offset; |
86 size_t section_end = section_header->sh_offset + section_header->sh_size; | 88 size_t section_end = section_header->sh_offset + section_header->sh_size; |
87 | 89 |
88 Elf32_Rel *section_relocs_iter = | 90 Elf32_Rel *section_relocs_iter = |
89 (Elf32_Rel *)OffsetToPointer(section_header->sh_offset); | 91 (Elf32_Rel *)OffsetToPointer(section_header->sh_offset); |
90 | 92 |
91 uint32 section_relocs_count = section_header->sh_size / | 93 uint32_t section_relocs_count = |
92 section_header->sh_entsize; | 94 section_header->sh_size / section_header->sh_entsize; |
93 | 95 |
94 if (abs32_locations_.empty()) | 96 if (abs32_locations_.empty()) |
95 match = false; | 97 match = false; |
96 | 98 |
97 if (abs32_locations_.size() > section_relocs_count) | 99 if (abs32_locations_.size() > section_relocs_count) |
98 match = false; | 100 match = false; |
99 | 101 |
100 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin(); | 102 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin(); |
101 | 103 |
102 while (match && (reloc_iter != abs32_locations_.end())) { | 104 while (match && (reloc_iter != abs32_locations_.end())) { |
103 if (section_relocs_iter->r_info != R_386_RELATIVE || | 105 if (section_relocs_iter->r_info != R_386_RELATIVE || |
104 section_relocs_iter->r_offset != *reloc_iter) | 106 section_relocs_iter->r_offset != *reloc_iter) |
105 match = false; | 107 match = false; |
106 section_relocs_iter++; | 108 section_relocs_iter++; |
107 reloc_iter++; | 109 reloc_iter++; |
108 } | 110 } |
109 | 111 |
110 if (match) { | 112 if (match) { |
111 // Skip over relocation tables | 113 // Skip over relocation tables |
112 if (!program->EmitElfRelocationInstruction()) | 114 if (!program->EmitElfRelocationInstruction()) |
113 return false; | 115 return false; |
114 file_offset += sizeof(Elf32_Rel) * abs32_locations_.size(); | 116 file_offset += sizeof(Elf32_Rel) * abs32_locations_.size(); |
115 } | 117 } |
116 | 118 |
117 return ParseSimpleRegion(file_offset, section_end, program); | 119 return ParseSimpleRegion(file_offset, section_end, program); |
118 } | 120 } |
119 | 121 |
120 CheckBool DisassemblerElf32X86::ParseRel32RelocsFromSection( | 122 CheckBool DisassemblerElf32X86::ParseRel32RelocsFromSection( |
121 const Elf32_Shdr* section_header) { | 123 const Elf32_Shdr* section_header) { |
| 124 uint32_t start_file_offset = section_header->sh_offset; |
| 125 uint32_t end_file_offset = start_file_offset + section_header->sh_size; |
122 | 126 |
123 uint32 start_file_offset = section_header->sh_offset; | 127 const uint8_t* start_pointer = OffsetToPointer(start_file_offset); |
124 uint32 end_file_offset = start_file_offset + section_header->sh_size; | 128 const uint8_t* end_pointer = OffsetToPointer(end_file_offset); |
125 | |
126 const uint8* start_pointer = OffsetToPointer(start_file_offset); | |
127 const uint8* end_pointer = OffsetToPointer(end_file_offset); | |
128 | 129 |
129 // Quick way to convert from Pointer to RVA within a single Section is to | 130 // Quick way to convert from Pointer to RVA within a single Section is to |
130 // subtract 'pointer_to_rva'. | 131 // subtract 'pointer_to_rva'. |
131 const uint8* const adjust_pointer_to_rva = start_pointer - | 132 const uint8_t* const adjust_pointer_to_rva = |
132 section_header->sh_addr; | 133 start_pointer - section_header->sh_addr; |
133 | 134 |
134 // Find the rel32 relocations. | 135 // Find the rel32 relocations. |
135 const uint8* p = start_pointer; | 136 const uint8_t* p = start_pointer; |
136 while (p < end_pointer) { | 137 while (p < end_pointer) { |
137 //RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); | 138 //RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); |
138 | 139 |
139 // Heuristic discovery of rel32 locations in instruction stream: are the | 140 // Heuristic discovery of rel32 locations in instruction stream: are the |
140 // next few bytes the start of an instruction containing a rel32 | 141 // next few bytes the start of an instruction containing a rel32 |
141 // addressing mode? | 142 // addressing mode? |
142 const uint8* rel32 = NULL; | 143 const uint8_t* rel32 = NULL; |
143 | 144 |
144 if (p + 5 <= end_pointer) { | 145 if (p + 5 <= end_pointer) { |
145 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 | 146 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 |
146 rel32 = p + 1; | 147 rel32 = p + 1; |
147 } | 148 } |
148 } | 149 } |
149 if (p + 6 <= end_pointer) { | 150 if (p + 6 <= end_pointer) { |
150 if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form | 151 if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form |
151 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely | 152 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely |
152 rel32 = p + 2; | 153 rel32 = p + 2; |
(...skipping 22 matching lines...) Expand all Loading... |
175 delete rel32_rva; | 176 delete rel32_rva; |
176 } | 177 } |
177 } | 178 } |
178 p += 1; | 179 p += 1; |
179 } | 180 } |
180 | 181 |
181 return true; | 182 return true; |
182 } | 183 } |
183 | 184 |
184 } // namespace courgette | 185 } // namespace courgette |
OLD | NEW |