123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859 |
- //patch.c
- //
- /*
- The MIT License (MIT)
- Copyright (c) 2012-2017 HouSisong
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
- The above copyright notice and this permission notice shall be
- included in all copies of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
- #include <kernel.h>
- #include <string.h>
- #include <soc.h>
- #include <mem_manager.h>
- #include "hpatch.h"
- #include "assert.h" //assert
- //__RUN_MEM_SAFE_CHECKIt is used to start memory access overrun check to prevent data that may be accidentally or intentionally damaged
- #define __RUN_MEM_SAFE_CHECK
- #define hpatch_TRUE (!hpatch_FALSE)
- #define _hpatch_FALSE hpatch_FALSE
- //int __debug_check_false_x=0; //for debug
- //#define _hpatch_FALSE (1/__debug_check_false_x)
- const int kSignTagBit=1;
- static hpatch_BOOL _bytesRle_load(TByte* out_data,TByte* out_dataEnd,
- const TByte* rle_code,const TByte* rle_code_end);
- static void addData(TByte* dst,const TByte* src,TUInt length);
- static hpatch_BOOL unpackPosWithTag(const TByte** src_code,const TByte* src_code_end,
- const unsigned int kTagBit,hpatch_StreamPos_t* result);
- static hpatch_BOOL _unpackUIntWithTag(const TByte** src_code,const TByte* src_code_end,
- const unsigned int kTagBit,TUInt* result){
- if (sizeof(TUInt)==sizeof(hpatch_StreamPos_t)){
- return unpackPosWithTag(src_code,src_code_end,kTagBit,(hpatch_StreamPos_t*)result);
- }else{
- hpatch_StreamPos_t u64;
- hpatch_BOOL rt=unpackPosWithTag(src_code,src_code_end,kTagBit,&u64);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (rt){
- TUInt u=(TUInt)u64;
- if (u==u64){
- *result=u;
- return hpatch_TRUE;
- }else{
- return _hpatch_FALSE;
- }
- }else{
- return _hpatch_FALSE;
- }
- #else
- *result=(TUInt)u64;
- return rt;
- #endif
- }
- }
- #define unpackUIntWithTagTo(puint,src_code,src_code_end,kTagBit) \
- { if (!_unpackUIntWithTag(src_code,src_code_end,kTagBit,puint)) return _hpatch_FALSE; }
- #define unpackUIntTo(puint,src_code,src_code_end) \
- unpackUIntWithTagTo(puint,src_code,src_code_end,0)
- hpatch_BOOL patch(TByte* out_newData,TByte* out_newData_end,
- const TByte* oldData,const TByte* oldData_end,
- const TByte* serializedDiff,const TByte* serializedDiff_end){
- const TByte *code_lengths, *code_lengths_end,
- *code_inc_newPos, *code_inc_newPos_end,
- *code_inc_oldPos, *code_inc_oldPos_end,
- *code_newDataDiff, *code_newDataDiff_end;
- TUInt ctrlCount;
- assert(out_newData<=out_newData_end);
- assert(oldData<=oldData_end);
- assert(serializedDiff<=serializedDiff_end);
- unpackUIntTo(&ctrlCount,&serializedDiff, serializedDiff_end);
- { //head
- TUInt lengthSize,inc_newPosSize,inc_oldPosSize,newDataDiffSize;
- unpackUIntTo(&lengthSize,&serializedDiff, serializedDiff_end);
- unpackUIntTo(&inc_newPosSize,&serializedDiff, serializedDiff_end);
- unpackUIntTo(&inc_oldPosSize,&serializedDiff, serializedDiff_end);
- unpackUIntTo(&newDataDiffSize,&serializedDiff, serializedDiff_end);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (lengthSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
- #endif
- code_lengths=serializedDiff; serializedDiff+=lengthSize;
- code_lengths_end=serializedDiff;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (inc_newPosSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
- #endif
- code_inc_newPos=serializedDiff; serializedDiff+=inc_newPosSize;
- code_inc_newPos_end=serializedDiff;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (inc_oldPosSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
- #endif
- code_inc_oldPos=serializedDiff; serializedDiff+=inc_oldPosSize;
- code_inc_oldPos_end=serializedDiff;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (newDataDiffSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
- #endif
- code_newDataDiff=serializedDiff; serializedDiff+=newDataDiffSize;
- code_newDataDiff_end=serializedDiff;
- }
- //decode rle ; rle data begin==serializedDiff;
- if (!_bytesRle_load(out_newData, out_newData_end, serializedDiff, serializedDiff_end))
- return _hpatch_FALSE;
- { //patch
- const TUInt newDataSize=(TUInt)(out_newData_end-out_newData);
- TUInt oldPosBack=0;
- TUInt newPosBack=0;
- TUInt i;
- for (i=0; i<ctrlCount; ++i){
- TUInt copyLength,addLength, oldPos,inc_oldPos,inc_oldPos_sign;
- unpackUIntTo(©Length,&code_inc_newPos, code_inc_newPos_end);
- unpackUIntTo(&addLength,&code_lengths, code_lengths_end);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (code_inc_oldPos>=code_inc_oldPos_end) return _hpatch_FALSE;
- #endif
- inc_oldPos_sign=(*code_inc_oldPos)>>(8-kSignTagBit);
- unpackUIntWithTagTo(&inc_oldPos,&code_inc_oldPos, code_inc_oldPos_end, kSignTagBit);
- if (inc_oldPos_sign==0)
- oldPos=oldPosBack+inc_oldPos;
- else
- oldPos=oldPosBack-inc_oldPos;
- if (copyLength>0){
- #ifdef __RUN_MEM_SAFE_CHECK
- if (copyLength>(TUInt)(newDataSize-newPosBack)) return _hpatch_FALSE;
- if (copyLength>(TUInt)(code_newDataDiff_end-code_newDataDiff)) return _hpatch_FALSE;
- #endif
- memcpy(out_newData+newPosBack,code_newDataDiff,copyLength);
- code_newDataDiff+=copyLength;
- newPosBack+=copyLength;
- }
- #ifdef __RUN_MEM_SAFE_CHECK
- if ( (addLength>(TUInt)(newDataSize-newPosBack)) ) return _hpatch_FALSE;
- if ( (oldPos>(TUInt)(oldData_end-oldData)) ||
- (addLength>(TUInt)(oldData_end-oldData-oldPos)) ) return _hpatch_FALSE;
- #endif
- addData(out_newData+newPosBack,oldData+oldPos,addLength);
- oldPosBack=oldPos;
- newPosBack+=addLength;
- }
- if (newPosBack<newDataSize){
- TUInt copyLength=newDataSize-newPosBack;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (copyLength>(TUInt)(code_newDataDiff_end-code_newDataDiff)) return _hpatch_FALSE;
- #endif
- memcpy(out_newData+newPosBack,code_newDataDiff,copyLength);
- code_newDataDiff+=copyLength;
- newPosBack=newDataSize;
- }
- }
- if ( (code_lengths==code_lengths_end)
- &&(code_inc_newPos==code_inc_newPos_end)
- &&(code_inc_oldPos==code_inc_oldPos_end)
- &&(code_newDataDiff==code_newDataDiff_end))
- return hpatch_TRUE;
- else
- return _hpatch_FALSE;
- }
- //Variable length positive integer coding scheme (x bit extra type flag bit, x < = 7), output 1 -- N byte from high bit :
- // x0* 7-x bit
- // x1* 0* 7+7-x bit
- // x1* 1* 0* 7+7+7-x bit
- // x1* 1* 1* 0* 7+7+7+7-x bit
- // x1* 1* 1* 1* 0* 7+7+7+7+7-x bit
- // ......
- static hpatch_BOOL unpackPosWithTag(const TByte** src_code,const TByte* src_code_end,
- const unsigned int kTagBit,hpatch_StreamPos_t* result){//Read the integer and advance the pointer .
- #ifdef __RUN_MEM_SAFE_CHECK
- const unsigned int kPackMaxTagBit=7;
- #endif
- hpatch_StreamPos_t value;
- TByte code;
- const TByte* pcode=*src_code;
- #ifdef __RUN_MEM_SAFE_CHECK
- assert(kTagBit<=kPackMaxTagBit);
- if (src_code_end-pcode<=0) return _hpatch_FALSE;
- #endif
- code=*pcode; ++pcode;
- value=code&((1<<(7-kTagBit))-1);
- if ((code&(1<<(7-kTagBit)))!=0){
- do {
- #ifdef __RUN_MEM_SAFE_CHECK
- if ((value>>(sizeof(value)*8-7))!=0) return _hpatch_FALSE;//cannot save 7bit
- if (src_code_end==pcode) return _hpatch_FALSE;
- #endif
- code=*pcode; ++pcode;
- value=(value<<7) | (code&((1<<7)-1));
- } while ((code&(1<<7))!=0);
- }
- (*src_code)=pcode;
- *result=value;
- return hpatch_TRUE;
- }
- static void addData(TByte* dst,const TByte* src,TUInt length){
- TUInt length_fast,i;
- length_fast=length&(~(TUInt)7);
- for (i=0;i<length_fast;i+=8){
- dst[i ]+=src[i ];
- dst[i+1]+=src[i+1];
- dst[i+2]+=src[i+2];
- dst[i+3]+=src[i+3];
- dst[i+4]+=src[i+4];
- dst[i+5]+=src[i+5];
- dst[i+6]+=src[i+6];
- dst[i+7]+=src[i+7];
- }
- for (;i<length;++i)
- dst[i]+=src[i];
- }
- //The packet type of data compressed by RLE is 2bit
- typedef enum TByteRleType{
- kByteRleType_rle0 = 0, //00 represents the compressed 0 stored later; (byte data is not required in the packet)
- kByteRleType_rle255= 1, //01 represents the compressed 255 stored later; (byte data is not required in the packet)
- kByteRleType_rle = 2, //10 represents the compressed data stored later; (only one byte of data needs to be stored in the packet)
- kByteRleType_unrle = 3 //11 represents the uncompressed data stored later; (multiple bytes of data are continuously stored in the packet)
- } TByteRleType;
- static const int kByteRleType_bit=2;
- static hpatch_BOOL _bytesRle_load(TByte* out_data,TByte* out_dataEnd,
- const TByte* rle_code,const TByte* rle_code_end){
- const TByte* ctrlBuf,*ctrlBuf_end;
- TUInt ctrlSize;
- unpackUIntTo(&ctrlSize,&rle_code,rle_code_end);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (ctrlSize>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
- #endif
- ctrlBuf=rle_code;
- rle_code+=ctrlSize;
- ctrlBuf_end=rle_code;
- while (ctrlBuf_end-ctrlBuf>0){
- enum TByteRleType type=(enum TByteRleType)((*ctrlBuf)>>(8-kByteRleType_bit));
- TUInt length;
- unpackUIntWithTagTo(&length,&ctrlBuf,ctrlBuf_end,kByteRleType_bit);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (length>=(TUInt)(out_dataEnd-out_data)) return _hpatch_FALSE;
- #endif
- ++length;
- switch (type){
- case kByteRleType_rle0:{
- memset(out_data,0,length);
- out_data+=length;
- }break;
- case kByteRleType_rle255:{
- memset(out_data,255,length);
- out_data+=length;
- }break;
- case kByteRleType_rle:{
- #ifdef __RUN_MEM_SAFE_CHECK
- if (1>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
- #endif
- memset(out_data,*rle_code,length);
- ++rle_code;
- out_data+=length;
- }break;
- case kByteRleType_unrle:{
- #ifdef __RUN_MEM_SAFE_CHECK
- if (length>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
- #endif
- memcpy(out_data,rle_code,length);
- rle_code+=length;
- out_data+=length;
- }break;
- }
- }
- if ( (ctrlBuf==ctrlBuf_end)
- &&(rle_code==rle_code_end)
- &&(out_data==out_dataEnd))
- return hpatch_TRUE;
- else
- return _hpatch_FALSE;
- }
- //----------------------
- //patch by stream
- #undef TUInt
- #define TUInt hpatch_StreamPos_t
- typedef struct TStreamClip{
- TUInt streamPos;
- TUInt streamPos_end;
- const struct hpatch_TStreamInput* srcStream;
- size_t cacheBegin;//cacheEnd==kStreamCacheSize
- TByte cacheBuf[kStreamCacheSize];
- } TStreamClip;
- static void _TStreamClip_init(struct TStreamClip* sclip,
- const struct hpatch_TStreamInput* srcStream,
- TUInt streamPos,TUInt streamPos_end){
- sclip->srcStream=srcStream;
- sclip->streamPos=streamPos;
- sclip->streamPos_end=streamPos_end;
- sclip->cacheBegin=kStreamCacheSize;
- }
- #define _TStreamClip_isFinish(sclip) ( 0==_TStreamClip_streamSize(sclip) )
- #define _TStreamClip_isCacheEmpty(sclip) ( (sclip)->cacheBegin==kStreamCacheSize )
- #define _TStreamClip_cachedSize(sclip) ( (size_t)(kStreamCacheSize-(sclip)->cacheBegin) )
- #define _TStreamClip_streamSize(sclip) \
- ( (TUInt)((sclip)->streamPos_end-(sclip)->streamPos) + (TUInt)_TStreamClip_cachedSize(sclip) )
- static void _TStreamClip_updateCache(struct TStreamClip* sclip)
- {
- TByte* buf0=&sclip->cacheBuf[0];
- const TUInt stremSize=(TUInt)(sclip->streamPos_end-sclip->streamPos);
- size_t readSize=sclip->cacheBegin;
- if (readSize>stremSize)
- readSize=(size_t)stremSize;
- if (readSize==0) return;
- if (!_TStreamClip_isCacheEmpty(sclip)){
- memmove(buf0+(size_t)(sclip->cacheBegin-readSize),
- buf0+sclip->cacheBegin,_TStreamClip_cachedSize(sclip));
- }
- if (sclip->srcStream->read(sclip->srcStream->streamHandle,sclip->streamPos,
- buf0+(size_t)(kStreamCacheSize-readSize),buf0+kStreamCacheSize)
- == readSize ){
- sclip->cacheBegin-=readSize;
- sclip->streamPos+=readSize;
- }else{ //read error
- sclip->cacheBegin=kStreamCacheSize;
- sclip->streamPos=sclip->streamPos_end;
- }
- }
- static TByte* _TStreamClip_accessData(struct TStreamClip* sclip,size_t readSize){
- assert(readSize<=kStreamCacheSize);
- if (readSize>_TStreamClip_cachedSize(sclip))
- _TStreamClip_updateCache(sclip);
- if(readSize<=_TStreamClip_cachedSize(sclip)){
- return &sclip->cacheBuf[sclip->cacheBegin];
- }else{
- return 0; //read error
- }
- }
- #define _TStreamClip_skipData_noCheck(sclip,skipSize) ((sclip)->cacheBegin+=skipSize)
- static TByte* _TStreamClip_readData(struct TStreamClip* sclip,size_t readSize){
- TByte* result=_TStreamClip_accessData(sclip,readSize);
- _TStreamClip_skipData_noCheck(sclip,readSize);
- return result;
- }
- static void _TStreamClip_resetPosEnd(struct TStreamClip* sclip,TUInt new_posEnd){
- sclip->streamPos_end=new_posEnd;
- if (sclip->streamPos>new_posEnd){//cache overfull, need pop
- TByte* cacheBegin=&sclip->cacheBuf[sclip->cacheBegin];
- TUInt popSize=(TUInt)(sclip->streamPos-new_posEnd);
- assert(popSize<=_TStreamClip_cachedSize(sclip));
- memmove(cacheBegin+popSize,cacheBegin,(size_t)(_TStreamClip_cachedSize(sclip)-popSize));
- sclip->cacheBegin+=(size_t)popSize;
- sclip->streamPos=new_posEnd; //eq. sclip->streamPos-=popSize
- }
- }
- static hpatch_BOOL _TStreamClip_unpackUIntWithTag(struct TStreamClip* sclip,
- const int kTagBit,TUInt* result){
- #define kMaxPackedByte ((sizeof(TUInt)*8+6)/7+1) //11
- TByte* curCode,*codeBegin;
- size_t readSize=kMaxPackedByte;
- const TUInt dataSize=_TStreamClip_streamSize(sclip);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (dataSize==0) return _hpatch_FALSE;
- #endif
- if (readSize>dataSize)
- readSize=(size_t)dataSize;
- codeBegin=_TStreamClip_accessData(sclip,readSize);
- if (codeBegin==0) return _hpatch_FALSE;
- curCode=codeBegin;
- if (!unpackPosWithTag((const TByte**)&curCode,codeBegin+readSize,kTagBit,result))
- return _hpatch_FALSE;
- _TStreamClip_skipData_noCheck(sclip,(size_t)(curCode-codeBegin));
- return hpatch_TRUE;
- }
- #define _TStreamClip_unpackUIntWithTagTo(puint,sclip,kTagBit) \
- { if (!_TStreamClip_unpackUIntWithTag(sclip,kTagBit,puint)) return _hpatch_FALSE; }
- #define _TStreamClip_unpackUIntTo(puint,sclip) \
- _TStreamClip_unpackUIntWithTagTo(puint,sclip,0)
- typedef struct _TBytesRle_load_stream{
- TUInt memCopyLength;
- TUInt memSetLength;
- const struct hpatch_TStreamInput* rle_stream;
- TByte memSetValue;
- struct TStreamClip ctrlClip;
- struct TStreamClip rleCodeClip;
- } _TBytesRle_load_stream;
- static hpatch_BOOL _TBytesRle_load_stream_init(_TBytesRle_load_stream* loader,
- const struct hpatch_TStreamInput* rle_stream,
- TUInt rle_code,TUInt rle_code_end){
- TUInt ctrlSize;
- struct TStreamClip* rleHeadClip=&loader->ctrlClip;//rename, share address
- _TStreamClip_init(rleHeadClip,rle_stream,rle_code,rle_code_end);
- _TStreamClip_unpackUIntTo(&ctrlSize,rleHeadClip);
- rle_code=(TUInt)(rle_code_end-_TStreamClip_streamSize(rleHeadClip));
- #ifdef __RUN_MEM_SAFE_CHECK
- if (ctrlSize>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
- #endif
- loader->rle_stream=rle_stream;
- //eq. _TStreamClip_init(&loader->ctrlClip,rle_stream,rle_code,rle_code+ctrlSize);
- _TStreamClip_resetPosEnd(&loader->ctrlClip,rle_code+ctrlSize);
- _TStreamClip_init(&loader->rleCodeClip,rle_stream,rle_code+ctrlSize,rle_code_end);
- loader->memSetLength=0;
- loader->memSetValue=0;//nil;
- loader->memCopyLength=0;
- return hpatch_TRUE;
- }
- static void memSet_add(TByte* dst,const TByte src,size_t length){
- size_t length_fast,i;
- length_fast=length&(~(size_t)7);
- for (i=0;i<length_fast;i+=8){
- dst[i ]+=src;
- dst[i+1]+=src;
- dst[i+2]+=src;
- dst[i+3]+=src;
- dst[i+4]+=src;
- dst[i+5]+=src;
- dst[i+6]+=src;
- dst[i+7]+=src;
- }
- for (;i<length;++i)
- dst[i]+=src;
- }
- static hpatch_BOOL _TBytesRle_load_stream_mem_add(_TBytesRle_load_stream* loader,
- size_t* _decodeSize,TByte** _out_data){
- size_t decodeSize=*_decodeSize;
- TByte* out_data=*_out_data;
- struct TStreamClip* rleCodeClip=&loader->rleCodeClip;
- while ((loader->memSetLength>0)&&(decodeSize>0)) {
- size_t memSetStep=decodeSize;
- if (memSetStep>loader->memSetLength)
- memSetStep=(size_t)loader->memSetLength;
- memSet_add(out_data,loader->memSetValue,memSetStep);
- out_data+=memSetStep;
- decodeSize-=memSetStep;
- loader->memSetLength-=memSetStep;
- }
- while ((loader->memCopyLength>0)&&(decodeSize>0)) {
- TByte* rleData;
- size_t decodeStep=kStreamCacheSize;
- if (decodeStep>decodeSize)
- decodeStep=decodeSize;
- if (decodeStep>loader->memCopyLength)
- decodeStep=(size_t)loader->memCopyLength;
- rleData=_TStreamClip_readData(rleCodeClip,decodeStep);
- if (rleData==0) return _hpatch_FALSE;
- addData(out_data,rleData,decodeStep);
- out_data+=decodeStep;
- decodeSize-=decodeStep;
- loader->memCopyLength-=decodeStep;
- }
- *_decodeSize=decodeSize;
- *_out_data=out_data;
- return hpatch_TRUE;
- }
- static hpatch_BOOL _TBytesRle_load_stream_isFinish(const _TBytesRle_load_stream* loader){
- return(loader->memSetLength==0)
- &&(loader->memCopyLength==0)
- &&(_TStreamClip_isFinish(&loader->rleCodeClip))
- &&(_TStreamClip_isFinish(&loader->ctrlClip));
- }
- //RLE compression algorithm
- static hpatch_BOOL _TBytesRle_load_stream_decode_add(_TBytesRle_load_stream* loader,
- size_t decodeSize,TByte* out_data){
- if (!_TBytesRle_load_stream_mem_add(loader,&decodeSize,&out_data))
- return _hpatch_FALSE;
- while ((decodeSize>0)&&(!_TStreamClip_isFinish(&loader->ctrlClip))){
- enum TByteRleType type;
- TUInt length;
- const TByte* pType=_TStreamClip_accessData(&loader->ctrlClip,1);
- if (pType==0) return _hpatch_FALSE;
- type=(enum TByteRleType)((*pType)>>(8-kByteRleType_bit));
- _TStreamClip_unpackUIntWithTagTo(&length,&loader->ctrlClip,kByteRleType_bit);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (length+1<length) return _hpatch_FALSE;
- #endif
- ++length;
- switch (type){
- case kByteRleType_rle0:{
- loader->memSetLength=length;
- loader->memSetValue=0;
- }break;
- case kByteRleType_rle255:{
- loader->memSetLength=length;
- loader->memSetValue=255;
- }break;
- case kByteRleType_rle:{
- const TByte* pSetValue;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (1>_TStreamClip_streamSize(&loader->rleCodeClip)) return _hpatch_FALSE;
- #endif
- loader->memSetLength=length;
- pSetValue=_TStreamClip_readData(&loader->rleCodeClip,1);
- if (pSetValue==0) return _hpatch_FALSE;
- loader->memSetValue=*pSetValue;
- }break;
- case kByteRleType_unrle:{
- #ifdef __RUN_MEM_SAFE_CHECK
- if (length>_TStreamClip_streamSize(&loader->rleCodeClip)) return _hpatch_FALSE;
- #endif
- loader->memCopyLength=length;
- }break;
- }
- if (!_TBytesRle_load_stream_mem_add(loader,&decodeSize,&out_data)) return _hpatch_FALSE;
- }
- if (decodeSize==0)
- return hpatch_TRUE;
- else
- return _hpatch_FALSE;
- }
- static hpatch_BOOL _patch_decode_from_clipOrStream(const struct hpatch_TStreamOutput* out_newData,TUInt writeToPos,
- _TBytesRle_load_stream* rle_loader,TUInt decodeLength,
- struct TStreamClip* srcClip,
- const struct hpatch_TStreamInput* srcStream,TUInt readPos)
- {
- //1kbyte temp buffer
- // TByte _tempMemBuf[kStreamCacheSize];
- // TByte* data=&_tempMemBuf[0];
- TByte *_tempMemBuf, *data;
- _tempMemBuf = mem_malloc(kStreamCacheSize);
- if (!_tempMemBuf) {
- printk("%s: malloc failed, size 0x%x\n", __func__, kStreamCacheSize);
- return _hpatch_FALSE;
- }
- data = _tempMemBuf;
- while (decodeLength>0)
- {
- size_t decodeStep=kStreamCacheSize;
- if (decodeStep>decodeLength)
- {
- decodeStep=(size_t)decodeLength;
- }
- //read data from cache or stream
- if (srcClip!=0)
- {
- assert(srcStream==0);
- data=_TStreamClip_readData(srcClip,decodeStep);
- if (data==0) {
- goto fail_exit;
- }
- }
- else
- {
- assert(srcStream!=0);
- if (decodeStep!=srcStream->read(srcStream->streamHandle,readPos,data,data+decodeStep)) {
- goto fail_exit;
- }
- }
- if (!_TBytesRle_load_stream_decode_add(rle_loader,decodeStep,data))
- {
- goto fail_exit;
- }
- //write new data
- if (decodeStep!=out_newData->write(out_newData->streamHandle,writeToPos,data,data+decodeStep))
- {
- goto fail_exit;
- }
- readPos+=decodeStep;
- writeToPos+=decodeStep;
- decodeLength-=decodeStep;
- }
- mem_free(_tempMemBuf);
- return hpatch_TRUE;
- fail_exit:
- mem_free(_tempMemBuf);
- return _hpatch_FALSE;
- }
- hpatch_BOOL patch_stream(const struct hpatch_TStreamOutput* out_newData,
- const struct hpatch_TStreamInput* oldData,
- const struct hpatch_TStreamInput* serializedDiff)
- {
- struct TStreamClip *code_lengthsClip = NULL; //size 418
- struct TStreamClip *code_inc_oldPosClip = NULL;
- struct TStreamClip *code_inc_newPosClip = NULL;
- struct TStreamClip *code_newDataDiffClip = NULL;
- struct _TBytesRle_load_stream *rle_loader = NULL; //size 848
- TUInt ctrlCount;
- hpatch_BOOL ret;
- assert(out_newData!=0);
- assert(out_newData->write!=0);
- assert(oldData!=0);
- assert(oldData->read!=0);
- assert(serializedDiff!=0);
- assert(serializedDiff->read!=0);
- assert(serializedDiff->streamSize>0);
- code_lengthsClip = mem_malloc(sizeof(struct TStreamClip));
- if (!code_lengthsClip) {
- printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
- return _hpatch_FALSE;
- }
- code_inc_oldPosClip = mem_malloc(sizeof(struct TStreamClip));
- if (!code_inc_oldPosClip) {
- printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
- mem_free(code_lengthsClip);
- return _hpatch_FALSE;
- }
- code_inc_newPosClip = mem_malloc(sizeof(struct TStreamClip));
- if (!code_inc_newPosClip) {
- printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
- mem_free(code_inc_oldPosClip);
- mem_free(code_lengthsClip);
- return _hpatch_FALSE;
- }
- code_newDataDiffClip = mem_malloc(sizeof(struct TStreamClip));
- if (!code_newDataDiffClip) {
- printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
- mem_free(code_inc_newPosClip);
- mem_free(code_inc_oldPosClip);
- mem_free(code_lengthsClip);
- return _hpatch_FALSE;
- }
- rle_loader = mem_malloc(sizeof(struct _TBytesRle_load_stream));
- if (!rle_loader) {
- printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct _TBytesRle_load_stream));
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- { //head
- TUInt lengthSize,inc_newPosSize,inc_oldPosSize,newDataDiffSize;
- TUInt diffPos0;
- const TUInt diffPos_end=serializedDiff->streamSize;
- struct TStreamClip* diffHeadClip=code_lengthsClip;//rename, share address
- _TStreamClip_init(diffHeadClip,serializedDiff,0,diffPos_end); //Initialize the diffheadclip structure and set the cache size of 2K
- _TStreamClip_unpackUIntTo(&ctrlCount,diffHeadClip);
- _TStreamClip_unpackUIntTo(&lengthSize,diffHeadClip);
- _TStreamClip_unpackUIntTo(&inc_newPosSize,diffHeadClip);
- _TStreamClip_unpackUIntTo(&inc_oldPosSize,diffHeadClip);
- _TStreamClip_unpackUIntTo(&newDataDiffSize,diffHeadClip);
- diffPos0=(TUInt)(diffPos_end-_TStreamClip_streamSize(diffHeadClip));
- #ifdef __RUN_MEM_SAFE_CHECK
- if (lengthSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- //eq. _TStreamClip_init(&code_lengthsClip,serializedDiff,diffPos0,diffPos0+lengthSize);
- _TStreamClip_resetPosEnd(code_lengthsClip,diffPos0+lengthSize);
- diffPos0+=lengthSize;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (inc_newPosSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- _TStreamClip_init(code_inc_newPosClip,serializedDiff,diffPos0,diffPos0+inc_newPosSize);
- diffPos0+=inc_newPosSize;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (inc_oldPosSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- _TStreamClip_init(code_inc_oldPosClip,serializedDiff,diffPos0,diffPos0+inc_oldPosSize);
- diffPos0+=inc_oldPosSize;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (newDataDiffSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- _TStreamClip_init(code_newDataDiffClip,serializedDiff,diffPos0,diffPos0+newDataDiffSize);
- diffPos0+=newDataDiffSize;
- //rle
- if (!_TBytesRle_load_stream_init(rle_loader,serializedDiff,diffPos0,diffPos_end)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- }
- {
- //patch
- const TUInt newDataSize=out_newData->streamSize;
- TUInt oldPosBack=0;
- TUInt newPosBack=0;
- TUInt i;
- for (i=0; i<ctrlCount; ++i)
- {
- TUInt copyLength,addLength, oldPos,inc_oldPos;
- TByte inc_oldPos_sign;
- const TByte* pSign;
- _TStreamClip_unpackUIntTo(©Length,code_inc_newPosClip);
- _TStreamClip_unpackUIntTo(&addLength,code_lengthsClip);
- #ifdef __RUN_MEM_SAFE_CHECK
- if (_TStreamClip_isFinish(code_inc_oldPosClip)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- pSign=_TStreamClip_accessData(code_inc_oldPosClip,1);
- if (pSign==0) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- inc_oldPos_sign=(*pSign)>>(8-kSignTagBit);
- _TStreamClip_unpackUIntWithTagTo(&inc_oldPos,code_inc_oldPosClip,kSignTagBit);
- if (inc_oldPos_sign==0)
- oldPos=oldPosBack+inc_oldPos;
- else
- oldPos=oldPosBack-inc_oldPos;
- if (copyLength>0){
- #ifdef __RUN_MEM_SAFE_CHECK
- if (copyLength>(TUInt)(newDataSize-newPosBack)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- if (copyLength>_TStreamClip_streamSize(code_newDataDiffClip)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- if (!_patch_decode_from_clipOrStream(out_newData,newPosBack,rle_loader,copyLength,
- code_newDataDiffClip,0,0)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- newPosBack+=copyLength;
- }
- #ifdef __RUN_MEM_SAFE_CHECK
- if ((addLength>(TUInt)(newDataSize-newPosBack))) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- if ( (oldPos>(oldData->streamSize)) ||
- (addLength>(TUInt)(oldData->streamSize-oldPos)) ) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- if (!_patch_decode_from_clipOrStream(out_newData,newPosBack,rle_loader,addLength,
- 0,oldData,oldPos)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- oldPosBack=oldPos;
- newPosBack+=addLength;
- }
- if (newPosBack<newDataSize){
- TUInt copyLength=newDataSize-newPosBack;
- #ifdef __RUN_MEM_SAFE_CHECK
- if (copyLength>_TStreamClip_streamSize(code_newDataDiffClip)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- #endif
- if (!_patch_decode_from_clipOrStream(out_newData,newPosBack,rle_loader,copyLength,
- code_newDataDiffClip,0,0)) {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- newPosBack=newDataSize;
- }
- }
- if ( _TBytesRle_load_stream_isFinish(rle_loader)
- && _TStreamClip_isFinish(code_lengthsClip)
- && _TStreamClip_isFinish(code_inc_newPosClip)
- && _TStreamClip_isFinish(code_inc_oldPosClip)
- && _TStreamClip_isFinish(code_newDataDiffClip) ) {
- ret = hpatch_TRUE;
- goto func_ret;
- } else {
- printk("%s %d: error\n", __func__, __LINE__);
- ret = _hpatch_FALSE;
- goto func_ret;
- }
- func_ret:
- if (rle_loader)
- mem_free(rle_loader);
- mem_free(code_newDataDiffClip);
- mem_free(code_inc_newPosClip);
- mem_free(code_inc_oldPosClip);
- mem_free(code_lengthsClip);
- return ret;
- }
|