void CMemoryBuffer::CopyTo(const CMemoryBuffer & buffer, size_t size, size_t off) const
{
	if(buffer.GetBufferSize() < size)
		NOVA_EXP("CMemoryBuffer::CopyTo: unput buffer too small...", MEM_ERROR);

	if((off + size) > mbSize)
		NOVA_EXP("CMemoryBuffer::CopyTo: offset param too large", MEM_ERROR);

	nova::nByte *p = (nova::nByte *)mBegin + off;
	memcpy(buffer.GetBegin(), p, size);
}
CMemoryBuffer CHardwarePixelBuffer::LockSource(size_t offset, size_t length, THardwareBufferLock opt)
{
	if(mSize == 0)
		throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \
		mSize == 0, null pixel box..", BAD_OPERATION);
	CMemoryBuffer data;
	GLuint face_target = 0;

	data.AllocBuffer(mSize);
	COpenGLFormats informat;
	informat.SetExFormat(mPixelFormat);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	GLenum type = TextureTarget(mTarget);

	if(mTarget == USE_CUBEMAP_TEXTURE)
		face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace;
	else
		face_target = type;

	glBindTexture(type, mTargetId);

	glGetTexImage(face_target, mLevel, informat.GetFormat(),
		GL_UNSIGNED_BYTE, data.GetBegin());

	glPixelStorei(GL_PACK_ALIGNMENT, 4);

	int error = glGetError();
	if(error != GL_NO_ERROR)
	{
		nstringstream str;
		str << "CHardwarePixelBuffer::LockSource - \
		detecting OpenGL error with code " << error;
		throw NOVA_EXP(str.str().c_str(), BAD_OPERATION);
	}

	CMemoryBuffer result;
	result.AllocBuffer(mLockActSize);
	size_t line = mLockWidth * informat.GetInternalChannels();

	nova::byte * source = (nova::byte *)data.GetBegin() + offset;
	nova::byte * dest = (nova::byte *)result.GetBegin();
	for(nova::uint i = 0; i < mLockDepth; ++i)
	{
		for(nova::uint j = 0; j < mLockHeight; ++j)
		{
			memcpy(dest, source, line);
			source += mRowPitch * informat.GetInternalChannels();
			dest += line;
		}
		source += mSlicePitch * informat.GetInternalChannels();
	}

	data.FreeBuffer();

	return result;
}
void CFilesPackage::PutFile(const CMemoryBuffer &buf , const nstring & name, const nstring & ext, const nstring &grs)
{
	TFileHeader fheader;
	memset(&fheader, 0, sizeof(TFileHeader));

	strcpy(fheader.file_name, name.c_str());
	strcpy(fheader.ext, ext.c_str());
	strcpy(fheader.resource_group, grs.c_str());

	if(!mIsOpened)
		throw NOVA_EXP("CFilesPackage::PutFile: package not opened, open package file first!", BAD_OPERATION);
	if(!mWritePackage)
		throw NOVA_EXP("CFilesPackage::PutFile: package opened for reading!", BAD_OPERATION);	

	if(InFileList(name))
		throw NOVA_EXP("CFilesPackage::PutFile: package already contains this name!", BAD_OPERATION);	

	fheader.pos = mFile->Tell() + sizeof(TFileHeader);
	fheader.number = mPackageMap.size() + 1;
	fheader.size = buf.GetBufferSize();

	mFile->Write(&fheader, sizeof(TFileHeader));
	mFile->Write(buf);

	std::pair<nstring, TFileHeader> pf;
	pf.first = name;
	pf.second = fheader;
	mPackageMap.insert(pf);

	mFile->Flush();
}
CMemoryBuffer CFilesPackage::GetFile(const nstring & name) const 
{
	stl<nstring, FileHeader>::map::const_iterator it;
	TFileHeader header;
	
	if(!mIsOpened)
		throw NOVA_EXP("CFilesPackage::GetFile: package not opened, open package file first!", BAD_OPERATION);
	if(mWritePackage)
		throw NOVA_EXP("CFilesPackage::GetFile: package opened for writing!", BAD_OPERATION);

	if((it = mPackageMap.find(name)) != mPackageMap.end())
		header = (*it).second;
	else
		return CMemoryBuffer();

	CMemoryBuffer result;
	mFile->Seek(header.pos);

	result.AllocBuffer(header.size);
	mFile->Read(result);

	return result;
}
Exemple #5
0
void COFF_PutNameInSectionHeader(SCOFF_SectionHeader & sec, const char * name, CMemoryBuffer & StringTable) {
   // Function to put a name into SCOFF_SectionHeader. 
   // Put name in string table if longer than 8 characters
   int len = (int)strlen(name);                  // Length of name
   if (len <= 8) {
      // Short name. store in section header
      memcpy(sec.Name, name, len);
      // Pad with zeroes
      for (; len < 8; len++) sec.Name[len] = 0;
   }
   else {
      // Long name. store in string table
      sprintf(sec.Name, "/%i", StringTable.PushString(name));
   }
}
Exemple #6
0
uint32 COFF_PutNameInSymbolTable(SCOFF_SymTableEntry & sym, const char * name, CMemoryBuffer & StringTable) {
   // Function to put a name into SCOFF_SymTableEntry. 
   // Put name in string table if longer than 8 characters.
   // Returns index into StringTable if StringTable used
   int len = (int)strlen(name);                  // Length of name
   if (len <= 8) {
      // Short name. store in section header
      memcpy(sym.s.Name, name, len);
      // Pad with zeroes
      for (; len < 8; len++) sym.s.Name[len] = 0;
   }
   else {
      // Long name. store in string table
      sym.stringindex.zeroes = 0;
      sym.stringindex.offset = StringTable.PushString(name);     // Second integer = entry into string table
      return sym.stringindex.offset;
   }
   return 0;
}
void CTextureSurfaceList::BuildSurfaceList(const CMemoryBuffer & data, size_t width, size_t height, size_t depth)
{
	if(!width || !height || !depth)
		throw NOVA_EXP("CTextureSurfaceList::BuildSurfaseList - incorrect input size param.", BAD_OPERATION);

	GLenum type = CHardwarePixelBuffer::TextureTarget(mType);
	bool mipmap_hardware_gen = CRenderSystem::GetSingelton().CheckCapabilities(TEXTURE_CATEGORY, CAP_AUTOMIPMAP);
	COpenGLFormats informat;
	informat.SetExFormat(mPixelFormat);
	mMaxMipmaps = GetMaxMipmaps(width, height, depth);

	glEnable(type);

	if(mType == CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE && mFace > 0) {}
	else
		glGenTextures(1, &mTargetId);

	glBindTexture(type, mTargetId);

	if(mMipState == USE_HARDWARE_MIPMAPS)
	{
		if(!mipmap_hardware_gen)
			mMipState = USE_SOFTWARE_MIPMAPS;
	}

	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	if(mMipState == DO_NOT_USE_MIPMAPS)
	{
		glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		mMaxMipmaps = 1;

		switch(mType)
		{
		case CHardwarePixelBuffer::USE_TEXTURE_1D:
			glTexImage1D(GL_TEXTURE_1D, 0, informat.GetInternalChannels(),
				width, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_2D:
			glTexImage2D(GL_TEXTURE_2D, 0, informat.GetInternalChannels(),
				width, height, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_3D:
			glTexImage3D(GL_TEXTURE_3D, 0, informat.GetInternalChannels(),
				width, height, depth, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE:
			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace, 0, informat.GetInternalChannels(),
				width, height, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		}
	}
	else if(mMipState == USE_SOFTWARE_MIPMAPS)
	{
		glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		switch(mType)
		{
		case CHardwarePixelBuffer::USE_TEXTURE_1D:
			gluBuild1DMipmaps(GL_TEXTURE_1D, informat.GetInternalChannels(),
				width, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_2D:
			gluBuild2DMipmaps(GL_TEXTURE_2D, informat.GetInternalChannels(),
				width, height, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE:
			gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace, informat.GetInternalChannels(),
				width, height, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_3D:
			throw NOVA_EXP("CTextureSurfaceList::BuildSurfaseList - \
				OpenGL can not support software 3D mipmaps", BAD_OPERATION);
			break;
		}
	}
void CHardwarePixelBuffer::UnlockSource(CMemoryBuffer & buf)
{
	if(mSize == 0)
		throw NOVA_EXP("CHardwarePixelBuffer::UnlockSource - \
		mSize == 0, null pixel box..", BAD_OPERATION);
	GLuint face_target = 0;
	void *ptr = buf.GetBegin();

	if(!ptr)
		throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \
			ptr == NULL, bad ptr..", BAD_OPERATION);

	COpenGLFormats informat;
	informat.SetExFormat(mPixelFormat);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	GLenum type = TextureTarget(mTarget);

	if(mTarget == USE_CUBEMAP_TEXTURE)
		face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace;
	else
		face_target = type;

	glBindTexture(type, mTargetId);

	size_t xoff, yoff, zoff;
	SizeToWHD(&xoff, &yoff, &zoff, mLockStart);

	nova::uint _width;
	nova::uint _height;
	nova::uint _depth;
	SizeToWHD(&_width, &_height, &_depth, mLockStart + mLockSize);

	_width -= (xoff-1);
	_height -= (yoff-1);
	_depth -= (zoff-1);

	switch(mTarget)
	{
	case USE_TEXTURE_1D:
		{
			glTexSubImage1D(GL_TEXTURE_1D, mLevel, xoff, _width, informat.GetFormat(),
				GL_UNSIGNED_BYTE, ptr);
		}
		break;
	case USE_TEXTURE_2D:
	case USE_CUBEMAP_TEXTURE:
		{
			glTexSubImage2D(face_target, mLevel, xoff, yoff, _width,
				_height, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr);
		}
		break;
	case USE_TEXTURE_3D:
		{
			glTexSubImage3D(GL_TEXTURE_3D, mLevel, xoff, yoff, zoff, _width,
				_height, _depth, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr);
		}
		break;
	}

	mLockWidth = 0;
	mLockHeight = 0;
	mLockDepth = 0;
	mLockActSize = 0;

	glPixelStorei(GL_PACK_ALIGNMENT, 4);

	buf.FreeBuffer();
}
Exemple #9
0
// MakeSegmentList
void COMF2ASM::MakeSegmentList() {
   // Make Sections list in Disasm
   int32  SegNum;                                // Segment number
   int32  Segment;                               // Segment number in OMF record
   uint32 RecNum;                                // OMF record number
   uint32 LastDataRecord;                        // OMF record number of last LEDATA record
   uint32 RecOffset;                             // Segment offset of LEDATA, LIDATA record
   uint32 RecSize;                               // Data size of LEDATA, LIDATA record
   uint32 LastDataRecordSize;                    // Last RecSize
   uint32 LastOffset;                            // Last RecOffset
   int8 * LastDataRecordPointer;                 // Point to last raw data
   uint32 BufOffset;                             // Offset of segment into SegmentData buffer
   CMemoryBuffer TempBuf;                        // Temporary buffer for building raw data

   // Loop through segments
   for (SegNum = 1; SegNum <= NumSegments; SegNum++) {

      // Get size
      uint32 SegmentSize = Segments[SegNum].Size;
      if (SegmentSize == 0) continue;            // Empty segment

      // Allocate temporary data buffer and reset it
      TempBuf.SetSize(SegmentSize + 16);
      int FillByte = 0;                          // Byte to fill memory with
      if (Segments[SegNum].Type == 1) {
         // Code segment. Fill any unused bytes with NOP opcode = 0x90
         FillByte = 0x90;
      }
      memset(TempBuf.Buf(), FillByte, SegmentSize + 16);// Reset to all 0 or NOP

      LastDataRecord = 0;
      LastDataRecordSize = 0;
      LastDataRecordPointer = 0;
      LastOffset = 0;
      int comdatsSoFar = 0;

      // Search for LEDATA, LIDATA and FIXUPP records for this segment
      for (RecNum = 0; RecNum < NumRecords; RecNum++) {

         if (Records[RecNum].Type2 == OMF_LEDATA) {

            // LEDATA record
            Records[RecNum].Index = 3;           // Initialize record reading
            Segment = Records[RecNum].GetIndex();// Read segment number

            if ((Segment & 0xC000) == 0x4000) {
               // Refers to Borland communal section
               Segment = (Segment & ~0x4000) + FirstComDatSection - 1;
            }

            if (Segment != SegNum) continue; // Does not refer to this segment

            RecOffset = Records[RecNum].GetNumeric();// Read offset of this record
            RecSize = Records[RecNum].End - Records[RecNum].Index; // Calculate size of data
            LastDataRecord = RecNum;             // Save for later FIXUPP that refers to this record

            if (RecOffset < LastOffset + LastDataRecordSize && LastOffset < RecOffset + RecSize) {
               // Overlapping data records
               if (RecOffset + 8 < LastOffset + LastDataRecordSize || Segments[SegNum].Type != 1) {
                  // Overlapping data by more than 7 bytes or not executable code
                  err.submit(1207);
               }
               else {
                  // Possibly backpatched code
                  err.submit(1208);              // Warning
                  err.ClearError(1208);          // Report only once
               }
            }

            LastDataRecordSize = RecSize;
            LastDataRecordPointer = Records[RecNum].buffer + Records[RecNum].FileOffset + Records[RecNum].Index;
            LastOffset = RecOffset;                 // Save offset for subsequent FIXUPP records

            // Check if data within segment
            if (RecOffset + RecSize > SegmentSize) {
               err.submit(2309, GetSegmentName(Segment));
               continue;
            }

            // Put raw data into temporary buffer
            memcpy(TempBuf.Buf() + RecOffset, LastDataRecordPointer, RecSize);

         } // Finished with LEDATA record

         if (Records[RecNum].Type2 == OMF_LIDATA) {
            // LIDATA record
            Records[RecNum].Index = 3;           // Initialize record reading
            Segment = Records[RecNum].GetIndex();

            if (Segment != SegNum) continue; // Does not refer to this segment

            LastDataRecord = RecNum;             // Save for later FIXUPP that refers to this record

            RecOffset = Records[RecNum].GetNumeric();// Read offset

            if (RecOffset > SegmentSize) {
               err.submit(2310); continue;       // Error: outside bounds
            }

            // Unpack LIDATA blocks recursively
            RecSize = Records[RecNum].UnpackLIDATABlock(TempBuf.Buf() + RecOffset, SegmentSize - RecOffset);

            if (RecOffset < LastOffset + LastDataRecordSize && LastOffset < RecOffset + RecSize) {
               // Overlapping data records
               err.submit(1207);                 // Warning
            }
            LastDataRecordSize = RecSize;           // Save data size
            LastOffset = RecOffset;                 // Save offset for subsequent FIXUPP records

         } // Finished with LIDATA record

         if (Records[RecNum].Type2 == OMF_COMDAT) {
            // COMDAT record.

            Records[RecNum].Index = 3;           // Initialize record reading
            uint16 flags = Records[RecNum].GetByte();
            if ((flags&1)==0) { // not a continuation
               ++comdatsSoFar;
               LastDataRecord = RecNum;             // Save for later FIXUPP that refers to this record
            }
            Segment = FirstComDatSection + comdatsSoFar-1;
            if (SegNum != Segment) continue;

            uint16 attribs = Records[RecNum].GetByte();
            Records[RecNum].GetByte(); // align (ignore)
            RecOffset = Records[RecNum].GetNumeric();
            Records[RecNum].GetIndex(); // type (ignore)
            if ((attribs&0xF)==0) {
               Records[RecNum].GetIndex(); // public base
               uint16 publicSegment = Records[RecNum].GetIndex();
               if (publicSegment==0) Records[RecNum].GetIndex(); // public frame (ignore)
            }
            Records[RecNum].GetIndex(); // public name (ignore)
            RecSize = Records[RecNum].End - Records[RecNum].Index; // Calculate size of data

            LastDataRecord = RecNum;             // Save for later FIXUPP that refers to this record
            LastDataRecordSize = RecSize;
            LastDataRecordPointer = Records[RecNum].buffer + Records[RecNum].Index+Records[RecNum].FileOffset;
            LastOffset = RecOffset;
            // Put raw data into temporary buffer
            memcpy(TempBuf.Buf() + RecOffset, LastDataRecordPointer, RecSize);
         } // Finished with COMDAT record

         if (Records[RecNum].Type2 == OMF_FIXUPP) {
            // FIXUPP record
            if (Segment != SegNum) continue; // Does not refer to this segment
            Records[RecNum].Index = 3;

            if (Records[LastDataRecord].Type2 == OMF_LEDATA) {
               // FIXUPP for last LEDATA record
               // Make relocation records
               MakeRelocations(Segment, RecNum, LastOffset, LastDataRecordSize, (uint8*)TempBuf.Buf());
            } 
            else if (Records[RecNum].Index < Records[RecNum].End) {
               // Non-empty FIXUPP record does not refer to LEDATA record
               if (Records[LastDataRecord].Type2 == OMF_COMDAT) {
                  // FIXUPP for last COMDAT record
                  // Make relocation records
                  MakeRelocations(Segment, RecNum, LastOffset, LastDataRecordSize, (uint8*)TempBuf.Buf());
               }
               else if (Records[LastDataRecord].Type2 == OMF_LIDATA) {
                  err.submit(2311);              // Error: Relocation of iterated data not supported
               }
               else {
                  err.submit(2312);              // Does not refer to data record
               }
            }
         }
      } // End of loop to search for LEDATA, LIDATA and FIXUPP records for this segment

      // Transfer raw data from TempBuf to SegmentData buffer
      BufOffset = SegmentData.Push(TempBuf.Buf(), SegmentSize);

      // Remember offset into SegmentData
      Segments[SegNum].BufOffset = BufOffset;

   } // End of first loop through segments

   // We must put all segments into SegmentData buffer before we assign pointers to
   // the raw data because otherwise the SegmentData buffer might me reallocated
   // when it grows and the pointers become invalid. This is the reasons why we
   // have two loops through the segments here.

   // Second loop through segments
   int totalcodesize=0;
   for (SegNum = 1; SegNum <= NumSegments; SegNum++) {

      // Pointer to merged raw data
      uint8 * RawDatap = (uint8*)SegmentData.Buf() + Segments[SegNum].BufOffset;

      // Size of raw data
      uint32 InitSize = (Segments[SegNum].Type == 3) ? 0 : Segments[SegNum].Size;

      // Define segment
      const char * SegmentName = NameBuffer.Buf() + Segments[SegNum].NameO;
      Disasm.AddSection(RawDatap, InitSize, Segments[SegNum].Size, Segments[SegNum].Offset,
         Segments[SegNum].Type, Segments[SegNum].Align, Segments[SegNum].WordSize, SegmentName);
      if (Segments[SegNum].Type == 1 || Segments[SegNum].Type == 0x1001) {
         totalcodesize += Segments[SegNum].Size;
      }
   }
}
Exemple #10
0
void CELF2ELF<ELFSTRUCTURES>::MakeSymbolTable() {
   uint32 SectionNumber;      // Section number
   char * SectionName;        // Section name
   uint32 SecNamei;           // Section name index
   uint32 OldSymi;            // Old symbol index
   uint32 NewSymi;            // New symbol index
   int isymt;                 // 0 = symtab, 1 = dynsym
   const char * name1;        // Old name of symbol
   const char * name2;        // Changed name of symbol
   int SymbolType;            // Symbol type for cmd.SymbolChange
   int action;                // Symbol change action
   int binding;               // Symbol binding
   TELF_Symbol sym;               // Symbol table entry
   TELF_Symbol AliasEntry;        // Symbol table alias entry
   uint32 symnamei;           // New symbol name index
   CMemoryBuffer TempGlobalSymbolTable; // Temporary storage of public and external symbols

   // Find symbol table and string tables
   for (SectionNumber = 0; SectionNumber < this->NSections; SectionNumber++) {
      // Get copy of 32-bit header or converted 64-bit header
      TELF_SectionHeader sheader = this->SectionHeaders[SectionNumber];
      switch (sheader.sh_type) {
      case SHT_SYMTAB:
         isymtab[0] = SectionNumber;                // Symbol table found
         istrtab[0] = this->SectionHeaders[SectionNumber].sh_link; // Associated string table
         break;

      case SHT_DYNSYM:
         isymtab[1] = SectionNumber;             // Dynamic symbol table found
         istrtab[1] = this->SectionHeaders[SectionNumber].sh_link; // Associated string table
         break;

      case SHT_STRTAB:
         SecNamei = sheader.sh_name;
         if (SecNamei >= this->SecStringTableLen) 
            err.submit(2112);
         SectionName = this->SecStringTable + SecNamei;
         if (SectionNumber == this->FileHeader.e_shstrndx || !strcmp(SectionName,".shstrtab")) {
            istrtab[2] = SectionNumber;           // Section header string table found
         }
         else if (!strcmp(SectionName,".strtab") && !istrtab[0]) {
            istrtab[0] = SectionNumber;     // Symbol string table found
         }
         else if (!strcmp(SectionName,".stabstr")) {
            istrtab[3] = SectionNumber;    // Debug string table found
         }
         break;
      }
   }

   // Make new symbol tables and string tables
   // Loop through possibly two symbol tables
   for (isymt = 0; isymt < 2; isymt++) {

      if (isymtab[isymt] && isymtab[isymt] < this->NSections 
      &&  istrtab[isymt] && istrtab[isymt] < this->NSections) {
         
         // Symbol table header
         uint32 SymTabHeaderOffset = uint32(this->FileHeader.e_shoff + isymtab[isymt] * this->SectionHeaderSize);
         //TELF_SectionHeader SymTabHeader = this->Get<TELF_SectionHeader>(SymTabHeaderOffset);
         // Some compilers fail with the double template here. Avoid the template:
         TELF_SectionHeader SymTabHeader = *(TELF_SectionHeader*)(this->Buf() + SymTabHeaderOffset);

         // Find symbol table
         uint32 symtabsize = (uint32)(SymTabHeader.sh_size);
         int8 * symtab = this->Buf() + SymTabHeader.sh_offset;
         int8 * symtabend = symtab + symtabsize;
         int entrysize = (int)(SymTabHeader.sh_entsize);
         if (entrysize <= 0) entrysize = sizeof(TELF_Symbol);

         // Find string table
         char * StringTable = this->Buf() + this->SectionHeaders[istrtab[isymt]].sh_offset;
         uint32 StringTableLen = uint32(this->SectionHeaders[istrtab[isymt]].sh_size);

         NewStringTable[isymt].Push(0, 1); // Initialize new string table, first entry 0

         if (isymt == 0) {
            // Allocate NewSymbolIndex
            NumOldSymbols = (symtabsize + entrysize - 1) / entrysize; // round up to nearest integer to be safe
            NewSymbolIndex.SetNum(NumOldSymbols);   // Allocate array
            NewSymbolIndex.SetZero();               // Initialize
         }

         // Loop through old symbol table
         for (OldSymi = 0; symtab < symtabend; symtab += entrysize, OldSymi++) {

            // Symbol table entry
            sym = *(TELF_Symbol*)symtab;

            // Symbol name
            if (sym.st_name < StringTableLen) {
               name1 = StringTable + sym.st_name;}
            else {
               err.submit(2035);  name1 = 0;
            }
            name2 = 0;

            // Symbol type
            int type = sym.st_type;
            binding = sym.st_bind;
            if (binding == STB_LOCAL) {
               SymbolType = SYMT_LOCAL;    // Symbol is local
            }
            else if (type == STT_OBJECT || type == STT_FUNC || type == STT_NOTYPE) {
               if (int16(sym.st_shndx) > 0) { // Check section number
                  SymbolType = SYMT_PUBLIC;  // Symbol is public
               }
               else {
                  SymbolType = SYMT_EXTERNAL; // Symbol is external
               }
            }
            else {
               SymbolType = SYMT_OTHER; // Symbol is section or filename or debug
            }

            // Check if any change required for this symbol
            action = cmd.SymbolChange(name1, &name2, SymbolType);

            switch (action) {
            case SYMA_NOCHANGE:
               // No change
               break;

            case SYMA_MAKE_WEAK:
               // Make symbol weak
               if (cmd.OutputType == FILETYPE_COFF) {
                  // PE/COFF format does not support weak publics. Use this only when converting to ELF
                  err.submit(2200);
               }
               // Make weak
               binding = STB_WEAK;
               sym.st_bind = binding;
               sym.st_type = type ;
               break;

            case SYMA_MAKE_LOCAL:
               // Make public symbol local, make external symbol ignored
               binding = STB_LOCAL;  SymbolType = SYMT_LOCAL;
               sym.st_bind = binding;
               sym.st_type = type ;
               break;

            case SYMA_CHANGE_NAME:
               // Change name of symbol
               name1 = name2;  name2 = 0;
               break;

            case SYMA_CHANGE_ALIAS: 
               // Make alias and keep old name
               if (isymt != 0) err.submit(1033, name1); // alias in dynsym not supported yet
               AliasEntry = sym;
               break;

            default:
               err.submit(9000); // unknown error
            }

            // Add entry to new string table
            if (name1 && *name1) {
               symnamei = NewStringTable[isymt].PushString(name1);
            }
            else {
               symnamei = 0;
            }
            sym.st_name = symnamei;

            if (isymt == 0) {
               // The symtab symbol table must be ordered with local symbols first.
               // Therefore the public and external symbols are temporarily stored
               // in TempGlobalSymbolTable and the high bit of NewSymi is set.
               // The two tables are joined together when the number of local symbols
               // is known and the indexes into TempGlobalSymbolTable are adjusted
               // to indexes into the joined table.
               if (SymbolType == SYMT_LOCAL) {
                  NewSymbolTable[isymt].Push(&sym, entrysize);
                  NewSymi = NewSymbolTable[isymt].GetLastIndex();
               }
               else {
                  TempGlobalSymbolTable.Push(&sym, entrysize);
                  NewSymi = TempGlobalSymbolTable.GetLastIndex() | 0x80000000;
               }
               // Insert into symbol index translation table
               NewSymbolIndex[OldSymi] = NewSymi;

               if (action == SYMA_CHANGE_ALIAS && name2 && *name2) {
                  // Make one more entry for new alias
                  symnamei = NewStringTable[isymt].PushString(name2);
                  AliasEntry.st_name = symnamei;
                  TempGlobalSymbolTable.Push(&AliasEntry, entrysize);
               }
            }
            else {
               // dynsym table has no local symbols
               // no index translation table is currently needed
               NewSymbolTable[isymt].Push(&sym, entrysize);
            }

         } // End of loop through old symbol table

         if (isymt == 0) {
            // The symbol table has been temporarily split into local and non-local
            // Save index to first nonlocal symbol
            FirstGlobalSymbol = NewSymbolTable[isymt].GetNumEntries();

            // Adjust symbol index translation table
            for (OldSymi = 0; OldSymi < NumOldSymbols; OldSymi++) {
               if (NewSymbolIndex[OldSymi] & 0x80000000) {
                  // Translate index into TempGlobalSymbolTable to index into joined table
                  NewSymbolIndex[OldSymi] = (NewSymbolIndex[OldSymi] & ~0x80000000) + FirstGlobalSymbol;
               }
            }

            // Join the two tables
            NewSymbolTable[isymt].Push(TempGlobalSymbolTable.Buf(), TempGlobalSymbolTable.GetDataSize());
         }
      }
   } // End of isymt loop through possibly two symbol tables
}
Exemple #11
0
void CELF2ELF<ELFSTRUCTURES>::MakeBinaryFile() {

   uint32 SectionNumber;               // Section number
   CMemoryBuffer NewSectionHeaders;    // Temporary storage of section headers

   // Copy file header
   ToFile.Push(this->Buf(), sizeof(TELF_Header));

   // Copy program header if any
   if (this->FileHeader.e_phnum) {
      ToFile.Push(this->Buf() + this->FileHeader.e_phoff, this->FileHeader.e_phentsize * this->FileHeader.e_phnum);
      ((TELF_Header*)ToFile.Buf())->e_phoff = sizeof(TELF_Header);
   }

   // Copy section data
   uint32 SectionHeaderOffset = uint32(this->FileHeader.e_shoff);
   TELF_SectionHeader sheader;                     // Section header

   // Loop through sections
   for (SectionNumber = 0; SectionNumber < this->NSections; SectionNumber++, SectionHeaderOffset += this->FileHeader.e_shentsize) {

      // Get section header
      //sheader = this->Get<TELF_SectionHeader>(SectionHeaderOffset);
      // Some compilers fail with the double template here. Avoid the template:
      sheader = *(TELF_SectionHeader*)(this->Buf() + SectionHeaderOffset);

      // Check for null section
      if (SectionNumber == 0 && sheader.sh_type != 0) {
         // First section must be null
         err.submit(2036, 0);
      }

      // Align
      ToFile.Align(16);

      // Check for sections that have been modified
      if (SectionNumber == isymtab[0]) {
         // Static symbol table .symtab
         sheader.sh_offset = ToFile.Push(NewSymbolTable[0].Buf(), NewSymbolTable[0].GetDataSize());
         sheader.sh_size = NewSymbolTable[0].GetDataSize();
         sheader.sh_info = FirstGlobalSymbol;
      }
      else if (SectionNumber == isymtab[1]) {
         // Dynamic symbol table .dynsym
         sheader.sh_offset = ToFile.Push(NewSymbolTable[1].Buf(), NewSymbolTable[1].GetDataSize());
         sheader.sh_size = NewSymbolTable[1].GetDataSize();
      }
      else if (SectionNumber == istrtab[0]) {
         // Symbol string table .strtab
         sheader.sh_offset = ToFile.Push(NewStringTable[0].Buf(), NewStringTable[0].GetDataSize());
         sheader.sh_size = NewStringTable[0].GetDataSize();
      }
      else if (SectionNumber == istrtab[1] && SectionNumber != istrtab[0]) {
         // Dynamic symbol string table if different from .strtab
         sheader.sh_offset = ToFile.Push(NewStringTable[1].Buf(), NewStringTable[1].GetDataSize());
         sheader.sh_size = NewStringTable[1].GetDataSize();
      }
      else if (SectionNumber == istrtab[2]) {
         // Section name string table .shstrtab
         sheader.sh_offset = ToFile.Push(NewStringTable[2].Buf(), NewStringTable[2].GetDataSize());
         sheader.sh_size = NewStringTable[2].GetDataSize();
      }
      else {
         // Any other section (including istrtab[3] = .stabstr)
         sheader.sh_offset = ToFile.Push(this->Buf() + (uint32)sheader.sh_offset, (uint32)sheader.sh_size);
      }

      // Store section header
      NewSectionHeaders.Push(&sheader, sizeof(sheader));

   } // End of section loop

   // Align
   ToFile.Align(16);

   // Store section headers
   uint32 SectionHeadersOffset = ToFile.Push(NewSectionHeaders.Buf(), NewSectionHeaders.GetDataSize());

   // Update file header
   ((TELF_Header*)ToFile.Buf())->e_shoff = SectionHeadersOffset;
   ((TELF_Header*)ToFile.Buf())->e_shentsize = sizeof(TELF_SectionHeader);
   ((TELF_Header*)ToFile.Buf())->e_shnum = NewSectionHeaders.GetNumEntries();
   ((TELF_Header*)ToFile.Buf())->e_shstrndx = istrtab[2];
}
Exemple #12
0
void CFreeFont::MakeLetter(wchar_t code)
{
	// Первая вещь, которую нам надо сделать, это вывести наш символ
	// в растр. Это делается набором команд FreeType

	// Загрузить глифы для каждого символа.
	if(FT_Load_Glyph(face, FT_Get_Char_Index(face, code), FT_LOAD_DEFAULT))
		throw NOVA_EXP("CFreeFont::MakeLetter - FT_Load_Glyph failed", BAD_OPERATION);

	// Поместить глиф в объект.
	FT_Glyph glyph;
	if(FT_Get_Glyph(face->glyph, &glyph))
		throw NOVA_EXP("CFreeFont::MakeLetter - FT_Get_Glyph failed", BAD_OPERATION);

	// Конвертировать глиф в растр.
	FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
	FT_BitmapGlyph bitmap_glyph = reinterpret_cast<FT_BitmapGlyph>(glyph);

	// С помощью этой ссылки, получаем легкий доступ до растра.
	FT_Bitmap & bitmap = bitmap_glyph->bitmap;

    // Используем нашу вспомогательную функцию для вычисления ширины и высоты
	// текстуры для нашего растра.
	nInt32 bwidth = NextP2(bitmap.width);
	nInt32 bheight = NextP2(bitmap.rows);

	// Выделим память для данных текстуры.
	//nByte * expanded_data = NULL;
	//expanded_data = getmem<nByte>(expanded_data, 2 * bwidth * bheight);
	CMemoryBuffer mem;
	mem.AllocBuffer(2 * bwidth * bheight);
	nByte * expanded_data = (nova::nByte *)mem.GetBegin();

	// Поместим данные в расширенный растр.
	// Отмечу, что использован двухканальный растр (Один для
	// канала яркости и один для альфа), но мы будем назначать
	// обоим каналам одно и тоже значение, которое мы
	// получим из растра FreeType.
	// Мы используем оператор ?: для того чтобы поместить 0 в зону вне растра FreeType.
	for(nInt32 j = 0; j < bheight; ++j)
		for(nInt32 i = 0; i < bwidth; ++i)
			expanded_data[2*(i + j * bwidth)] = expanded_data[2*(i + j * bwidth)+1] =
				(i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];

/*	GLuint texture;
	glGenTextures(1, &texture);

	glBindTexture( GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	// Здесь мы создаем текстуру
	// Помните, что используем GL_LUMINANCE_ALPHA, чтобы было два альфа канала данных
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bwidth, bheight, 0,
		GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
*/
	//nInt32 tid = CTextureManager::GetSingeltonPtr()->AddTexture(GL_TEXTURE_2D,
	//	expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA);
/*	CTexturePtr ptex = CTextureManager::GetSingeltonPtr()->AddTexture(new CTexture(fname.c_str(), GL_TEXTURE_2D));
	ptex->SetEnvType(GL_MODULATE);
	ptex->CreateTexture(expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA, GL_CLAMP);

	// После создания текстуры, мы больше не нуждаемся в промежуточных данных.
	freemems(expanded_data);

	CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6,
		slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows,
		code, ptex);

*/
	nstring resnamet;
	nstring resnamei("TempFontImage");
	resnamet = mName + "_" + CStringUtils::IntTo16xString(static_cast<nInt32>(code));
// Создаем промежуточное изображение в памяти
	CImagePtr pImage = CImageManager::GetSingelton().CreateNewImage(resnamei, mName, mem,
		bwidth, bheight, 1, CImageFormats::NF_LUMINANCE_ALPHA, CResource::NV_FREE);
// На базе изображения создаем текстуру
	CTexturePtr texp = CTextureManager::GetSingelton().CreateNewTexture(resnamet, mName, pImage);

	// После создания текстуры, мы больше не нуждаемся в промежуточных данных.
	mem.FreeBuffer();

	CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6,
		slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows,
		code, texp);
	mSize += texp->GetSize();

/// Создаем дисплейный список на букву ///////////////////////////////////////////////
	letter.GetDispList().CreateList();
	letter.GetDispList().BeginList();
/// //////////////////////////////////////////////////////////////////////////////////
	if(!texp.IsNull())
		texp->ApplyTexture();

// Вычислим какая часть нашей текстуры будет заполнена пустым пространством.
// Мы рисуем только ту часть текстуры, в которой находится символ, и сохраняем
// информацию в переменных x и y, затем, когда мы рисуем четырехугольник,
// мы будем только ссылаться на ту часть текстуры, в которой непосредственно
// содержится символ.
	nReal x = static_cast<nReal>(letter.GetBitmapw()) / static_cast<nReal>(letter.GetWidth()),
		y = static_cast<nReal>(letter.GetBitmapr()) / static_cast<nReal>(letter.GetHeight());

	//glBindTexture(GL_TEXTURE_2D, let.GetTex());

	glBegin(GL_QUADS);
		glTexCoord2f(0,0);
		glVertex2i(0,0);
		glTexCoord2f(0,y);
		glVertex2i(0,letter.GetBitmapr());
		glTexCoord2f(x,y);
		glVertex2i(letter.GetBitmapw(), letter.GetBitmapr());
		glTexCoord2f(x,0);
		glVertex2i(letter.GetBitmapw(), 0);
	glEnd();

/// Завершаем дисплейный список //////////////////////////////////////////////////
	letter.GetDispList().EndList();
/// //////////////////////////////////////////////////////////////////////////////

	letters_map[code] = letter;
}
void CDevILCodec::DecodeFromBuffer(const CMemoryBuffer & input, CImage *image,
		CImageFormats::NovaPixelFormats format, ESaveFormats ext)
{
	ILuint image_id;
	// Generate the main image name to use.
	ilGenImages(1, &image_id);

	// Bind this image name.
	ilBindImage(image_id);

	ILenum type = 0;
	switch(ext)
	{
	case SF_BMP:
		type = IL_BMP;
		break;
	case SF_ICO:
		type = IL_ICO;
		break;
	case SF_JPG:
		type = IL_JPG;
		break;
	case SF_PCX:
		type = IL_PCX;
		break;
	case SF_PIC:
		type = IL_PIC;
		break;
	case SF_PNG:
		type = IL_PNG;
		break;
	case SF_TGA:
		type = IL_TGA;
		break;
	case SF_TIF:
		type = IL_TIF;
		break;
	case SF_GIF:
		type = IL_GIF;
		break;
	case SF_DDS:
		type = IL_DDS;
		break;
	case SF_PIX:
		type = IL_PIX;
		break;
	case SF_HDR:
		type = IL_HDR;
		break;

	default:
		return;
	}

	if(!ilLoadL(type, input.GetBegin(), input.GetBufferSize()))
	{
		ILenum Error = 0;
		if((Error = ilGetError()) != NULL)
		{
			nstring str("CDevILCodec::DecodeFormStream: Can not load image lump - ");
			str.append(iluErrorString(Error));
			throw NOVA_EXP(str.c_str(), BAD_OPERATION);
		}
	}

	image->GetImageSource().mHeight = ilGetInteger(IL_IMAGE_HEIGHT);
	image->GetImageSource().mWidth = ilGetInteger(IL_IMAGE_WIDTH);
	image->GetImageSource().mDepth = ilGetInteger(IL_IMAGE_DEPTH);

	//if (ilGetInteger(IL_IMAGE_ORIGIN) == IL_ORIGIN_UPPER_LEFT)
	//	iluFlipImage();

	if(format == CImageFormats::NF_DEFAULT)
	{
		CDevILFormats inf;
		inf.SetFormat(ilGetInteger(IL_IMAGE_FORMAT));
		format = inf.GetExFormat();
	}

	CDevILFormats informat;
	informat.SetExFormat(format);
	image->GetImageSource().mPixelFormat = format;


	size_t _size = image->GetWidth() * image->GetHeight() * image->GetDepth() * ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
	image->GetBits().FreeBuffer();
	image->GetBits().AllocBuffer(_size);

	ilCopyPixels(0, 0, 0, image->GetWidth(), image->GetHeight(),
		image->GetDepth(), informat.GetFormat(), IL_UNSIGNED_BYTE, image->GetBits().GetBegin());

	ilDeleteImages(1, &image_id);

	ILenum Error = 0;
	if((Error = ilGetError()) != NULL)
	{
		nstring str("CDevILCodec::DecodeFormStream(): Can not load image file - ");
		str.append(iluErrorString(Error));
		throw NOVA_EXP(str.c_str(), BAD_OPERATION);
	}
}
void CDevILCodec::CodeToBuffer(CMemoryBuffer & out, const CImage &image,
							   ESaveFormats ext)
{
	ILuint imageid;
	CDevILFormats informat;
	informat.SetExFormat(image.GetPixelFormat());
	// Generate the main image name to use.
	ilGenImages(1, &imageid);

	// Bind this image name.
	ilBindImage(imageid);

	ilTexImage(image.GetWidth(), image.GetHeight(), image.GetDepth(), informat.GetInternalChannels(),
		informat.GetFormat(), IL_UNSIGNED_BYTE, image.GetBitsPtr());

	ILenum type = 0;
	switch(ext)
	{
	case SF_BMP:
		type = IL_BMP;
		break;
	case SF_ICO:
		type = IL_ICO;
		break;
	case SF_JPG:
		type = IL_JPG;
		break;
	case SF_PCX:
		type = IL_PCX;
		break;
	case SF_PIC:
		type = IL_PIC;
		break;
	case SF_PNG:
		type = IL_PNG;
		break;
	case SF_TGA:
		type = IL_TGA;
		break;
	case SF_TIF:
		type = IL_TIF;
		break;
	case SF_GIF:
		type = IL_GIF;
		break;
	case SF_DDS:
		type = IL_DDS;
		break;
	case SF_PIX:
		type = IL_PIX;
		break;
	case SF_HDR:
		type = IL_HDR;
		break;

	default:
		return;
	}

	out.AllocBuffer(image.GetSize()+0xff);
	ilSaveL(type, out.GetBegin(), out.GetBufferSize());

	ilDeleteImages(1, &imageid);

	ILenum Error = 0;
	if((Error = ilGetError()) != NULL)
	{
		nstring str("CDevILCodec::CodeToStream: ");
		str.append(iluErrorString(Error));
		throw NOVA_EXP(str.c_str(), BAD_OPERATION);
	}
}