courgette_flow.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COURGETTE_COURGETTE_FLOW_H_
  5. #define COURGETTE_COURGETTE_FLOW_H_
  6. #include <memory>
  7. #include <string>
  8. #include "courgette/courgette.h"
  9. #include "courgette/region.h"
  10. #include "courgette/streams.h"
  11. namespace courgette {
  12. class AssemblyProgram;
  13. class Disassembler;
  14. class EncodedProgram;
  15. // An adaptor for Region as BasicBuffer.
  16. class RegionBuffer : public BasicBuffer {
  17. public:
  18. explicit RegionBuffer(const Region& region) : region_(region) {}
  19. RegionBuffer(const RegionBuffer&) = delete;
  20. RegionBuffer& operator=(const RegionBuffer&) = delete;
  21. ~RegionBuffer() override {}
  22. // BasicBuffer:
  23. const uint8_t* data() const override { return region_.start(); }
  24. size_t length() const override { return region_.length(); }
  25. private:
  26. Region region_;
  27. };
  28. // CourgetteFlow stores Courgette data arranged into groups, and exposes
  29. // "commands" that operate on them. On the first occurrence of an error, the
  30. // Courgette error code is recorded, error messages are generated and stored,
  31. // and all subsequent commands become no-op. This allows callers to concisely
  32. // specify high-level logic with minimal code for error handling.
  33. class CourgetteFlow {
  34. public:
  35. // A group of Courgette data, for a single executable. Takes negligible space
  36. // when unused.
  37. struct Data {
  38. Data();
  39. ~Data();
  40. std::unique_ptr<Disassembler> disassembler;
  41. std::unique_ptr<AssemblyProgram> program;
  42. std::unique_ptr<EncodedProgram> encoded;
  43. SinkStreamSet sinks;
  44. SourceStreamSet sources;
  45. };
  46. // Group enumeration into |data_*_| fields.
  47. enum Group {
  48. ONLY, // The only file processed.
  49. OLD, // The "old" file during patching.
  50. NEW, // The "new" file during patching.
  51. };
  52. CourgetteFlow();
  53. CourgetteFlow(const CourgetteFlow&) = delete;
  54. CourgetteFlow& operator=(const CourgetteFlow&) = delete;
  55. ~CourgetteFlow();
  56. static const char* name(Group group);
  57. Data* data(Group group); // Allows caller to modify.
  58. bool ok();
  59. bool failed();
  60. Status status();
  61. const std::string& message();
  62. // Commands that perform no-op on error. This allows caller to concisely
  63. // specify high-level logic, and perform a single error check at the end. Care
  64. // must be taken w.r.t. error handling if |data()| is harvested between
  65. // commands.
  66. // Reads |buffer| to initialize |data(group)->sources|.
  67. void ReadSourceStreamSetFromBuffer(Group group, const BasicBuffer& buffer);
  68. // Reads |buffer| to initialize |data(group)->disassembler|.
  69. void ReadDisassemblerFromBuffer(Group group, const BasicBuffer& buffer);
  70. // Reads |opt_sources| if given, or else |data(group)->sources| to initialize
  71. // |data(group).encoded|.
  72. void ReadEncodedProgramFromSourceStreamSet(
  73. Group group,
  74. SourceStreamSet* opt_sources = nullptr);
  75. // Uses |data(group)->disassembler| to initialize |data(group)->program|,
  76. // passing |annotate| as initialization parameter (should be true if
  77. // AdjustNewAssemblyProgramToMatchOld() gets called later).
  78. void CreateAssemblyProgramFromDisassembler(Group group, bool annotate);
  79. // Uses |data(group)->disassembler| and |data(group)->program| to initialize
  80. // |data(group)->encoded|.
  81. void CreateEncodedProgramFromDisassemblerAndAssemblyProgram(Group group);
  82. // Serializese |data(group)->sinks| to |sink|.
  83. void WriteSinkStreamFromSinkStreamSet(Group group, SinkStream* sink);
  84. // Serializes |data(group)->encoded| to |opt_sinks| if given, or else to
  85. // |data(group)->sinks|.
  86. void WriteSinkStreamSetFromEncodedProgram(Group group,
  87. SinkStreamSet* opt_sinks = nullptr);
  88. // Converts |data(group)->encoded| to an exectuable and writes the result to
  89. // |sink|.
  90. void WriteExecutableFromEncodedProgram(Group group, SinkStream* sink);
  91. // Adjusts |data(NEW)->program| Labels to match |data(OLD)->program| Labels.
  92. void AdjustNewAssemblyProgramToMatchOld();
  93. // Destructor commands to reduce memory usage.
  94. void DestroyDisassembler(Group group);
  95. void DestroyAssemblyProgram(Group group);
  96. void DestroyEncodedProgram(Group group);
  97. private:
  98. // Utilities to process return values from Courgette functions, and assign
  99. // |status_| and |message_|. Usage:
  100. // if (!check(some_courgette_function(param1, ...)))
  101. // setMessage("format string %s...", value1, ...);
  102. // Reassigns |status_|, and returns true if |C_OK|.
  103. bool check(Status new_status);
  104. // check() alternative for functions that return true on success. On failure
  105. // assigns |status_| to |failure_mode|.
  106. bool check(bool success, Status failure_mode);
  107. void setMessage(const char* format, ...);
  108. Status status_ = C_OK;
  109. std::string message_;
  110. Data data_only_;
  111. Data data_old_;
  112. Data data_new_;
  113. };
  114. } // namespace courgette
  115. #endif // COURGETTE_COURGETTE_FLOW_H_