diff -r 1af5c1be89f8 -r 92d87f2e53c2 tools/elf4rom/src/elfrom.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfrom.cpp Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,567 @@
+/*
+* 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
+#include
+#include
+#include
+
+using namespace std;
+
+#include "elfromerror.h"
+#include "elfrom.h"
+#include "inputfile.h"
+
+#define NO_GAPS
+
+void ElfRom::SetupE32RomData() {
+ SetupRomElf32_EHdr();
+ SetupRomImage();
+}
+
+// TODO: don't use primary file - fill header in by hand.
+void ElfRom::SetupRomElf32_EHdr() {
+ //create ELF header
+
+ unsigned char c[EI_NIDENT] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS32, ELFDATA2LSB, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ Elf32_Ehdr elf32_ehdr;
+
+ for (int i=0; i iRomPhysAddr;
+ elf32_ehdr.e_shoff = sizeof(Elf32_Ehdr);
+
+// ARM specific flags
+// e_entry contains a program-loader entry point
+#define EF_ARM_HASENTRY 0x02
+// Each subsection of the symbol table is sorted by symbol value
+#define EF_ARM_SYMSARESORTED 0x04
+// Symbols in dynamic symbol tables that are defined in sections
+// included in program segment n have st_shndx = n+ 1.
+#define EF_ARM_DYNSYMSUSESEGIDX 0x8
+// Mapping symbols precede other local symbols in the symbol table
+#define EF_ARM_MAPSYMSFIRST 0x10
+// This masks an 8-bit version number, the version of the ARM EABI to
+// which this ELF file conforms. This EABI is version 2. A value of 0
+// denotes unknown conformance. (current version is 0x02000000)
+#define EF_ARM_EABIMASK 0xFF000000
+
+#define EF_ARM_EABI_VERSION 0x02000000
+#define EF_ARM_BPABI_VERSION 0x04000000
+
+ elf32_ehdr.e_flags = EF_ARM_BPABI_VERSION | EF_ARM_HASENTRY;
+ elf32_ehdr.e_ehsize = sizeof(Elf32_Ehdr);
+ elf32_ehdr.e_phentsize = sizeof(Elf32_Phdr);
+ elf32_ehdr.e_shentsize = sizeof(Elf32_Shdr);
+ elf32_ehdr.e_shnum = 0;
+ elf32_ehdr.e_shstrndx = 0;
+ elf32_ehdr.e_phnum = 02;
+ new (&iElf32Header) Elf32Header(elf32_ehdr);
+#if 0
+ iElf32Header.SetEntryPoint(iRomDetails->iRomPhysAddr);
+ elf_end(e);
+ close(fd);
+#endif
+ iElf32Header.SetEntryPoint(iRomDetails->iRomPhysAddr);
+ iElf32Header.AddData(iOutputFile);
+ assert(iElf32Header.GetOffset() == 0);
+ if (iRomDetails->iTrace){
+ cout << "\nElf header added.\n";
+ }
+
+}
+
+
+void ElfRom::SetupRomImage(){
+ // ensure image size is known and we know how to get hold of it
+ iE32RomImage.SetupRomData();
+ iE32RomImage.AddData(iOutputFile);
+ assert(iE32RomImage.GetOffset() == iElf32Header.Size());
+ if (iRomDetails->iTrace){
+ size_t offset = iE32RomImage.GetOffset();
+ size_t size = iE32RomImage.Size();
+ cout << "\nAdded ROM image " << iRomDetails->iRomFile << "\n";
+ cout.fill('0');
+ cout << hex << " offset 0x" << setw(8)
+ << offset << " size = 0x" << setw(8) << size << "\n" ;
+ }
+}
+
+void ElfRom::SetupProgramHeaderTable(){
+ size_t offsetx = AddBootStrapProgramHeader();
+ RomDetails::XIPFileList::iterator aXIPFile = iRomDetails->iXIPFiles.begin();
+ RomDetails::XIPFileList::iterator end = iRomDetails->iXIPFiles.end();
+ unsigned int p = iRomDetails->iRomPhysAddr;
+ unsigned int v = iRomDetails->iRomBaseLinearAddr;
+ int addend = v > p ? -(v - p) : p - v;
+
+ if (iRomDetails->iTrace){
+ cout << "\nAdding program headers for e32images\n";
+ }
+
+ while (aXIPFile != end) {
+ offsetx = SetupProgramHeaders(*aXIPFile, offsetx, addend);
+ aXIPFile++;
+ }
+ AddFinalHeader(offsetx);
+
+#ifdef NO_GAPS
+ // check there are no gaps or overlaps in the phdrs
+ Elf32_Word bsz = iBootStrapPHdr.GetPhdrFilesz();
+ Elf32_Word coffset = iBootStrapPHdr.GetPhdrOffset() + bsz;
+ Elf32_Addr phys_addr = iBootStrapPHdr.GetPhdrPaddr() + bsz;
+ ElfPHdrList::iterator aCheckHdr = iElfPHdrList.begin();
+ ElfPHdrList::iterator endCheckHdr = iElfPHdrList.end();
+ while(aCheckHdr != endCheckHdr) {
+ Elf32_Word o = aCheckHdr->GetPhdrOffset();
+ if (coffset != o){
+ cerr << "Error: Phdr table broken - offsets incorrect\n";
+ assert(coffset == o);
+ }
+ Elf32_Addr addr = aCheckHdr->GetPhdrPaddr();
+ if (phys_addr > addr){
+ cerr << "Error: Phdr table broken - physical addresses incorrect\n";
+ assert(phys_addr <= addr);
+ }
+ size_t sz = aCheckHdr->GetPhdrFilesz();
+ coffset = o + sz;
+ phys_addr = addr + sz;
+ aCheckHdr++;
+ }
+#endif
+
+ ElfPHdrList::iterator aHdr = iElfPHdrList.begin();
+ ElfPHdrList::iterator endHdr = iElfPHdrList.end();
+ while (aHdr != endHdr) {
+ aHdr->AddData(iOutputFile);
+ aHdr++;
+ }
+}
+
+size_t ElfRom::AddBootStrapProgramHeader(){
+ iBootStrapPHdr.SetPhdrType(PT_LOAD);
+ iBootStrapPHdr.SetPhdrOffset(iE32RomImage.GetOffset());
+ iBootStrapPHdr.SetPhdrVaddr(iRomDetails->iRomPhysAddr);
+ iBootStrapPHdr.SetPhdrPaddr(iRomDetails->iRomPhysAddr);
+ iBootStrapPHdr.SetPhdrAlign(4);
+ iBootStrapPHdr.SetPhdrFlags(PF_X + PF_R);
+ size_t bootstrapsize = iRomDetails->iXIPFiles[0].iLoadAddr - iRomDetails->iRomBaseLinearAddr;
+ iBootStrapPHdr.SetPhdrFilesz(bootstrapsize);
+ iBootStrapPHdr.SetPhdrMemsz(bootstrapsize);
+
+ iBootStrapPHdr.AddData(iOutputFile);
+ assert((iElf32Header.Size() + iE32RomImage.Size()) == iBootStrapPHdr.GetOffset());
+ iElf32Header.AddProgramHdr();
+ iElf32Header.SetProgramHdrOffset(iBootStrapPHdr.GetOffset());
+ if (iRomDetails->iTrace){
+ size_t offset = iBootStrapPHdr.GetOffset();
+ cout << "\nAdded PHdr for bootstrap\n";
+ cout.fill('0');
+ cout << hex << " offset 0x" << setw(8) << offset
+ << " size = 0x" << setw(8) << bootstrapsize << "\n";
+ }
+
+ return iE32RomImage.GetOffset() + bootstrapsize;
+}
+
+static inline size_t InitE32HdrPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word size){
+ hdr.SetPhdrType(PT_LOAD);
+ hdr.SetPhdrOffset(offset);
+ hdr.SetPhdrVaddr(vaddr);
+ hdr.SetPhdrPaddr(paddr);
+ hdr.SetPhdrAlign(0);
+ hdr.SetPhdrFlags(PF_R);
+ hdr.SetPhdrFilesz(size);
+ hdr.SetPhdrMemsz(size);
+
+ return offset + size;
+
+}
+static inline size_t InitROPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word size){
+ hdr.SetPhdrType(PT_LOAD);
+ hdr.SetPhdrOffset(offset);
+ hdr.SetPhdrVaddr(vaddr);
+ hdr.SetPhdrPaddr(paddr);
+ hdr.SetPhdrAlign(4);
+ hdr.SetPhdrFlags(PF_X + PF_R);
+ hdr.SetPhdrFilesz(size);
+ hdr.SetPhdrMemsz(size);
+
+ return offset + size;
+
+}
+
+static inline size_t InitRWPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word fsize, Elf32_Word msize){
+ hdr.SetPhdrType(PT_LOAD);
+ hdr.SetPhdrOffset(offset);
+ hdr.SetPhdrVaddr(vaddr);
+ hdr.SetPhdrPaddr(paddr);
+ hdr.SetPhdrAlign(4);
+ hdr.SetPhdrFlags(PF_X + PF_R);
+ hdr.SetPhdrFilesz(fsize);
+ hdr.SetPhdrMemsz(msize);
+
+ return offset + fsize;
+
+}
+
+size_t ElfRom::SetupProgramHeaders(XIPFileDetails & aXIPFileDetails, size_t offset, int addend){
+ ElfPHdr e32hdr;
+ Elf32_Word e32hdrVaddr = aXIPFileDetails.iLoadAddr;
+ Elf32_Word e32hdrPaddr = aXIPFileDetails.iLoadAddr + addend;
+ Elf32_Word e32hdrSize = aXIPFileDetails.iROAddr - aXIPFileDetails.iLoadAddr ;
+ size_t e32hdrOffsetInRom = aXIPFileDetails.iLoadAddr - iRomDetails->iRomBaseLinearAddr;
+ size_t e32hdrOffsetInElf = iE32RomImage.GetOffset() + e32hdrOffsetInRom;
+#ifdef NO_GAPS
+ // But actually the offset we'll use is the one we were given as an argument.
+ // This means we need to adjust the size, vaddr and paddr by the difference
+ size_t diff = e32hdrOffsetInElf - offset;
+ e32hdrSize += diff;
+ e32hdrVaddr -= diff;
+ e32hdrPaddr -= diff;
+ offset = InitE32HdrPHdr(e32hdr, offset, e32hdrVaddr, e32hdrPaddr, e32hdrSize);
+#else
+ offset = InitE32HdrPHdr(e32hdr, e32hdrOffsetInElf, e32hdrVaddr, e32hdrPaddr, e32hdrSize);
+#endif
+ iElf32Header.AddProgramHdr();
+ iElfPHdrList.push_back(e32hdr);
+ ElfPHdr thdr;
+ Elf32_Word textVaddr = aXIPFileDetails.iROAddr;
+ Elf32_Word textPaddr = aXIPFileDetails.iROAddr + addend;
+ Elf32_Word textSize = aXIPFileDetails.iROSize;
+ size_t textOffsetInRom = aXIPFileDetails.iROAddr - iRomDetails->iRomBaseLinearAddr;
+ size_t textOffsetInElf = iE32RomImage.GetOffset() + textOffsetInRom;
+ offset = InitROPHdr(thdr, textOffsetInElf, textVaddr, textPaddr, textSize);
+ iElf32Header.AddProgramHdr();
+ iElfPHdrList.push_back(thdr);
+
+ if (iRomDetails->iTrace){
+ cout << " " << aXIPFileDetails.iE32File << "\n";
+ cout.fill(' ');
+ cout << left << " .text\n";
+ cout.fill('0');
+ cout << " paddr = 0x" << right << setw(8) << textPaddr << " vaddr = 0x" << right << setw(8)<< textVaddr
+ << " offset = 0x" << right << setw(8) << textOffsetInElf
+ << " size = 0x" << setw(8) << textSize << "\n" << flush;
+ }
+
+ if (aXIPFileDetails.iRWSize > 0){
+ ElfPHdr dhdr;
+ Elf32_Word dataVaddr = aXIPFileDetails.iRWAddr;
+ Elf32_Word dataPaddr = aXIPFileDetails.iROMDataAddr + addend;
+ Elf32_Word fsize = aXIPFileDetails.iRWSize;
+ Elf32_Word msize = aXIPFileDetails.iBSSDataSize;
+ size_t dataOffsetInRom = aXIPFileDetails.iROMDataAddr - iRomDetails->iRomBaseLinearAddr;
+ size_t dataOffsetInElf = iE32RomImage.GetOffset() + dataOffsetInRom;
+ offset = InitRWPHdr(dhdr, dataOffsetInElf, dataVaddr, dataPaddr, fsize, msize);
+ iElf32Header.AddProgramHdr();
+ iElfPHdrList.push_back(dhdr);
+
+ if (iRomDetails->iTrace){
+ cout.fill(' ');
+ cout << left << " .data\n";
+ cout.fill('0');
+ cout << " paddr = 0x" << right << setw(8) << dataPaddr << " vaddr = 0x" << right << setw(8)<< dataVaddr
+ << " offset = 0x" << right << setw(8)<< dataOffsetInElf
+ << " size = 0x" << right << setw(8) << fsize << "\n" << flush;
+ }
+
+ }
+ return offset;
+}
+
+// This adds a header for the remainder of the ROM image after the last XIP file
+size_t ElfRom::AddFinalHeader(size_t offset){
+ ElfPHdr & lastHdr = iElfPHdrList.back();
+ Elf32_Word startAddr = lastHdr.GetPhdrPaddr() + lastHdr.GetPhdrFilesz();
+ ElfPHdr e32hdr;
+ Elf32_Word e32hdrVaddr = startAddr;
+ Elf32_Word e32hdrPaddr = startAddr;
+ Elf32_Word e32hdrSize = iE32RomImage.Size() - offset + iE32RomImage.GetOffset();
+
+ offset = InitE32HdrPHdr(e32hdr, offset, e32hdrVaddr, e32hdrPaddr, e32hdrSize);
+
+ iElf32Header.AddProgramHdr();
+ iElfPHdrList.push_back(e32hdr);
+
+ if (iRomDetails->iTrace){
+ cout << "\nAdded final PHdr\n" << " offset 0x" << hex << right << setw(8) << offset
+ << " size = 0x" << setw(8) << e32hdrSize << "\n";
+ }
+ return offset;
+}
+
+void ElfRom::SetupAuxilarySections(){
+ SetupLogFile();
+}
+
+void ElfRom::SetupLogFile(){
+ if (!iRomDetails->iLogFile.size()) return;
+ InputFile * aLogFile = new InputFile(iRomDetails->iLogFile);
+ ElfSectionFileData * aLogFileData = new ElfSectionFileData(aLogFile);
+ Elf32_Shdr shdr;
+ shdr.sh_name = 0; // for now.
+ shdr.sh_offset = 0; // for now
+ shdr.sh_info = 0;
+ shdr.sh_link = SHN_UNDEF;
+ shdr.sh_addr = 0;
+ shdr.sh_addralign = 0;
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_size = 0; // for now.
+ shdr.sh_flags = 0;
+ shdr.sh_entsize = 0;
+
+ ElfSection aLogFileSection(aLogFileData, "ROMLogFile", shdr);
+ iElfSectionManager.AddSection(aLogFileSection);
+
+}
+
+void ElfRom::SetupELFRomData() {
+ SetupProgramHeaderTable();
+ SetupAuxilarySections();
+ if (!iRomDetails->iStrip){
+ SetupSectionHeaderTable();
+ SetupSymbolTable();
+ if (!iRomDetails->iNoDwarf){
+ SetupDwarfSections();
+ }
+ }
+}
+
+void ElfRom::SetupSectionHeaderTable(){
+ RomDetails::XIPFileList::iterator aXIPFile = iRomDetails->iXIPFiles.begin();
+ RomDetails::XIPFileList::iterator end = iRomDetails->iXIPFiles.end();
+
+ if (iRomDetails->iTrace && aXIPFile != end){
+ cout << "\nAdding Section headers from associated ELF files\n";
+ }
+
+ while (aXIPFile != end) {
+ SetupSectionHeaders(*aXIPFile);
+ aXIPFile++;
+ }
+}
+
+void ElfRom::SetupSectionHeaders(XIPFileDetails & aXIPFileDetails) {
+ // Open ELF file
+ PathName aPath = aXIPFileDetails.iElfFile;
+
+ if (aPath.size() == 0) return;
+
+ int fd;
+ Elf * e;
+ size_t shstrndx;
+ bool hasSectionStringTable = true;
+
+
+ if ((fd = open(aPath.c_str(), O_RDONLY|O_BINARY, 0)) < 0){
+ warnx(EX_NOINPUT, "open \"%s\" failed\n", aPath.c_str());
+ goto finish;
+ }
+ if ((e = elf_begin(fd, ELF_C_READ , NULL)) == NULL)
+ errx(EX_SOFTWARE, "elf_begin() failed: %s.\n", elf_errmsg(-1));
+ if (elf_kind(e) != ELF_K_ELF)
+ errx(EX_SOFTWARE, "file not of kind ELF_K_ELF: %s.\n", aPath.c_str());
+ if (elf_getshstrndx(e, &shstrndx) == 0) {
+ hasSectionStringTable = false;
+ warnx(EX_SOFTWARE, "getshstrndx() failed for \"%s\"\n", aPath.c_str());
+ }
+ if (hasSectionStringTable){
+ SetUpSegmentInfo(aXIPFileDetails, e);
+ SetupSectionHeaders(aXIPFileDetails, e, shstrndx);
+ }
+
+ elf_end(e);
+ close(fd);
+finish:
+ return;
+}
+
+void ElfRom::SetupSectionHeaders(XIPFileDetails & aXIPFileDetails, Elf * e, size_t shstrndx){
+ // Iterate through sections looking for the ones we're after. Namely:
+ // text, data, bss/zi, symtab, strtable, and .debug*
+ Elf_Scn * scn = NULL;
+ Elf32_Shdr * shdr;
+ SectionNumberMap aSectionNumberMap;
+ SectionVaddrAddendMap aSectionVaddrAddendMap;
+
+ String aPath(aXIPFileDetails.iElfFile);
+
+ const char * debugName = ".debug";
+ const size_t debugNameLength = strlen(debugName);
+ const char * staticStrTab = ".strtab";
+
+ if (iRomDetails->iTrace){
+ cout << " " << aXIPFileDetails.iElfFile << "\n";
+ }
+
+ while ((scn = elf_nextscn(e, scn)) != NULL) {
+
+ if ((shdr = elf32_getshdr(scn)) == NULL)
+ errx(EX_SOFTWARE, "getshdr() failed: %s.\n", elf_errmsg(-1));
+
+ size_t aOldNdx = elf_ndxscn(scn);
+ char * name = elf_strptr(e, shstrndx, shdr->sh_name);
+ VirtualAddr sectionAddr = shdr->sh_addr;
+
+ switch (shdr->sh_type) {
+ case SHT_NOBITS:
+ // Check for BSS or ZI
+ if ((shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_ALLOC)) {
+ // set up section number mapping
+ size_t aNew = AddBssSectionHeader(aXIPFileDetails, shdr, name);
+ aSectionNumberMap.push_back(SectionNumberMapping(aOldNdx, aNew));
+ // set up address adjustment for relocation of e.g. symbols
+ int addend = aXIPFileDetails.iBSSAddr - sectionAddr;
+ aSectionVaddrAddendMap.push_back(SectionVaddrAddendMapping(aOldNdx, addend));
+ }
+ break;
+#define ARM_EXIDX (SHT_LOPROC + 1)
+ case ARM_EXIDX:
+ case SHT_PROGBITS:
+ // text/ro or data/rw will have SHF_ALLOC set
+ if (shdr->sh_flags & SHF_ALLOC) {
+ size_t aNew = 0;
+ int addend = 0;
+ if (shdr->sh_flags & SHF_WRITE) {
+ aNew = AddRwSectionHeader(aXIPFileDetails, shdr, name);
+ addend = aXIPFileDetails.iRWAddr - sectionAddr;
+ } else {
+ aNew = AddRoSectionHeader(aXIPFileDetails, shdr, name);
+ addend = aXIPFileDetails.iROAddr - sectionAddr;
+ }
+ // set up section number mapping
+ aSectionNumberMap.push_back(SectionNumberMapping(aOldNdx, aNew));
+ // set up address adjustment for relocation of e.g. symbols
+ aSectionVaddrAddendMap.push_back(SectionVaddrAddendMapping(aOldNdx, addend));
+ } else if (!iRomDetails->iNoDwarf && !strncmp(debugName, name, debugNameLength)) {
+ iDwarfFound = true;
+ iDwarfManager.AddSection(aXIPFileDetails, name, shdr);
+ }
+ break;
+ case SHT_SYMTAB:
+ iElfSymbolTableManager.AddSymbolTable(aPath, shdr->sh_offset, shdr->sh_size, shdr->sh_info);
+ break;
+ case SHT_STRTAB:
+ if (!strcmp(staticStrTab, name))
+ iElfSymbolTableManager.AddStringTable(aPath, shdr->sh_offset, shdr->sh_size);
+ break;
+ }
+ }
+ iElfSymbolTableManager.Finalize(aSectionNumberMap, aSectionVaddrAddendMap);
+}
+
+size_t ElfRom::AddRoSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){
+ size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfTextBase;
+ VirtualAddr vaddr = aXIPFileDetails.iROAddr + delta;
+ size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr;
+ size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom;
+ aShdr->sh_addr = vaddr;
+ return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf );
+}
+
+size_t ElfRom::AddRwSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){
+ size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfDataBase;
+ VirtualAddr vaddr = aXIPFileDetails.iROMDataAddr + delta;
+ size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr;
+ size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom;
+ aShdr->sh_addr = aXIPFileDetails.iRWAddr;
+ return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf);
+}
+
+size_t ElfRom::AddBssSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){
+ size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfDataBase;
+ VirtualAddr vaddr = aXIPFileDetails.iROMDataAddr + delta;
+ size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr;
+ size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom;
+ aShdr->sh_addr = aXIPFileDetails.iBSSAddr;
+ return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf);
+}
+
+size_t ElfRom::AddROMSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName, size_t aOffset){
+ ElfSectionData * romData = aOffset ?
+ (ElfSectionData *)new ElfSectionRomData(aOffset, aShdr->sh_size)
+ : (ElfSectionData *)new ElfSectionNoData();
+ ElfSection aSection(romData, aName, *aShdr);
+ iElfSectionManager.AddSection(aSection);
+
+ if (iRomDetails->iTrace){
+ cout.fill(' ');
+ cout << " " << left << setw(22) << aName << "\n";
+ cout.fill('0');
+ cout << " vaddr = 0x" << right << hex << setw(8) << aShdr->sh_addr << " offset = 0x"
+ << right << hex << setw(8) << aOffset
+ << " size = 0x" << right << hex << setw(8) << aShdr->sh_size << "\n";
+ }
+ return aSection.GetIndex();
+}
+
+void ElfRom::SetUpSegmentInfo(XIPFileDetails & aXIPFileDetails, Elf * e){
+ Elf32_Ehdr * ehdr = elf32_getehdr(e);
+ if (ehdr == NULL)
+ errx(EX_SOFTWARE, "elf32_getehdr() failed: %s.", elf_errmsg(-1));
+ size_t n = ehdr->e_phnum;
+ Elf32_Phdr * phdr = elf32_getphdr(e);
+ if (phdr == NULL)
+ errx(EX_SOFTWARE, "elf32_getphdr() failed: %s.", elf_errmsg(-1));
+
+ for (size_t i = 0; i < n; i++) {
+ if (phdr[i].p_flags & PF_X){
+ VirtualAddr segmentAddr = phdr[i].p_vaddr;
+ aXIPFileDetails.iElfTextBase = segmentAddr;
+ aXIPFileDetails.iElfTextLimit = segmentAddr + phdr[i].p_memsz;
+
+ } else if (phdr[i].p_flags & PF_W){
+ aXIPFileDetails.iElfDataBase = phdr[i].p_vaddr;
+ }
+ }
+}
+
+void ElfRom::SetupSymbolTable(){
+ iElfSymbolTableManager.AddSymbolTable();
+ if (iRomDetails->iTrace){
+ cout << "\nAdded section headers for combined symbol table and symbol string table\n";
+ }
+}
+
+void ElfRom::SetupDwarfSections(){
+ if (iRomDetails->iTrace && iDwarfFound){
+ cout << "\nSetting up Dwarf Sections\n";
+ } else if (iRomDetails->iTrace && !iDwarfFound && !iRomDetails->iNoDwarf){
+ cout << "\nWarning: No Dwarf information found\n";
+ return;
+ }
+ iDwarfManager.SetupSections();
+}
+
+void ElfRom::AddData() {
+ iElfSectionManager.AddData();
+ iElf32Header.SetSectionHdrOffset(iElfSectionManager.GetOffset());
+}
+
+void ElfRom::Dump(){
+ iOutputFile.Dump();
+ if (iRomDetails->iTrace){
+ cout << "\nWrote " << iRomDetails->iElfRomFile << " " << dec << iOutputFile.Size() << " bytes\n";
+ }
+}