~ubuntu-branches/ubuntu/jaunty/google-perftools/jaunty

« back to all changes in this revision

Viewing changes to src/windows/mini_disassembler.cc

  • Committer: Bazaar Package Importer
  • Author(s): Daigo Moriwaki
  • Date: 2008-06-15 23:41:36 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20080615234136-al5gawvdvt5vhdtz
Tags: 0.98-1
* New upstream release. (Closes: #425147)
* Compiled with GCC 4.3. (Closes: #454841)
* debian/watch: can now report upstream's version (Closes: #450294)
* Because of a file conflict between tau and libgoogle-perftools the
  binary pprof is renamed as google-pprof. (Closes: #404001)
  Great thanks to Michael Mende.
* debian/rules: autoconf files are now generated at the build time.
* Bumped up Standards-Version to 3.7.3, no changes are required.
* Split a new package, libtcmallc_minimal0. The upstream supports
  this module for wider platforms. So I leave its architecture to be
  `any'.
* libgoogle-perftools0's architecture is now i386. The upstream
  supports this module for x86 and x86_64. However, x86_64 requires
  libunwind's development head, which Debian does not have yet.
* Removed an unnecessary patch, debian/patches/02_profiler.cc_alpha.diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2007, Google Inc.
 
2
 * All rights reserved.
 
3
 * 
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are
 
6
 * met:
 
7
 * 
 
8
 *     * Redistributions of source code must retain the above copyright
 
9
 * notice, this list of conditions and the following disclaimer.
 
10
 *     * Redistributions in binary form must reproduce the above
 
11
 * copyright notice, this list of conditions and the following disclaimer
 
12
 * in the documentation and/or other materials provided with the
 
13
 * distribution.
 
14
 *     * Neither the name of Google Inc. nor the names of its
 
15
 * contributors may be used to endorse or promote products derived from
 
16
 * this software without specific prior written permission.
 
17
 * 
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
19
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
20
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
21
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
22
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
23
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
24
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
28
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 *
 
30
 * ---
 
31
 * Author: Joi Sigurdsson
 
32
 *
 
33
 * Implementation of MiniDisassembler.
 
34
 */
 
35
 
 
36
#include "mini_disassembler.h"
 
37
 
 
38
namespace sidestep {
 
39
 
 
40
MiniDisassembler::MiniDisassembler(bool operand_default_is_32_bits,
 
41
                                   bool address_default_is_32_bits)
 
42
    : operand_default_is_32_bits_(operand_default_is_32_bits),
 
43
      address_default_is_32_bits_(address_default_is_32_bits) {
 
44
  Initialize();
 
45
}
 
46
 
 
47
MiniDisassembler::MiniDisassembler()
 
48
    : operand_default_is_32_bits_(true),
 
49
      address_default_is_32_bits_(true) {
 
50
  Initialize();
 
51
}
 
52
 
 
53
InstructionType MiniDisassembler::Disassemble(
 
54
    byte* start_byte,
 
55
    unsigned int& instruction_bytes) {
 
56
  // Clean up any state from previous invocations.
 
57
  Initialize();
 
58
 
 
59
  // Start by processing any prefixes.
 
60
  byte* current_byte = start_byte;
 
61
  unsigned int size = 0;
 
62
  InstructionType instruction_type = ProcessPrefixes(current_byte, size);
 
63
 
 
64
  if (IT_UNKNOWN == instruction_type)
 
65
    return instruction_type;
 
66
 
 
67
  current_byte += size;
 
68
  size = 0;
 
69
 
 
70
  // Invariant: We have stripped all prefixes, and the operand_is_32_bits_
 
71
  // and address_is_32_bits_ flags are correctly set.
 
72
 
 
73
  instruction_type = ProcessOpcode(current_byte, 0, size);
 
74
 
 
75
  // Check for error processing instruction
 
76
  if ((IT_UNKNOWN == instruction_type_) || (IT_UNUSED == instruction_type_)) {
 
77
    return IT_UNKNOWN;
 
78
  }
 
79
 
 
80
  current_byte += size;
 
81
 
 
82
  // Invariant: operand_bytes_ indicates the total size of operands
 
83
  // specified by the opcode and/or ModR/M byte and/or SIB byte.
 
84
  // pCurrentByte points to the first byte after the ModR/M byte, or after
 
85
  // the SIB byte if it is present (i.e. the first byte of any operands
 
86
  // encoded in the instruction).
 
87
 
 
88
  // We get the total length of any prefixes, the opcode, and the ModR/M and
 
89
  // SIB bytes if present, by taking the difference of the original starting
 
90
  // address and the current byte (which points to the first byte of the
 
91
  // operands if present, or to the first byte of the next instruction if
 
92
  // they are not).  Adding the count of bytes in the operands encoded in
 
93
  // the instruction gives us the full length of the instruction in bytes.
 
94
  instruction_bytes += operand_bytes_ + (current_byte - start_byte);
 
95
 
 
96
  // Return the instruction type, which was set by ProcessOpcode().
 
97
  return instruction_type_;
 
98
}
 
99
 
 
100
void MiniDisassembler::Initialize() {
 
101
  operand_is_32_bits_ = operand_default_is_32_bits_;
 
102
  address_is_32_bits_ = address_default_is_32_bits_;
 
103
  operand_bytes_ = 0;
 
104
  have_modrm_ = false;
 
105
  should_decode_modrm_ = false;
 
106
  instruction_type_ = IT_UNKNOWN;
 
107
  got_f2_prefix_ = false;
 
108
  got_f3_prefix_ = false;
 
109
  got_66_prefix_ = false;
 
110
}
 
111
 
 
112
InstructionType MiniDisassembler::ProcessPrefixes(byte* start_byte,
 
113
                                                  unsigned int& size) {
 
114
  InstructionType instruction_type = IT_GENERIC; 
 
115
  const Opcode& opcode = s_ia32_opcode_map_[0].table_[*start_byte];
 
116
 
 
117
  switch (opcode.type_) {
 
118
    case IT_PREFIX_ADDRESS:
 
119
      address_is_32_bits_ = !address_default_is_32_bits_;
 
120
      goto nochangeoperand;
 
121
    case IT_PREFIX_OPERAND:
 
122
      operand_is_32_bits_ = !operand_default_is_32_bits_;
 
123
      nochangeoperand:
 
124
    case IT_PREFIX:
 
125
  
 
126
      if (0xF2 == (*start_byte))
 
127
        got_f2_prefix_ = true;
 
128
      else if (0xF3 == (*start_byte))
 
129
        got_f3_prefix_ = true;
 
130
      else if (0x66 == (*start_byte))
 
131
        got_66_prefix_ = true;
 
132
  
 
133
      instruction_type = opcode.type_;
 
134
      size ++;
 
135
      // we got a prefix, so add one and check next byte
 
136
      ProcessPrefixes(start_byte + 1, size);
 
137
    default:
 
138
      break;   // not a prefix byte
 
139
  }
 
140
 
 
141
  return instruction_type;
 
142
}
 
143
 
 
144
InstructionType MiniDisassembler::ProcessOpcode(byte* start_byte,
 
145
                                                unsigned int table_index,
 
146
                                                unsigned int& size) {
 
147
  const OpcodeTable& table = s_ia32_opcode_map_[table_index];   // Get our table
 
148
  byte current_byte = (*start_byte) >> table.shift_;
 
149
  current_byte = current_byte & table.mask_;  // Mask out the bits we will use
 
150
  
 
151
  // Check whether the byte we have is inside the table we have.
 
152
  if (current_byte < table.min_lim_ || current_byte > table.max_lim_) {
 
153
    instruction_type_ = IT_UNKNOWN;
 
154
    return instruction_type_;
 
155
  }
 
156
 
 
157
  const Opcode& opcode = table.table_[current_byte];
 
158
  if (IT_UNUSED == opcode.type_) {
 
159
    // This instruction is not used by the IA-32 ISA, so we indicate
 
160
    // this to the user.  Probably means that we were pointed to
 
161
    // a byte in memory that was not the start of an instruction.
 
162
    instruction_type_ = IT_UNUSED;
 
163
    return instruction_type_;
 
164
  } else if (IT_REFERENCE == opcode.type_) {
 
165
    // We are looking at an opcode that has more bytes (or is continued
 
166
    // in the ModR/M byte).  Recursively find the opcode definition in
 
167
    // the table for the opcode's next byte.
 
168
    size++;
 
169
    ProcessOpcode(start_byte + 1, opcode.table_index_, size);
 
170
    return instruction_type_;
 
171
  }
 
172
 
 
173
  const SpecificOpcode* specific_opcode = (SpecificOpcode*)&opcode;
 
174
  if (opcode.is_prefix_dependent_) {
 
175
    if (got_f2_prefix_ && opcode.opcode_if_f2_prefix_.mnemonic_ != 0) {
 
176
      specific_opcode = &opcode.opcode_if_f2_prefix_;
 
177
    } else if (got_f3_prefix_ && opcode.opcode_if_f3_prefix_.mnemonic_ != 0) {
 
178
      specific_opcode = &opcode.opcode_if_f3_prefix_;
 
179
    } else if (got_66_prefix_ && opcode.opcode_if_66_prefix_.mnemonic_ != 0) {
 
180
      specific_opcode = &opcode.opcode_if_66_prefix_;
 
181
    }
 
182
  }
 
183
 
 
184
  // Inv: The opcode type is known.
 
185
  instruction_type_ = specific_opcode->type_;
 
186
 
 
187
  // Let's process the operand types to see if we have any immediate
 
188
  // operands, and/or a ModR/M byte.
 
189
 
 
190
  ProcessOperand(specific_opcode->flag_dest_);
 
191
  ProcessOperand(specific_opcode->flag_source_);
 
192
  ProcessOperand(specific_opcode->flag_aux_);
 
193
 
 
194
  // Inv: We have processed the opcode and incremented operand_bytes_
 
195
  // by the number of bytes of any operands specified by the opcode
 
196
  // that are stored in the instruction (not registers etc.).  Now
 
197
  // we need to return the total number of bytes for the opcode and
 
198
  // for the ModR/M or SIB bytes if they are present.
 
199
 
 
200
  if (table.mask_ != 0xff) {
 
201
    if (have_modrm_) {
 
202
      // we're looking at a ModR/M byte so we're not going to
 
203
      // count that into the opcode size
 
204
      ProcessModrm(start_byte, size);
 
205
      return IT_GENERIC;
 
206
    } else {
 
207
      // need to count the ModR/M byte even if it's just being
 
208
      // used for opcode extension
 
209
      size++;
 
210
      return IT_GENERIC;
 
211
    }
 
212
  } else {
 
213
    if (have_modrm_) {
 
214
      // The ModR/M byte is the next byte.
 
215
      size++;
 
216
      ProcessModrm(start_byte + 1, size);
 
217
      return IT_GENERIC;
 
218
    } else {
 
219
      size++;
 
220
      return IT_GENERIC;
 
221
    }
 
222
  }
 
223
}
 
224
 
 
225
bool MiniDisassembler::ProcessOperand(int flag_operand) {
 
226
  bool succeeded = true;
 
227
  if (AM_NOT_USED == flag_operand)
 
228
    return succeeded;
 
229
 
 
230
  // Decide what to do based on the addressing mode.
 
231
  switch (flag_operand & AM_MASK) {
 
232
    // No ModR/M byte indicated by these addressing modes, and no
 
233
    // additional (e.g. immediate) parameters.
 
234
    case AM_A: // Direct address
 
235
    case AM_F: // EFLAGS register
 
236
    case AM_X: // Memory addressed by the DS:SI register pair
 
237
    case AM_Y: // Memory addressed by the ES:DI register pair
 
238
    case AM_IMPLICIT: // Parameter is implicit, occupies no space in 
 
239
                       // instruction
 
240
      break;
 
241
  
 
242
    // There is a ModR/M byte but it does not necessarily need
 
243
    // to be decoded.
 
244
    case AM_C: // reg field of ModR/M selects a control register
 
245
    case AM_D: // reg field of ModR/M selects a debug register
 
246
    case AM_G: // reg field of ModR/M selects a general register
 
247
    case AM_P: // reg field of ModR/M selects an MMX register
 
248
    case AM_R: // mod field of ModR/M may refer only to a general register
 
249
    case AM_S: // reg field of ModR/M selects a segment register
 
250
    case AM_T: // reg field of ModR/M selects a test register
 
251
    case AM_V: // reg field of ModR/M selects a 128-bit XMM register
 
252
      have_modrm_ = true;
 
253
      break;
 
254
  
 
255
    // In these addressing modes, there is a ModR/M byte and it needs to be
 
256
    // decoded. No other (e.g. immediate) params than indicated in ModR/M.
 
257
    case AM_E: // Operand is either a general-purpose register or memory, 
 
258
                 // specified by ModR/M byte
 
259
    case AM_M: // ModR/M byte will refer only to memory
 
260
    case AM_Q: // Operand is either an MMX register or memory (complex 
 
261
                 // evaluation), specified by ModR/M byte
 
262
    case AM_W: // Operand is either a 128-bit XMM register or memory (complex 
 
263
                 // eval), specified by ModR/M byte
 
264
      have_modrm_ = true;
 
265
      should_decode_modrm_ = true;
 
266
      break;
 
267
  
 
268
    // These addressing modes specify an immediate or an offset value
 
269
    // directly, so we need to look at the operand type to see how many
 
270
    // bytes.
 
271
    case AM_I: // Immediate data.
 
272
    case AM_J: // Jump to offset.
 
273
    case AM_O: // Operand is at offset.
 
274
      switch (flag_operand & OT_MASK) {
 
275
        case OT_B: // Byte regardless of operand-size attribute.
 
276
          operand_bytes_ += OS_BYTE;
 
277
          break;
 
278
        case OT_C: // Byte or word, depending on operand-size attribute.
 
279
          if (operand_is_32_bits_)
 
280
            operand_bytes_ += OS_WORD;
 
281
          else
 
282
            operand_bytes_ += OS_BYTE;
 
283
          break;
 
284
        case OT_D: // Doubleword, regardless of operand-size attribute.
 
285
          operand_bytes_ += OS_DOUBLE_WORD;
 
286
          break;
 
287
        case OT_DQ: // Double-quadword, regardless of operand-size attribute.
 
288
          operand_bytes_ += OS_DOUBLE_QUAD_WORD;
 
289
          break;
 
290
        case OT_P: // 32-bit or 48-bit pointer, depending on operand-size 
 
291
                     // attribute.
 
292
          if (operand_is_32_bits_)
 
293
            operand_bytes_ += OS_48_BIT_POINTER;
 
294
          else
 
295
            operand_bytes_ += OS_32_BIT_POINTER;
 
296
          break;
 
297
        case OT_PS: // 128-bit packed single-precision floating-point data.
 
298
          operand_bytes_ += OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING;
 
299
          break;
 
300
        case OT_Q: // Quadword, regardless of operand-size attribute.
 
301
          operand_bytes_ += OS_QUAD_WORD;
 
302
          break;
 
303
        case OT_S: // 6-byte pseudo-descriptor.
 
304
          operand_bytes_ += OS_PSEUDO_DESCRIPTOR;
 
305
          break;
 
306
        case OT_SD: // Scalar Double-Precision Floating-Point Value
 
307
        case OT_PD: // Unaligned packed double-precision floating point value
 
308
          operand_bytes_ += OS_DOUBLE_PRECISION_FLOATING;
 
309
          break;
 
310
        case OT_SS:
 
311
          // Scalar element of a 128-bit packed single-precision 
 
312
          // floating data.
 
313
          // We simply return enItUnknown since we don't have to support 
 
314
          // floating point
 
315
          succeeded = false;
 
316
          break;
 
317
        case OT_V: // Word or doubleword, depending on operand-size attribute.
 
318
          if (operand_is_32_bits_)
 
319
            operand_bytes_ += OS_DOUBLE_WORD;
 
320
          else
 
321
            operand_bytes_ += OS_WORD;
 
322
          break;
 
323
        case OT_W: // Word, regardless of operand-size attribute.
 
324
          operand_bytes_ += OS_WORD;
 
325
          break;
 
326
    
 
327
        // Can safely ignore these.
 
328
        case OT_A: // Two one-word operands in memory or two double-word 
 
329
                     // operands in memory
 
330
        case OT_PI: // Quadword MMX technology register (e.g. mm0)
 
331
        case OT_SI: // Doubleword integer register (e.g., eax)
 
332
          break;
 
333
    
 
334
        default:
 
335
          break;
 
336
      }
 
337
      break;
 
338
  
 
339
    default:
 
340
      break;
 
341
  }
 
342
 
 
343
  return succeeded;
 
344
}
 
345
 
 
346
bool MiniDisassembler::ProcessModrm(byte* start_byte, 
 
347
                                    unsigned int& size) {
 
348
  // If we don't need to decode, we just return the size of the ModR/M
 
349
  // byte (there is never a SIB byte in this case).
 
350
  if (!should_decode_modrm_) {
 
351
    size++;
 
352
    return true;
 
353
  }
 
354
 
 
355
  // We never care about the reg field, only the combination of the mod
 
356
  // and r/m fields, so let's start by packing those fields together into
 
357
  // 5 bits.
 
358
  byte modrm = (*start_byte);
 
359
  byte mod = modrm & 0xC0; // mask out top two bits to get mod field
 
360
  modrm = modrm & 0x07; // mask out bottom 3 bits to get r/m field
 
361
  mod = mod >> 3; // shift the mod field to the right place
 
362
  modrm = mod | modrm; // combine the r/m and mod fields as discussed
 
363
  mod = mod >> 3; // shift the mod field to bits 2..0
 
364
 
 
365
  // Invariant: modrm contains the mod field in bits 4..3 and the r/m field
 
366
  // in bits 2..0, and mod contains the mod field in bits 2..0
 
367
 
 
368
  const ModrmEntry* modrm_entry = 0;
 
369
  if (address_is_32_bits_)
 
370
    modrm_entry = &s_ia32_modrm_map_[modrm];
 
371
  else
 
372
    modrm_entry = &s_ia16_modrm_map_[modrm];
 
373
 
 
374
  // Invariant: modrm_entry points to information that we need to decode
 
375
  // the ModR/M byte.
 
376
  
 
377
  // Add to the count of operand bytes, if the ModR/M byte indicates
 
378
  // that some operands are encoded in the instruction.
 
379
  if (modrm_entry->is_encoded_in_instruction_)
 
380
    operand_bytes_ += modrm_entry->operand_size_;
 
381
 
 
382
  // Process the SIB byte if necessary, and return the count
 
383
  // of ModR/M and SIB bytes.
 
384
  if (modrm_entry->use_sib_byte_) {
 
385
    size++;
 
386
    return ProcessSib(start_byte + 1, mod, size);
 
387
  } else {
 
388
    size++;
 
389
    return true;
 
390
  }
 
391
}
 
392
 
 
393
bool MiniDisassembler::ProcessSib(byte* start_byte, 
 
394
                                  byte mod, 
 
395
                                  unsigned int& size) {
 
396
  // get the mod field from the 2..0 bits of the SIB byte
 
397
  byte sib_base = (*start_byte) & 0x07;
 
398
  if (0x05 == sib_base) {
 
399
    switch (mod) {
 
400
    case 0x00: // mod == 00
 
401
    case 0x02: // mod == 10
 
402
      operand_bytes_ += OS_DOUBLE_WORD;
 
403
      break;
 
404
    case 0x01: // mod == 01
 
405
      operand_bytes_ += OS_BYTE;
 
406
      break;
 
407
    case 0x03: // mod == 11
 
408
      // According to the IA-32 docs, there does not seem to be a disp
 
409
      // value for this value of mod
 
410
    default:
 
411
      break;
 
412
    }
 
413
  }
 
414
 
 
415
  size++;
 
416
  return true;
 
417
}
 
418
 
 
419
};  // namespace sidestep