Modify framebuffer and NGA framebuffer to read screen size from board model dtb file. Optimise memory usuage of frame buffer
Add example minigui application with hooks to profiler (which writes results to S:\). Modified NGA framebuffer to run its own dfc queue at high priority
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libelf.h>
#include <map>
#include "elfsymboltablemanager.h"
void ElfFileSymbolFragments::AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal){
iPath = aPath;
// drop the inital 'undefined' symbol
iSymbolTableOffset = aOffset + sizeof(Elf32_Sym);
iSymbolTableSize = aSize - sizeof(Elf32_Sym);
iFirstGlobal = aFirstGlobal - 1;
}
void ElfFileSymbolFragments::AddStringTable(String & aPath, size_t aOffset, size_t aSize){
iPath = aPath;
// drop the inital "\0"
iStringTableOffset = aOffset + 1;
iStringTableSize = aSize - 1;
}
size_t ElfFileSymbolFragments::LookupSection(size_t ndx){
SectionNumberMap::iterator aMapping = iSectionNumberMap.begin();
SectionNumberMap::iterator end = iSectionNumberMap.end();
while (aMapping != end) {
if (aMapping->iOld == ndx)
return aMapping->iNew;
aMapping++;
}
return ndx;
}
int ElfFileSymbolFragments::LookupVaddrAddend(size_t ndx){
SectionVaddrAddendMap::iterator aMapping = iSectionVaddrAddendMap.begin();
SectionVaddrAddendMap::iterator end = iSectionVaddrAddendMap.end();
while (aMapping != end) {
if (aMapping->iSectionNumber == ndx)
return aMapping->iAddend;
aMapping++;
}
return 0;
}
size_t ElfSymTabStringTable::Size(){
return iElfSymbolTableManager.GetSymTabStringsSectionSize();
}
void ElfSymbolTableManager::Finalize(SectionNumberMap & aSectionNumberMap, SectionVaddrAddendMap & aSectionVaddrAddendMap ){
iCurrentFragment.SetSectionNumberMap(aSectionNumberMap);
iCurrentFragment.SetSectionVaddrAddendMap(aSectionVaddrAddendMap);
iCurrentFragment.Validate();
iSymbolFragments.push_back(iCurrentFragment);
iCurrentFragment.Reset();
}
// TODO: This could be done more efficiently and with out the use of the ElfStringTable object.
void ElfSymbolTableManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
size_t symTabSize = GetSymTabSectionSize();
iData = new char[symTabSize];
Elf32_Sym * syms = (Elf32_Sym *)iData;
// set up UNDEF symbol
syms[0].st_info = 0;
syms[0].st_name = 0;
syms[0].st_other = 0;
syms[0].st_shndx = 0;
syms[0].st_size = 0;
syms[0].st_value = 0;
// set up 'cursors' into final symbol table so we put locals first
// and globals at the end
Elf32_Sym * lsym = &syms[1];
size_t firstGlobal = GetFirstNonLocalIndex();
Elf32_Sym * gsym = &syms[firstGlobal];
Elf32_Sym * lsymLim = gsym;
iStringTable.AllocateInitialNullString();
SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
SymbolFragmentList::iterator end = iSymbolFragments.end();
while (aFrag != end) {
//InputFile aFile((char *)(aFrag->GetPath().c_str()));
InputFile aFile(aFrag->GetPath());
aFile.SetOffset(aFrag->GetSymbolTableOffset());
size_t symSize = aFrag->GetSymbolTableSize();
size_t limit = symSize / sizeof(Elf32_Sym);
char * symtabData = aFile.GetData(symSize);
Elf32_Sym * symtab = (Elf32_Sym *)symtabData;
aFile.SetOffset(aFrag->GetStringTableOffset());
char * strtabx = aFile.GetData(aFrag->GetStringTableSize());
// set strtab back one to 'add' "\0" back in so indexs works with addition.
char * strtab = strtabx - 1;
size_t firstNonLocal = aFrag->GetFirstGlobal();
typedef std::map<size_t, size_t> SymbolNdxMap;
SymbolNdxMap symNdxMap;
for (size_t i = 0; i < limit; i++){
size_t strndx = symtab[i].st_name;
if (strndx != 0) {
// see if we've already seen this index
SymbolNdxMap::iterator res = symNdxMap.find(strndx);
size_t newndx;
if (res != symNdxMap.end()){
newndx = res->second;
symtab[i].st_name = newndx;
} else {
char * name = &strtab[strndx];
newndx = iStringTable.AddString(name);
symNdxMap[strndx] = symtab[i].st_name = newndx;
}
}
if (!(symtab[i].st_value || symtab[i].st_size)){
symtab[i].st_shndx = SHN_UNDEF;
} else {
size_t oldNdx = symtab[i].st_shndx;
// retrieve new section index
size_t newscnndx = aFrag->LookupSection(oldNdx);
// retrieve the vaddr adjustment to add to the symbol's value
int addend = aFrag->LookupVaddrAddend(oldNdx);
symtab[i].st_shndx = newscnndx;
symtab[i].st_value += addend;
}
if (i < firstNonLocal){
assert(lsym < lsymLim);
*(lsym++) = symtab[i];
} else {
*(gsym++) = symtab[i];
}
}
delete [] symtabData;
delete strtabx;
aFrag++;
}
SetFileFragmentData(aFileFragmentData, symTabSize, reinterpret_cast<char *>(iData));
}
size_t ElfSymbolTableManager::Size(){
return GetSymTabSectionSize();
}
void ElfSymbolTableManager::DeleteFileFragmentData(){
char * d = iData;
iData = NULL;
delete [] d;
}
void ElfSymbolTableManager::AddData(OutputFile & aOutputFile){
const FileFragment & aSectionFrag = iOutputFile.GetFileFragment(this);
SetOffset(aSectionFrag.GetOffset());
}
void ElfSymbolTableManager::AddSymbolTable(){
// The sym table section needs to record the index of its associated
// string table in its link field and record the index of the first non-local
// symbol in its info field
int symTabSize = GetSymTabSectionSize();
size_t firstNonLocal = GetFirstNonLocalIndex();
size_t nextSectionIndex = iElfSectionManager.NumSections();
ElfSectionElfData * aSymTabSectionData = new ElfSectionElfData(*this);
Elf32_Shdr symTabShdr;
symTabShdr.sh_name = 0; // for now.
symTabShdr.sh_type = SHT_SYMTAB;
symTabShdr.sh_flags = 0;
symTabShdr.sh_addr = 0;
symTabShdr.sh_offset = 0; // for now
symTabShdr.sh_size = symTabSize; // for now.
// symTabShdr will be @ index nextSectionIndex so the .strtab will
// be @ nextSectionIndex +1
symTabShdr.sh_link = nextSectionIndex + 1;
symTabShdr.sh_info = firstNonLocal;
symTabShdr.sh_addralign = 4;
symTabShdr.sh_entsize = sizeof(Elf32_Sym);
ElfSection aSymTabSection(aSymTabSectionData, ".symtab", symTabShdr);
iElfSectionManager.AddSection(aSymTabSection);
ElfSectionElfData * aStringTableSectionData = new ElfSectionElfData(iStringTable);
Elf32_Shdr shdr;
shdr.sh_name = 0; // for now.
shdr.sh_type = SHT_STRTAB;
shdr.sh_flags = 0;
shdr.sh_addr = 0;
shdr.sh_offset = 0; // for now
shdr.sh_size = GetSymTabStringsSectionSize();
shdr.sh_link = 0;
shdr.sh_info = 0;
shdr.sh_addralign = 0;
shdr.sh_entsize = 0;
ElfSection aStringTableSection(aStringTableSectionData, ".strtab", shdr);
iElfSectionManager.AddSection(aStringTableSection);
}
size_t ElfSymbolTableManager::GetSymTabSectionSize(){
int symTabSize = sizeof(Elf32_Sym); // add the 'undefined' symbols
SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
SymbolFragmentList::iterator end = iSymbolFragments.end();
while (aFrag != end) {
symTabSize += aFrag->GetSymbolTableSize();
aFrag++;
}
return symTabSize;
}
size_t ElfSymbolTableManager::GetSymTabStringsSectionSize(){
if (iSymbolStringTableSizeValid)
return iSymbolStringTableSize;
int stringsSize = 1; // add the leading "\0"
SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
SymbolFragmentList::iterator end = iSymbolFragments.end();
while (aFrag != end) {
stringsSize += aFrag->GetStringTableSize();
aFrag++;
}
iSymbolStringTableSizeValid = true;
return iSymbolStringTableSize = stringsSize;
}
size_t ElfSymbolTableManager::GetFirstNonLocalIndex(){
int ndx = 1; // add the 'undefined' symbols
SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
SymbolFragmentList::iterator end = iSymbolFragments.end();
while (aFrag != end) {
ndx += aFrag->GetFirstGlobal();
aFrag++;
}
return ndx;
}