|
20 | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | 21 | */ |
22 | 22 | #include "writer.h" |
23 | | -#include "runtime/helpers/string.h" |
24 | 23 | #include <cstring> |
25 | 24 |
|
26 | | -namespace CLElfLib { |
27 | | -/******************************************************************************\ |
28 | | - Constructor: CElfWriter::CElfWriter |
29 | | -\******************************************************************************/ |
30 | | -CElfWriter::CElfWriter( |
31 | | - E_EH_TYPE type, |
32 | | - E_EH_MACHINE machine, |
33 | | - Elf64_Xword flags) { |
34 | | - m_type = type; |
35 | | - m_machine = machine; |
36 | | - m_flags = flags; |
37 | | -} |
38 | | - |
39 | | -/******************************************************************************\ |
40 | | - Destructor: CElfWriter::~CElfWriter |
41 | | -\******************************************************************************/ |
42 | | -CElfWriter::~CElfWriter() { |
43 | | - SSectionNode *pNode = nullptr; |
44 | | - |
45 | | - // Walk through the section nodes |
46 | | - while (m_nodeQueue.empty() == false) { |
47 | | - pNode = m_nodeQueue.front(); |
48 | | - m_nodeQueue.pop(); |
49 | | - |
50 | | - // delete the node and it's data |
51 | | - if (pNode) { |
52 | | - if (pNode->pData) { |
53 | | - delete[] pNode->pData; |
54 | | - pNode->pData = nullptr; |
55 | | - } |
56 | | - |
57 | | - delete pNode; |
58 | | - pNode = nullptr; |
59 | | - } |
60 | | - } |
61 | | -} |
62 | | - |
63 | | -/******************************************************************************\ |
64 | | - Member Function: CElfWriter::Create |
65 | | -\******************************************************************************/ |
66 | | -CElfWriter *CElfWriter::create( |
67 | | - E_EH_TYPE type, |
68 | | - E_EH_MACHINE machine, |
69 | | - Elf64_Xword flags) { |
70 | | - CElfWriter *pWriter = new CElfWriter(type, machine, flags); |
71 | | - |
72 | | - if (!pWriter->initialize()) { |
73 | | - destroy(pWriter); |
74 | | - } |
75 | | - |
76 | | - return pWriter; |
77 | | -} |
78 | | - |
79 | | -/******************************************************************************\ |
80 | | - Member Function: CElfWriter::Delete |
81 | | -\******************************************************************************/ |
82 | | -void CElfWriter::destroy( |
83 | | - CElfWriter *&pWriter) { |
84 | | - if (pWriter) { |
85 | | - delete pWriter; |
86 | | - pWriter = nullptr; |
87 | | - } |
88 | | -} |
89 | | - |
90 | | -/******************************************************************************\ |
91 | | - Member Function: CElfWriter::AddSection |
92 | | -\******************************************************************************/ |
93 | | -bool CElfWriter::addSection( |
94 | | - SSectionNode *pSectionNode) { |
95 | | - bool retVal = true; |
96 | | - SSectionNode *pNode = nullptr; |
97 | | - size_t nameSize = 0; |
98 | | - unsigned int dataSize = 0; |
99 | | - |
100 | | - // The section header must be non-NULL |
101 | | - if (pSectionNode) { |
102 | | - pNode = new SSectionNode(); |
103 | | - if (!pNode) |
104 | | - return false; |
105 | | - } else { |
106 | | - return false; |
107 | | - } |
108 | | - |
109 | | - pNode->Flags = pSectionNode->Flags; |
110 | | - pNode->Type = pSectionNode->Type; |
111 | | - |
112 | | - nameSize = pSectionNode->Name.size() + 1; |
113 | | - dataSize = pSectionNode->DataSize; |
114 | | - |
115 | | - pNode->Name = pSectionNode->Name; |
116 | | - |
117 | | - // ok to have NULL data |
118 | | - if (dataSize > 0) { |
119 | | - pNode->pData = new char[dataSize]; |
120 | | - if (pNode->pData) { |
121 | | - memcpy_s(pNode->pData, dataSize, pSectionNode->pData, dataSize); |
122 | | - pNode->DataSize = dataSize; |
123 | | - } else { |
124 | | - retVal = false; |
125 | | - } |
126 | | - } |
127 | | - |
128 | | - if (retVal) { |
129 | | - // push the node onto the queue |
130 | | - m_nodeQueue.push(pNode); |
| 25 | +// Need for linux compatibility with memcpy_s |
| 26 | +#include "runtime/helpers/string.h" |
131 | 27 |
|
132 | | - // increment the sizes for each section |
133 | | - m_dataSize += dataSize; |
134 | | - m_stringTableSize += nameSize; |
135 | | - m_numSections++; |
136 | | - } else { |
137 | | - delete pNode; |
138 | | - pNode = nullptr; |
| 28 | +namespace CLElfLib { |
| 29 | +void CElfWriter::resolveBinary(ElfBinaryStorage &binary) { |
| 30 | + SElf64SectionHeader *curSectionHeader = nullptr; |
| 31 | + char *data = nullptr; |
| 32 | + char *stringTable = nullptr; |
| 33 | + char *curString = nullptr; |
| 34 | + |
| 35 | + if (binary.size() < getTotalBinarySize()) { |
| 36 | + binary.resize(getTotalBinarySize()); |
139 | 37 | } |
140 | 38 |
|
141 | | - return retVal; |
142 | | -} |
143 | | - |
144 | | -/******************************************************************************\ |
145 | | - Member Function: CElfWriter::ResolveBinary |
146 | | -\******************************************************************************/ |
147 | | -bool CElfWriter::resolveBinary( |
148 | | - char *const pBinary, |
149 | | - size_t &binarySize) { |
150 | | - bool retVal = true; |
151 | | - SSectionNode *pNode = nullptr; |
152 | | - SElf64SectionHeader *pCurSectionHeader = nullptr; |
153 | | - char *pData = nullptr; |
154 | | - char *pStringTable = nullptr; |
155 | | - char *pCurString = nullptr; |
156 | | - |
157 | | - m_totalBinarySize = |
158 | | - sizeof(SElf64Header) + |
159 | | - ((m_numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry |
160 | | - m_dataSize + |
161 | | - m_stringTableSize; |
162 | | - |
163 | | - if (pBinary) { |
164 | | - // get a pointer to the first section header |
165 | | - pCurSectionHeader = reinterpret_cast<SElf64SectionHeader *>(pBinary + sizeof(SElf64Header)); |
166 | | - |
167 | | - // get a pointer to the data |
168 | | - pData = pBinary + |
169 | | - sizeof(SElf64Header) + |
170 | | - ((m_numSections + 1) * sizeof(SElf64SectionHeader)); // +1 to account for string table entry |
171 | | - |
172 | | - // get a pointer to the string table |
173 | | - pStringTable = pBinary + sizeof(SElf64Header) + |
174 | | - ((m_numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry |
175 | | - m_dataSize; |
176 | | - |
177 | | - pCurString = pStringTable; |
178 | | - |
179 | | - // Walk through the section nodes |
180 | | - while (m_nodeQueue.empty() == false) { |
181 | | - pNode = m_nodeQueue.front(); |
182 | | - |
183 | | - if (pNode) { |
184 | | - m_nodeQueue.pop(); |
| 39 | + // get a pointer to the first section header |
| 40 | + curSectionHeader = reinterpret_cast<SElf64SectionHeader *>(binary.data() + sizeof(SElf64Header)); |
185 | 41 |
|
186 | | - // Copy data into the section header |
187 | | - memset(pCurSectionHeader, 0, sizeof(SElf64SectionHeader)); |
188 | | - pCurSectionHeader->Type = pNode->Type; |
189 | | - pCurSectionHeader->Flags = pNode->Flags; |
190 | | - pCurSectionHeader->DataSize = pNode->DataSize; |
191 | | - pCurSectionHeader->DataOffset = pData - pBinary; |
192 | | - pCurSectionHeader->Name = static_cast<Elf64_Word>(pCurString - pStringTable); |
193 | | - pCurSectionHeader = reinterpret_cast<SElf64SectionHeader *>(reinterpret_cast<unsigned char *>(pCurSectionHeader) + sizeof(SElf64SectionHeader)); |
| 42 | + // get a pointer to the data |
| 43 | + data = binary.data() + |
| 44 | + sizeof(SElf64Header) + |
| 45 | + ((numSections + 1) * sizeof(SElf64SectionHeader)); // +1 to account for string table entry |
194 | 46 |
|
195 | | - // copy the data, move the data pointer |
196 | | - memcpy_s(pData, pNode->DataSize, pNode->pData, pNode->DataSize); |
197 | | - pData += pNode->DataSize; |
| 47 | + // get a pointer to the string table |
| 48 | + stringTable = binary.data() + sizeof(SElf64Header) + |
| 49 | + ((numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry |
| 50 | + dataSize; |
198 | 51 |
|
199 | | - // copy the name into the string table, move the string pointer |
200 | | - if (pNode->Name.size() > 0) { |
201 | | - memcpy_s(pCurString, pNode->Name.size(), pNode->Name.c_str(), pNode->Name.size()); |
202 | | - pCurString += pNode->Name.size(); |
203 | | - } |
204 | | - *(pCurString++) = '\0'; // NOLINT |
| 52 | + curString = stringTable; |
205 | 53 |
|
206 | | - // delete the node and it's data |
207 | | - if (pNode->pData) { |
208 | | - delete[] pNode->pData; |
209 | | - pNode->pData = nullptr; |
210 | | - } |
211 | | - |
212 | | - delete pNode; |
213 | | - pNode = nullptr; |
214 | | - } |
| 54 | + // Walk through the section nodes |
| 55 | + while (nodeQueue.empty() == false) { |
| 56 | + // Copy data into the section header |
| 57 | + const auto &queueFront = nodeQueue.front(); |
| 58 | + |
| 59 | + curSectionHeader->Type = queueFront.type; |
| 60 | + curSectionHeader->Flags = queueFront.flag; |
| 61 | + curSectionHeader->DataSize = queueFront.dataSize; |
| 62 | + curSectionHeader->DataOffset = data - binary.data(); |
| 63 | + curSectionHeader->Name = static_cast<Elf64_Word>(curString - stringTable); |
| 64 | + curSectionHeader = reinterpret_cast<SElf64SectionHeader *>(reinterpret_cast<unsigned char *>(curSectionHeader) + sizeof(SElf64SectionHeader)); |
| 65 | + |
| 66 | + // copy the data, move the data pointer |
| 67 | + memcpy_s(data, queueFront.dataSize, queueFront.data.c_str(), queueFront.dataSize); |
| 68 | + data += queueFront.dataSize; |
| 69 | + |
| 70 | + // copy the name into the string table, move the string pointer |
| 71 | + if (queueFront.name.size() > 0) { |
| 72 | + memcpy_s(curString, queueFront.name.size(), queueFront.name.c_str(), queueFront.name.size()); |
| 73 | + curString += queueFront.name.size(); |
215 | 74 | } |
| 75 | + *(curString++) = '\0'; // NOLINT |
216 | 76 |
|
217 | | - // add the string table section header |
218 | | - SElf64SectionHeader stringSectionHeader = {0}; |
219 | | - stringSectionHeader.Type = E_SH_TYPE::SH_TYPE_STR_TBL; |
220 | | - stringSectionHeader.Flags = E_SH_FLAG::SH_FLAG_NONE; |
221 | | - stringSectionHeader.DataOffset = pStringTable - pBinary; |
222 | | - stringSectionHeader.DataSize = m_stringTableSize; |
223 | | - stringSectionHeader.Name = 0; |
224 | | - |
225 | | - // Copy into the last section header |
226 | | - memcpy_s(pCurSectionHeader, sizeof(SElf64SectionHeader), |
227 | | - &stringSectionHeader, sizeof(SElf64SectionHeader)); |
228 | | - |
229 | | - // Add to our section number |
230 | | - m_numSections++; |
231 | | - |
232 | | - // patch up the ELF header |
233 | | - retVal = patchElfHeader(pBinary); |
| 77 | + nodeQueue.pop(); |
234 | 78 | } |
235 | 79 |
|
236 | | - if (retVal) { |
237 | | - binarySize = m_totalBinarySize; |
238 | | - } |
| 80 | + // add the string table section header |
| 81 | + SElf64SectionHeader stringSectionHeader = {0}; |
| 82 | + stringSectionHeader.Type = E_SH_TYPE::SH_TYPE_STR_TBL; |
| 83 | + stringSectionHeader.Flags = E_SH_FLAG::SH_FLAG_NONE; |
| 84 | + stringSectionHeader.DataOffset = stringTable - &binary[0]; |
| 85 | + stringSectionHeader.DataSize = stringTableSize; |
| 86 | + stringSectionHeader.Name = 0; |
239 | 87 |
|
240 | | - return retVal; |
241 | | -} |
| 88 | + // Copy into the last section header |
| 89 | + memcpy_s(curSectionHeader, sizeof(SElf64SectionHeader), |
| 90 | + &stringSectionHeader, sizeof(SElf64SectionHeader)); |
242 | 91 |
|
243 | | -/******************************************************************************\ |
244 | | - Member Function: CElfWriter::Initialize |
245 | | -\******************************************************************************/ |
246 | | -bool CElfWriter::initialize() { |
247 | | - SSectionNode emptySection; |
| 92 | + // Add to our section number |
| 93 | + numSections++; |
248 | 94 |
|
249 | | - // Add an empty section 0 (points to "no-bits") |
250 | | - return addSection(&emptySection); |
| 95 | + // patch up the ELF header |
| 96 | + patchElfHeader(*reinterpret_cast<SElf64Header *>(binary.data())); |
251 | 97 | } |
252 | 98 |
|
253 | | -/******************************************************************************\ |
254 | | - Member Function: CElfWriter::PatchElfHeader |
255 | | -\******************************************************************************/ |
256 | | -bool CElfWriter::patchElfHeader(char *const pBinary) { |
257 | | - SElf64Header *pElfHeader = reinterpret_cast<SElf64Header *>(pBinary); |
258 | | - |
259 | | - if (pElfHeader) { |
260 | | - // Setup the identity |
261 | | - memset(pElfHeader, 0x00, sizeof(SElf64Header)); |
262 | | - pElfHeader->Identity[ELFConstants::idIdxMagic0] = ELFConstants::elfMag0; |
263 | | - pElfHeader->Identity[ELFConstants::idIdxMagic1] = ELFConstants::elfMag1; |
264 | | - pElfHeader->Identity[ELFConstants::idIdxMagic2] = ELFConstants::elfMag2; |
265 | | - pElfHeader->Identity[ELFConstants::idIdxMagic3] = ELFConstants::elfMag3; |
266 | | - pElfHeader->Identity[ELFConstants::idIdxClass] = static_cast<uint32_t>(E_EH_CLASS::EH_CLASS_64); |
267 | | - pElfHeader->Identity[ELFConstants::idIdxVersion] = static_cast<uint32_t>(E_EHT_VERSION::EH_VERSION_CURRENT); |
268 | | - |
269 | | - // Add other non-zero info |
270 | | - pElfHeader->Type = m_type; |
271 | | - pElfHeader->Machine = m_machine; |
272 | | - pElfHeader->Flags = static_cast<uint32_t>(m_flags); |
273 | | - pElfHeader->ElfHeaderSize = static_cast<uint32_t>(sizeof(SElf64Header)); |
274 | | - pElfHeader->SectionHeaderEntrySize = static_cast<uint32_t>(sizeof(SElf64SectionHeader)); |
275 | | - pElfHeader->NumSectionHeaderEntries = m_numSections; |
276 | | - pElfHeader->SectionHeadersOffset = static_cast<uint32_t>(sizeof(SElf64Header)); |
277 | | - pElfHeader->SectionNameTableIndex = m_numSections - 1; // last index |
278 | | - |
279 | | - return true; |
280 | | - } |
281 | | - |
282 | | - return false; |
| 99 | +void CElfWriter::patchElfHeader(SElf64Header &binary) { |
| 100 | + // Setup the identity |
| 101 | + binary.Identity[ELFConstants::idIdxMagic0] = ELFConstants::elfMag0; |
| 102 | + binary.Identity[ELFConstants::idIdxMagic1] = ELFConstants::elfMag1; |
| 103 | + binary.Identity[ELFConstants::idIdxMagic2] = ELFConstants::elfMag2; |
| 104 | + binary.Identity[ELFConstants::idIdxMagic3] = ELFConstants::elfMag3; |
| 105 | + binary.Identity[ELFConstants::idIdxClass] = static_cast<uint32_t>(E_EH_CLASS::EH_CLASS_64); |
| 106 | + binary.Identity[ELFConstants::idIdxVersion] = static_cast<uint32_t>(E_EHT_VERSION::EH_VERSION_CURRENT); |
| 107 | + |
| 108 | + // Add other non-zero info |
| 109 | + binary.Type = type; |
| 110 | + binary.Machine = machine; |
| 111 | + binary.Flags = static_cast<uint32_t>(flag); |
| 112 | + binary.ElfHeaderSize = static_cast<uint32_t>(sizeof(SElf64Header)); |
| 113 | + binary.SectionHeaderEntrySize = static_cast<uint32_t>(sizeof(SElf64SectionHeader)); |
| 114 | + binary.NumSectionHeaderEntries = numSections; |
| 115 | + binary.SectionHeadersOffset = static_cast<uint32_t>(sizeof(SElf64Header)); |
| 116 | + binary.SectionNameTableIndex = numSections - 1; // last index |
283 | 117 | } |
284 | | - |
285 | 118 | } // namespace CLElfLib |
0 commit comments