1 /* 2 * File: GHSSecInfo.cpp 3 * 4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 * See included license file for license details. 6 */ 7 8 #include "GHSSecInfo.h" 9 #include <stdexcept> 10 #include "Logging.h" 11 #include "EndianUtilities.h" 12 13 //! The name of the GHS-specific section info table ELF section. 14 const char * const kSecInfoSectionName = ".secinfo"; 15 16 using namespace elftosb; 17 18 //! The ELF file passed into this constructor as the \a elf argument must remain 19 //! valid for the life of this object. 20 //! 21 //! \param elf The ELF file parser. An assertion is raised if this is NULL. 22 GHSSecInfo::GHSSecInfo(StELFFile * elf) 23 : m_elf(elf), m_hasInfo(false), m_info(0), m_entryCount(0) 24 { 25 assert(elf); 26 27 // look up the section. if it's not there just leave m_info and m_entryCount to 0 28 unsigned sectionIndex = m_elf->getIndexOfSectionWithName(kSecInfoSectionName); 29 if (sectionIndex == SHN_UNDEF) 30 { 31 return; 32 } 33 34 // get the section data 35 const Elf32_Shdr & secInfo = m_elf->getSectionAtIndex(sectionIndex); 36 if (secInfo.sh_type != SHT_PROGBITS) 37 { 38 // .secinfo section isn't the right type, so something is wrong 39 return; 40 } 41 42 m_hasInfo = true; 43 m_info = (ghs_secinfo_t *)m_elf->getSectionDataAtIndex(sectionIndex); 44 m_entryCount = secInfo.sh_size / sizeof(ghs_secinfo_t); 45 } 46 47 //! Looks up \a addr for \a length in the .secinfo array. Only if that address is in the 48 //! .secinfo array does this section need to be filled. If the section is found but the 49 //! length does not match the \a length argument, a message is logged at the 50 //! #Logger::WARNING level. 51 //! 52 //! If the .secinfo section is not present in the ELF file, this method always returns 53 //! true. 54 //! 55 //! \param addr The start address of the section to query. 56 //! \param length The length of the section. If a section with a start address matching 57 //! \a addr is found, its length must match \a length to be considered. 58 //! 59 //! \retval true The section matching \a addr and \a length was found and should be filled. 60 //! True is also returned when the ELF file does not have a .secinfo section. 61 //! \retval false The section was not found and should not be filled. 62 bool GHSSecInfo::isSectionFilled(uint32_t addr, uint32_t length) 63 { 64 if (!m_hasInfo) 65 { 66 return true; 67 } 68 69 unsigned i; 70 for (i = 0; i < m_entryCount; ++i) 71 { 72 // byte swap these values into host endianness 73 uint32_t clearAddr = ENDIAN_LITTLE_TO_HOST_U32(m_info[i].m_clearAddr); 74 uint32_t numBytesToClear = ENDIAN_LITTLE_TO_HOST_U32(m_info[i].m_numBytesToClear); 75 76 // we only consider non-zero length clear regions 77 if ((addr == clearAddr) && (numBytesToClear != 0)) 78 { 79 // it is an error if the address matches but the length does not 80 if (length != numBytesToClear) 81 { 82 Log::log(Logger::WARNING, "ELF Error: Size mismatch @ sect=%u, .secinfo=%u at addr 0x%08X\n", length, numBytesToClear, addr); 83 } 84 return true; 85 } 86 } 87 88 return false; 89 } 90 91 //! Simply calls through to isSectionFilled(uint32_t, uint32_t) to determine 92 //! if \a section should be filled. 93 //! 94 //! If the .secinfo section is not present in the ELF file, this method always returns 95 //! true. 96 bool GHSSecInfo::isSectionFilled(const Elf32_Shdr & section) 97 { 98 return isSectionFilled(section.sh_addr, section.sh_size); 99 } 100 101