hpatch.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. //patch.c
  2. //
  3. /*
  4. The MIT License (MIT)
  5. Copyright (c) 2012-2017 HouSisong
  6. Permission is hereby granted, free of charge, to any person
  7. obtaining a copy of this software and associated documentation
  8. files (the "Software"), to deal in the Software without
  9. restriction, including without limitation the rights to use,
  10. copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the
  12. Software is furnished to do so, subject to the following
  13. conditions:
  14. The above copyright notice and this permission notice shall be
  15. included in all copies of the Software.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #include <kernel.h>
  26. #include <string.h>
  27. #include <soc.h>
  28. #include <mem_manager.h>
  29. #include "hpatch.h"
  30. #include "assert.h" //assert
  31. //__RUN_MEM_SAFE_CHECKIt is used to start memory access overrun check to prevent data that may be accidentally or intentionally damaged
  32. #define __RUN_MEM_SAFE_CHECK
  33. #define hpatch_TRUE (!hpatch_FALSE)
  34. #define _hpatch_FALSE hpatch_FALSE
  35. //int __debug_check_false_x=0; //for debug
  36. //#define _hpatch_FALSE (1/__debug_check_false_x)
  37. const int kSignTagBit=1;
  38. static hpatch_BOOL _bytesRle_load(TByte* out_data,TByte* out_dataEnd,
  39. const TByte* rle_code,const TByte* rle_code_end);
  40. static void addData(TByte* dst,const TByte* src,TUInt length);
  41. static hpatch_BOOL unpackPosWithTag(const TByte** src_code,const TByte* src_code_end,
  42. const unsigned int kTagBit,hpatch_StreamPos_t* result);
  43. static hpatch_BOOL _unpackUIntWithTag(const TByte** src_code,const TByte* src_code_end,
  44. const unsigned int kTagBit,TUInt* result){
  45. if (sizeof(TUInt)==sizeof(hpatch_StreamPos_t)){
  46. return unpackPosWithTag(src_code,src_code_end,kTagBit,(hpatch_StreamPos_t*)result);
  47. }else{
  48. hpatch_StreamPos_t u64;
  49. hpatch_BOOL rt=unpackPosWithTag(src_code,src_code_end,kTagBit,&u64);
  50. #ifdef __RUN_MEM_SAFE_CHECK
  51. if (rt){
  52. TUInt u=(TUInt)u64;
  53. if (u==u64){
  54. *result=u;
  55. return hpatch_TRUE;
  56. }else{
  57. return _hpatch_FALSE;
  58. }
  59. }else{
  60. return _hpatch_FALSE;
  61. }
  62. #else
  63. *result=(TUInt)u64;
  64. return rt;
  65. #endif
  66. }
  67. }
  68. #define unpackUIntWithTagTo(puint,src_code,src_code_end,kTagBit) \
  69. { if (!_unpackUIntWithTag(src_code,src_code_end,kTagBit,puint)) return _hpatch_FALSE; }
  70. #define unpackUIntTo(puint,src_code,src_code_end) \
  71. unpackUIntWithTagTo(puint,src_code,src_code_end,0)
  72. hpatch_BOOL patch(TByte* out_newData,TByte* out_newData_end,
  73. const TByte* oldData,const TByte* oldData_end,
  74. const TByte* serializedDiff,const TByte* serializedDiff_end){
  75. const TByte *code_lengths, *code_lengths_end,
  76. *code_inc_newPos, *code_inc_newPos_end,
  77. *code_inc_oldPos, *code_inc_oldPos_end,
  78. *code_newDataDiff, *code_newDataDiff_end;
  79. TUInt ctrlCount;
  80. assert(out_newData<=out_newData_end);
  81. assert(oldData<=oldData_end);
  82. assert(serializedDiff<=serializedDiff_end);
  83. unpackUIntTo(&ctrlCount,&serializedDiff, serializedDiff_end);
  84. { //head
  85. TUInt lengthSize,inc_newPosSize,inc_oldPosSize,newDataDiffSize;
  86. unpackUIntTo(&lengthSize,&serializedDiff, serializedDiff_end);
  87. unpackUIntTo(&inc_newPosSize,&serializedDiff, serializedDiff_end);
  88. unpackUIntTo(&inc_oldPosSize,&serializedDiff, serializedDiff_end);
  89. unpackUIntTo(&newDataDiffSize,&serializedDiff, serializedDiff_end);
  90. #ifdef __RUN_MEM_SAFE_CHECK
  91. if (lengthSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
  92. #endif
  93. code_lengths=serializedDiff; serializedDiff+=lengthSize;
  94. code_lengths_end=serializedDiff;
  95. #ifdef __RUN_MEM_SAFE_CHECK
  96. if (inc_newPosSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
  97. #endif
  98. code_inc_newPos=serializedDiff; serializedDiff+=inc_newPosSize;
  99. code_inc_newPos_end=serializedDiff;
  100. #ifdef __RUN_MEM_SAFE_CHECK
  101. if (inc_oldPosSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
  102. #endif
  103. code_inc_oldPos=serializedDiff; serializedDiff+=inc_oldPosSize;
  104. code_inc_oldPos_end=serializedDiff;
  105. #ifdef __RUN_MEM_SAFE_CHECK
  106. if (newDataDiffSize>(TUInt)(serializedDiff_end-serializedDiff)) return _hpatch_FALSE;
  107. #endif
  108. code_newDataDiff=serializedDiff; serializedDiff+=newDataDiffSize;
  109. code_newDataDiff_end=serializedDiff;
  110. }
  111. //decode rle ; rle data begin==serializedDiff;
  112. if (!_bytesRle_load(out_newData, out_newData_end, serializedDiff, serializedDiff_end))
  113. return _hpatch_FALSE;
  114. { //patch
  115. const TUInt newDataSize=(TUInt)(out_newData_end-out_newData);
  116. TUInt oldPosBack=0;
  117. TUInt newPosBack=0;
  118. TUInt i;
  119. for (i=0; i<ctrlCount; ++i){
  120. TUInt copyLength,addLength, oldPos,inc_oldPos,inc_oldPos_sign;
  121. unpackUIntTo(&copyLength,&code_inc_newPos, code_inc_newPos_end);
  122. unpackUIntTo(&addLength,&code_lengths, code_lengths_end);
  123. #ifdef __RUN_MEM_SAFE_CHECK
  124. if (code_inc_oldPos>=code_inc_oldPos_end) return _hpatch_FALSE;
  125. #endif
  126. inc_oldPos_sign=(*code_inc_oldPos)>>(8-kSignTagBit);
  127. unpackUIntWithTagTo(&inc_oldPos,&code_inc_oldPos, code_inc_oldPos_end, kSignTagBit);
  128. if (inc_oldPos_sign==0)
  129. oldPos=oldPosBack+inc_oldPos;
  130. else
  131. oldPos=oldPosBack-inc_oldPos;
  132. if (copyLength>0){
  133. #ifdef __RUN_MEM_SAFE_CHECK
  134. if (copyLength>(TUInt)(newDataSize-newPosBack)) return _hpatch_FALSE;
  135. if (copyLength>(TUInt)(code_newDataDiff_end-code_newDataDiff)) return _hpatch_FALSE;
  136. #endif
  137. memcpy(out_newData+newPosBack,code_newDataDiff,copyLength);
  138. code_newDataDiff+=copyLength;
  139. newPosBack+=copyLength;
  140. }
  141. #ifdef __RUN_MEM_SAFE_CHECK
  142. if ( (addLength>(TUInt)(newDataSize-newPosBack)) ) return _hpatch_FALSE;
  143. if ( (oldPos>(TUInt)(oldData_end-oldData)) ||
  144. (addLength>(TUInt)(oldData_end-oldData-oldPos)) ) return _hpatch_FALSE;
  145. #endif
  146. addData(out_newData+newPosBack,oldData+oldPos,addLength);
  147. oldPosBack=oldPos;
  148. newPosBack+=addLength;
  149. }
  150. if (newPosBack<newDataSize){
  151. TUInt copyLength=newDataSize-newPosBack;
  152. #ifdef __RUN_MEM_SAFE_CHECK
  153. if (copyLength>(TUInt)(code_newDataDiff_end-code_newDataDiff)) return _hpatch_FALSE;
  154. #endif
  155. memcpy(out_newData+newPosBack,code_newDataDiff,copyLength);
  156. code_newDataDiff+=copyLength;
  157. newPosBack=newDataSize;
  158. }
  159. }
  160. if ( (code_lengths==code_lengths_end)
  161. &&(code_inc_newPos==code_inc_newPos_end)
  162. &&(code_inc_oldPos==code_inc_oldPos_end)
  163. &&(code_newDataDiff==code_newDataDiff_end))
  164. return hpatch_TRUE;
  165. else
  166. return _hpatch_FALSE;
  167. }
  168. //Variable length positive integer coding scheme (x bit extra type flag bit, x < = 7), output 1 -- N byte from high bit :
  169. // x0* 7-x bit
  170. // x1* 0* 7+7-x bit
  171. // x1* 1* 0* 7+7+7-x bit
  172. // x1* 1* 1* 0* 7+7+7+7-x bit
  173. // x1* 1* 1* 1* 0* 7+7+7+7+7-x bit
  174. // ......
  175. static hpatch_BOOL unpackPosWithTag(const TByte** src_code,const TByte* src_code_end,
  176. const unsigned int kTagBit,hpatch_StreamPos_t* result){//Read the integer and advance the pointer .
  177. #ifdef __RUN_MEM_SAFE_CHECK
  178. const unsigned int kPackMaxTagBit=7;
  179. #endif
  180. hpatch_StreamPos_t value;
  181. TByte code;
  182. const TByte* pcode=*src_code;
  183. #ifdef __RUN_MEM_SAFE_CHECK
  184. assert(kTagBit<=kPackMaxTagBit);
  185. if (src_code_end-pcode<=0) return _hpatch_FALSE;
  186. #endif
  187. code=*pcode; ++pcode;
  188. value=code&((1<<(7-kTagBit))-1);
  189. if ((code&(1<<(7-kTagBit)))!=0){
  190. do {
  191. #ifdef __RUN_MEM_SAFE_CHECK
  192. if ((value>>(sizeof(value)*8-7))!=0) return _hpatch_FALSE;//cannot save 7bit
  193. if (src_code_end==pcode) return _hpatch_FALSE;
  194. #endif
  195. code=*pcode; ++pcode;
  196. value=(value<<7) | (code&((1<<7)-1));
  197. } while ((code&(1<<7))!=0);
  198. }
  199. (*src_code)=pcode;
  200. *result=value;
  201. return hpatch_TRUE;
  202. }
  203. static void addData(TByte* dst,const TByte* src,TUInt length){
  204. TUInt length_fast,i;
  205. length_fast=length&(~(TUInt)7);
  206. for (i=0;i<length_fast;i+=8){
  207. dst[i ]+=src[i ];
  208. dst[i+1]+=src[i+1];
  209. dst[i+2]+=src[i+2];
  210. dst[i+3]+=src[i+3];
  211. dst[i+4]+=src[i+4];
  212. dst[i+5]+=src[i+5];
  213. dst[i+6]+=src[i+6];
  214. dst[i+7]+=src[i+7];
  215. }
  216. for (;i<length;++i)
  217. dst[i]+=src[i];
  218. }
  219. //The packet type of data compressed by RLE is 2bit
  220. typedef enum TByteRleType{
  221. kByteRleType_rle0 = 0, //00 represents the compressed 0 stored later; (byte data is not required in the packet)
  222. kByteRleType_rle255= 1, //01 represents the compressed 255 stored later; (byte data is not required in the packet)
  223. kByteRleType_rle = 2, //10 represents the compressed data stored later; (only one byte of data needs to be stored in the packet)
  224. kByteRleType_unrle = 3 //11 represents the uncompressed data stored later; (multiple bytes of data are continuously stored in the packet)
  225. } TByteRleType;
  226. static const int kByteRleType_bit=2;
  227. static hpatch_BOOL _bytesRle_load(TByte* out_data,TByte* out_dataEnd,
  228. const TByte* rle_code,const TByte* rle_code_end){
  229. const TByte* ctrlBuf,*ctrlBuf_end;
  230. TUInt ctrlSize;
  231. unpackUIntTo(&ctrlSize,&rle_code,rle_code_end);
  232. #ifdef __RUN_MEM_SAFE_CHECK
  233. if (ctrlSize>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
  234. #endif
  235. ctrlBuf=rle_code;
  236. rle_code+=ctrlSize;
  237. ctrlBuf_end=rle_code;
  238. while (ctrlBuf_end-ctrlBuf>0){
  239. enum TByteRleType type=(enum TByteRleType)((*ctrlBuf)>>(8-kByteRleType_bit));
  240. TUInt length;
  241. unpackUIntWithTagTo(&length,&ctrlBuf,ctrlBuf_end,kByteRleType_bit);
  242. #ifdef __RUN_MEM_SAFE_CHECK
  243. if (length>=(TUInt)(out_dataEnd-out_data)) return _hpatch_FALSE;
  244. #endif
  245. ++length;
  246. switch (type){
  247. case kByteRleType_rle0:{
  248. memset(out_data,0,length);
  249. out_data+=length;
  250. }break;
  251. case kByteRleType_rle255:{
  252. memset(out_data,255,length);
  253. out_data+=length;
  254. }break;
  255. case kByteRleType_rle:{
  256. #ifdef __RUN_MEM_SAFE_CHECK
  257. if (1>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
  258. #endif
  259. memset(out_data,*rle_code,length);
  260. ++rle_code;
  261. out_data+=length;
  262. }break;
  263. case kByteRleType_unrle:{
  264. #ifdef __RUN_MEM_SAFE_CHECK
  265. if (length>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
  266. #endif
  267. memcpy(out_data,rle_code,length);
  268. rle_code+=length;
  269. out_data+=length;
  270. }break;
  271. }
  272. }
  273. if ( (ctrlBuf==ctrlBuf_end)
  274. &&(rle_code==rle_code_end)
  275. &&(out_data==out_dataEnd))
  276. return hpatch_TRUE;
  277. else
  278. return _hpatch_FALSE;
  279. }
  280. //----------------------
  281. //patch by stream
  282. #undef TUInt
  283. #define TUInt hpatch_StreamPos_t
  284. typedef struct TStreamClip{
  285. TUInt streamPos;
  286. TUInt streamPos_end;
  287. const struct hpatch_TStreamInput* srcStream;
  288. size_t cacheBegin;//cacheEnd==kStreamCacheSize
  289. TByte cacheBuf[kStreamCacheSize];
  290. } TStreamClip;
  291. static void _TStreamClip_init(struct TStreamClip* sclip,
  292. const struct hpatch_TStreamInput* srcStream,
  293. TUInt streamPos,TUInt streamPos_end){
  294. sclip->srcStream=srcStream;
  295. sclip->streamPos=streamPos;
  296. sclip->streamPos_end=streamPos_end;
  297. sclip->cacheBegin=kStreamCacheSize;
  298. }
  299. #define _TStreamClip_isFinish(sclip) ( 0==_TStreamClip_streamSize(sclip) )
  300. #define _TStreamClip_isCacheEmpty(sclip) ( (sclip)->cacheBegin==kStreamCacheSize )
  301. #define _TStreamClip_cachedSize(sclip) ( (size_t)(kStreamCacheSize-(sclip)->cacheBegin) )
  302. #define _TStreamClip_streamSize(sclip) \
  303. ( (TUInt)((sclip)->streamPos_end-(sclip)->streamPos) + (TUInt)_TStreamClip_cachedSize(sclip) )
  304. static void _TStreamClip_updateCache(struct TStreamClip* sclip)
  305. {
  306. TByte* buf0=&sclip->cacheBuf[0];
  307. const TUInt stremSize=(TUInt)(sclip->streamPos_end-sclip->streamPos);
  308. size_t readSize=sclip->cacheBegin;
  309. if (readSize>stremSize)
  310. readSize=(size_t)stremSize;
  311. if (readSize==0) return;
  312. if (!_TStreamClip_isCacheEmpty(sclip)){
  313. memmove(buf0+(size_t)(sclip->cacheBegin-readSize),
  314. buf0+sclip->cacheBegin,_TStreamClip_cachedSize(sclip));
  315. }
  316. if (sclip->srcStream->read(sclip->srcStream->streamHandle,sclip->streamPos,
  317. buf0+(size_t)(kStreamCacheSize-readSize),buf0+kStreamCacheSize)
  318. == readSize ){
  319. sclip->cacheBegin-=readSize;
  320. sclip->streamPos+=readSize;
  321. }else{ //read error
  322. sclip->cacheBegin=kStreamCacheSize;
  323. sclip->streamPos=sclip->streamPos_end;
  324. }
  325. }
  326. static TByte* _TStreamClip_accessData(struct TStreamClip* sclip,size_t readSize){
  327. assert(readSize<=kStreamCacheSize);
  328. if (readSize>_TStreamClip_cachedSize(sclip))
  329. _TStreamClip_updateCache(sclip);
  330. if(readSize<=_TStreamClip_cachedSize(sclip)){
  331. return &sclip->cacheBuf[sclip->cacheBegin];
  332. }else{
  333. return 0; //read error
  334. }
  335. }
  336. #define _TStreamClip_skipData_noCheck(sclip,skipSize) ((sclip)->cacheBegin+=skipSize)
  337. static TByte* _TStreamClip_readData(struct TStreamClip* sclip,size_t readSize){
  338. TByte* result=_TStreamClip_accessData(sclip,readSize);
  339. _TStreamClip_skipData_noCheck(sclip,readSize);
  340. return result;
  341. }
  342. static void _TStreamClip_resetPosEnd(struct TStreamClip* sclip,TUInt new_posEnd){
  343. sclip->streamPos_end=new_posEnd;
  344. if (sclip->streamPos>new_posEnd){//cache overfull, need pop
  345. TByte* cacheBegin=&sclip->cacheBuf[sclip->cacheBegin];
  346. TUInt popSize=(TUInt)(sclip->streamPos-new_posEnd);
  347. assert(popSize<=_TStreamClip_cachedSize(sclip));
  348. memmove(cacheBegin+popSize,cacheBegin,(size_t)(_TStreamClip_cachedSize(sclip)-popSize));
  349. sclip->cacheBegin+=(size_t)popSize;
  350. sclip->streamPos=new_posEnd; //eq. sclip->streamPos-=popSize
  351. }
  352. }
  353. static hpatch_BOOL _TStreamClip_unpackUIntWithTag(struct TStreamClip* sclip,
  354. const int kTagBit,TUInt* result){
  355. #define kMaxPackedByte ((sizeof(TUInt)*8+6)/7+1) //11
  356. TByte* curCode,*codeBegin;
  357. size_t readSize=kMaxPackedByte;
  358. const TUInt dataSize=_TStreamClip_streamSize(sclip);
  359. #ifdef __RUN_MEM_SAFE_CHECK
  360. if (dataSize==0) return _hpatch_FALSE;
  361. #endif
  362. if (readSize>dataSize)
  363. readSize=(size_t)dataSize;
  364. codeBegin=_TStreamClip_accessData(sclip,readSize);
  365. if (codeBegin==0) return _hpatch_FALSE;
  366. curCode=codeBegin;
  367. if (!unpackPosWithTag((const TByte**)&curCode,codeBegin+readSize,kTagBit,result))
  368. return _hpatch_FALSE;
  369. _TStreamClip_skipData_noCheck(sclip,(size_t)(curCode-codeBegin));
  370. return hpatch_TRUE;
  371. }
  372. #define _TStreamClip_unpackUIntWithTagTo(puint,sclip,kTagBit) \
  373. { if (!_TStreamClip_unpackUIntWithTag(sclip,kTagBit,puint)) return _hpatch_FALSE; }
  374. #define _TStreamClip_unpackUIntTo(puint,sclip) \
  375. _TStreamClip_unpackUIntWithTagTo(puint,sclip,0)
  376. typedef struct _TBytesRle_load_stream{
  377. TUInt memCopyLength;
  378. TUInt memSetLength;
  379. const struct hpatch_TStreamInput* rle_stream;
  380. TByte memSetValue;
  381. struct TStreamClip ctrlClip;
  382. struct TStreamClip rleCodeClip;
  383. } _TBytesRle_load_stream;
  384. static hpatch_BOOL _TBytesRle_load_stream_init(_TBytesRle_load_stream* loader,
  385. const struct hpatch_TStreamInput* rle_stream,
  386. TUInt rle_code,TUInt rle_code_end){
  387. TUInt ctrlSize;
  388. struct TStreamClip* rleHeadClip=&loader->ctrlClip;//rename, share address
  389. _TStreamClip_init(rleHeadClip,rle_stream,rle_code,rle_code_end);
  390. _TStreamClip_unpackUIntTo(&ctrlSize,rleHeadClip);
  391. rle_code=(TUInt)(rle_code_end-_TStreamClip_streamSize(rleHeadClip));
  392. #ifdef __RUN_MEM_SAFE_CHECK
  393. if (ctrlSize>(TUInt)(rle_code_end-rle_code)) return _hpatch_FALSE;
  394. #endif
  395. loader->rle_stream=rle_stream;
  396. //eq. _TStreamClip_init(&loader->ctrlClip,rle_stream,rle_code,rle_code+ctrlSize);
  397. _TStreamClip_resetPosEnd(&loader->ctrlClip,rle_code+ctrlSize);
  398. _TStreamClip_init(&loader->rleCodeClip,rle_stream,rle_code+ctrlSize,rle_code_end);
  399. loader->memSetLength=0;
  400. loader->memSetValue=0;//nil;
  401. loader->memCopyLength=0;
  402. return hpatch_TRUE;
  403. }
  404. static void memSet_add(TByte* dst,const TByte src,size_t length){
  405. size_t length_fast,i;
  406. length_fast=length&(~(size_t)7);
  407. for (i=0;i<length_fast;i+=8){
  408. dst[i ]+=src;
  409. dst[i+1]+=src;
  410. dst[i+2]+=src;
  411. dst[i+3]+=src;
  412. dst[i+4]+=src;
  413. dst[i+5]+=src;
  414. dst[i+6]+=src;
  415. dst[i+7]+=src;
  416. }
  417. for (;i<length;++i)
  418. dst[i]+=src;
  419. }
  420. static hpatch_BOOL _TBytesRle_load_stream_mem_add(_TBytesRle_load_stream* loader,
  421. size_t* _decodeSize,TByte** _out_data){
  422. size_t decodeSize=*_decodeSize;
  423. TByte* out_data=*_out_data;
  424. struct TStreamClip* rleCodeClip=&loader->rleCodeClip;
  425. while ((loader->memSetLength>0)&&(decodeSize>0)) {
  426. size_t memSetStep=decodeSize;
  427. if (memSetStep>loader->memSetLength)
  428. memSetStep=(size_t)loader->memSetLength;
  429. memSet_add(out_data,loader->memSetValue,memSetStep);
  430. out_data+=memSetStep;
  431. decodeSize-=memSetStep;
  432. loader->memSetLength-=memSetStep;
  433. }
  434. while ((loader->memCopyLength>0)&&(decodeSize>0)) {
  435. TByte* rleData;
  436. size_t decodeStep=kStreamCacheSize;
  437. if (decodeStep>decodeSize)
  438. decodeStep=decodeSize;
  439. if (decodeStep>loader->memCopyLength)
  440. decodeStep=(size_t)loader->memCopyLength;
  441. rleData=_TStreamClip_readData(rleCodeClip,decodeStep);
  442. if (rleData==0) return _hpatch_FALSE;
  443. addData(out_data,rleData,decodeStep);
  444. out_data+=decodeStep;
  445. decodeSize-=decodeStep;
  446. loader->memCopyLength-=decodeStep;
  447. }
  448. *_decodeSize=decodeSize;
  449. *_out_data=out_data;
  450. return hpatch_TRUE;
  451. }
  452. static hpatch_BOOL _TBytesRle_load_stream_isFinish(const _TBytesRle_load_stream* loader){
  453. return(loader->memSetLength==0)
  454. &&(loader->memCopyLength==0)
  455. &&(_TStreamClip_isFinish(&loader->rleCodeClip))
  456. &&(_TStreamClip_isFinish(&loader->ctrlClip));
  457. }
  458. //RLE compression algorithm
  459. static hpatch_BOOL _TBytesRle_load_stream_decode_add(_TBytesRle_load_stream* loader,
  460. size_t decodeSize,TByte* out_data){
  461. if (!_TBytesRle_load_stream_mem_add(loader,&decodeSize,&out_data))
  462. return _hpatch_FALSE;
  463. while ((decodeSize>0)&&(!_TStreamClip_isFinish(&loader->ctrlClip))){
  464. enum TByteRleType type;
  465. TUInt length;
  466. const TByte* pType=_TStreamClip_accessData(&loader->ctrlClip,1);
  467. if (pType==0) return _hpatch_FALSE;
  468. type=(enum TByteRleType)((*pType)>>(8-kByteRleType_bit));
  469. _TStreamClip_unpackUIntWithTagTo(&length,&loader->ctrlClip,kByteRleType_bit);
  470. #ifdef __RUN_MEM_SAFE_CHECK
  471. if (length+1<length) return _hpatch_FALSE;
  472. #endif
  473. ++length;
  474. switch (type){
  475. case kByteRleType_rle0:{
  476. loader->memSetLength=length;
  477. loader->memSetValue=0;
  478. }break;
  479. case kByteRleType_rle255:{
  480. loader->memSetLength=length;
  481. loader->memSetValue=255;
  482. }break;
  483. case kByteRleType_rle:{
  484. const TByte* pSetValue;
  485. #ifdef __RUN_MEM_SAFE_CHECK
  486. if (1>_TStreamClip_streamSize(&loader->rleCodeClip)) return _hpatch_FALSE;
  487. #endif
  488. loader->memSetLength=length;
  489. pSetValue=_TStreamClip_readData(&loader->rleCodeClip,1);
  490. if (pSetValue==0) return _hpatch_FALSE;
  491. loader->memSetValue=*pSetValue;
  492. }break;
  493. case kByteRleType_unrle:{
  494. #ifdef __RUN_MEM_SAFE_CHECK
  495. if (length>_TStreamClip_streamSize(&loader->rleCodeClip)) return _hpatch_FALSE;
  496. #endif
  497. loader->memCopyLength=length;
  498. }break;
  499. }
  500. if (!_TBytesRle_load_stream_mem_add(loader,&decodeSize,&out_data)) return _hpatch_FALSE;
  501. }
  502. if (decodeSize==0)
  503. return hpatch_TRUE;
  504. else
  505. return _hpatch_FALSE;
  506. }
  507. static hpatch_BOOL _patch_decode_from_clipOrStream(const struct hpatch_TStreamOutput* out_newData,TUInt writeToPos,
  508. _TBytesRle_load_stream* rle_loader,TUInt decodeLength,
  509. struct TStreamClip* srcClip,
  510. const struct hpatch_TStreamInput* srcStream,TUInt readPos)
  511. {
  512. //1kbyte temp buffer
  513. // TByte _tempMemBuf[kStreamCacheSize];
  514. // TByte* data=&_tempMemBuf[0];
  515. TByte *_tempMemBuf, *data;
  516. _tempMemBuf = mem_malloc(kStreamCacheSize);
  517. if (!_tempMemBuf) {
  518. printk("%s: malloc failed, size 0x%x\n", __func__, kStreamCacheSize);
  519. return _hpatch_FALSE;
  520. }
  521. data = _tempMemBuf;
  522. while (decodeLength>0)
  523. {
  524. size_t decodeStep=kStreamCacheSize;
  525. if (decodeStep>decodeLength)
  526. {
  527. decodeStep=(size_t)decodeLength;
  528. }
  529. //read data from cache or stream
  530. if (srcClip!=0)
  531. {
  532. assert(srcStream==0);
  533. data=_TStreamClip_readData(srcClip,decodeStep);
  534. if (data==0) {
  535. goto fail_exit;
  536. }
  537. }
  538. else
  539. {
  540. assert(srcStream!=0);
  541. if (decodeStep!=srcStream->read(srcStream->streamHandle,readPos,data,data+decodeStep)) {
  542. goto fail_exit;
  543. }
  544. }
  545. if (!_TBytesRle_load_stream_decode_add(rle_loader,decodeStep,data))
  546. {
  547. goto fail_exit;
  548. }
  549. //write new data
  550. if (decodeStep!=out_newData->write(out_newData->streamHandle,writeToPos,data,data+decodeStep))
  551. {
  552. goto fail_exit;
  553. }
  554. readPos+=decodeStep;
  555. writeToPos+=decodeStep;
  556. decodeLength-=decodeStep;
  557. }
  558. mem_free(_tempMemBuf);
  559. return hpatch_TRUE;
  560. fail_exit:
  561. mem_free(_tempMemBuf);
  562. return _hpatch_FALSE;
  563. }
  564. hpatch_BOOL patch_stream(const struct hpatch_TStreamOutput* out_newData,
  565. const struct hpatch_TStreamInput* oldData,
  566. const struct hpatch_TStreamInput* serializedDiff)
  567. {
  568. struct TStreamClip *code_lengthsClip = NULL; //size 418
  569. struct TStreamClip *code_inc_oldPosClip = NULL;
  570. struct TStreamClip *code_inc_newPosClip = NULL;
  571. struct TStreamClip *code_newDataDiffClip = NULL;
  572. struct _TBytesRle_load_stream *rle_loader = NULL; //size 848
  573. TUInt ctrlCount;
  574. hpatch_BOOL ret;
  575. assert(out_newData!=0);
  576. assert(out_newData->write!=0);
  577. assert(oldData!=0);
  578. assert(oldData->read!=0);
  579. assert(serializedDiff!=0);
  580. assert(serializedDiff->read!=0);
  581. assert(serializedDiff->streamSize>0);
  582. code_lengthsClip = mem_malloc(sizeof(struct TStreamClip));
  583. if (!code_lengthsClip) {
  584. printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
  585. return _hpatch_FALSE;
  586. }
  587. code_inc_oldPosClip = mem_malloc(sizeof(struct TStreamClip));
  588. if (!code_inc_oldPosClip) {
  589. printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
  590. mem_free(code_lengthsClip);
  591. return _hpatch_FALSE;
  592. }
  593. code_inc_newPosClip = mem_malloc(sizeof(struct TStreamClip));
  594. if (!code_inc_newPosClip) {
  595. printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
  596. mem_free(code_inc_oldPosClip);
  597. mem_free(code_lengthsClip);
  598. return _hpatch_FALSE;
  599. }
  600. code_newDataDiffClip = mem_malloc(sizeof(struct TStreamClip));
  601. if (!code_newDataDiffClip) {
  602. printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct TStreamClip));
  603. mem_free(code_inc_newPosClip);
  604. mem_free(code_inc_oldPosClip);
  605. mem_free(code_lengthsClip);
  606. return _hpatch_FALSE;
  607. }
  608. rle_loader = mem_malloc(sizeof(struct _TBytesRle_load_stream));
  609. if (!rle_loader) {
  610. printk("%s: malloc failed, size 0x%x\n", __func__, (uint32_t)sizeof(struct _TBytesRle_load_stream));
  611. ret = _hpatch_FALSE;
  612. goto func_ret;
  613. }
  614. { //head
  615. TUInt lengthSize,inc_newPosSize,inc_oldPosSize,newDataDiffSize;
  616. TUInt diffPos0;
  617. const TUInt diffPos_end=serializedDiff->streamSize;
  618. struct TStreamClip* diffHeadClip=code_lengthsClip;//rename, share address
  619. _TStreamClip_init(diffHeadClip,serializedDiff,0,diffPos_end); //Initialize the diffheadclip structure and set the cache size of 2K
  620. _TStreamClip_unpackUIntTo(&ctrlCount,diffHeadClip);
  621. _TStreamClip_unpackUIntTo(&lengthSize,diffHeadClip);
  622. _TStreamClip_unpackUIntTo(&inc_newPosSize,diffHeadClip);
  623. _TStreamClip_unpackUIntTo(&inc_oldPosSize,diffHeadClip);
  624. _TStreamClip_unpackUIntTo(&newDataDiffSize,diffHeadClip);
  625. diffPos0=(TUInt)(diffPos_end-_TStreamClip_streamSize(diffHeadClip));
  626. #ifdef __RUN_MEM_SAFE_CHECK
  627. if (lengthSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
  628. printk("%s %d: error\n", __func__, __LINE__);
  629. ret = _hpatch_FALSE;
  630. goto func_ret;
  631. }
  632. #endif
  633. //eq. _TStreamClip_init(&code_lengthsClip,serializedDiff,diffPos0,diffPos0+lengthSize);
  634. _TStreamClip_resetPosEnd(code_lengthsClip,diffPos0+lengthSize);
  635. diffPos0+=lengthSize;
  636. #ifdef __RUN_MEM_SAFE_CHECK
  637. if (inc_newPosSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
  638. printk("%s %d: error\n", __func__, __LINE__);
  639. ret = _hpatch_FALSE;
  640. goto func_ret;
  641. }
  642. #endif
  643. _TStreamClip_init(code_inc_newPosClip,serializedDiff,diffPos0,diffPos0+inc_newPosSize);
  644. diffPos0+=inc_newPosSize;
  645. #ifdef __RUN_MEM_SAFE_CHECK
  646. if (inc_oldPosSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
  647. printk("%s %d: error\n", __func__, __LINE__);
  648. ret = _hpatch_FALSE;
  649. goto func_ret;
  650. }
  651. #endif
  652. _TStreamClip_init(code_inc_oldPosClip,serializedDiff,diffPos0,diffPos0+inc_oldPosSize);
  653. diffPos0+=inc_oldPosSize;
  654. #ifdef __RUN_MEM_SAFE_CHECK
  655. if (newDataDiffSize>(TUInt)(serializedDiff->streamSize-diffPos0)) {
  656. printk("%s %d: error\n", __func__, __LINE__);
  657. ret = _hpatch_FALSE;
  658. goto func_ret;
  659. }
  660. #endif
  661. _TStreamClip_init(code_newDataDiffClip,serializedDiff,diffPos0,diffPos0+newDataDiffSize);
  662. diffPos0+=newDataDiffSize;
  663. //rle
  664. if (!_TBytesRle_load_stream_init(rle_loader,serializedDiff,diffPos0,diffPos_end)) {
  665. printk("%s %d: error\n", __func__, __LINE__);
  666. ret = _hpatch_FALSE;
  667. goto func_ret;
  668. }
  669. }
  670. {
  671. //patch
  672. const TUInt newDataSize=out_newData->streamSize;
  673. TUInt oldPosBack=0;
  674. TUInt newPosBack=0;
  675. TUInt i;
  676. for (i=0; i<ctrlCount; ++i)
  677. {
  678. TUInt copyLength,addLength, oldPos,inc_oldPos;
  679. TByte inc_oldPos_sign;
  680. const TByte* pSign;
  681. _TStreamClip_unpackUIntTo(&copyLength,code_inc_newPosClip);
  682. _TStreamClip_unpackUIntTo(&addLength,code_lengthsClip);
  683. #ifdef __RUN_MEM_SAFE_CHECK
  684. if (_TStreamClip_isFinish(code_inc_oldPosClip)) {
  685. printk("%s %d: error\n", __func__, __LINE__);
  686. ret = _hpatch_FALSE;
  687. goto func_ret;
  688. }
  689. #endif
  690. pSign=_TStreamClip_accessData(code_inc_oldPosClip,1);
  691. if (pSign==0) {
  692. printk("%s %d: error\n", __func__, __LINE__);
  693. ret = _hpatch_FALSE;
  694. goto func_ret;
  695. }
  696. inc_oldPos_sign=(*pSign)>>(8-kSignTagBit);
  697. _TStreamClip_unpackUIntWithTagTo(&inc_oldPos,code_inc_oldPosClip,kSignTagBit);
  698. if (inc_oldPos_sign==0)
  699. oldPos=oldPosBack+inc_oldPos;
  700. else
  701. oldPos=oldPosBack-inc_oldPos;
  702. if (copyLength>0){
  703. #ifdef __RUN_MEM_SAFE_CHECK
  704. if (copyLength>(TUInt)(newDataSize-newPosBack)) {
  705. printk("%s %d: error\n", __func__, __LINE__);
  706. ret = _hpatch_FALSE;
  707. goto func_ret;
  708. }
  709. if (copyLength>_TStreamClip_streamSize(code_newDataDiffClip)) {
  710. printk("%s %d: error\n", __func__, __LINE__);
  711. ret = _hpatch_FALSE;
  712. goto func_ret;
  713. }
  714. #endif
  715. if (!_patch_decode_from_clipOrStream(out_newData,newPosBack,rle_loader,copyLength,
  716. code_newDataDiffClip,0,0)) {
  717. printk("%s %d: error\n", __func__, __LINE__);
  718. ret = _hpatch_FALSE;
  719. goto func_ret;
  720. }
  721. newPosBack+=copyLength;
  722. }
  723. #ifdef __RUN_MEM_SAFE_CHECK
  724. if ((addLength>(TUInt)(newDataSize-newPosBack))) {
  725. printk("%s %d: error\n", __func__, __LINE__);
  726. ret = _hpatch_FALSE;
  727. goto func_ret;
  728. }
  729. if ( (oldPos>(oldData->streamSize)) ||
  730. (addLength>(TUInt)(oldData->streamSize-oldPos)) ) {
  731. printk("%s %d: error\n", __func__, __LINE__);
  732. ret = _hpatch_FALSE;
  733. goto func_ret;
  734. }
  735. #endif
  736. if (!_patch_decode_from_clipOrStream(out_newData,newPosBack,rle_loader,addLength,
  737. 0,oldData,oldPos)) {
  738. printk("%s %d: error\n", __func__, __LINE__);
  739. ret = _hpatch_FALSE;
  740. goto func_ret;
  741. }
  742. oldPosBack=oldPos;
  743. newPosBack+=addLength;
  744. }
  745. if (newPosBack<newDataSize){
  746. TUInt copyLength=newDataSize-newPosBack;
  747. #ifdef __RUN_MEM_SAFE_CHECK
  748. if (copyLength>_TStreamClip_streamSize(code_newDataDiffClip)) {
  749. printk("%s %d: error\n", __func__, __LINE__);
  750. ret = _hpatch_FALSE;
  751. goto func_ret;
  752. }
  753. #endif
  754. if (!_patch_decode_from_clipOrStream(out_newData,newPosBack,rle_loader,copyLength,
  755. code_newDataDiffClip,0,0)) {
  756. printk("%s %d: error\n", __func__, __LINE__);
  757. ret = _hpatch_FALSE;
  758. goto func_ret;
  759. }
  760. newPosBack=newDataSize;
  761. }
  762. }
  763. if ( _TBytesRle_load_stream_isFinish(rle_loader)
  764. && _TStreamClip_isFinish(code_lengthsClip)
  765. && _TStreamClip_isFinish(code_inc_newPosClip)
  766. && _TStreamClip_isFinish(code_inc_oldPosClip)
  767. && _TStreamClip_isFinish(code_newDataDiffClip) ) {
  768. ret = hpatch_TRUE;
  769. goto func_ret;
  770. } else {
  771. printk("%s %d: error\n", __func__, __LINE__);
  772. ret = _hpatch_FALSE;
  773. goto func_ret;
  774. }
  775. func_ret:
  776. if (rle_loader)
  777. mem_free(rle_loader);
  778. mem_free(code_newDataDiffClip);
  779. mem_free(code_inc_newPosClip);
  780. mem_free(code_inc_oldPosClip);
  781. mem_free(code_lengthsClip);
  782. return ret;
  783. }