/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize, unsigned long fw_arg0, unsigned long fw_arg1, unsigned long fw_arg2, unsigned long fw_arg3) { CLzmaDec state; ISzAlloc dummy; ISeqInStream stream; ELzmaStatus status; unsigned int i; /* temp value */ unsigned int osize; /* uncompressed size */ dummy.Alloc = dummy_alloc; dummy.Free = dummy_free; stream.Read = read_bytes; /* look for trx header, 32-bit data access */ for (data = ((unsigned char *)KSEG1ADDR(BCM4710_FLASH)); ((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); /* compressed kernel is in the partition 1 */ data += ((struct trx_header *)data)->offsets[1]; offset = 0; /* read lzma stream header */ SeqInStream_Read(&stream, workspace, LZMA_PROPS_SIZE + 8); /* read the lower half of uncompressed size in the header */ osize = (workspace[LZMA_PROPS_SIZE + 0]) + (workspace[LZMA_PROPS_SIZE + 1] << 8) + (workspace[LZMA_PROPS_SIZE + 2] << 16) + (workspace[LZMA_PROPS_SIZE + 3] << 24); LzmaDec_Construct(&state); LzmaDec_AllocateProbs(&state, workspace, LZMA_PROPS_SIZE, &dummy); state.dic = (unsigned char *)LOADADDR; state.dicBufSize = osize; /* decompress kernel */ LzmaDec_Init(&state); do { i = LZMA_REQUIRED_INPUT_MAX; SeqInStream_Read(&stream, workspace, i); if (LzmaDec_DecodeToDic(&state, osize, workspace, &i, LZMA_FINISH_ANY, &status) != SZ_OK) { /* something went wrong */ return; } } while (status == LZMA_STATUS_NEEDS_MORE_INPUT); blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* jump to load address */ ((void (*)(unsigned long, unsigned long, unsigned long, unsigned long))LOADADDR)(fw_arg0, fw_arg1, fw_arg2, fw_arg3); }
static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inStream, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) { CLzmaDec state; int res = SZ_OK; size_t _inSize; Byte *inBuf = NULL; LzmaDec_Construct(&state); RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); state.dic = outBuffer; state.dicBufSize = outSize; LzmaDec_Init(&state); _inSize = 0; for (;;) { if (_inSize == 0) { _inSize = (1 << 18); if (_inSize > inSize) _inSize = (size_t)(inSize); res = inStream->Read((void *)inStream, (void **)&inBuf, &_inSize); if (res != SZ_OK) break; inSize -= _inSize; } { SizeT inProcessed = _inSize, dicPos = state.dicPos; ELzmaStatus status; res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); _inSize -= inProcessed; inBuf = (Byte *)inBuf + inProcessed; if (res != SZ_OK) break; if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) { if (state.dicBufSize != outSize || _inSize != 0 || (status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) res = SZ_ERROR_DATA; break; } } } LzmaDec_FreeProbs(&state, allocMain); return res; }
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) { CLzmaDec state; SRes res = SZ_OK; LzmaDec_Construct(&state); RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); state.dic = outBuffer; state.dicBufSize = outSize; LzmaDec_Init(&state); for (;;) { Byte *inBuf = NULL; size_t lookahead = (1 << 18); if (lookahead > inSize) lookahead = (size_t)inSize; res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); if (res != SZ_OK) break; { SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; ELzmaStatus status; res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); lookahead -= inProcessed; inSize -= inProcessed; if (res != SZ_OK) break; if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) { if (state.dicBufSize != outSize || lookahead != 0 || (status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) res = SZ_ERROR_DATA; break; } res = inStream->Skip((void *)inStream, inProcessed); if (res != SZ_OK) break; } } LzmaDec_FreeProbs(&state, allocMain); return res; }
bool LZMADecoder::CodeTo(const MemoryByteData& data,MemoryByteData& outData) const { const byte* inBuffer=data.GetData(); size_t inSize=data.GetSize(); const size_t propSize=5; ELzmaStatus outStatus; ISzAlloc myAlloc; myAlloc.Alloc=LZMAAlloc; myAlloc.Free=LZMAFree; CLzmaDec p; SRes res; if (inSize < propSize) return false; LzmaDec_Construct(&p); res = LzmaDec_AllocateProbs(&p, inBuffer, propSize, &myAlloc); uint64 fileSize = 0; for (int i = 0; i < 8; i++) fileSize |= ((uint64)inBuffer[propSize + i]) << (8 * i); if (outData.GetSize()!=(size_t)fileSize) { LzmaDec_FreeProbs(&p, &myAlloc); return false; } else { LzmaDec_Init(&p); p.dic = outData.GetData(); p.dicBufSize = (size_t)fileSize; size_t outSize=inSize-13; res = LzmaDec_DecodeToDic(&p, (size_t)fileSize, inBuffer+13, &outSize, LZMA_FINISH_ANY, &outStatus); if (res == SZ_OK && outStatus == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; LzmaDec_FreeProbs(&p, &myAlloc); return true; } }
size_t LZMADecoder::OnCode(const MemoryData& input, MemoryData& output) const { RETURN_ZERO_IF_EMPTY(input); const byte* inBuffer = input.Data(); size_t inSize = input.Size(); ELzmaStatus outStatus; ISzAlloc myAlloc; myAlloc.Alloc = LZMAAlloc; myAlloc.Free = LZMAFree; CLzmaDec p; SRes res; LzmaDec_Construct(&p); res = LzmaDec_AllocateProbs(&p, inBuffer, LZMA_PROPS_SIZE, &myAlloc); uint64 fileSize = 0; for (int i = 0; i < 8; i++) fileSize |= ((uint64)inBuffer[LZMA_PROPS_SIZE + i]) << (8 * i); if (output.Size()<(size_t)fileSize) { Log::AssertFailedFormat("output size:{} < expected size{}", output.Size(), fileSize); LzmaDec_FreeProbs(&p, &myAlloc); return 0; } LzmaDec_Init(&p); p.dic = output.MutableData(); p.dicBufSize = (size_t)fileSize; size_t outSize = inSize - 13; res = LzmaDec_DecodeToDic(&p, (size_t)fileSize, inBuffer + 13, &outSize, LZMA_FINISH_ANY, &outStatus); if (res == SZ_OK && outStatus == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; LzmaDec_FreeProbs(&p, &myAlloc); return (size_t)fileSize; }
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) { SizeT inSize = *srcLen; *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; while (p->state != LZMA2_STATE_ERROR) { SizeT dicPos; if (p->state == LZMA2_STATE_FINISHED) { *status = LZMA_STATUS_FINISHED_WITH_MARK; return SZ_OK; } dicPos = p->decoder.dicPos; if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) { *status = LZMA_STATUS_NOT_FINISHED; return SZ_OK; } if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) { if (*srcLen == inSize) { *status = LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } (*srcLen)++; p->state = Lzma2Dec_UpdateState(p, *src++); if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) break; continue; } { SizeT inCur = inSize - *srcLen; SizeT outCur = dicLimit - dicPos; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; if (outCur >= p->unpackSize) { outCur = (SizeT)p->unpackSize; curFinishMode = LZMA_FINISH_END; } if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { if (inCur == 0) { *status = LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } if (p->state == LZMA2_STATE_DATA) { BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); LzmaDec_InitDicAndState(&p->decoder, initDic, False); } if (inCur > outCur) inCur = outCur; if (inCur == 0) break; LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); src += inCur; *srcLen += inCur; p->unpackSize -= (UInt32)inCur; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; } else { SRes res; if (p->state == LZMA2_STATE_DATA) { BoolInt initDic = (p->control >= 0xE0); BoolInt initState = (p->control >= 0xA0); LzmaDec_InitDicAndState(&p->decoder, initDic, initState); p->state = LZMA2_STATE_DATA_CONT; } if (inCur > p->packSize) inCur = (SizeT)p->packSize; res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status); src += inCur; *srcLen += inCur; p->packSize -= (UInt32)inCur; outCur = p->decoder.dicPos - dicPos; p->unpackSize -= (UInt32)outCur; if (res != 0) break; if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) { if (p->packSize == 0) break; return SZ_OK; } if (inCur == 0 && outCur == 0) { if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || p->unpackSize != 0 || p->packSize != 0) break; p->state = LZMA2_STATE_CONTROL; } *status = LZMA_STATUS_NOT_SPECIFIED; } } } *status = LZMA_STATUS_NOT_SPECIFIED; p->state = LZMA2_STATE_ERROR; return SZ_ERROR_DATA; }
HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { if (_inBuf == 0 || !_propsWereSet) return S_FALSE; UInt64 startInProgress = _inSizeProcessed; for (;;) { if (_inPos == _inSize) { _inPos = _inSize = 0; RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize)); } SizeT dicPos = _state.dicPos; SizeT curSize = _state.dicBufSize - dicPos; const UInt32 kStepSize = ((UInt32)1 << 22); if (curSize > kStepSize) curSize = (SizeT)kStepSize; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; if (_outSizeDefined) { const UInt64 rem = _outSize - _outSizeProcessed; if (rem < curSize) { curSize = (SizeT)rem; if (FinishStream) finishMode = LZMA_FINISH_END; } } SizeT inSizeProcessed = _inSize - _inPos; ELzmaStatus status; SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); _inPos += (UInt32)inSizeProcessed; _inSizeProcessed += inSizeProcessed; SizeT outSizeProcessed = _state.dicPos - dicPos; _outSizeProcessed += outSizeProcessed; bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); if (res != 0 || _state.dicPos == _state.dicBufSize || finished || stopDecoding) { HRESULT res2 = WriteStream(outStream, _state.dic, _state.dicPos); if (res != 0) return S_FALSE; RINOK(res2); if (stopDecoding) return S_OK; if (finished) return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); } if (_state.dicPos == _state.dicBufSize) _state.dicPos = 0; if (progress) { UInt64 inSize = _inSizeProcessed - startInProgress; RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed)); } } }
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) { SizeT inSize = *srcLen; *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; while (p->state != LZMA2_STATE_FINISHED) { SizeT dicPos = p->decoder.dicPos; if (p->state == LZMA2_STATE_ERROR) return SZ_ERROR_DATA; if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) { *status = LZMA_STATUS_NOT_FINISHED; return SZ_OK; } if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) { if (*srcLen == inSize) { *status = LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } (*srcLen)++; p->state = Lzma2Dec_UpdateState(p, *src++); continue; } { SizeT destSizeCur = dicLimit - dicPos; SizeT srcSizeCur = inSize - *srcLen; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; if (p->unpackSize <= destSizeCur) { destSizeCur = (SizeT)p->unpackSize; curFinishMode = LZMA_FINISH_END; } if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { if (*srcLen == inSize) { *status = LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; } if (p->state == LZMA2_STATE_DATA) { Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); if (initDic) p->needInitProp = p->needInitState = True; else if (p->needInitDic) return SZ_ERROR_DATA; p->needInitDic = False; LzmaDec_InitDicAndState(&p->decoder, initDic, False); } if (srcSizeCur > destSizeCur) srcSizeCur = destSizeCur; if (srcSizeCur == 0) return SZ_ERROR_DATA; LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); src += srcSizeCur; *srcLen += srcSizeCur; p->unpackSize -= (UInt32)srcSizeCur; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; } else { SizeT outSizeProcessed; SRes res; if (p->state == LZMA2_STATE_DATA) { int mode = LZMA2_GET_LZMA_MODE(p); Bool initDic = (mode == 3); Bool initState = (mode > 0); if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) return SZ_ERROR_DATA; LzmaDec_InitDicAndState(&p->decoder, initDic, initState); p->needInitDic = False; p->needInitState = False; p->state = LZMA2_STATE_DATA_CONT; } if (srcSizeCur > p->packSize) srcSizeCur = (SizeT)p->packSize; res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); src += srcSizeCur; *srcLen += srcSizeCur; p->packSize -= (UInt32)srcSizeCur; outSizeProcessed = p->decoder.dicPos - dicPos; p->unpackSize -= (UInt32)outSizeProcessed; RINOK(res); if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) return res; if (srcSizeCur == 0 && outSizeProcessed == 0) { if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || p->unpackSize != 0 || p->packSize != 0) return SZ_ERROR_DATA; p->state = LZMA2_STATE_CONTROL; } if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) *status = LZMA_STATUS_NOT_FINISHED; } } } *status = LZMA_STATUS_FINISHED_WITH_MARK; return SZ_OK; }
HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { if (_inBuf == 0 || !_propsWereSet) return S_FALSE; UInt64 startInProgress = _inSizeProcessed; SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize); for (;;) { if (_inPos == _inSize) { _inPos = _inSize = 0; RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); } SizeT dicPos = _state.dicPos; SizeT curSize = next - dicPos; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; if (_outSizeDefined) { const UInt64 rem = _outSize - _outSizeProcessed; if (rem <= curSize) { curSize = (SizeT)rem; if (FinishStream) finishMode = LZMA_FINISH_END; } } SizeT inSizeProcessed = _inSize - _inPos; ELzmaStatus status; SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); _inPos += (UInt32)inSizeProcessed; _inSizeProcessed += inSizeProcessed; SizeT outSizeProcessed = _state.dicPos - dicPos; _outSizeProcessed += outSizeProcessed; bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); if (res != 0 || _state.dicPos == next || finished || stopDecoding) { HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos); _wrPos = _state.dicPos; if (_state.dicPos == _state.dicBufSize) { _state.dicPos = 0; _wrPos = 0; } next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize); if (res != 0) return S_FALSE; RINOK(res2); if (stopDecoding) { if (status == LZMA_STATUS_NEEDS_MORE_INPUT) NeedMoreInput = true; if (FinishStream && status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) return S_FALSE; return S_OK; } if (finished) { if (status == LZMA_STATUS_NEEDS_MORE_INPUT) NeedMoreInput = true; return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); } } if (progress) { UInt64 inSize = _inSizeProcessed - startInProgress; RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed)); } } }