| Index: courgette/encoded_program.cc
|
| diff --git a/courgette/encoded_program.cc b/courgette/encoded_program.cc
|
| index e14b37efeba46fc615fd8bdff5471d5b7ef51bbd..129728a79860b47b20f216fbeaa08505f1769eeb 100644
|
| --- a/courgette/encoded_program.cc
|
| +++ b/courgette/encoded_program.cc
|
| @@ -137,38 +137,15 @@ bool ReadVectorU8(V* items, SourceStream* buffer) {
|
| EncodedProgram::EncodedProgram() {}
|
| EncodedProgram::~EncodedProgram() {}
|
|
|
| -CheckBool EncodedProgram::DefineLabels(const RVAToLabel& abs32_labels,
|
| - const RVAToLabel& rel32_labels) {
|
| - // which == 0 => abs32; which == 1 => rel32.
|
| - for (int which = 0; which < 2; ++which) {
|
| - const RVAToLabel& labels = which == 0 ? abs32_labels : rel32_labels;
|
| - RvaVector& rvas = which == 0 ? abs32_rva_ : rel32_rva_;
|
| -
|
| - if (!rvas.resize(LabelManager::GetIndexBound(labels), kUnassignedRVA))
|
| - return false;
|
| -
|
| - // For each Label, write its RVA to assigned index.
|
| - for (const auto& rva_and_label : labels) {
|
| - const Label& label = *rva_and_label.second;
|
| - DCHECK_EQ(rva_and_label.first, label.rva_);
|
| - DCHECK_NE(label.index_, Label::kNoIndex);
|
| - DCHECK_EQ(rvas[label.index_], kUnassignedRVA)
|
| - << "DefineLabels() double assigned " << label.index_;
|
| - rvas[label.index_] = label.rva_;
|
| - }
|
| -
|
| - // Replace all unassigned slots with the value at the previous index so they
|
| - // delta-encode to zero. (There might be better values than zero. The way to
|
| - // get that is have the higher level assembly program assign the unassigned
|
| - // slots.)
|
| - RVA previous = 0;
|
| - for (RVA& rva : rvas) {
|
| - if (rva == kUnassignedRVA)
|
| - rva = previous;
|
| - else
|
| - previous = rva;
|
| - }
|
| +CheckBool EncodedProgram::ImportLabels(
|
| + const LabelManager& abs32_label_manager,
|
| + const LabelManager& rel32_label_manager) {
|
| + if (!WriteRvasToList(abs32_label_manager, &abs32_rva_) ||
|
| + !WriteRvasToList(rel32_label_manager, &rel32_rva_)) {
|
| + return false;
|
| }
|
| + FillUnassignedRvaSlots(&abs32_rva_);
|
| + FillUnassignedRvaSlots(&rel32_rva_);
|
| return true;
|
| }
|
|
|
| @@ -733,6 +710,43 @@ class RelocBlock {
|
| RelocBlockPOD pod;
|
| };
|
|
|
| +// static
|
| +// Updates |rvas| so |rvas[label.index_] == label.rva_| for each |label| in
|
| +// |label_manager|, assuming |label.index_| is properly assigned. Takes care of
|
| +// |rvas| resizing. Unused slots in |rvas| are assigned |kUnassignedRVA|.
|
| +// Returns true on success, and false otherwise.
|
| +CheckBool EncodedProgram::WriteRvasToList(const LabelManager& label_manager,
|
| + RvaVector* rvas) {
|
| + rvas->clear();
|
| + int index_bound = LabelManager::GetLabelIndexBound(label_manager.Labels());
|
| + if (!rvas->resize(index_bound, kUnassignedRVA))
|
| + return false;
|
| +
|
| + // For each Label, write its RVA to assigned index.
|
| + for (const Label& label : label_manager.Labels()) {
|
| + DCHECK_NE(label.index_, Label::kNoIndex);
|
| + DCHECK_EQ((*rvas)[label.index_], kUnassignedRVA)
|
| + << "ExportToList() double assigned " << label.index_;
|
| + (*rvas)[label.index_] = label.rva_;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// static
|
| +// Replaces all unassigned slots in |rvas| with the value at the previous index
|
| +// so they delta-encode to zero. (There might be better values than zero. The
|
| +// way to get that is have the higher level assembly program assign the
|
| +// unassigned slots.)
|
| +void EncodedProgram::FillUnassignedRvaSlots(RvaVector* rvas) {
|
| + RVA previous = 0;
|
| + for (RVA& rva : *rvas) {
|
| + if (rva == kUnassignedRVA)
|
| + rva = previous;
|
| + else
|
| + previous = rva;
|
| + }
|
| +}
|
| +
|
| CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer,
|
| uint8_t type) {
|
| std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
|
|
|