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

Side by Side Diff: courgette/disassembler_elf_32_x86.cc

Issue 1792603006: Revert of [Courgette] Clean up Disassembler; fix ELF Memory leaks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months 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_elf_32_x86.h ('k') | courgette/disassembler_elf_32_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) 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
10 #include <algorithm>
11 #include <string>
7 #include <vector> 12 #include <vector>
8 13
9 #include "base/logging.h" 14 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 15
11 #include "courgette/assembly_program.h" 16 #include "courgette/assembly_program.h"
12 #include "courgette/courgette.h" 17 #include "courgette/courgette.h"
18 #include "courgette/encoded_program.h"
13 19
14 namespace courgette { 20 namespace courgette {
15 21
16 CheckBool DisassemblerElf32X86::TypedRVAX86::ComputeRelativeTarget( 22 DisassemblerElf32X86::DisassemblerElf32X86(const void* start, size_t length)
17 const uint8_t* op_pointer) { 23 : DisassemblerElf32(start, length) {
18 set_relative_target(Read32LittleEndian(op_pointer) + 4);
19 return true;
20 } 24 }
21 25
22 CheckBool DisassemblerElf32X86::TypedRVAX86::EmitInstruction( 26 // Convert an ELF relocation struction into an RVA
23 AssemblyProgram* program, 27 CheckBool DisassemblerElf32X86::RelToRVA(Elf32_Rel rel, RVA* result) const {
24 RVA target_rva) {
25 return program->EmitRel32(program->FindOrMakeRel32Label(target_rva));
26 }
27 28
28 uint16_t DisassemblerElf32X86::TypedRVAX86::op_size() const { 29 // The rightmost byte of r_info is the type...
29 return 4; 30 elf32_rel_386_type_values type =
30 } 31 (elf32_rel_386_type_values)(unsigned char)rel.r_info;
31 32
32 DisassemblerElf32X86::DisassemblerElf32X86(const void* start, size_t length) 33 // The other 3 bytes of r_info are the symbol
33 : DisassemblerElf32(start, length) {
34 }
35
36 // Convert an ELF relocation struction into an RVA.
37 CheckBool DisassemblerElf32X86::RelToRVA(Elf32_Rel rel, RVA* result) const {
38 // The rightmost byte of r_info is the type.
39 elf32_rel_386_type_values type =
40 static_cast<elf32_rel_386_type_values>(rel.r_info & 0xFF);
41
42 // The other 3 bytes of r_info are the symbol.
43 uint32_t symbol = rel.r_info >> 8; 34 uint32_t symbol = rel.r_info >> 8;
44 35
45 switch (type) { 36 switch(type)
37 {
46 case R_386_NONE: 38 case R_386_NONE:
47 case R_386_32: 39 case R_386_32:
48 case R_386_PC32: 40 case R_386_PC32:
49 case R_386_GOT32: 41 case R_386_GOT32:
50 case R_386_PLT32: 42 case R_386_PLT32:
51 case R_386_COPY: 43 case R_386_COPY:
52 case R_386_GLOB_DAT: 44 case R_386_GLOB_DAT:
53 case R_386_JMP_SLOT: 45 case R_386_JMP_SLOT:
54 return false; 46 return false;
55 47
56 case R_386_RELATIVE: 48 case R_386_RELATIVE:
57 if (symbol != 0) 49 if (symbol != 0)
58 return false; 50 return false;
59 51
60 // This is a basic ABS32 relocation address. 52 // This is a basic ABS32 relocation address
61 *result = rel.r_offset; 53 *result = rel.r_offset;
62 return true; 54 return true;
63 55
64 case R_386_GOTOFF: 56 case R_386_GOTOFF:
65 case R_386_GOTPC: 57 case R_386_GOTPC:
66 case R_386_TLS_TPOFF: 58 case R_386_TLS_TPOFF:
67 return false; 59 return false;
68 } 60 }
69 61
70 return false; 62 return false;
71 } 63 }
72 64
73 CheckBool DisassemblerElf32X86::ParseRelocationSection( 65 CheckBool DisassemblerElf32X86::ParseRelocationSection(
74 const Elf32_Shdr* section_header, 66 const Elf32_Shdr *section_header,
75 AssemblyProgram* program) { 67 AssemblyProgram* program) {
76 // We can reproduce the R_386_RELATIVE entries in one of the relocation table 68 // We can reproduce the R_386_RELATIVE entries in one of the relocation
77 // based on other information in the patch, given these conditions: 69 // table based on other information in the patch, given these
70 // conditions....
78 // 71 //
79 // All R_386_RELATIVE entries are: 72 // All R_386_RELATIVE entries are:
80 // 1) In the same relocation table 73 // 1) In the same relocation table
81 // 2) Are consecutive 74 // 2) Are consecutive
82 // 3) Are sorted in memory address order 75 // 3) Are sorted in memory address order
83 // 76 //
84 // Happily, this is normally the case, but it's not required by spec, so we 77 // Happily, this is normally the case, but it's not required by spec
85 // check, and just don't do it if we don't match up. 78 // so we check, and just don't do it if we don't match up.
86 79
87 // The expectation is that one relocation section will contain all of our 80 // The expectation is that one relocation section will contain
88 // R_386_RELATIVE entries in the expected order followed by assorted other 81 // all of our R_386_RELATIVE entries in the expected order followed
89 // entries we can't use special handling for. 82 // by assorted other entries we can't use special handling for.
90 83
91 bool match = true; 84 bool match = true;
92 85
93 // 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
94 FileOffset file_offset = section_header->sh_offset; 87 size_t file_offset = section_header->sh_offset;
95 FileOffset section_end = file_offset + section_header->sh_size; 88 size_t section_end = section_header->sh_offset + section_header->sh_size;
96 89
97 const Elf32_Rel* section_relocs_iter = reinterpret_cast<const Elf32_Rel*>( 90 Elf32_Rel *section_relocs_iter =
98 FileOffsetToPointer(section_header->sh_offset)); 91 (Elf32_Rel *)OffsetToPointer(section_header->sh_offset);
99 92
100 uint32_t section_relocs_count = 93 uint32_t section_relocs_count =
101 section_header->sh_size / section_header->sh_entsize; 94 section_header->sh_size / section_header->sh_entsize;
102 95
103 if (abs32_locations_.empty()) 96 if (abs32_locations_.empty())
104 match = false; 97 match = false;
105 98
106 if (abs32_locations_.size() > section_relocs_count) 99 if (abs32_locations_.size() > section_relocs_count)
107 match = false; 100 match = false;
108 101
109 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin(); 102 std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin();
110 103
111 while (match && (reloc_iter != abs32_locations_.end())) { 104 while (match && (reloc_iter != abs32_locations_.end())) {
112 if (section_relocs_iter->r_info != R_386_RELATIVE || 105 if (section_relocs_iter->r_info != R_386_RELATIVE ||
113 section_relocs_iter->r_offset != *reloc_iter) { 106 section_relocs_iter->r_offset != *reloc_iter)
114 match = false; 107 match = false;
115 } 108 section_relocs_iter++;
116 ++section_relocs_iter; 109 reloc_iter++;
117 ++reloc_iter;
118 } 110 }
119 111
120 if (match) { 112 if (match) {
121 // Skip over relocation tables. 113 // Skip over relocation tables
122 if (!program->EmitElfRelocationInstruction()) 114 if (!program->EmitElfRelocationInstruction())
123 return false; 115 return false;
124 file_offset += sizeof(Elf32_Rel) * abs32_locations_.size(); 116 file_offset += sizeof(Elf32_Rel) * abs32_locations_.size();
125 } 117 }
126 118
127 return ParseSimpleRegion(file_offset, section_end, program); 119 return ParseSimpleRegion(file_offset, section_end, program);
128 } 120 }
129 121
130 // TODO(huangs): Detect and avoid overlap with abs32 addresses.
131 CheckBool DisassemblerElf32X86::ParseRel32RelocsFromSection( 122 CheckBool DisassemblerElf32X86::ParseRel32RelocsFromSection(
132 const Elf32_Shdr* section_header) { 123 const Elf32_Shdr* section_header) {
133 FileOffset start_file_offset = section_header->sh_offset; 124 uint32_t start_file_offset = section_header->sh_offset;
134 FileOffset end_file_offset = start_file_offset + section_header->sh_size; 125 uint32_t end_file_offset = start_file_offset + section_header->sh_size;
135 126
136 const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset); 127 const uint8_t* start_pointer = OffsetToPointer(start_file_offset);
137 const uint8_t* end_pointer = FileOffsetToPointer(end_file_offset); 128 const uint8_t* end_pointer = OffsetToPointer(end_file_offset);
138 129
139 // 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
140 // subtract |pointer_to_rva|. 131 // subtract 'pointer_to_rva'.
141 const uint8_t* const adjust_pointer_to_rva = 132 const uint8_t* const adjust_pointer_to_rva =
142 start_pointer - section_header->sh_addr; 133 start_pointer - section_header->sh_addr;
143 134
144 // Find the rel32 relocations. 135 // Find the rel32 relocations.
145 const uint8_t* p = start_pointer; 136 const uint8_t* p = start_pointer;
146 while (p < end_pointer) { 137 while (p < end_pointer) {
138 //RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva);
139
147 // Heuristic discovery of rel32 locations in instruction stream: are the 140 // Heuristic discovery of rel32 locations in instruction stream: are the
148 // next few bytes the start of an instruction containing a rel32 141 // next few bytes the start of an instruction containing a rel32
149 // addressing mode? 142 // addressing mode?
150 const uint8_t* rel32 = nullptr; 143 const uint8_t* rel32 = NULL;
151 144
152 if (p + 5 <= end_pointer) { 145 if (p + 5 <= end_pointer) {
153 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 146 if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32
154 rel32 = p + 1; 147 rel32 = p + 1;
155 } 148 }
156 } 149 }
157 if (p + 6 <= end_pointer) { 150 if (p + 6 <= end_pointer) {
158 if (*p == 0x0F && (p[1] & 0xF0) == 0x80) { // Jcc long form 151 if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form
159 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely 152 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely
160 rel32 = p + 2; 153 rel32 = p + 2;
161 } 154 }
162 } 155 }
163 if (rel32) { 156 if (rel32) {
164 RVA rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); 157 RVA rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva);
165 scoped_ptr<TypedRVAX86> rel32_rva(new TypedRVAX86(rva)); 158 TypedRVAX86* rel32_rva = new TypedRVAX86(rva);
166 159
167 if (!rel32_rva->ComputeRelativeTarget(rel32)) 160 if (!rel32_rva->ComputeRelativeTarget(rel32)) {
161 delete rel32_rva;
168 return false; 162 return false;
163 }
169 164
170 RVA target_rva = rel32_rva->rva() + rel32_rva->relative_target(); 165 RVA target_rva = rel32_rva->rva() + rel32_rva->relative_target();
171 if (IsValidTargetRVA(target_rva)) { 166 // To be valid, rel32 target must be within image, and within this
172 rel32_locations_.push_back(rel32_rva.release()); 167 // section.
168 if (IsValidRVA(target_rva)) {
169 rel32_locations_.push_back(rel32_rva);
173 #if COURGETTE_HISTOGRAM_TARGETS 170 #if COURGETTE_HISTOGRAM_TARGETS
174 ++rel32_target_rvas_[target_rva]; 171 ++rel32_target_rvas_[target_rva];
175 #endif 172 #endif
176 p = rel32 + 4; 173 p = rel32 + 4;
177 continue; 174 continue;
175 } else {
176 delete rel32_rva;
178 } 177 }
179 } 178 }
180 p += 1; 179 p += 1;
181 } 180 }
182 181
183 return true; 182 return true;
184 } 183 }
185 184
186 } // namespace courgette 185 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/disassembler_elf_32_x86.h ('k') | courgette/disassembler_elf_32_x86_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698