tools/elf4rom/src/elfsectionmanager.cpp
changeset 34 92d87f2e53c2
--- /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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+
+#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<char *>(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());
+}