123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- // Copyright (c) 2011 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_
- #define COURGETTE_ASSEMBLY_PROGRAM_H_
- #include <stdint.h>
- #include <vector>
- #include "courgette/courgette.h"
- #include "courgette/image_utils.h"
- #include "courgette/instruction_utils.h"
- #include "courgette/label_manager.h"
- #include "courgette/memory_allocator.h" // For CheckBool.
- namespace courgette {
- class EncodedProgram;
- // An AssemblyProgram stores Labels extracted from an executable file, and
- // (optionally) Label annotations. It is initialized by a Disassembler, but
- // stores separate state so that the Disassembler can be deleted. Typical usage:
- //
- // * The Disassembler calls PrecomputeLabels() and injects RVAs for abs32/rel32
- // references. These are used to initialize labels.
- // * The Disassembler calls DefaultAssignIndexes() to assign addresses to
- // positions in the address tables.
- // * [Optional step]
- // * The Disassembler can use Labels in AssemblyProgram to convert the
- // executable file to an EncodedProgram, serialized to an output stream.
- // * Later, the Disassembler can use the AssemblyProgram to can be deserialized
- // and assembled into the original executable file via an EncodedProgram.
- //
- // The optional step is to adjust Labels in the AssemblyProgram. One form of
- // adjustment is to assign indexes in such a way as to make the EncodedProgram
- // for an executable look more like the EncodedProgram for another exectuable.
- // The adjustment process should call UnassignIndexes(), do its own assignment,
- // and then call AssignRemainingIndexes() to ensure all indexes are assigned.
- class AssemblyProgram {
- public:
- AssemblyProgram(ExecutableType kind, uint64_t image_base);
- AssemblyProgram(const AssemblyProgram&) = delete;
- AssemblyProgram& operator=(const AssemblyProgram&) = delete;
- ~AssemblyProgram();
- ExecutableType kind() const { return kind_; }
- const std::vector<Label*>& abs32_label_annotations() const {
- return abs32_label_annotations_;
- }
- const std::vector<Label*>& rel32_label_annotations() const {
- return rel32_label_annotations_;
- }
- // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels.
- void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor);
- void UnassignIndexes();
- void DefaultAssignIndexes();
- void AssignRemainingIndexes();
- // Looks up abs32 label. Returns null if none found.
- Label* FindAbs32Label(RVA rva);
- // Looks up rel32 label. Returns null if none found.
- Label* FindRel32Label(RVA rva);
- // Uses |gen| to initializes |*_label_annotations_|.
- CheckBool AnnotateLabels(const InstructionGenerator& gen);
- // Initializes |encoded| by injecting basic data and Label data.
- bool PrepareEncodedProgram(EncodedProgram* encoded) const;
- private:
- static const int kLabelLowerLimit;
- // Looks up a label or creates a new one. Might return nullptr.
- Label* FindLabel(RVA rva, RVAToLabel* labels);
- const ExecutableType kind_;
- const uint64_t image_base_; // Desired or mandated base address of image.
- // Storage and lookup of Labels associated with target addresses. We use
- // separate abs32 and rel32 labels.
- LabelManager abs32_label_manager_;
- LabelManager rel32_label_manager_;
- // Label pointers for each abs32 and rel32 location, sorted by file offset.
- // These are used by Label adjustment during patch generation.
- std::vector<Label*> abs32_label_annotations_;
- std::vector<Label*> rel32_label_annotations_;
- };
- } // namespace courgette
- #endif // COURGETTE_ASSEMBLY_PROGRAM_H_
|