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