status_t BlobCache::unflatten(void const* buffer, size_t size, int fds[], size_t count) { // All errors should result in the BlobCache being in an empty state. mCacheEntries.clear(); if (count != 0) { ALOGE("unflatten: nonzero fd count: %d", count); return BAD_VALUE; } // Read the cache header if (size < sizeof(Header)) { ALOGE("unflatten: not enough room for cache header"); return BAD_VALUE; } const Header* header = reinterpret_cast<const Header*>(buffer); if (header->mMagicNumber != blobCacheMagic) { ALOGE("unflatten: bad magic number: %d", header->mMagicNumber); return BAD_VALUE; } if (header->mBlobCacheVersion != blobCacheVersion || header->mDeviceVersion != blobCacheDeviceVersion) { // We treat version mismatches as an empty cache. return OK; } // Read cache entries const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer); off_t byteOffset = align4(sizeof(Header)); size_t numEntries = header->mNumEntries; for (size_t i = 0; i < numEntries; i++) { if (byteOffset + sizeof(EntryHeader) > size) { mCacheEntries.clear(); ALOGE("unflatten: not enough room for cache entry headers"); return BAD_VALUE; } const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>( &byteBuffer[byteOffset]); size_t keySize = eheader->mKeySize; size_t valueSize = eheader->mValueSize; size_t entrySize = sizeof(EntryHeader) + keySize + valueSize; if (byteOffset + entrySize > size) { mCacheEntries.clear(); ALOGE("unflatten: not enough room for cache entry headers"); return BAD_VALUE; } const uint8_t* data = eheader->mData; set(data, keySize, data + keySize, valueSize); byteOffset += align4(entrySize); } return OK; }
size_t BlobCache::getFlattenedSize() const { size_t size = align4(sizeof(Header) + PROPERTY_VALUE_MAX); for (const CacheEntry& e : mCacheEntries) { std::shared_ptr<Blob> const& keyBlob = e.getKey(); std::shared_ptr<Blob> const& valueBlob = e.getValue(); size += align4(sizeof(EntryHeader) + keyBlob->getSize() + valueBlob->getSize()); } return size; }
int BlobCache::unflatten(void const* buffer, size_t size) { // All errors should result in the BlobCache being in an empty state. mCacheEntries.clear(); // Read the cache header if (size < sizeof(Header)) { ALOGE("unflatten: not enough room for cache header"); return -EINVAL; } const Header* header = reinterpret_cast<const Header*>(buffer); if (header->mMagicNumber != blobCacheMagic) { ALOGE("unflatten: bad magic number: %" PRIu32, header->mMagicNumber); return -EINVAL; } char buildId[PROPERTY_VALUE_MAX]; int len = property_get("ro.build.id", buildId, ""); if (header->mBlobCacheVersion != blobCacheVersion || header->mDeviceVersion != blobCacheDeviceVersion || len != header->mBuildIdLength || strncmp(buildId, header->mBuildId, len)) { // We treat version mismatches as an empty cache. return 0; } // Read cache entries const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer); off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength); size_t numEntries = header->mNumEntries; for (size_t i = 0; i < numEntries; i++) { if (byteOffset + sizeof(EntryHeader) > size) { mCacheEntries.clear(); ALOGE("unflatten: not enough room for cache entry header"); return -EINVAL; } const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>( &byteBuffer[byteOffset]); size_t keySize = eheader->mKeySize; size_t valueSize = eheader->mValueSize; size_t entrySize = sizeof(EntryHeader) + keySize + valueSize; size_t totalSize = align4(entrySize); if (byteOffset + totalSize > size) { mCacheEntries.clear(); ALOGE("unflatten: not enough room for cache entry"); return -EINVAL; } const uint8_t* data = eheader->mData; set(data, keySize, data + keySize, valueSize); byteOffset += totalSize; } return 0; }
status_t BlobCache::flatten(void* buffer, size_t size) const { // Write the cache header if (size < sizeof(Header)) { ALOGE("flatten: not enough room for cache header"); return BAD_VALUE; } Header* header = reinterpret_cast<Header*>(buffer); header->mMagicNumber = blobCacheMagic; header->mBlobCacheVersion = blobCacheVersion; header->mDeviceVersion = blobCacheDeviceVersion; header->mNumEntries = mCacheEntries.size(); char buildId[PROPERTY_VALUE_MAX]; header->mBuildIdLength = property_get("ro.build.id", buildId, ""); memcpy(header->mBuildId, buildId, header->mBuildIdLength); // Write cache entries uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer); off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength); for (size_t i = 0; i < mCacheEntries.size(); i++) { const CacheEntry& e(mCacheEntries[i]); sp<Blob> keyBlob = e.getKey(); sp<Blob> valueBlob = e.getValue(); size_t keySize = keyBlob->getSize(); size_t valueSize = valueBlob->getSize(); size_t entrySize = sizeof(EntryHeader) + keySize + valueSize; size_t totalSize = align4(entrySize); if (byteOffset + totalSize > size) { ALOGE("flatten: not enough room for cache entries"); return BAD_VALUE; } EntryHeader* eheader = reinterpret_cast<EntryHeader*>( &byteBuffer[byteOffset]); eheader->mKeySize = keySize; eheader->mValueSize = valueSize; memcpy(eheader->mData, keyBlob->getData(), keySize); memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize); if (totalSize > entrySize) { // We have padding bytes. Those will get written to storage, and contribute to the CRC, // so make sure we zero-them to have reproducible results. memset(eheader->mData + keySize + valueSize, 0, totalSize - entrySize); } byteOffset += totalSize; } return OK; }
void* mm_realloc(void* ptr, size_t size) { #ifdef MM_USE_STUBS return realloc(ptr, size); #else if(size==0){ free(ptr); return ptr; } if(!ptr) return malloc(size); t_block last; t_block b = valid_addr(ptr,&last); if(!b) return ptr; size_t s = align4(size); if(b->size >= s){ if(b->size > s+BLOCK_SIZE+4) split_block(b,s); return ptr; } void *new = malloc(s); if(!new) return NULL; size_t i,s4,*sp,*newp; s4=s/(sizeof(size_t)); sp=(size_t*)(p); newp=(size_t*)(new); for(i=0;i<s4;i++) newp[i]=sp[i]; free(ptr); return new; //#error Not implemented. #endif }
void* mm_malloc(size_t size) { #ifdef MM_USE_STUBS return calloc(1, size); #else s_block_ptr block, last; size_t s; s = align4(size); if(foot){ last = foot; block = find_block(last, s); if(block){ if((block->size - s) >= (BLOCK_SIZE + 4)) split_block(block, s); block->free = 0; } else{ block = extend_heap(last, s); if(!block) return NULL; } } else{ block = extend_heap(NULL, s); if(!block) return NULL; foot = block; } return block->data; //#error Not implemented. #endif }
status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count) const { if (count != 0) { ALOGE("flatten: nonzero fd count: %d", count); return BAD_VALUE; } // Write the cache header if (size < sizeof(Header)) { ALOGE("flatten: not enough room for cache header"); return BAD_VALUE; } Header* header = reinterpret_cast<Header*>(buffer); header->mMagicNumber = blobCacheMagic; header->mBlobCacheVersion = blobCacheVersion; header->mDeviceVersion = blobCacheDeviceVersion; header->mNumEntries = mCacheEntries.size(); // Write cache entries uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer); off_t byteOffset = align4(sizeof(Header)); for (size_t i = 0; i < mCacheEntries.size(); i++) { const CacheEntry& e(mCacheEntries[i]); sp<Blob> keyBlob = e.getKey(); sp<Blob> valueBlob = e.getValue(); size_t keySize = keyBlob->getSize(); size_t valueSize = valueBlob->getSize(); size_t entrySize = sizeof(EntryHeader) + keySize + valueSize; if (byteOffset + entrySize > size) { ALOGE("flatten: not enough room for cache entries"); return BAD_VALUE; } EntryHeader* eheader = reinterpret_cast<EntryHeader*>( &byteBuffer[byteOffset]); eheader->mKeySize = keySize; eheader->mValueSize = valueSize; memcpy(eheader->mData, keyBlob->getData(), keySize); memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize); byteOffset += align4(entrySize); } return OK; }
/*! A strdup version that aligns on 4 bytes. To avoid warning from valgrind */ static inline char * strdup4(char *str) { char *dup; int len; len = align4(strlen(str)+1); if ((dup = malloc(len)) == NULL) return NULL; strncpy(dup, str, len); return dup; }
void QPAGenerator::writeHeader() { QFontEngineQPA::Header header; header.magic[0] = 'Q'; header.magic[1] = 'P'; header.magic[2] = 'F'; header.magic[3] = '2'; header.lock = 1; header.majorVersion = QFontEngineQPA::CurrentMajorVersion; header.minorVersion = QFontEngineQPA::CurrentMinorVersion; header.dataSize = 0; dev->write((const char *)&header, sizeof(header)); writeTaggedString(QFontEngineQPA::Tag_FontName, fe->fontDef.family.toUtf8()); QFontEngine::FaceId face = fe->faceId(); writeTaggedString(QFontEngineQPA::Tag_FileName, face.filename); writeTaggedUInt32(QFontEngineQPA::Tag_FileIndex, face.index); { uchar data[4]; uint len = 4; bool ok = fe->getSfntTableData(MAKE_TAG('h', 'e', 'a', 'd'), data, &len); if (ok) { const quint32 revision = qFromBigEndian<quint32>(data); writeTaggedUInt32(QFontEngineQPA::Tag_FontRevision, revision); } } writeTaggedQFixed(QFontEngineQPA::Tag_Ascent, fe->ascent()); writeTaggedQFixed(QFontEngineQPA::Tag_Descent, fe->descent()); writeTaggedQFixed(QFontEngineQPA::Tag_Leading, fe->leading()); writeTaggedQFixed(QFontEngineQPA::Tag_XHeight, fe->xHeight()); writeTaggedQFixed(QFontEngineQPA::Tag_AverageCharWidth, fe->averageCharWidth()); writeTaggedQFixed(QFontEngineQPA::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth())); writeTaggedQFixed(QFontEngineQPA::Tag_LineThickness, fe->lineThickness()); writeTaggedQFixed(QFontEngineQPA::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing())); writeTaggedQFixed(QFontEngineQPA::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing())); writeTaggedQFixed(QFontEngineQPA::Tag_UnderlinePosition, fe->underlinePosition()); writeTaggedUInt8(QFontEngineQPA::Tag_PixelSize, fe->fontDef.pixelSize); writeTaggedUInt8(QFontEngineQPA::Tag_Weight, fe->fontDef.weight); writeTaggedUInt8(QFontEngineQPA::Tag_Style, fe->fontDef.style); writeTaggedUInt8(QFontEngineQPA::Tag_GlyphFormat, QFontEngineQPA::AlphamapGlyphs); writeTaggedString(QFontEngineQPA::Tag_EndOfHeader, QByteArray()); align4(); const quint64 size = dev->pos(); header.dataSize = qToBigEndian<quint16>(size - sizeof(header)); dev->seek(0); dev->write((const char *)&header, sizeof(header)); dev->seek(size); }
void QPF::addHeader(QFontEngine *fontEngine) { QFontEngineQPF::Header *header = reinterpret_cast<QFontEngineQPF::Header *>(addBytes(sizeof(QFontEngineQPF::Header))); header->magic[0] = 'Q'; header->magic[1] = 'P'; header->magic[2] = 'F'; header->magic[3] = '2'; if (options & RenderGlyphs) header->lock = 0xffffffff; else header->lock = 0; header->majorVersion = QFontEngineQPF::CurrentMajorVersion; header->minorVersion = QFontEngineQPF::CurrentMinorVersion; header->dataSize = 0; int oldSize = qpf.size(); addTaggedString(QFontEngineQPF::Tag_FontName, fontEngine->fontDef.family.toUtf8()); QFontEngine::FaceId face = fontEngine->faceId(); addTaggedString(QFontEngineQPF::Tag_FileName, face.filename); addTaggedUInt32(QFontEngineQPF::Tag_FileIndex, face.index); { const QByteArray head = fontEngine->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd')); const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData()) + 4); addTaggedUInt32(QFontEngineQPF::Tag_FontRevision, revision); } addTaggedQFixed(QFontEngineQPF::Tag_Ascent, fontEngine->ascent()); addTaggedQFixed(QFontEngineQPF::Tag_Descent, fontEngine->descent()); addTaggedQFixed(QFontEngineQPF::Tag_Leading, fontEngine->leading()); addTaggedQFixed(QFontEngineQPF::Tag_XHeight, fontEngine->xHeight()); addTaggedQFixed(QFontEngineQPF::Tag_AverageCharWidth, fontEngine->averageCharWidth()); addTaggedQFixed(QFontEngineQPF::Tag_MaxCharWidth, QFixed::fromReal(fontEngine->maxCharWidth())); addTaggedQFixed(QFontEngineQPF::Tag_LineThickness, fontEngine->lineThickness()); addTaggedQFixed(QFontEngineQPF::Tag_MinLeftBearing, QFixed::fromReal(fontEngine->minLeftBearing())); addTaggedQFixed(QFontEngineQPF::Tag_MinRightBearing, QFixed::fromReal(fontEngine->minRightBearing())); addTaggedQFixed(QFontEngineQPF::Tag_UnderlinePosition, fontEngine->underlinePosition()); addTaggedUInt8(QFontEngineQPF::Tag_PixelSize, fontEngine->fontDef.pixelSize); addTaggedUInt8(QFontEngineQPF::Tag_Weight, fontEngine->fontDef.weight); addTaggedUInt8(QFontEngineQPF::Tag_Style, fontEngine->fontDef.style); QByteArray writingSystemBitField = getWritingSystems(fontEngine); if (!writingSystemBitField.isEmpty()) addTaggedString(QFontEngineQPF::Tag_WritingSystems, writingSystemBitField); addTaggedUInt8(QFontEngineQPF::Tag_GlyphFormat, QFontEngineQPF::AlphamapGlyphs); addTaggedString(QFontEngineQPF::Tag_EndOfHeader, QByteArray()); align4(); header = reinterpret_cast<QFontEngineQPF::Header *>(qpf.data()); header->dataSize = qToBigEndian<quint16>(qpf.size() - oldSize); }
static void dump_png24_impl( png_struct * ppng, png_info * pinfo, const uint8_t * data, const size_t width, const size_t height, const size_t rowsize, const bool bgr, IsOk is_ok ) { assert(align4(rowsize) == rowsize); png_set_IHDR(ppng, pinfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(ppng, pinfo); // send image buffer to file, one pixel row at once const uint8_t * row = data; if (bgr) { uint8_t bgrtmp[8192*4]; for (size_t k = 0 ; k < height && is_ok(); ++k) { const uint8_t * s = row; uint8_t * t = bgrtmp; uint8_t * e = t + (width / 4) * 12; for (; t < e; s += 12, t += 12){ t[0] = s[2]; t[1] = s[1]; t[2] = s[0]; t[3] = s[5]; t[4] = s[4]; t[5] = s[3]; t[6] = s[8]; t[7] = s[7]; t[8] = s[6]; t[9] = s[11]; t[10] = s[10]; t[11] = s[9]; } png_write_row(ppng, const_cast<unsigned char*>(bgrtmp)); row += rowsize; } } else { for (size_t k = 0 ; k < height && is_ok(); ++k) { png_write_row(ppng, const_cast<unsigned char*>(row)); row += rowsize; } } }
void* mymalloc(size_t size) { t_block b, last; size = align4(size); if (base) { b = find_block(size, &last); if (b) { if (b->size - size >= BLOCK_SIZE + 4) { split_block(b, size); } b->free = 0; } else { b = extend_heap(last, size); } } else { b = extend_heap(NULL, size); if (!b) base = b; } return b ? b->data : NULL; }
static inline uint32_t aligned_size(int width, int height, uint8_t bpp) { return align4(width) * height * ((bpp<=8)?1:(bpp<=16)?2:4); }
//============================================================================== inline int datasize() const noexcept //============================================================================== { return align4(nbbytes(this->width) * this->height); }
static int jz_lcd_hw_init(vidinfo_t *vid) { struct jz_fb_info *fbi = &vid->jz_fb; unsigned int val = 0; unsigned int pclk; unsigned int stnH; #if defined(CONFIG_MIPS_JZ4740) int pll_div; #endif /* Setting Control register */ switch (jzfb.bpp) { case 1: val |= LCD_CTRL_BPP_1; break; case 2: val |= LCD_CTRL_BPP_2; break; case 4: val |= LCD_CTRL_BPP_4; break; case 8: val |= LCD_CTRL_BPP_8; break; case 15: val |= LCD_CTRL_RGB555; case 16: val |= LCD_CTRL_BPP_16; break; #if defined(CONFIG_MIPS_JZ4740) case 17 ... 32: val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */ break; #endif default: printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp); val |= LCD_CTRL_BPP_16; break; } switch (jzfb.cfg & MODE_MASK) { case MODE_STN_MONO_DUAL: case MODE_STN_COLOR_DUAL: case MODE_STN_MONO_SINGLE: case MODE_STN_COLOR_SINGLE: switch (jzfb.bpp) { case 1: /* val |= LCD_CTRL_PEDN; */ case 2: val |= LCD_CTRL_FRC_2; break; case 4: val |= LCD_CTRL_FRC_4; break; case 8: default: val |= LCD_CTRL_FRC_16; break; } break; } val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */ val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */ switch (jzfb.cfg & MODE_MASK) { case MODE_STN_MONO_DUAL: case MODE_STN_COLOR_DUAL: case MODE_STN_MONO_SINGLE: case MODE_STN_COLOR_SINGLE: switch (jzfb.cfg & STN_DAT_PINMASK) { #define align2(n) (n)=((((n)+1)>>1)<<1) #define align4(n) (n)=((((n)+3)>>2)<<2) #define align8(n) (n)=((((n)+7)>>3)<<3) case STN_DAT_PIN1: /* Do not adjust the hori-param value. */ break; case STN_DAT_PIN2: align2(jzfb.hsw); align2(jzfb.elw); align2(jzfb.blw); break; case STN_DAT_PIN4: align4(jzfb.hsw); align4(jzfb.elw); align4(jzfb.blw); break; case STN_DAT_PIN8: align8(jzfb.hsw); align8(jzfb.elw); align8(jzfb.blw); break; } break; } REG_LCD_CTRL = val; switch (jzfb.cfg & MODE_MASK) { case MODE_STN_MONO_DUAL: case MODE_STN_COLOR_DUAL: case MODE_STN_MONO_SINGLE: case MODE_STN_COLOR_SINGLE: if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) || ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL)) stnH = jzfb.h >> 1; else stnH = jzfb.h; REG_LCD_VSYNC = (0 << 16) | jzfb.vsw; REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw); /* Screen setting */ REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw); REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w); REG_LCD_DAV = (0 << 16) | (stnH); /* AC BIAs signal */ REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw); break; case MODE_TFT_GEN: case MODE_TFT_SHARP: case MODE_TFT_CASIO: case MODE_TFT_SAMSUNG: case MODE_8BIT_SERIAL_TFT: case MODE_TFT_18BIT: REG_LCD_VSYNC = (0 << 16) | jzfb.vsw; REG_LCD_HSYNC = (0 << 16) | jzfb.hsw; #if defined(CONFIG_JZLCD_INNOLUX_AT080TN42) REG_LCD_DAV = (0 << 16) | ( jzfb.h ); #else REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h); #endif /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/ REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w ); REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \ | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw); break; }
void model_draw(const shader_t *s, GLuint utrans, GLuint uquats, const GLuint *texture, const uint32_t *mdl, int anim_id, double frame, const float *teamcolor, const float *color, uint16_t tex_over) { /* assumes valid model data */ uint8_t ngeo, teamcolor_end, nbone, nanim; const uint8_t *p, *tr, *qt; const chunkinfo_t *ck; const anim_t *anim; const bone_t *b; vec3 trans, ptrans; vec4 rot, prot; int vis, i, offset, tex; vec3 rtrans[maxbones]; vec4 rotation[maxbones]; /* parse header */ p = (const uint8_t*)mdl; ngeo = p[0]; teamcolor_end = p[1]; nbone = p[2]; nanim = p[3]; anim = (const anim_t*)&p[4]; ck = (const chunkinfo_t*)&anim[nanim]; p = (const uint8_t*)&ck[ngeo]; anim += anim_id; vis = anim->vis; frame = frame * anim->frames; /* calculate transformations for frame */ i = 0; do { b = (const bone_t*)p; tr = (const uint8_t*)&b[1]; qt = tr + nanim; p = qt + nanim; p = align4(p); get_trans(&trans, p, tr, anim_id, frame); p += b->keyframes[0] * sizeof(keyframe_t); get_rot(&rot, p, qt, anim_id, frame); p += b->keyframes[1] * sizeof(keyframe4_t); if(b->parent < 0) { ptrans = vec3(0.0, 0.0, 0.0); prot = vec4(0.0, 0.0, 0.0, 1.0); } else { ptrans = rtrans[b->parent]; prot = rotation[b->parent]; } rotation[i] = mul4(rot, prot); trans = add3(ptrans, qrot3(add3(b->pivot, trans), prot)); rtrans[i] = add3(qrot3(neg3(b->pivot), rotation[i]), trans); } while (++i < nbone); /* load transformations */ glUniform4fv(uquats, nbone, (float*)rotation); glUniform3fv(utrans, nbone, (float*)rtrans); //GLuint test; //glGenBuffers(1, &test); // //glBufferData(GL_ELEMENT_ARRAY_BUFFER, ck[ngeo - 1].index, indices, GL_STATIC_DRAW); /* draw visible vertices */ i = 0; offset = 0; tex = 0xFFFF; glUniform4fv(s->k, 1, teamcolor); glUniform4fv(s->samp, 1, color); do { if(i == teamcolor_end) glUniform4fv(s->k, 1, transparency); if((vis & (1 << i))) { if (tex_over != 0xFFFF) { glBindTexture(GL_TEXTURE_2D, tex_over == 0xFFFE ? 0 : texture[tex_over]); } else if (ck[i].texture != tex) { tex = ck[i].texture; glBindTexture(GL_TEXTURE_2D, texture[tex]); } glDrawElements(GL_TRIANGLES, ck[i].index - offset, GL_UNSIGNED_SHORT, (void*)(size_t)offset); } offset = ck[i].index; } while(++i != ngeo); //glDeleteBuffers(1, &test); }
/*---------------------------------------------------------------------------*/ int elfloader_load(char* filename, char* fltfile) { struct elf32_ehdr ehdr; struct elf32_shdr shdr; struct elf32_shdr strtable; unsigned int strs; unsigned int shdrptr; unsigned int nameptr; char name[12]; int i; unsigned short shdrnum, shdrsize; int ret; /* Ensure that we have a correct and compatible ELF header. */ ret = b_seek_read( 0, (char *)&ehdr, sizeof(ehdr)); if (ret != sizeof(ehdr)) return ELFFLT_INPUT_ERROR; if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { PRINTERR(stderr, "ELF header problems\n"); return ELFFLT_BAD_ELF_HEADER; } if ( FLAG_VERBOSE ) printf ("Grab section header\n"); // Grab the section header. shdrptr = ehdr.e_shoff; ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr)); if (ret != sizeof(shdr)) return ELFFLT_INPUT_ERROR; shdrsize = ehdr.e_shentsize; shdrnum = ehdr.e_shnum; if ( FLAG_VERBOSE ) printf ("Grab string table section\n"); // Grab the string table section for the names of the sections. ret = b_seek_read( ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, (char *)&strtable, sizeof(strtable)); if (ret != sizeof(strtable)) return ELFFLT_INPUT_ERROR; strs = strtable.sh_offset; /* Parse segments headers to releavant_section entries. .text = actual code from the ELF file .data = initialized data .rodata = contains read-only data .bss = segment holds the size of the unitialized data segment .rel.text, .rel.data = relocation information for the contents of the ".text" and ".data" segments, respectively. .symtab = symbol table for this file .strtab = points to the actual string names used by the symbol table. */ // Zero size is indicator of unitialized (not found) section text.size = text.relasize = data.size = data.relasize = rodata.size = rodata.relasize = symtabsize = strtabsize = 0; bss.number = data.number = rodata.number = text.number = -1; shdrptr = ehdr.e_shoff; for(i = 0; i < shdrnum; ++i) { ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr)); DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize ); if (ret != sizeof(shdr)) { PRINTERR(stderr, "input error at %s:%d :loaded%d",__FILE__,__LINE__,ret);return ELFFLT_INPUT_ERROR;} /* The name of the section is contained in the strings table. */ nameptr = strs + shdr.sh_name; DEBUGPRINTF("==nameptr=%x(%x+%x), size=%d\n",nameptr,strs,shdr.sh_name,sizeof(name) ); ret = b_seek_read( nameptr, name, sizeof(name)); if (ret != sizeof(name)) {PRINTERR(stderr, "input error at %s:%d",__FILE__,__LINE__); return ELFFLT_INPUT_ERROR;} DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize ); if ( FLAG_DUMP_SECTIONS ) printf ("Section #%d: %-15s [section header 0x%x, offset=0x%x, size %d, vma=0x%x]\n",i,name,shdrptr, shdr.sh_offset,shdr.sh_size, shdr.sh_addr); if(strncmp(name, ".text", 5) == 0) { text.number = i; text.offset = shdr.sh_offset; text.size = shdr.sh_size; text.base_addr = shdr.sh_addr; } else if(strncmp(name, ".rel.text", 9) == 0) { text.relaoff = shdr.sh_offset; text.relasize = shdr.sh_size; } else if(strncmp(name, ".data", 5) == 0) { data.number = i; data.offset = shdr.sh_offset; data.size = shdr.sh_size; data.base_addr = shdr.sh_addr; } else if(strncmp(name, ".rodata", 7) == 0) { rodata.number = i; rodata.offset = shdr.sh_offset; rodata.size = shdr.sh_size; rodata.base_addr = shdr.sh_addr; } else if(strncmp(name, ".rel.rodata", 11) == 0) { rodata.relaoff = shdr.sh_offset; rodata.relasize = shdr.sh_size; } else if(strncmp(name, ".rel.data", 9) == 0) { data.relaoff = shdr.sh_offset; data.relasize = shdr.sh_size; } else if(strncmp(name, ".rela.", 6) == 0) { PRINTERR(stderr,"RELA relocs are not supported."); return ELFFLT_INPUT_ERROR; } else if(strncmp(name, ".symtab", 7) == 0) { symtaboff = shdr.sh_offset; symtabsize = shdr.sh_size; } else if(strncmp(name, ".strtab", 7) == 0) { strtaboff = shdr.sh_offset; strtabsize = shdr.sh_size; } else if(strncmp(name, ".bss", 4) == 0) { bss.size = shdr.sh_size; bss.number = i; bss.offset = 0; } shdrptr += shdrsize; } if(symtabsize == 0) { PRINTERR(stderr,"No symbol table found."); return ELFFLT_NO_SYMTAB; } if(strtabsize == 0) { PRINTERR(stderr,"No strings table found."); return ELFFLT_NO_STRTAB; } if(text.size == 0) { PRINTERR(stderr, "No .text segment found."); return ELFFLT_NO_TEXT; } if ( (text.relasize + rodata.relasize+ data.relasize) <=0 ) { PRINTERR(stderr,"Found no reloc sections. Please link with -r -d options.\n"); return ELFFLT_UNHANDLED_RELOC; } if (bss.size) { bss.address = (char *)malloc(bss.size); if (!bss.address) return ELFFLT_OUTPUT_ERROR; } if (data.size) { data.address = (char *)malloc(data.size); if (!data.address) return ELFFLT_OUTPUT_ERROR; } if (text.size) { text.address = (char *)malloc(text.size); if (!text.address) return ELFFLT_OUTPUT_ERROR; } if (rodata.size) { rodata.address = (char *)malloc(rodata.size); if (!rodata.address) return ELFFLT_OUTPUT_ERROR; } rodata.name=".rodata"; bss.name=".bss"; text.name=".text"; data.name=".data"; b_seek_read(text.offset, text.address, text.size); b_seek_read(data.offset, data.address, data.size); b_seek_read(rodata.offset, rodata.address, rodata.size); if ( FLAG_DUMP_SOURCE ) { dump_section( text.name, (unsigned char *)text.address, text.size ); dump_section( data.name, (unsigned char *)data.address, data.size ); dump_section( rodata.name, (unsigned char *)rodata.address, rodata.size ); } if ( FLAG_DUMP_SYMBOLS ) { dump_symtable(); } if ( FLAG_DUMP_SYMBOLS || FLAG_DUMP_SOURCE || FLAG_VERBOSE ) printf("\n\n"); if ( FLAG_VERBOSE ) printf ("Prepare flat\n"); int div0hack_size = sizeof(div0_arm); int flatmainsize = sizeof(struct flat_hdr)+text.size+div0hack_size+data.size+rodata.size+bss.size; int flatrelocsize = text.relasize+rodata.relasize+data.relasize; // Take to account aligning to int32 each section flatmainsize += align4(text.size) + align4(data.size) + align4(rodata.size) + align4(bss.size); flat_buf=malloc( flatmainsize+flatrelocsize ); if ( !flat_buf) { PRINTERR(stderr, "fail to malloc flat buf\n"); return ELFFLT_OUTPUT_ERROR;} memset(flat_buf, 0, flatmainsize+flatrelocsize); //import is subset of full reloc list, so same count is enough // but apply multiplier to take into account difference between sizeofs flat_import_buf=malloc( flatrelocsize* sizeof(import_record_t)/sizeof(reloc_record_t) ); if ( !flat_import_buf) { PRINTERR(stderr, "fail to malloc flat import buf\n"); return ELFFLT_OUTPUT_ERROR;} memset(flat_import_buf, 0, flatrelocsize); // Fill flat with sections aligned to int32 flat = (struct flat_hdr*) flat_buf; if ( FLAG_VERBOSE ) printf(">>elf2flt: load segments\n"); int offset=sizeof(struct flat_hdr); text.flat_offset = offset; memcpy( flat_buf+offset, text.address, text.size ); DEBUGPRINTF("load .txt to %x (%x->%x)\n",offset,text.size,text.size+align4(text.size)); offset+=text.size+div0hack_size+align4(text.size); rodata.flat_offset = offset; DEBUGPRINTF("load .rodata to %x (%x->%x)\n",offset,rodata.size,rodata.size+align4(rodata.size)); memcpy( flat_buf+offset, rodata.address, rodata.size ); offset+=rodata.size+align4(rodata.size); data.flat_offset = offset; DEBUGPRINTF("load .data to %x (%x->%x)\n",offset,data.size,data.size+align4(data.size)); memcpy( flat_buf+offset, data.address, data.size ); offset+=data.size+align4(data.size); bss.flat_offset = offset; DEBUGPRINTF(".bss to %x (%x->%x)\n",offset,bss.size,bss.size+align4(bss.size)); DEBUGPRINTF("result=%x\n", flatmainsize); // Initialize flat headers memcpy(flat->magic, FLAT_MAGIC_NUMBER, sizeof(flat->magic)); // Set magic (CHDK_FLAT) flat->rev = FLAT_VERSION; flat->entry = text.flat_offset; flat->data_start = rodata.flat_offset; flat->bss_start = bss.flat_offset; flat->reloc_start = flatmainsize; flat_reloc_count = 0; flat->import_start = 0; flat_import_count = 0; flat_reloc = (reloc_record_t*)(flat_buf+flatmainsize); flat_reloc_cur = flat_reloc; flat_import_cur = flat_import_buf; // _div0_arm hack add_div0_arm(); flag_unsafe_sym = 0; // Do relocations ret = relocate_section( &text); if(ret != ELFFLT_OK) return ret; ret = relocate_section( &rodata); if(ret != ELFFLT_OK) return ret; ret = relocate_section( &data); if(ret != ELFFLT_OK) return ret; if ( flag_unsafe_sym ) return ELFFLT_UNSAFE_SYMBOL; flat->import_start = flat->reloc_start+flat_reloc_count*sizeof(reloc_record_t); // Init offsets to the entry symbols if ( FLAG_VERBOSE ) printf(">>elf2flt: lookup entry symbols\n"); flat->_module_info_offset = find_symbol_inflat("_module_info", &data ); if ( flat->_module_info_offset <=0 ) { PRINTERR(stderr, "No or invalid section of _module_info. This symbol should be initialized as ModuleInfo structure.\n"); return ELFFLT_NO_MODULEINFO; } struct ModuleInfo* _module_info = (struct ModuleInfo*) (flat_buf + flat->_module_info_offset); if ( _module_info->magicnum != MODULEINFO_V1_MAGICNUM ) { PRINTERR(stderr, "Wrong _module_info->magicnum value. Please check correct filling of this structure\n"); return ELFFLT_NO_MODULEINFO; } if ( _module_info->sizeof_struct != sizeof(struct ModuleInfo) ) { PRINTERR(stderr, "Wrong _module_info->sizeof_struct value. Please check correct filling of this structure\n"); return ELFFLT_NO_MODULEINFO; } // Group import relocations // Input = array of offset/index pairs - one for each address to be relocated to a core CHDK symbol // Output = list of entries of the form: // Index, Offset1 | (N<<24), Offset2, ..., OffsetN // where each offset is a reference to the same core CHDK symbol uint32_t *new_import_buf = malloc(flat_import_count*3*sizeof(uint32_t)); uint32_t new_import_cnt = 0; int process = 1; while (process) { process = 0; for (i=0; i<flat_import_count; i++) { if (flat_import_buf[i].offs != 0) { process = 1; int cnt = 0; uint32_t idx = flat_import_buf[i].importidx; new_import_buf[new_import_cnt++] = idx; int pcnt = new_import_cnt; int j; for (j=0; j<flat_import_count; j++) { if (flat_import_buf[j].importidx == idx) { new_import_buf[new_import_cnt++] = flat_import_buf[j].offs; flat_import_buf[j].offs = 0; cnt++; } } new_import_buf[pcnt] = (cnt << 24) | new_import_buf[pcnt]; } } } flat->file_size = flat->import_start+new_import_cnt*sizeof(uint32_t); if ( FLAG_DUMP_FLT_HEADERS ) { printf("\nFLT Headers:\n"); printf("->entry 0x%x (size %d)\n", flat->entry, flat->data_start - flat->entry ); printf("->data_start 0x%x (size %d)\n", flat->data_start, flat->bss_start - flat->data_start ); printf("->bss_start 0x%x (size %d)\n", flat->bss_start, flat->reloc_start - flat->bss_start ); printf("->reloc_start 0x%x (size %d)\n", flat->reloc_start, flat_reloc_count*sizeof(reloc_record_t) ); printf("->import_start 0x%x (size %d %d)\n", flat->import_start, flat->file_size-flat->import_start, flat_import_count*sizeof(import_record_t) ); printf("\n"); printf("\nModule info:\n"); printf("->Module Name: %s\n", get_flat_string(_module_info->moduleName) ); printf("->Module Ver: %d.%d\n", _module_info->module_version.major, _module_info->module_version.minor ); char* branches_str[] = {"any branch","CHDK", "CHDK_DE", "CHDK_SDM", "PRIVATEBUILD"}; int branch = (_module_info->chdk_required_branch>REQUIRE_CHDK_PRIVATEBUILD) ? REQUIRE_CHDK_PRIVATEBUILD : _module_info->chdk_required_branch; printf("->Require: %s-build%d. ", branches_str[branch], _module_info->chdk_required_ver ); if ( _module_info->chdk_required_platfid == 0 ) printf("Any platform.\n"); else printf(" Platform #%d only.\n", _module_info->chdk_required_platfid ); printf("->Description: %s\n", get_flat_string(_module_info->description) ); print_offs("->lib = ", (int)_module_info->lib,"\n"); //print_offs("->_module_loader() = ", (int)_module_info->loader,"\n"); //print_offs("->_module_unloader() = ", (int)_module_info->unloader,"\n"); //print_offs("->_module_can_unload()= ", (int)_module_info->can_unload,"\n"); //print_offs("->_module_exit_alt() = ", (int)_module_info->exit_alt,"\n"); } if ( FLAG_DUMP_FLAT ) { dump_section( "FLT_header", (unsigned char*)flat_buf, sizeof(struct flat_hdr) ); dump_section( "FLT_text", (unsigned char*)flat_buf+flat->entry, flat->data_start-flat->entry ); dump_section( "FLT_data", (unsigned char*)flat_buf+flat->data_start, flat->bss_start-flat->data_start); dump_section( "FLT_bss", (unsigned char*)flat_buf+flat->bss_start, flat->reloc_start-flat->bss_start ); printf("\nDump relocations 0x%x (size=%d):\n",flat->reloc_start,flat_reloc_count*sizeof(reloc_record_t)); for( i = 0; i< flat_reloc_count; i++) { print_offs("Offs: ",*(int*)(flat_buf+flat->reloc_start+i*sizeof(reloc_record_t)), "\n"); } printf("\nDump imports 0x%x (size=%d):\n",flat->import_start,new_import_cnt*sizeof(uint32_t)); for (i = 0; i< new_import_cnt;) { uint32_t idx = new_import_buf[i++]; int cnt = new_import_buf[i] >> 24; int j; for (j=0; j<cnt; j++) { uint32_t offs = new_import_buf[i++] & 0x00FFFFFF; print_offs((j==0)?"Offs: ":" ",offs,""); int addend = *(uint32_t*)(flat_buf+offs); printf(" = sym_%08x[%s]+0x%x\n",idx,get_import_symbol(idx),addend); } } } int filesize = flat->file_size; printf("\n\nOutput file %s (size=%d bytes)\n",fltfile,filesize); int output_fd = open(fltfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0777); i = write(output_fd, flat_buf, flat->import_start); i = write(output_fd, new_import_buf, new_import_cnt*sizeof(uint32_t)); close(output_fd); return ELFFLT_OK; }
static inline uint32_t row_size(int width, uint8_t bpp) { return align4(width * nbbytes(bpp)); }
data->page_pos_x = 0; data->page_pos_y = 0; data->page_line_height = 0; } return page; } static unsigned char *alloc_glyph_region(ALLEGRO_TTF_FONT_DATA *data, int ft_index, int w, int h, bool new, ALLEGRO_TTF_GLYPH_DATA *glyph, bool lock_more) { ALLEGRO_BITMAP *page; bool relock; int w4 = align4(w); int h4 = align4(h); int glyph_size = w4 > h4 ? w4 : h4; if (_al_vector_is_empty(&data->page_bitmaps) || new) { page = push_new_page(data, glyph_size); relock = true; if (!page) return NULL; } else { ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps); page = *back; relock = !data->page_lr; }
// 4 byte padded strings ! int getString( char * data, char **output ) { size_t l = strlen(data)+1; *output = data; return align4(l); }