Fixes to syborg-graphicswrapper.vcproj
These changes allow syborg-graphicswrapper to link against the hostthreadadapter and khronosapiwrapper libraries built by the graphics.simulator component.
The .vcproj file uses relative paths, which requires that the following three packages are laid out as follows:
os/
graphics
adapt/
graphics.simulator
qemu
/*
* 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 <iostream>
#include <iomanip>
#include "dwarfmanager.h"
#include "inputfile.h"
#include "outputfile.h"
#include "filefragment.h"
void DwarfSectionManager::AddSection(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr){
if (iRomDetails->iTrace){
cout << " " << GetSectionName() << " - DWARF\n";
}
FileShdrPair aFileShdrPair(aXIPFileDetails, aShdr);
iFileShdrList.push_back(aFileShdrPair);
}
void DwarfSectionManager::SetupSection(){
if (!iFileShdrList.empty()){
ElfSectionElfData * aDwarfSectionData = new ElfSectionElfData(*this);
Elf32_Shdr aDwarfShdr;
aDwarfShdr.sh_name = 0; // for now.
aDwarfShdr.sh_type = SHT_PROGBITS;
aDwarfShdr.sh_flags = 0;
aDwarfShdr.sh_addr = 0;
aDwarfShdr.sh_offset = 0; // for now
aDwarfShdr.sh_size = 0; // for now.
aDwarfShdr.sh_link = 0;
aDwarfShdr.sh_info = 0;
aDwarfShdr.sh_addralign = 4;
aDwarfShdr.sh_entsize = sizeof(Elf32_Sym);
ElfSection aDwarfSection(aDwarfSectionData, GetSectionName().c_str(), aDwarfShdr);
iElfSectionManager.AddSection(aDwarfSection);
}
}
Dwarf_Unsigned DwarfSectionManager::DecodeUnsignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length){
Dwarf_Ubyte byte;
Dwarf_Word word_number;
Dwarf_Unsigned number;
Dwarf_Sword shift;
Dwarf_Sword byte_length;
/* The following unrolls-the-loop for the first few bytes and
unpacks into 32 bits to make this as fast as possible.
word_number is assumed big enough that the shift has a defined
result. */
if ((*leb128 & 0x80) == 0) {
leb128_length = 1;
return *leb128;
} else if ((*(leb128 + 1) & 0x80) == 0) {
leb128_length = 2;
word_number = *leb128 & 0x7f;
word_number |= (*(leb128 + 1) & 0x7f) << 7;
return word_number;
} else if ((*(leb128 + 2) & 0x80) == 0) {
leb128_length = 3;
word_number = *leb128 & 0x7f;
word_number |= (*(leb128 + 1) & 0x7f) << 7;
word_number |= (*(leb128 + 2) & 0x7f) << 14;
return word_number;
} else if ((*(leb128 + 3) & 0x80) == 0) {
leb128_length = 4;
word_number = *leb128 & 0x7f;
word_number |= (*(leb128 + 1) & 0x7f) << 7;
word_number |= (*(leb128 + 2) & 0x7f) << 14;
word_number |= (*(leb128 + 3) & 0x7f) << 21;
return word_number;
}
/* The rest handles long numbers Because the 'number' may be larger
than the default int/unsigned, we must cast the 'byte' before
the shift for the shift to have a defined result. */
number = 0;
shift = 0;
byte_length = 1;
byte = *(leb128);
for (;;) {
number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
if ((byte & 0x80) == 0) {
leb128_length = byte_length;
return number;
}
shift += 7;
byte_length++;
++leb128;
byte = *leb128;
}
}
#define BITSINBYTE 8
Dwarf_Signed DwarfSectionManager::DecodeSignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length){
Dwarf_Signed number = 0;
Dwarf_Bool sign = 0;
Dwarf_Word shift = 0;
Dwarf_Ubyte byte = *leb128;
Dwarf_Word byte_length = 1;
/* byte_length being the number of bytes of data absorbed so far in
turning the leb into a Dwarf_Signed. */
for (;;) {
sign = byte & 0x40;
number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
shift += 7;
if ((byte & 0x80) == 0) {
break;
}
++leb128;
byte = *leb128;
byte_length++;
}
if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
number |= -((Dwarf_Signed) 1 << shift);
}
leb128_length = byte_length;
return number;
}
Dwarf_Byte_Ptr DwarfSectionManager::GetSectionData(FileShdrPair & aPair){
InputFile in(aPair.iXIPFileDetails.iElfFile);
in.SetOffset(aPair.iShdr.sh_offset);
return (Dwarf_Byte_Ptr)in.GetData(aPair.iShdr.sh_size);
}
void DwarfConcatenatedSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
ConcatenateData();
if (iRomDetails->iTrace){
cout << "\nGenerating DWARF section " << GetSectionName() << " size = "
<< dec << Size() << " bytes\n";
}
FileShdrList::iterator e = iFileShdrList.end();
for (FileShdrList::iterator i = iFileShdrList.begin(); i < e; i++){
if (iRomDetails->iTrace){
cout << " " << i->iXIPFileDetails.iElfFile << " " << dec << i->iShdr.sh_size << " bytes\n" << flush;
}
ProcessSection(*i);
}
SetFileFragmentData(aFileFragmentData, iSize, reinterpret_cast<char *>(iData));
}
void DwarfConcatenatedSectionManager::ConcatenateData(){
if (iData == NULL) {
size_t sectionSize = Size();
iData = new Dwarf_Ubyte[sectionSize];
Dwarf_Byte_Ptr p = iData;
FileShdrList::iterator e = iFileShdrList.end();
for (FileShdrList::iterator i = iFileShdrList.begin(); i < e; i++){
size_t off = p - iData;
size_t soff = GetSectionOffset(i->iXIPFileDetails.iElfFile);
if (off >= sectionSize)
assert(off < sectionSize);
if (off != soff)
assert(off == soff);
size_t n = i->iShdr.sh_size;
Dwarf_Byte_Ptr contrib = GetSectionData(*i);
memcpy(p, contrib, n);
p += n;
delete [] contrib;
}
}
}
size_t DwarfConcatenatedSectionManager::Size(){
if (iSizeValid)
return iSize;
//cerr << "Size for " << GetSectionName() << "\n";
size_t offset = 0;
FileShdrList::iterator e = iFileShdrList.end();
for (FileShdrList::iterator i = iFileShdrList.begin(); i != e; i++){
//cerr << "offset = 0x" << offset << "\t";
SetSectionOffset(i->iXIPFileDetails.iElfFile, offset);
size_t size = i->iShdr.sh_size;
//cerr << "section size for " << i->iXIPFileDetails.iElfFile << " 0x" << size << "\n";
SetSectionSize(i->iXIPFileDetails.iElfFile, size);
size_t newOffset = offset + size;
if (newOffset < offset){
cerr << "Error: The combined section " << GetSectionName()
<< " requires translation from 32 to 64 bit Dwarf which is not currently supported.\n"
<< "Exclude the following files (or their equivalent in terms of their contribution to Dwarf):\n";
for (; i != e; i++){
cerr << i->iXIPFileDetails.iE32File << "\n";
}
exit(EXIT_FAILURE);
}
offset = newOffset;
}
//cerr << "Size = 0x" << offset << "\n";
iSizeValid = true;
return iSize = offset;
}
void DwarfConcatenatedSectionManager::ProcessSection(FileShdrPair & aPair){
Dwarf_Byte_Ptr start = GetSection(aPair.iXIPFileDetails.iElfFile);
Dwarf_Byte_Ptr end = start + aPair.iShdr.sh_size;
ProcessSection(aPair, start, end);
}
void DwarfConcatenatedSectionManager::SetSectionOffset(PathName & aPathName, size_t aOffset) {
iPathNameSectionOffsetMap[aPathName] = aOffset;
}
void DwarfConcatenatedSectionManager::InitOffsetMap(){
Size(); // forces the map to be set up if it hasn't been already
}
size_t DwarfConcatenatedSectionManager::GetSectionOffset(PathName & aPathName){
if (!iSizeValid) // if the size is valid then so must be the offsets.
InitOffsetMap();
return iPathNameSectionOffsetMap[aPathName];
}
void DwarfConcatenatedSectionManager::SetSectionSize(PathName & aPathName, size_t aSize) {
iPathNameSectionSizeMap[aPathName] = aSize;
}
size_t DwarfConcatenatedSectionManager::GetSectionSize(PathName & aPathName){
if (!iSizeValid) // if the size is valid then so must be the offsets.
InitOffsetMap();
return iPathNameSectionSizeMap[aPathName];
}
Dwarf_Byte_Ptr DwarfConcatenatedSectionManager::GetSection(PathName & aPathName){
ConcatenateData();
size_t offset = GetSectionOffset(aPathName);
return iData + offset;
}
class ElfSectionFragmentedDwarfData : public ElfSectionElfData {
public:
ElfSectionFragmentedDwarfData(FileFragmentOwner & aSource) :
ElfSectionElfData(aSource)
{}
ElfSectionFragmentedDwarfData(const ElfSectionElfData & aData) :
ElfSectionElfData(aData)
{}
// ElfSection protocol
virtual ElfSectionFragmentedDwarfData * Clone(){
return new ElfSectionFragmentedDwarfData(*this);
}
virtual void AddData(OutputFile & aOutputFile){
return;
}
};
class DwarfSectionFragment : public FileFragmentOwner {
public:
DwarfSectionFragment(DwarfFragmentedSectionManager & aSource,
FileShdrPair & aPair):
iSource(aSource),
iPair(aPair),
iData(NULL)
{}
// Bitwise copy is OK so don't need to write our own copy ctor etc.
// The FileFragmentOwner protocol
virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
virtual size_t Size();
virtual void DeleteFileFragmentData();
private:
DwarfSectionFragment();
private:
DwarfFragmentedSectionManager & iSource;
FileShdrPair & iPair;
Dwarf_Byte_Ptr iData;
};
void DwarfSectionFragment::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
iSource.ProcessSection(iPair, iData);
SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast<char *>(iData));
}
size_t DwarfSectionFragment::Size(){
return iPair.iShdr.sh_size;
}
void DwarfSectionFragment::DeleteFileFragmentData(){
delete [] iData;
//
delete this;
}
void DwarfFragmentedSectionManager::SetupSection(){
if (!iFileShdrList.empty()){
ElfSectionFragmentedDwarfData * aDwarfSectionData = new ElfSectionFragmentedDwarfData(*this);
Elf32_Shdr aDwarfShdr;
aDwarfShdr.sh_name = 0; // for now.
aDwarfShdr.sh_type = SHT_PROGBITS;
aDwarfShdr.sh_flags = 0;
aDwarfShdr.sh_addr = 0;
aDwarfShdr.sh_offset = 0; // for now
aDwarfShdr.sh_size = 0; // for now.
aDwarfShdr.sh_link = 0;
aDwarfShdr.sh_info = 0;
aDwarfShdr.sh_addralign = 4;
aDwarfShdr.sh_entsize = sizeof(Elf32_Sym);
// aDwarfSectionData will ask the secton manager (i.e. its source) for the offset of the section.
// So we better record it here. We assume that it is the current size of the output file.
// As long as we are single threaded and all the fragments get added consecutively as below
// this is a safe assumption.
SetOffset(iDwarfManager.GetOutputFile().Size());
ElfSection aDwarfSection(aDwarfSectionData, GetSectionName().c_str(), aDwarfShdr);
iElfSectionManager.AddSection(aDwarfSection);
for (FileShdrList::iterator i = iFileShdrList.begin(); i < iFileShdrList.end(); i++ ){
DwarfSectionFragment * aFrag = new DwarfSectionFragment(*this, *i);
aFrag->AddData(iDwarfManager.GetOutputFile());
}
}
}
// NB the section itself doesn't write any data
// The FileFragmentOwner protocol
void DwarfFragmentedSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
SetFileFragmentData(aFileFragmentData, 0, reinterpret_cast<char *>(NULL));
}
// This should never get called
void DwarfFragmentedSectionManager::ConcatenateData(){
assert(1 == 0);
return;
}
void DwarfFragmentedSectionManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr & aData){
if (iInitialTraceMessage & iRomDetails->iTrace){
cout << "\nGenerating DWARF section " << GetSectionName() << " size = "
<< dec << Size() << " bytes\n";
iInitialTraceMessage = false;
}
if (iRomDetails->iTrace){
cout << " " << aPair.iXIPFileDetails.iElfFile << " size = "
<< dec << aPair.iShdr.sh_size << "\n" << flush;
}
Dwarf_Byte_Ptr start = GetSectionData(aPair);
aData = start;
Dwarf_Byte_Ptr end = start + aPair.iShdr.sh_size;
ProcessSection(aPair, start, end);
}
#if 0
// This should never get called
void DwarfFragmentedSectionManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){
assert(1 == 0);
return;
}
#endif
const string DwarfMacinfoManager::iMacinfoSectionName(".debug_macinfo");
const string DwarfStrManager::iStrSectionName(".debug_str");
void DwarfManager::AddSection(XIPFileDetails & aXIPFileDetails, string aSectionName, Elf32_Shdr * aShdr){
if (iDwarfAbbrevManager.GetSectionName() == aSectionName)
iDwarfAbbrevManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfArangesManager.GetSectionName() == aSectionName)
iDwarfArangesManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfFrameManager.GetSectionName() == aSectionName)
iDwarfFrameManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfInfoManager.GetSectionName() == aSectionName)
iDwarfInfoManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfLineManager.GetSectionName() == aSectionName)
iDwarfLineManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfLocManager.GetSectionName() == aSectionName)
iDwarfLocManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfMacinfoManager.GetSectionName() == aSectionName)
iDwarfMacinfoManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfPubnamesManager.GetSectionName() == aSectionName)
iDwarfPubnamesManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfPubtypesManager.GetSectionName() == aSectionName)
iDwarfPubtypesManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfRangesManager.GetSectionName() == aSectionName)
iDwarfRangesManager.AddSection(aXIPFileDetails, aShdr);
else if (iDwarfStrManager.GetSectionName() == aSectionName)
iDwarfStrManager.AddSection(aXIPFileDetails, aShdr);
#if 0
else
cerr << "Warning: unrecognised debug section name " << aSectionName << " ignored\n";
#endif
}
void DwarfManager::SetupSections(){
// The order here is important for fix up
// first the purely concatenated 'leaf' sections
// See the diagram on p.182 of the Dwarf 3 spec
// to understand the 'dependenices'
iDwarfAbbrevManager.SetupSection();
iDwarfFrameManager.SetupSection();
iDwarfPubnamesManager.SetupSection();
iDwarfPubtypesManager.SetupSection();
iDwarfArangesManager.SetupSection();
iDwarfMacinfoManager.SetupSection();
iDwarfInfoManager.SetupSection();
iDwarfLineManager.SetupSection();
iDwarfLocManager.SetupSection();
iDwarfRangesManager.SetupSection();
iDwarfStrManager.SetupSection();
}