Coverage for /Syzygy/block_graph/basic_block_assembler.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
96.2%1271320.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  #include "syzygy/block_graph/basic_block_assembler.h"
  16    :  
  17    :  namespace block_graph {
  18    :  
  19    :  namespace {
  20    :  
  21  E :  ValueSize ValueSizeFromConstant(uint32 input_value) {
  22    :    // IA32 assembly may/will sign-extend 8-bit literals, so we attempt to encode
  23    :    // in 8 bits only those literals whose value will be unchanged by that
  24    :    // treatment.
  25  E :    input_value |= 0x7F;
  26    :  
  27  E :    if (input_value == 0xFFFFFFFF || input_value == 0x7F)
  28  E :      return assm::kSize8Bit;
  29    :  
  30  E :    return assm::kSize32Bit;
  31  E :  }
  32    :  
  33  E :  size_t ToBytes(assm::ReferenceSize size) {
  34  E :    switch (size) {
  35  E :      case assm::kSize8Bit: return 1;
  36  E :      case assm::kSize32Bit: return 4;
  37    :    }
  38  i :    NOTREACHED();
  39  i :    return 0;
  40  E :  }
  41    :  
  42    :  // Completes a UntypedReference, converting it to a BasicBlockReference
  43    :  // using the associated type and size information.
  44    :  BasicBlockReference CompleteUntypedReference(
  45  E :      const BasicBlockAssembler::ReferenceInfo& info) {
  46  E :    DCHECK(info.reference.IsValid());
  47    :  
  48  E :    size_t size = ToBytes(info.size);
  49  E :    BlockGraph::ReferenceType type = BlockGraph::ABSOLUTE_REF;
  50  E :    if (info.pc_relative)
  51  E :      type = BlockGraph::PC_RELATIVE_REF;
  52    :  
  53    :    if (info.reference.referred_type() ==
  54  E :            BasicBlockReference::REFERRED_TYPE_BLOCK) {
  55  E :      DCHECK(info.reference.block() != NULL);
  56    :      return BasicBlockReference(type, size, info.reference.block(),
  57  E :                                 info.reference.offset(), info.reference.base());
  58    :    }
  59    :  
  60    :    DCHECK_EQ(BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK,
  61  E :              info.reference.referred_type());
  62  E :    DCHECK(info.reference.basic_block() != NULL);
  63  E :    return BasicBlockReference(type, size, info.reference.basic_block());
  64  E :  }
  65    :  
  66    :  }  // namespace
  67    :  
  68  E :  BasicBlockAssembler::Immediate Immediate() {
  69  E :    return BasicBlockAssembler::Immediate();
  70  E :  }
  71    :  
  72  E :  BasicBlockAssembler::Immediate Immediate(uint32 value) {
  73  E :    return BasicBlockAssembler::Immediate(value, ValueSizeFromConstant(value));
  74  E :  }
  75    :  
  76  E :  BasicBlockAssembler::Immediate Immediate(uint32 value, ValueSize size) {
  77  E :    return BasicBlockAssembler::Immediate(value, size);
  78  E :  }
  79    :  
  80  E :  BasicBlockAssembler::Immediate Immediate(BasicBlock* bb) {
  81    :    return BasicBlockAssembler::Immediate(
  82  E :        0, assm::kSize32Bit, UntypedReference(bb));
  83  E :  }
  84    :  
  85    :  BasicBlockAssembler::Immediate Immediate(
  86  E :      BlockGraph::Block* block, BlockGraph::Offset offset) {
  87    :    return BasicBlockAssembler::Immediate(
  88  E :        0, assm::kSize32Bit, UntypedReference(block, offset, offset));
  89  E :  }
  90    :  
  91    :  BasicBlockAssembler::Immediate Immediate(BlockGraph::Block* block,
  92    :                                           BlockGraph::Offset offset,
  93  E :                                           BlockGraph::Offset base) {
  94    :    return BasicBlockAssembler::Immediate(
  95  E :        0, assm::kSize32Bit, UntypedReference(block, offset, base));
  96  E :  }
  97    :  
  98    :  BasicBlockAssembler::Immediate Immediate(
  99  E :      uint32 value, ValueSize size, const UntypedReference& ref) {
 100  E :    DCHECK(ref.IsValid());
 101  E :    return BasicBlockAssembler::Immediate(value, size, ref);
 102  E :  }
 103    :  
 104  E :  BasicBlockAssembler::Displacement Displacement() {
 105  E :    return BasicBlockAssembler::Displacement();
 106  E :  }
 107    :  
 108  E :  BasicBlockAssembler::Displacement Displacement(uint32 value) {
 109    :    return BasicBlockAssembler::Displacement(value,
 110  E :                                             ValueSizeFromConstant(value));
 111  E :  }
 112    :  
 113  E :  BasicBlockAssembler::Displacement Displacement(uint32 value, ValueSize size) {
 114  E :    return BasicBlockAssembler::Displacement(value, size);
 115  E :  }
 116    :  
 117  E :  BasicBlockAssembler::Displacement Displacement(BasicBlock* bb) {
 118    :    return BasicBlockAssembler::Displacement(
 119  E :        0, assm::kSize32Bit, UntypedReference(bb));
 120  E :  }
 121    :  
 122    :  BasicBlockAssembler::Displacement Displacement(
 123  E :      BlockGraph::Block* block, BlockGraph::Offset offset) {
 124    :    return BasicBlockAssembler::Displacement(
 125  E :        0, assm::kSize32Bit, UntypedReference(block, offset, offset));
 126  E :  }
 127    :  
 128    :  BasicBlockAssembler::Displacement Displacement(
 129    :      BlockGraph::Block* block, BlockGraph::Offset offset,
 130  E :      BlockGraph::Offset base) {
 131    :    return BasicBlockAssembler::Displacement(
 132  E :        0, assm::kSize32Bit, UntypedReference(block, offset, base));
 133  E :  }
 134    :  
 135    :  BasicBlockAssembler::Displacement Displacement(
 136  E :      uint32 value, ValueSize size, const UntypedReference& ref) {
 137  E :    DCHECK(ref.IsValid());
 138  E :    return BasicBlockAssembler::Displacement(value, size, ref);
 139  E :  }
 140    :  
 141  E :  BasicBlockAssembler::Operand Operand(const assm::Register32& base) {
 142  E :    return BasicBlockAssembler::Operand(base);
 143  E :  }
 144    :  
 145    :  BasicBlockAssembler::Operand Operand(
 146    :      const assm::Register32& base,
 147  E :      const BasicBlockAssembler::Displacement& displ) {
 148  E :    return BasicBlockAssembler::Operand(base, displ);
 149  E :  }
 150    :  
 151    :  BasicBlockAssembler::Operand Operand(
 152  E :      const BasicBlockAssembler::Displacement& displ) {
 153  E :    return BasicBlockAssembler::Operand(displ);
 154  E :  }
 155    :  
 156    :  BasicBlockAssembler::Operand Operand(
 157    :      const assm::Register32& base, const assm::Register32& index,
 158  E :      assm::ScaleFactor scale, const BasicBlockAssembler::Displacement& displ) {
 159  E :    return BasicBlockAssembler::Operand(base, index, scale, displ);
 160  E :  }
 161    :  
 162    :  BasicBlockAssembler::Operand Operand(const assm::Register32& base,
 163    :                                       const assm::Register32& index,
 164  E :                                       assm::ScaleFactor scale) {
 165  E :    return BasicBlockAssembler::Operand(base, index, scale);
 166  E :  }
 167    :  
 168    :  BasicBlockAssembler::Operand Operand(
 169    :      const assm::Register32& index, assm::ScaleFactor scale,
 170  E :      const BasicBlockAssembler::Displacement& displ) {
 171  E :    return BasicBlockAssembler::Operand(index, scale, displ);
 172  E :  }
 173    :  
 174    :  BasicBlockAssembler::BasicBlockSerializer::BasicBlockSerializer(
 175    :      const Instructions::iterator& where, Instructions* list)
 176  E :          : where_(where), list_(list) {
 177  E :    DCHECK(list != NULL);
 178  E :  }
 179    :  
 180    :  void BasicBlockAssembler::BasicBlockSerializer::AppendInstruction(
 181    :      uint32 location, const uint8* bytes, size_t num_bytes,
 182  E :      const ReferenceInfo* refs, size_t num_refs) {
 183  E :    Instruction instruction;
 184  E :    CHECK(Instruction::FromBuffer(bytes, num_bytes, &instruction));
 185  E :    instruction.set_source_range(source_range_);
 186    :  
 187  E :    Instructions::iterator it = list_->insert(where_, instruction);
 188    :  
 189  E :    for (size_t i = 0; i < num_refs; ++i) {
 190  E :      BasicBlockReference bbref = CompleteUntypedReference(refs[i]);
 191  E :      DCHECK(bbref.IsValid());
 192  E :      it->SetReference(refs[i].offset, bbref);
 193  E :    }
 194  E :  }
 195    :  
 196    :  bool BasicBlockAssembler::BasicBlockSerializer::FinalizeLabel(
 197  i :      uint32 location, const uint8* bytes, size_t num_bytes) {
 198    :    // No support for labels.
 199  i :    return false;
 200  i :  }
 201    :  
 202    :  BasicBlockAssembler::BasicBlockAssembler(const Instructions::iterator& where,
 203    :                                           Instructions* list)
 204  E :      : Super(0, &serializer_), serializer_(where, list) {
 205  E :  }
 206    :  
 207    :  BasicBlockAssembler::BasicBlockAssembler(uint32 location,
 208    :                                           const Instructions::iterator& where,
 209    :                                           Instructions* list)
 210  E :      : Super(location, &serializer_), serializer_(where, list) {
 211  E :  }
 212    :  
 213  E :  void BasicBlockAssembler::call(const Immediate& dst) {
 214    :    // In the context of BasicBlockAssembler it only makes sense for calls with
 215    :    // immediate parameters to be backed by a 32-bit reference.
 216  E :    DCHECK(dst.reference().IsValid());
 217  E :    DCHECK_EQ(assm::kSize32Bit, dst.size());
 218  E :    Super::call(dst);
 219  E :  }
 220    :  
 221  E :  void BasicBlockAssembler::call(const Operand& dst) {
 222  E :    const UntypedReference& ref = dst.displacement().reference();
 223  E :    DCHECK(!ref.IsValid() || dst.displacement().size() == assm::kSize32Bit);
 224  E :    Super::call(dst);
 225  E :  }
 226    :  
 227  E :  void BasicBlockAssembler::jmp(const Immediate& dst) {
 228  E :    DCHECK(dst.reference().IsValid());
 229  E :    Super::jmp(dst);
 230  E :  }
 231    :  
 232  E :  void BasicBlockAssembler::jmp(const Operand& dst) {
 233  E :    const UntypedReference& ref = dst.displacement().reference();
 234  E :    DCHECK(!ref.IsValid() || dst.displacement().size() == assm::kSize32Bit);
 235  E :    Super::jmp(dst);
 236  E :  }
 237    :  
 238  E :  void BasicBlockAssembler::j(ConditionCode code, const Immediate& dst) {
 239  E :    DCHECK(dst.reference().IsValid());
 240  E :    Super::j(code, dst);
 241  E :  }
 242    :  
 243    :  }  // namespace block_graph

Coverage information generated Thu Jan 14 17:40:38 2016.