diff -r 1af5c1be89f8 -r 92d87f2e53c2 tools/elf4rom/src/elfsectionmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/elfsectionmanager.cpp Fri Jan 15 09:07:44 2010 +0000 @@ -0,0 +1,155 @@ +/* +* 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 . +*/ + +#include + +#include "elfsectionmanager.h" + +void ElfSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){ + int nSections = iSections.size(); + if (nSections > 0){ + iData = new Elf32_Shdr[nSections]; + Elf32_Shdr * p = iData; + SectionList::iterator aSection = iSections.begin(); + SectionList::iterator end = iSections.end(); + while (aSection != end) { + *p = aSection->GetSectionHeader().iElf32Shdr; + p++; + aSection++; + } + SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast(iData)); + } +} + +size_t ElfSectionManager::Size(){ + return SectionHeaderSize(); +} + +void ElfSectionManager::DeleteFileFragmentData(){ + if (iData) { + Elf32_Shdr * d = iData; + iData = NULL; + delete[] d; + } +} + +void ElfSectionManager::AddData(){ + AddData(iOutputFile); +} + +void ElfSectionManager::AddData(OutputFile & aOutputFile){ + if (iSections.size() > 0) { + SectionList::iterator aSection = iSections.begin(); + SectionList::iterator end = iSections.end(); + while (aSection != end) { + aSection->AddData(aOutputFile); + aSection++; + } + AddSectionTable(); + } +} + +void ElfSectionManager::EnsureSectionStringTableSectionAdded(){ + if (iSectionStringTableSectionAdded) return; + + // set iSectionStringTableSectionAdded true now so we don't do the next bit twice; + iSectionStringTableSectionAdded = true; + + // first create the UNDEF section + ElfSectionNoData * aUndefData = new ElfSectionNoData(); + + Elf32_Shdr undef; + undef.sh_name = 0; + undef.sh_type = SHT_NULL; + undef.sh_flags = 0; + undef.sh_addr = 0; + undef.sh_offset = 0; + undef.sh_size = 0; + undef.sh_link = 0; + undef.sh_info = 0; + undef.sh_addralign = 0; + undef.sh_entsize = 0; + + ElfSection aUndefSection(aUndefData, "", undef); + AddSection(aUndefSection); + + ElfSectionElfData * aSectionStringTableSectionData = 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 = 0; // for now. + shdr.sh_link = SHN_UNDEF; + shdr.sh_info = 0; + shdr.sh_addralign = 0; + shdr.sh_entsize = 0; + + ElfSection aSectionStringTableSection(aSectionStringTableSectionData, ".shstrtab", shdr); + AddSection(aSectionStringTableSection); + iElf32Header.SetSectionStringNdx(iSections.size() - 1); +} +void ElfSectionManager::AddSection(ElfSection & aSection){ + EnsureSectionStringTableSectionAdded(); + if (aSection.GetName().size() > 0){ + // rename sections for GDB (yuk!) + String sectionName(aSection.GetName()); + String ro("ER_RO"); + String text(".text"); + if (sectionName == ro){ + sectionName = text; + } else { + String rw("ER_RW"); + String data(".data"); + if (sectionName == rw){ + sectionName = data; + } else { + String zi("ER_ZI"); + String bss(".bss"); + if (sectionName == zi) + sectionName = bss; + } + } + size_t nameOffset = iStringTable.AddName(sectionName); + aSection.SetNameOffset(nameOffset); + } else { + // use the initial Null String. + size_t nameOffset = iStringTable.AllocateInitialNullString(); + aSection.SetNameOffset(nameOffset); + } + aSection.SetIndex(iSections.size()); + iSections.push_back(aSection); + iElf32Header.AddSectionHdr(); +} + +size_t ElfSectionManager::SectionHeaderSize(){ + return iSections.size() * sizeof(Elf32_Shdr); +} + +void ElfSectionManager::AddSectionStringTable(){ + // Assume the section header already setup and we've got hold of it. We need to say where the strings ended up. + const FileFragment & aSectionTableFrag = iOutputFile.GetFileFragment(this); + SetOffset(aSectionTableFrag.GetOffset()); +} + +void ElfSectionManager::AddSectionTable(){ + const FileFragment & aSectionTableFrag = iOutputFile.GetFileFragment(this); + SetOffset(aSectionTableFrag.GetOffset()); + iElf32Header.SetSectionHdrOffset(GetOffset()); +}