15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef COURGETTE_COURGETTE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COURGETTE_COURGETTE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h>   // Required to define size_t on GCC
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace courgette {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Status codes for Courgette APIs.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Client code should only rely on the distintion between C_OK and the other
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// status codes.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum Status {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_OK = 1,                       // Successful operation.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_GENERAL_ERROR = 2,            // Error other than listed below.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_READ_OPEN_ERROR = 3,          // Could not open input file for reading.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_READ_ERROR = 4,               // Could not read from opened input file.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_WRITE_OPEN_ERROR = 3,         // Could not open output file for writing.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_WRITE_ERROR = 4,              // Could not write to opened output file.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BAD_ENSEMBLE_MAGIC = 5,       // Ensemble patch has bad magic.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BAD_ENSEMBLE_VERSION = 6,     // Ensemble patch has wrong version.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BAD_ENSEMBLE_HEADER = 7,      // Ensemble patch has corrupt header.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BAD_ENSEMBLE_CRC = 8,         // Ensemble patch has corrupt data.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BAD_TRANSFORM = 12,           // Transform mis-specified.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BAD_BASE = 13,                // Base for transform malformed.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_BINARY_DIFF_CRC_ERROR = 14,   // Internal diff input doesn't have expected
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  // CRC.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Internal errors.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_STREAM_ERROR = 20,            // Unexpected error from streams.h.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_STREAM_NOT_CONSUMED = 21,     // Stream has extra data, is expected to be
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  // used up.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_SERIALIZATION_FAILED = 22,    //
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_DESERIALIZATION_FAILED = 23,  //
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_INPUT_NOT_RECOGNIZED = 24,    // Unrecognized input (not an executable).
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_DISASSEMBLY_FAILED = 25,      //
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_ASSEMBLY_FAILED = 26,         //
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C_ADJUSTMENT_FAILED = 27,       //
512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  C_TRIM_FAILED = 28,             // TrimLabels failed
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What type of executable is something
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is part of the patch format. Never reuse an id number.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ExecutableType {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXE_UNKNOWN = 0,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXE_WIN_32_X86 = 1,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXE_ELF_32_X86 = 2,
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXE_ELF_32_ARM = 3,
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXE_WIN_32_X64 = 4,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SinkStream;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SinkStreamSet;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SourceStream;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SourceStreamSet;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AssemblyProgram;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EncodedProgram;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Applies the patch to the bytes in |old| and writes the transformed ensemble
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to |output|.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK unless something went wrong.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status ApplyEnsemblePatch(SourceStream* old, SourceStream* patch,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          SinkStream* output);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Applies the patch in |patch_file_name| to the bytes in |old_file_name| and
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writes the transformed ensemble to |new_file_name|.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK unless something went wrong.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function first validates that the patch file has a proper header, so the
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function can be used to 'try' a patch.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ApplyEnsemblePatch(const base::FilePath::CharType* old_file_name,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const base::FilePath::CharType* patch_file_name,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const base::FilePath::CharType* new_file_name);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generates a patch that will transform the bytes in |old| into the bytes in
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |target|.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK unless something when wrong (unexpected).
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status GenerateEnsemblePatch(SourceStream* old, SourceStream* target,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SinkStream* patch);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Detects the type of an executable file, and it's length. The length
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// may be slightly smaller than some executables (like ELF), but will include
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all bytes the courgette algorithm has special benefit for.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On sucess:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Fill in type and detected_length, and return C_OK.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On failure:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Fill in type with UNKNOWN, detected_length with 0, and
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   return C_INPUT_NOT_RECOGNIZED
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status DetectExecutableType(const void* buffer, size_t length,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ExecutableType* type,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            size_t* detected_length);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Attempts to detect the type of executable, and parse it with the
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// appropriate tools, storing the pointer to the AssemblyProgram in |*output|.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK if successful, otherwise returns an error status and sets
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |*output| to NULL.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status ParseDetectedExecutable(const void* buffer, size_t length,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               AssemblyProgram** output);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Trims labels used fewer than a given number of times from an
1132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// assembly program in-place.
1142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochStatus TrimLabels(AssemblyProgram* program);
1152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts |program| into encoded form, returning it as |*output|.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK if succeeded, otherwise returns an error status and
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sets |*output| to NULL
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status Encode(AssemblyProgram* program, EncodedProgram** output);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Serializes |encoded| into the stream set.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK if succeeded, otherwise returns an error status.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assembles |encoded|, emitting the bytes into |buffer|.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK if succeeded, otherwise returns an error status and leaves
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |buffer| in an undefined state.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status Assemble(EncodedProgram* encoded, SinkStream* buffer);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deserializes program from the stream set.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns C_OK if succeeded, otherwise returns an error status and
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sets |*output| to NULL
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status ReadEncodedProgram(SourceStreamSet* source, EncodedProgram** output);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to free an AssemblyProgram returned by other APIs.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteAssemblyProgram(AssemblyProgram* program);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to free an EncodedProgram returned by other APIs.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteEncodedProgram(EncodedProgram* encoded);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adjusts |program| to look more like |model|.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Status Adjust(const AssemblyProgram& model, AssemblyProgram *program);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace courgette
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // COURGETTE_COURGETTE_H_
147