OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/encoded_program.h" | 5 #include "courgette/encoded_program.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } // namespace | 130 } // namespace |
131 | 131 |
132 //////////////////////////////////////////////////////////////////////////////// | 132 //////////////////////////////////////////////////////////////////////////////// |
133 | 133 |
134 // Constructor is here rather than in the header. Although the constructor | 134 // Constructor is here rather than in the header. Although the constructor |
135 // appears to do nothing it is fact quite large because of the implicit calls to | 135 // appears to do nothing it is fact quite large because of the implicit calls to |
136 // field constructors. Ditto for the destructor. | 136 // field constructors. Ditto for the destructor. |
137 EncodedProgram::EncodedProgram() {} | 137 EncodedProgram::EncodedProgram() {} |
138 EncodedProgram::~EncodedProgram() {} | 138 EncodedProgram::~EncodedProgram() {} |
139 | 139 |
140 CheckBool EncodedProgram::DefineLabels(const RVAToLabel& abs32_labels, | 140 CheckBool EncodedProgram::ImportLabels( |
141 const RVAToLabel& rel32_labels) { | 141 const LabelManager& abs32_label_manager, |
142 // which == 0 => abs32; which == 1 => rel32. | 142 const LabelManager& rel32_label_manager) { |
143 for (int which = 0; which < 2; ++which) { | 143 if (!WriteRvasToList(abs32_label_manager, &abs32_rva_) || |
144 const RVAToLabel& labels = which == 0 ? abs32_labels : rel32_labels; | 144 !WriteRvasToList(rel32_label_manager, &rel32_rva_)) { |
145 RvaVector& rvas = which == 0 ? abs32_rva_ : rel32_rva_; | 145 return false; |
146 | |
147 if (!rvas.resize(LabelManager::GetIndexBound(labels), kUnassignedRVA)) | |
148 return false; | |
149 | |
150 // For each Label, write its RVA to assigned index. | |
151 for (const auto& rva_and_label : labels) { | |
152 const Label& label = *rva_and_label.second; | |
153 DCHECK_EQ(rva_and_label.first, label.rva_); | |
154 DCHECK_NE(label.index_, Label::kNoIndex); | |
155 DCHECK_EQ(rvas[label.index_], kUnassignedRVA) | |
156 << "DefineLabels() double assigned " << label.index_; | |
157 rvas[label.index_] = label.rva_; | |
158 } | |
159 | |
160 // Replace all unassigned slots with the value at the previous index so they | |
161 // delta-encode to zero. (There might be better values than zero. The way to | |
162 // get that is have the higher level assembly program assign the unassigned | |
163 // slots.) | |
164 RVA previous = 0; | |
165 for (RVA& rva : rvas) { | |
166 if (rva == kUnassignedRVA) | |
167 rva = previous; | |
168 else | |
169 previous = rva; | |
170 } | |
171 } | 146 } |
| 147 FillUnassignedRvaSlots(&abs32_rva_); |
| 148 FillUnassignedRvaSlots(&rel32_rva_); |
172 return true; | 149 return true; |
173 } | 150 } |
174 | 151 |
175 CheckBool EncodedProgram::AddOrigin(RVA origin) { | 152 CheckBool EncodedProgram::AddOrigin(RVA origin) { |
176 return ops_.push_back(ORIGIN) && origins_.push_back(origin); | 153 return ops_.push_back(ORIGIN) && origins_.push_back(origin); |
177 } | 154 } |
178 | 155 |
179 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) { | 156 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) { |
180 const uint8_t* source = static_cast<const uint8_t*>(bytes); | 157 const uint8_t* source = static_cast<const uint8_t*>(bytes); |
181 | 158 |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 Add(0); | 703 Add(0); |
727 } | 704 } |
728 ok = buffer->Write(&pod, pod.block_size); | 705 ok = buffer->Write(&pod, pod.block_size); |
729 pod.block_size = 8; | 706 pod.block_size = 8; |
730 } | 707 } |
731 return ok; | 708 return ok; |
732 } | 709 } |
733 RelocBlockPOD pod; | 710 RelocBlockPOD pod; |
734 }; | 711 }; |
735 | 712 |
| 713 // static |
| 714 // Updates |rvas| so |rvas[label.index_] == label.rva_| for each |label| in |
| 715 // |label_manager|, assuming |label.index_| is properly assigned. Takes care of |
| 716 // |rvas| resizing. Unused slots in |rvas| are assigned |kUnassignedRVA|. |
| 717 // Returns true on success, and false otherwise. |
| 718 CheckBool EncodedProgram::WriteRvasToList(const LabelManager& label_manager, |
| 719 RvaVector* rvas) { |
| 720 rvas->clear(); |
| 721 int index_bound = LabelManager::GetLabelIndexBound(label_manager.Labels()); |
| 722 if (!rvas->resize(index_bound, kUnassignedRVA)) |
| 723 return false; |
| 724 |
| 725 // For each Label, write its RVA to assigned index. |
| 726 for (const Label& label : label_manager.Labels()) { |
| 727 DCHECK_NE(label.index_, Label::kNoIndex); |
| 728 DCHECK_EQ((*rvas)[label.index_], kUnassignedRVA) |
| 729 << "ExportToList() double assigned " << label.index_; |
| 730 (*rvas)[label.index_] = label.rva_; |
| 731 } |
| 732 return true; |
| 733 } |
| 734 |
| 735 // static |
| 736 // Replaces all unassigned slots in |rvas| with the value at the previous index |
| 737 // so they delta-encode to zero. (There might be better values than zero. The |
| 738 // way to get that is have the higher level assembly program assign the |
| 739 // unassigned slots.) |
| 740 void EncodedProgram::FillUnassignedRvaSlots(RvaVector* rvas) { |
| 741 RVA previous = 0; |
| 742 for (RVA& rva : *rvas) { |
| 743 if (rva == kUnassignedRVA) |
| 744 rva = previous; |
| 745 else |
| 746 previous = rva; |
| 747 } |
| 748 } |
| 749 |
736 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer, | 750 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer, |
737 uint8_t type) { | 751 uint8_t type) { |
738 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); | 752 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); |
739 DCHECK(abs32_relocs_.empty() || abs32_relocs_.back() != kUnassignedRVA); | 753 DCHECK(abs32_relocs_.empty() || abs32_relocs_.back() != kUnassignedRVA); |
740 | 754 |
741 RelocBlock block; | 755 RelocBlock block; |
742 | 756 |
743 bool ok = true; | 757 bool ok = true; |
744 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) { | 758 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) { |
745 uint32_t rva = abs32_relocs_[i]; | 759 uint32_t rva = abs32_relocs_[i]; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 } | 806 } |
793 | 807 |
794 Status Assemble(EncodedProgram* encoded, SinkStream* buffer) { | 808 Status Assemble(EncodedProgram* encoded, SinkStream* buffer) { |
795 bool assembled = encoded->AssembleTo(buffer); | 809 bool assembled = encoded->AssembleTo(buffer); |
796 if (assembled) | 810 if (assembled) |
797 return C_OK; | 811 return C_OK; |
798 return C_ASSEMBLY_FAILED; | 812 return C_ASSEMBLY_FAILED; |
799 } | 813 } |
800 | 814 |
801 } // namespace courgette | 815 } // namespace courgette |
OLD | NEW |