std::vector<asymbol*> getSymbolsSortedFiltered(bfd* abfd, asymbol** symtab, size_t symcount) { std::vector<asymbol*> result; result.reserve(symcount); for (size_t i = 0; i < symcount; ++i) { asymbol* sym = symtab[i]; if (sym && keepSymbol(abfd, sym)) result.push_back(sym); } // sort by section, then by offset within section, then by size (reverse) - that way larger symbol survives after unique() std::sort(result.begin(), result.end(), [=](asymbol* lhs, asymbol* rhs) { return lhs->section != rhs->section ? lhs->section < rhs->section : lhs->value != rhs->value ? lhs->value < rhs->value : getSymbolSize(abfd, lhs) > getSymbolSize(abfd, rhs); }); // remove duplicate symbols result.erase( std::unique(result.begin(), result.end(), [](asymbol* lhs, asymbol* rhs) { return lhs->section == rhs->section && lhs->value == rhs->value; }), result.end()); return std::move(result); }
inline size_t Compressor_M3::getRepeatCodeLength(size_t d, size_t n) const { size_t nBits = 0; if (d == 0) { nBits = (getSymbolSize((unsigned int) n) << 1) + 1; } else { nBits = (getSymbolSize((unsigned int) (n - 1)) << 1) + getSymbolSize(d + size_t(n == 2)) + (n == 2 ? 4 : 5); } return nBits; }
void readByNameExample(std::ostream& out, long port, const AmsAddr& server) { static const char handleName[] = "MAIN.byByte[4]"; uint32_t bytesRead; out << __FUNCTION__ << "():\n"; const uint32_t handle = getHandleByNameExample(out, port, server, handleName); const uint32_t bufferSize = getSymbolSize(out, port, server, handleName); const auto buffer = std::unique_ptr<uint8_t>(new uint8_t[bufferSize]); for (size_t i = 0; i < 8; ++i) { const long status = AdsSyncReadReqEx2(port, &server, ADSIGRP_SYM_VALBYHND, handle, bufferSize, buffer.get(), &bytesRead); if (status) { out << "ADS read failed with: " << std::dec << status << '\n'; return; } out << "ADS read " << std::dec << bytesRead << " bytes:" << std::hex; for (size_t i = 0; i < bytesRead; ++i) { out << ' ' << (int)buffer.get()[i]; } out << '\n'; } releaseHandleExample(out, port, server, handle); }
void Compressor_M3::writeRepeatCode(std::vector< unsigned int >& buf, size_t d, size_t n) { if (d > 0) { n--; if (n == 1) { if (d > 510) throw Ep128Emu::Exception("internal error: match offset overflow"); d++; } } unsigned char nBits = (unsigned char) getSymbolSize((unsigned int) n); buf.push_back(((unsigned int) (nBits + 1) << 24) | ((1U << (nBits + 1)) - 2U)); if (n > 1) buf.push_back(encodeSymbol((unsigned int) n)); if (d < 1) return; nBits = (unsigned char) getSymbolSize((unsigned int) d); buf.push_back((n == 1 ? 0x03000000U : 0x04000000U) | (unsigned int) (nBits - (unsigned char) (n == 1))); if (d > 1) buf.push_back(encodeSymbol((unsigned int) d)); }
bfd_vma getSymbolPaddedSize(bfd* abfd, asymbol* sym, asymbol* next) { bfd_section* sec = bfd_get_section(sym); // If next symbol is from the same section, size is considered to be the address difference // Otherwise, symbol is assumed to occupy the rest of the section // Exception to the rule is when symbol VMA is not in the section (this can happen for TLS symbols) // Then just fall back to the ELF-specified size return (next && sec == bfd_get_section(next) && next->value < sec->size) ? bfd_asymbol_value(next) - bfd_asymbol_value(sym) : sym->value < sec->size ? sec->size - sym->value : getSymbolSize(abfd, sym); }
int getSymbolSize(symbol_t const *symbol) { if(symbol->type.indirectionCount > 0) { if((symbol->type.constMask & (1 << symbol->type.indirectionCount)) != 0) { dereferencedSymbol_t first = getArrayIndex(symbol->name, 0); if(first.symbol != NULL) { return getSymbolSize(first.symbol) * (symbol->address - first.symbol->address); } } return SIZEOF_PTR; } else if(symbol->type.baseType == BT_CHAR) { return 1; } else if(symbol->type.baseType == BT_INT) { return SIZEOF_INT; } return 0; }
void Compressor_M3::optimizeMatches(LZMatchParameters *matchTable, size_t *bitCountTable, unsigned char *bitIncMaxTable, size_t nBytes) { size_t maxLen = (config.splitOptimizationDepth < 9 ? maxRepeatLen : 1023); size_t minLen = (config.minLength > 2 ? config.minLength : 2); for (size_t i = nBytes; --i > 0; ) { size_t bestSize = 0x7FFFFFFF; size_t bestLen = 1; size_t bestOffs = 0; const unsigned int *matchPtr = searchTable->getMatches(i); size_t len = *matchPtr; // match length if (len >= minLen) { bestLen = len; bestOffs = *(++matchPtr) >> 10; bestSize = getRepeatCodeLength(bestOffs, len) + size_t((i + len) < nBytes) + bitCountTable[i + len]; if (len > maxLen) { // long LZ77 match if (bestOffs == 1) { // if a long RLE match is possible, use that matchTable[i].d = 1; matchTable[i].len = (unsigned short) len; bitCountTable[i] = bestSize; bitIncMaxTable[i] = bitIncMaxTable[i + len]; continue; } len = maxLen; } // otherwise check all possible LZ77 match lengths, for ( ; len > 0; len = (*matchPtr & 0x03FFU)) { unsigned int d = *matchPtr >> 10; size_t nxtLen = *(++matchPtr) & 0x03FFU; nxtLen = (nxtLen >= minLen ? nxtLen : (minLen - 1)); size_t nBitsBase = getSymbolSize(d) + 6; while (len > nxtLen) { size_t nBits = (getSymbolSize((unsigned int) (len - 1)) << 1) + nBitsBase + bitCountTable[i + len]; if (EP128EMU_UNLIKELY(len < 3)) { if (EP128EMU_UNLIKELY(d > 510U)) nBits = 0x7FFFFFFF; else nBits = (nBits - nBitsBase) + (getSymbolSize(d + 1) + 5); } if (nBits < bestSize) { bestSize = nBits; bestOffs = d; bestLen = len; } len--; } } } { size_t nBitsBase = 9; for (size_t k = 1; (i + k) <= nBytes; k++) { // and all possible literal sequence lengths size_t nBits = bitCountTable[i + k] + nBitsBase; nBitsBase += size_t((k & (k + 1)) != 0 ? 8 : 10); if (nBits <= bestSize && !((i + k) < nBytes && matchTable[i + k].d == 0)) { // a literal sequence can only be followed by an LZ77 match bestSize = nBits; bestOffs = 0; bestLen = k; } else if (nBits > (bestSize + 31)) { break; } } } matchTable[i].d = (unsigned short) bestOffs; matchTable[i].len = (unsigned short) bestLen; // store total compressed size in bits from this position bitCountTable[i] = bestSize; // store maximum size increase in bits from this position bitIncMaxTable[i] = bitIncMaxTable[i + bestLen]; if (bestSize > ((nBytes - i) << 3)) { unsigned char tmp = (unsigned char) (bestSize - ((nBytes - i) << 3)); if (tmp > bitIncMaxTable[i]) bitIncMaxTable[i] = tmp; } }