1 // Copyright 2017 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.
5 #ifndef COURGETTE_COURGETTE_FLOW_H_
6 #define COURGETTE_COURGETTE_FLOW_H_
11 #include "courgette/courgette.h"
12 #include "courgette/region.h"
13 #include "courgette/streams.h"
17 class AssemblyProgram;
21 // An adaptor for Region as BasicBuffer.
22 class RegionBuffer : public BasicBuffer {
24 explicit RegionBuffer(const Region& region) : region_(region) {}
26 RegionBuffer(const RegionBuffer&) = delete;
27 RegionBuffer& operator=(const RegionBuffer&) = delete;
29 ~RegionBuffer() override {}
32 const uint8_t* data() const override { return region_.start(); }
33 size_t length() const override { return region_.length(); }
39 // CourgetteFlow stores Courgette data arranged into groups, and exposes
40 // "commands" that operate on them. On the first occurrence of an error, the
41 // Courgette error code is recorded, error messages are generated and stored,
42 // and all subsequent commands become no-op. This allows callers to concisely
43 // specify high-level logic with minimal code for error handling.
46 // A group of Courgette data, for a single executable. Takes negligible space
52 std::unique_ptr<Disassembler> disassembler;
53 std::unique_ptr<AssemblyProgram> program;
54 std::unique_ptr<EncodedProgram> encoded;
56 SourceStreamSet sources;
59 // Group enumeration into |data_*_| fields.
61 ONLY, // The only file processed.
62 OLD, // The "old" file during patching.
63 NEW, // The "new" file during patching.
68 CourgetteFlow(const CourgetteFlow&) = delete;
69 CourgetteFlow& operator=(const CourgetteFlow&) = delete;
73 static const char* name(Group group);
74 Data* data(Group group); // Allows caller to modify.
78 const std::string& message();
80 // Commands that perform no-op on error. This allows caller to concisely
81 // specify high-level logic, and perform a single error check at the end. Care
82 // must be taken w.r.t. error handling if |data()| is harvested between
85 // Reads |buffer| to initialize |data(group)->sources|.
86 void ReadSourceStreamSetFromBuffer(Group group, const BasicBuffer& buffer);
88 // Reads |buffer| to initialize |data(group)->disassembler|.
89 void ReadDisassemblerFromBuffer(Group group, const BasicBuffer& buffer);
91 // Reads |opt_sources| if given, or else |data(group)->sources| to initialize
92 // |data(group).encoded|.
93 void ReadEncodedProgramFromSourceStreamSet(
95 SourceStreamSet* opt_sources = nullptr);
97 // Uses |data(group)->disassembler| to initialize |data(group)->program|,
98 // passing |annotate| as initialization parameter (should be true if
99 // AdjustNewAssemblyProgramToMatchOld() gets called later).
100 void CreateAssemblyProgramFromDisassembler(Group group, bool annotate);
102 // Uses |data(group)->disassembler| and |data(group)->program| to initialize
103 // |data(group)->encoded|.
104 void CreateEncodedProgramFromDisassemblerAndAssemblyProgram(Group group);
106 // Serializese |data(group)->sinks| to |sink|.
107 void WriteSinkStreamFromSinkStreamSet(Group group, SinkStream* sink);
109 // Serializes |data(group)->encoded| to |opt_sinks| if given, or else to
110 // |data(group)->sinks|.
111 void WriteSinkStreamSetFromEncodedProgram(Group group,
112 SinkStreamSet* opt_sinks = nullptr);
114 // Converts |data(group)->encoded| to an exectuable and writes the result to
116 void WriteExecutableFromEncodedProgram(Group group, SinkStream* sink);
118 // Adjusts |data(NEW)->program| Labels to match |data(OLD)->program| Labels.
119 void AdjustNewAssemblyProgramToMatchOld();
121 // Destructor commands to reduce memory usage.
123 void DestroyDisassembler(Group group);
125 void DestroyAssemblyProgram(Group group);
127 void DestroyEncodedProgram(Group group);
130 // Utilities to process return values from Courgette functions, and assign
131 // |status_| and |message_|. Usage:
132 // if (!check(some_courgette_function(param1, ...)))
133 // setMessage("format string %s...", value1, ...);
135 // Reassigns |status_|, and returns true if |C_OK|.
136 bool check(Status new_status);
138 // check() alternative for functions that return true on success. On failure
139 // assigns |status_| to |failure_mode|.
140 bool check(bool success, Status failure_mode);
142 void setMessage(const char* format, ...);
144 Status status_ = C_OK;
145 std::string message_;
151 } // namespace courgette
153 #endif // COURGETTE_COURGETTE_FLOW_H_