]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/GHSSecInfo.cpp
Unified codebase for TX28, TX48, TX51, TX53
[karo-tx-uboot.git] / tools / elftosb / common / GHSSecInfo.cpp
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