[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / courgette / disassembler.cc
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "courgette/disassembler.h"
6
7 #include "base/check_op.h"
8 #include "base/memory/ptr_util.h"
9 #include "courgette/assembly_program.h"
10 #include "courgette/encoded_program.h"
11
12 namespace courgette {
13
14 Disassembler::RvaVisitor_Abs32::RvaVisitor_Abs32(
15     const std::vector<RVA>& rva_locations,
16     const AddressTranslator& translator)
17     : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
18 }
19
20 RVA Disassembler::RvaVisitor_Abs32::Get() const {
21   // For Abs32 targets, get target RVA from architecture-dependent functions.
22   return translator_.PointerToTargetRVA(translator_.RVAToPointer(*it_));
23 }
24
25 Disassembler::RvaVisitor_Rel32::RvaVisitor_Rel32(
26     const std::vector<RVA>& rva_locations,
27     const AddressTranslator& translator)
28     : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
29 }
30
31 RVA Disassembler::RvaVisitor_Rel32::Get() const {
32   // For Rel32 targets, only handle 32-bit offsets.
33   return *it_ + 4 + Read32LittleEndian(translator_.RVAToPointer(*it_));
34 }
35
36 Disassembler::Disassembler(const uint8_t* start, size_t length)
37     : failure_reason_("uninitialized") {
38   start_ = start;
39   length_ = length;
40   end_ = start_ + length_;
41 }
42
43 Disassembler::~Disassembler() = default;
44
45 const uint8_t* Disassembler::FileOffsetToPointer(FileOffset file_offset) const {
46   CHECK_LE(file_offset, static_cast<FileOffset>(end_ - start_));
47   return start_ + file_offset;
48 }
49
50 const uint8_t* Disassembler::RVAToPointer(RVA rva) const {
51   FileOffset file_offset = RVAToFileOffset(rva);
52   if (file_offset == kNoFileOffset)
53     return nullptr;
54
55   return FileOffsetToPointer(file_offset);
56 }
57
58 std::unique_ptr<AssemblyProgram> Disassembler::CreateProgram(bool annotate) {
59   if (!ok() || !ExtractAbs32Locations() || !ExtractRel32Locations())
60     return nullptr;
61
62   std::unique_ptr<AssemblyProgram> program =
63       std::make_unique<AssemblyProgram>(kind(), image_base());
64
65   PrecomputeLabels(program.get());
66   RemoveUnusedRel32Locations(program.get());
67   program->DefaultAssignIndexes();
68
69   if (annotate) {
70     if (!program->AnnotateLabels(GetInstructionGenerator(program.get())))
71       return nullptr;
72   }
73
74   return program;
75 }
76
77 Status Disassembler::DisassembleAndEncode(AssemblyProgram* program,
78                                           EncodedProgram* encoded) {
79   program->PrepareEncodedProgram(encoded);
80   return encoded->GenerateInstructions(program->kind(),
81                                        GetInstructionGenerator(program))
82              ? C_OK
83              : C_DISASSEMBLY_FAILED;
84 }
85
86 bool Disassembler::Good() {
87   failure_reason_ = nullptr;
88   return true;
89 }
90
91 bool Disassembler::Bad(const char* reason) {
92   failure_reason_ = reason;
93   return false;
94 }
95
96 void Disassembler::PrecomputeLabels(AssemblyProgram* program) {
97   std::unique_ptr<RvaVisitor> abs32_visitor(CreateAbs32TargetRvaVisitor());
98   std::unique_ptr<RvaVisitor> rel32_visitor(CreateRel32TargetRvaVisitor());
99   program->PrecomputeLabels(abs32_visitor.get(), rel32_visitor.get());
100 }
101
102 void Disassembler::ReduceLength(size_t reduced_length) {
103   CHECK_LE(reduced_length, length_);
104   length_ = reduced_length;
105   end_ = start_ + length_;
106 }
107
108 }  // namespace courgette