Coverage for /Syzygy/block_graph/basic_block_assembler.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
96.2%1281330.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_t 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  E :    if (info.reference.referred_type() ==
  54    :            BasicBlockReference::REFERRED_TYPE_BLOCK) {
  55  E :      DCHECK(info.reference.block() != NULL);
  56  E :      return BasicBlockReference(type, size, info.reference.block(),
  57    :                                 info.reference.offset(), info.reference.base());
  58    :    }
  59    :  
  60  E :    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_t value) {
  73  E :    return BasicBlockAssembler::Immediate(value, ValueSizeFromConstant(value));
  74  E :  }
  75    :  
  76  E :  BasicBlockAssembler::Immediate Immediate(uint32_t value, ValueSize size) {
  77  E :    return BasicBlockAssembler::Immediate(value, size);
  78  E :  }
  79    :  
  80  E :  BasicBlockAssembler::Immediate Immediate(BasicBlock* bb) {
  81  E :    return BasicBlockAssembler::Immediate(
  82    :        0, assm::kSize32Bit, UntypedReference(bb));
  83  E :  }
  84    :  
  85    :  BasicBlockAssembler::Immediate Immediate(
  86  E :      BlockGraph::Block* block, BlockGraph::Offset offset) {
  87  E :    return BasicBlockAssembler::Immediate(
  88    :        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  E :    return BasicBlockAssembler::Immediate(
  95    :        0, assm::kSize32Bit, UntypedReference(block, offset, base));
  96  E :  }
  97    :  
  98    :  BasicBlockAssembler::Immediate Immediate(uint32_t value,
  99    :                                           ValueSize size,
 100  E :                                           const UntypedReference& ref) {
 101  E :    DCHECK(ref.IsValid());
 102  E :    return BasicBlockAssembler::Immediate(value, size, ref);
 103  E :  }
 104    :  
 105  E :  BasicBlockAssembler::Displacement Displacement() {
 106  E :    return BasicBlockAssembler::Displacement();
 107  E :  }
 108    :  
 109  E :  BasicBlockAssembler::Displacement Displacement(uint32_t value) {
 110  E :    return BasicBlockAssembler::Displacement(value,
 111    :                                             ValueSizeFromConstant(value));
 112  E :  }
 113    :  
 114  E :  BasicBlockAssembler::Displacement Displacement(uint32_t value, ValueSize size) {
 115  E :    return BasicBlockAssembler::Displacement(value, size);
 116  E :  }
 117    :  
 118  E :  BasicBlockAssembler::Displacement Displacement(BasicBlock* bb) {
 119  E :    return BasicBlockAssembler::Displacement(
 120    :        0, assm::kSize32Bit, UntypedReference(bb));
 121  E :  }
 122    :  
 123    :  BasicBlockAssembler::Displacement Displacement(
 124  E :      BlockGraph::Block* block, BlockGraph::Offset offset) {
 125  E :    return BasicBlockAssembler::Displacement(
 126    :        0, assm::kSize32Bit, UntypedReference(block, offset, offset));
 127  E :  }
 128    :  
 129    :  BasicBlockAssembler::Displacement Displacement(
 130    :      BlockGraph::Block* block, BlockGraph::Offset offset,
 131  E :      BlockGraph::Offset base) {
 132  E :    return BasicBlockAssembler::Displacement(
 133    :        0, assm::kSize32Bit, UntypedReference(block, offset, base));
 134  E :  }
 135    :  
 136    :  BasicBlockAssembler::Displacement Displacement(uint32_t value,
 137    :                                                 ValueSize size,
 138  E :                                                 const UntypedReference& ref) {
 139  E :    DCHECK(ref.IsValid());
 140  E :    return BasicBlockAssembler::Displacement(value, size, ref);
 141  E :  }
 142    :  
 143  E :  BasicBlockAssembler::Operand Operand(const assm::Register32& base) {
 144  E :    return BasicBlockAssembler::Operand(base);
 145  E :  }
 146    :  
 147    :  BasicBlockAssembler::Operand Operand(
 148    :      const assm::Register32& base,
 149  E :      const BasicBlockAssembler::Displacement& displ) {
 150  E :    return BasicBlockAssembler::Operand(base, displ);
 151  E :  }
 152    :  
 153    :  BasicBlockAssembler::Operand Operand(
 154  E :      const BasicBlockAssembler::Displacement& displ) {
 155  E :    return BasicBlockAssembler::Operand(displ);
 156  E :  }
 157    :  
 158    :  BasicBlockAssembler::Operand Operand(
 159    :      const assm::Register32& base, const assm::Register32& index,
 160  E :      assm::ScaleFactor scale, const BasicBlockAssembler::Displacement& displ) {
 161  E :    return BasicBlockAssembler::Operand(base, index, scale, displ);
 162  E :  }
 163    :  
 164    :  BasicBlockAssembler::Operand Operand(const assm::Register32& base,
 165    :                                       const assm::Register32& index,
 166  E :                                       assm::ScaleFactor scale) {
 167  E :    return BasicBlockAssembler::Operand(base, index, scale);
 168  E :  }
 169    :  
 170    :  BasicBlockAssembler::Operand Operand(
 171    :      const assm::Register32& index, assm::ScaleFactor scale,
 172  E :      const BasicBlockAssembler::Displacement& displ) {
 173  E :    return BasicBlockAssembler::Operand(index, scale, displ);
 174  E :  }
 175    :  
 176    :  BasicBlockAssembler::BasicBlockSerializer::BasicBlockSerializer(
 177    :      const Instructions::iterator& where, Instructions* list)
 178  E :          : where_(where), list_(list) {
 179  E :    DCHECK(list != NULL);
 180  E :  }
 181    :  
 182    :  void BasicBlockAssembler::BasicBlockSerializer::AppendInstruction(
 183    :      uint32_t location,
 184    :      const uint8_t* bytes,
 185    :      uint32_t num_bytes,
 186    :      const ReferenceInfo* refs,
 187  E :      size_t num_refs) {
 188  E :    Instruction instruction;
 189  E :    CHECK(Instruction::FromBuffer(bytes, num_bytes, &instruction));
 190  E :    instruction.set_source_range(source_range_);
 191    :  
 192  E :    Instructions::iterator it = list_->insert(where_, instruction);
 193    :  
 194  E :    for (size_t i = 0; i < num_refs; ++i) {
 195  E :      BasicBlockReference bbref = CompleteUntypedReference(refs[i]);
 196  E :      DCHECK(bbref.IsValid());
 197  E :      it->SetReference(refs[i].offset, bbref);
 198  E :    }
 199  E :  }
 200    :  
 201    :  bool BasicBlockAssembler::BasicBlockSerializer::FinalizeLabel(
 202    :      uint32_t location,
 203    :      const uint8_t* bytes,
 204  i :      size_t num_bytes) {
 205    :    // No support for labels.
 206  i :    return false;
 207  i :  }
 208    :  
 209    :  BasicBlockAssembler::BasicBlockAssembler(const Instructions::iterator& where,
 210    :                                           Instructions* list)
 211  E :      : Super(0, &serializer_), serializer_(where, list) {
 212  E :  }
 213    :  
 214    :  BasicBlockAssembler::BasicBlockAssembler(uint32_t location,
 215    :                                           const Instructions::iterator& where,
 216    :                                           Instructions* list)
 217  E :      : Super(location, &serializer_), serializer_(where, list) {
 218  E :  }
 219    :  
 220  E :  void BasicBlockAssembler::call(const Immediate& dst) {
 221    :    // In the context of BasicBlockAssembler it only makes sense for calls with
 222    :    // immediate parameters to be backed by a 32-bit reference.
 223  E :    DCHECK(dst.reference().IsValid());
 224  E :    DCHECK_EQ(assm::kSize32Bit, dst.size());
 225  E :    Super::call(dst);
 226  E :  }
 227    :  
 228  E :  void BasicBlockAssembler::call(const Operand& dst) {
 229  E :    const UntypedReference& ref = dst.displacement().reference();
 230  E :    DCHECK(!ref.IsValid() || dst.displacement().size() == assm::kSize32Bit);
 231  E :    Super::call(dst);
 232  E :  }
 233    :  
 234  E :  void BasicBlockAssembler::jmp(const Immediate& dst) {
 235  E :    DCHECK(dst.reference().IsValid());
 236  E :    Super::jmp(dst);
 237  E :  }
 238    :  
 239  E :  void BasicBlockAssembler::jmp(const Operand& dst) {
 240  E :    const UntypedReference& ref = dst.displacement().reference();
 241  E :    DCHECK(!ref.IsValid() || dst.displacement().size() == assm::kSize32Bit);
 242  E :    Super::jmp(dst);
 243  E :  }
 244    :  
 245  E :  void BasicBlockAssembler::j(ConditionCode code, const Immediate& dst) {
 246  E :    DCHECK(dst.reference().IsValid());
 247  E :    Super::j(code, dst);
 248  E :  }
 249    :  
 250    :  }  // namespace block_graph

Coverage information generated Fri Jul 29 11:00:21 2016.