20 #include "pedigree/kernel/linker/Elf.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/linker/KernelElf.h" 23 #include "pedigree/kernel/process/Process.h" 24 #include "pedigree/kernel/process/Thread.h" 25 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 26 #include "pedigree/kernel/processor/Processor.h" 27 #include "pedigree/kernel/processor/ProcessorInformation.h" 28 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 29 #include "pedigree/kernel/utilities/Iterator.h" 30 #include "pedigree/kernel/utilities/MemoryAllocator.h" 31 #include "pedigree/kernel/utilities/assert.h" 32 #include "pedigree/kernel/utilities/utility.h" 34 #define TRACK_HIDDEN_SYMBOLS 1 36 static void resolveNeeded()
38 FATAL(
"ELF: resolveNeeded() called but binary should have been fully " 45 static T *copy(T *buff,
size_t numBytes)
47 T *ret =
new T[numBytes /
sizeof(T)];
48 MemoryCopy(ret, buff, numBytes);
57 size_t nProgramHeaders, T *pCurrent,
size_t size)
59 for (
size_t i = 0; i < nProgramHeaders; i++)
62 if ((ph.vaddr <= reinterpret_cast<uintptr_t>(pCurrent)) &&
63 (reinterpret_cast<uintptr_t>(pCurrent) < ph.vaddr + ph.filesz))
65 uintptr_t loc =
reinterpret_cast<uintptr_t
>(pCurrent) - ph.vaddr;
66 pCurrent =
new T[size /
sizeof(T)];
68 reinterpret_cast<uint8_t *>(pCurrent), &pBuffer[loc], size);
76 : m_pSymbolTable(0), m_nSymbolTableSize(0), m_pStringTable(0),
77 m_nStringTableSize(0), m_pShstrtab(0), m_nShstrtabSize(0), m_pGotTable(0),
78 m_pRelTable(0), m_pRelaTable(0), m_nRelTableSize(0), m_nRelaTableSize(0),
79 m_pPltRelTable(0), m_pPltRelaTable(0), m_bUsesRela(false),
80 m_pDebugTable(0), m_nDebugTableSize(0), m_pDynamicSymbolTable(0),
81 m_nDynamicSymbolTableSize(0), m_pDynamicStringTable(0),
82 m_nDynamicStringTableSize(0), m_pSectionHeaders(0), m_nSectionHeaders(0),
83 m_pProgramHeaders(0), m_nProgramHeaders(0), m_nPltSize(0), m_nEntry(0),
84 m_NeededLibraries(), m_SymbolTable(this), m_InitFunc(0), m_FiniFunc(0)
90 delete[] m_pSymbolTable;
91 delete[] m_pStringTable;
95 delete[] m_pRelaTable;
96 delete[] m_pPltRelTable;
97 delete[] m_pPltRelaTable;
98 delete[] m_pDebugTable;
99 delete[] m_pDynamicSymbolTable;
100 delete[] m_pDynamicStringTable;
101 delete[] m_pSectionHeaders;
102 delete[] m_pProgramHeaders;
106 : m_pSymbolTable(0), m_nSymbolTableSize(elf.m_nSymbolTableSize),
107 m_pStringTable(), m_nStringTableSize(elf.m_nStringTableSize),
108 m_pShstrtab(0), m_nShstrtabSize(elf.m_nShstrtabSize),
109 m_pGotTable(elf.m_pGotTable), m_pRelTable(0), m_pRelaTable(0),
110 m_nRelTableSize(elf.m_nRelTableSize),
111 m_nRelaTableSize(elf.m_nRelaTableSize), m_pPltRelTable(0),
112 m_pPltRelaTable(0), m_bUsesRela(elf.m_bUsesRela), m_pDebugTable(0),
113 m_nDebugTableSize(elf.m_nDebugTableSize), m_pDynamicSymbolTable(0),
114 m_nDynamicSymbolTableSize(elf.m_nDynamicSymbolTableSize),
115 m_pDynamicStringTable(0),
116 m_nDynamicStringTableSize(elf.m_nDynamicStringTableSize),
117 m_pSectionHeaders(0), m_nSectionHeaders(elf.m_nSectionHeaders),
118 m_pProgramHeaders(0), m_nProgramHeaders(elf.m_nProgramHeaders),
119 m_nPltSize(elf.m_nPltSize), m_nEntry(elf.m_nEntry),
120 m_NeededLibraries(elf.m_NeededLibraries), m_SymbolTable(this),
121 m_InitFunc(elf.m_InitFunc), m_FiniFunc(elf.m_FiniFunc)
124 m_pSymbolTable = copy(elf.m_pSymbolTable, m_nSymbolTableSize);
127 m_pStringTable = copy(elf.m_pStringTable, m_nStringTableSize);
130 m_pShstrtab = copy(elf.m_pShstrtab, m_nShstrtabSize);
133 m_pRelTable = copy(elf.m_pRelTable, m_nRelTableSize);
134 m_pRelaTable = copy(elf.m_pRelaTable, m_nRelaTableSize);
138 m_pPltRelaTable = copy(elf.m_pPltRelaTable, m_nPltSize);
140 m_pPltRelTable = copy(elf.m_pPltRelTable, m_nPltSize);
143 m_pDebugTable = copy(elf.m_pDebugTable, m_nDebugTableSize);
146 m_pDynamicSymbolTable =
147 copy(elf.m_pDynamicSymbolTable, m_nDynamicSymbolTableSize);
150 m_pDynamicStringTable =
151 copy(elf.m_pDynamicStringTable, m_nDynamicStringTableSize);
154 m_pSectionHeaders = copy(
158 m_pProgramHeaders = copy(
162 intptr_t diff =
reinterpret_cast<uintptr_t
>(m_pDynamicStringTable) -
163 reinterpret_cast<uintptr_t>(elf.m_pDynamicStringTable);
165 it != m_NeededLibraries.
end(); it++)
171 m_SymbolTable.
copyTable(
this, elf.m_SymbolTable);
176 #ifdef VERBOSE_KERNEL 178 "Elf::createNeededOnly: buffer at " 179 <<
Hex << reinterpret_cast<uintptr_t>(pBuffer) <<
", len " << length);
181 if (!pBuffer || !length)
188 if ((pHeader->ident[1] !=
'E') || (pHeader->ident[2] !=
'L') ||
189 (pHeader->ident[3] !=
'F') || (pHeader->ident[0] != 127))
192 "ELF file: ident check failed [" 193 <<
String(reinterpret_cast<const char *>(pHeader->ident)) <<
"]!");
198 if (pHeader->ident[4] !=
206 ERROR(
"ELF file: wrong bit length!");
210 if (pHeader->phnum > 0)
212 m_nProgramHeaders = pHeader->phnum;
215 reinterpret_cast<uint8_t *>(m_pProgramHeaders),
216 &pBuffer[pHeader->phoff],
219 size_t nDynamicStringTableSize = 0;
222 for (
size_t i = 0; i < m_nProgramHeaders; i++)
224 if (m_pProgramHeaders[i].type == PT_DYNAMIC)
228 reinterpret_cast<ElfDyn_t *
>(&pBuffer[pDynamic->offset]);
231 while (pDyn->tag != DT_NULL)
237 reinterpret_cast<char *>(pDyn->un.ptr));
240 m_pDynamicStringTable =
241 reinterpret_cast<char *
>(pDyn->un.ptr);
244 nDynamicStringTableSize = pDyn->un.val;
251 else if (m_pProgramHeaders[i].type == PT_INTERP)
255 String(reinterpret_cast<char *>(&pBuffer[pInterp->offset]));
257 #ifdef VERBOSE_KERNEL 259 "ELF::createNeededOnly interpreter is " << m_sInterpreter);
264 if (m_pDynamicStringTable)
266 m_pDynamicStringTable =
elfCopy(
267 pBuffer, m_pProgramHeaders, m_nProgramHeaders,
268 m_pDynamicStringTable, nDynamicStringTableSize);
273 it != m_NeededLibraries.
end(); it++)
275 *it = *it +
reinterpret_cast<uintptr_t
>(m_pDynamicStringTable);
293 if ((pHeader->ident[1] !=
'E') || (pHeader->ident[2] !=
'L') ||
294 (pHeader->ident[3] !=
'F') || (pHeader->ident[0] != 127))
299 if (pHeader->ident[4] !=
316 "Elf::create: buffer at " <<
Hex << reinterpret_cast<uintptr_t>(pBuffer)
317 <<
", len " << length);
322 if ((pHeader->ident[1] !=
'E') || (pHeader->ident[2] !=
'L') ||
323 (pHeader->ident[3] !=
'F') || (pHeader->ident[0] != 127))
326 "ELF file: ident check failed [" 327 <<
String(reinterpret_cast<const char *>(pHeader->ident)) <<
"]!");
332 if (pHeader->ident[4] !=
340 ERROR(
"ELF file: wrong bit length!");
344 m_nSectionHeaders = pHeader->shnum;
347 reinterpret_cast<uint8_t *>(m_pSectionHeaders),
354 m_nShstrtabSize = pShstrtab->size;
355 m_pShstrtab =
new char[m_nShstrtabSize];
357 reinterpret_cast<uint8_t *>(m_pShstrtab), &pBuffer[pShstrtab->offset],
362 for (
int i = 0; i < pHeader->shnum; i++)
364 const char *pStr = m_pShstrtab + m_pSectionHeaders[i].name;
365 if (!StringCompare(pStr,
".symtab"))
366 pSymbolTable = &m_pSectionHeaders[i];
367 if (!StringCompare(pStr,
".strtab"))
368 pStringTable = &m_pSectionHeaders[i];
371 if (pSymbolTable == 0)
373 WARNING(
"ELF: symbol table not found!");
377 m_nSymbolTableSize = pSymbolTable->size;
381 reinterpret_cast<uint8_t *>(m_pSymbolTable),
382 &pBuffer[pSymbolTable->offset], pSymbolTable->size);
385 if (pStringTable == 0)
387 WARNING(
"ELF: string table not found!");
391 m_nStringTableSize = pStringTable->size;
392 m_pStringTable =
new char[m_nStringTableSize];
394 reinterpret_cast<uint8_t *>(m_pStringTable),
395 &pBuffer[pStringTable->offset], m_nStringTableSize);
399 if (pHeader->phnum > 0)
401 m_nProgramHeaders = pHeader->phnum;
404 reinterpret_cast<uint8_t *>(m_pProgramHeaders),
405 &pBuffer[pHeader->phoff],
411 for (
size_t i = 0; i < m_nProgramHeaders; i++)
413 if (m_pProgramHeaders[i].type == PT_DYNAMIC)
417 reinterpret_cast<ElfDyn_t *
>(&pBuffer[pDynamic->offset]);
420 while (pDyn->tag != DT_NULL)
426 reinterpret_cast<char *>(pDyn->un.ptr));
429 m_pDynamicSymbolTable =
433 m_pDynamicStringTable =
434 reinterpret_cast<char *
>(pDyn->un.ptr);
442 m_nDynamicStringTableSize = pDyn->un.val;
446 reinterpret_cast<ElfRela_t *
>(pDyn->un.ptr);
450 reinterpret_cast<ElfRel_t *
>(pDyn->un.ptr);
453 m_nRelTableSize = pDyn->un.val;
456 m_nRelaTableSize = pDyn->un.val;
460 reinterpret_cast<uintptr_t *
>(pDyn->un.ptr);
466 reinterpret_cast<ElfRela_t *
>(pDyn->un.ptr);
469 reinterpret_cast<ElfRel_t *
>(pDyn->un.ptr);
474 if (pDyn->un.val == DT_RELA)
481 m_nPltSize = pDyn->un.val;
484 m_InitFunc = pDyn->un.val;
487 m_FiniFunc = pDyn->un.val;
494 else if (m_pProgramHeaders[i].type == PT_INTERP)
498 String(reinterpret_cast<char *>(&pBuffer[pInterp->offset]));
500 NOTICE(
"ELF::create interpreter is " << m_sInterpreter);
504 m_nDynamicSymbolTableSize =
505 reinterpret_cast<uintptr_t
>(m_pDynamicStringTable) -
506 reinterpret_cast<uintptr_t>(m_pDynamicSymbolTable);
510 if (m_pDynamicSymbolTable)
511 m_pDynamicSymbolTable =
elfCopy(
512 pBuffer, m_pProgramHeaders, m_nProgramHeaders,
513 m_pDynamicSymbolTable, m_nDynamicSymbolTableSize);
514 if (m_pDynamicStringTable)
516 m_pDynamicStringTable =
elfCopy(
517 pBuffer, m_pProgramHeaders, m_nProgramHeaders,
518 m_pDynamicStringTable, m_nDynamicStringTableSize);
523 it != m_NeededLibraries.
end(); it++)
525 *it = *it +
reinterpret_cast<uintptr_t
>(m_pDynamicStringTable);
530 pBuffer, m_pProgramHeaders, m_nProgramHeaders, m_pRelTable,
534 pBuffer, m_pProgramHeaders, m_nProgramHeaders, m_pRelaTable,
538 pBuffer, m_pProgramHeaders, m_nProgramHeaders, m_pPltRelTable,
542 pBuffer, m_pProgramHeaders, m_nProgramHeaders, m_pPltRelaTable,
546 m_nEntry = pHeader->entry;
553 uint8_t *pBuffer,
size_t length, uintptr_t &loadBase,
size_t &loadSize,
562 for (
size_t i = 0; i < m_nProgramHeaders; ++i)
564 if (m_pProgramHeaders[i].type == PT_LOAD)
566 loadSize += m_pProgramHeaders[i].vaddr + m_pProgramHeaders[i].memsz;
569 if (loadSize & pageSzMask)
571 loadSize = (loadSize & ~pageSzMask) + pageSz;
574 NOTICE(
"ELF: need " << loadSize <<
" bytes!");
580 "ELF: could not allocate space for this module [loadSize=" 585 m_LoadBase = loadBase;
587 for (
size_t i = 0; i < m_nProgramHeaders; ++i)
589 if (m_pProgramHeaders[i].type == PT_LOAD)
591 m_pProgramHeaders[i].vaddr += loadBase;
592 uintptr_t baseAddr = m_pProgramHeaders[i].vaddr;
593 uintptr_t loadEnd = baseAddr + m_pProgramHeaders[i].memsz;
594 if (loadEnd & pageSzMask)
596 loadEnd = (loadEnd & ~pageSzMask) + pageSz;
599 for (uintptr_t addr = baseAddr; addr < loadEnd; addr += pageSz)
601 void *virt =
reinterpret_cast<void *
>(addr);
604 physical_uintptr_t phys =
616 reinterpret_cast<void *>(baseAddr),
617 pBuffer + m_pProgramHeaders[i].offset,
618 m_pProgramHeaders[i].filesz);
619 if (m_pProgramHeaders[i].memsz > m_pProgramHeaders[i].filesz)
622 reinterpret_cast<void *>(
623 baseAddr + m_pProgramHeaders[i].filesz),
625 m_pProgramHeaders[i].memsz - m_pProgramHeaders[i].filesz);
631 for (
size_t i = 0; i < m_nSectionHeaders; i++)
634 if (m_pSectionHeaders[i].flags & SHF_ALLOC)
636 m_pSectionHeaders[i].addr += loadBase;
639 if ((m_pSectionHeaders[i].flags & SHF_ALLOC) == 0)
642 const char *pStr = m_pShstrtab + m_pSectionHeaders[i].name;
643 if (!StringCompare(pStr,
".debug_frame"))
646 reinterpret_cast<uint32_t *
>(m_pSectionHeaders[i].addr);
647 uintptr_t *debugTablePointers =
648 reinterpret_cast<uintptr_t *
>(m_pSectionHeaders[i].addr);
649 m_nDebugTableSize = m_pSectionHeaders[i].size;
655 while (nIndex < m_nDebugTableSize)
658 assert(!(nIndex %
sizeof(uint32_t)));
659 uint32_t nLength = m_pDebugTable[nIndex /
sizeof(uint32_t)];
661 nIndex +=
sizeof(uint32_t);
663 const uint32_t k_nCieId = 0xFFFFFFFF;
665 if (nLength == 0xFFFFFFFF)
667 ERROR(
"64-bit DWARF file detected, but not supported!");
673 uint32_t nCie = m_pDebugTable[nIndex /
sizeof(uint32_t)];
674 nIndex +=
sizeof(uint32_t);
677 if (nCie == k_nCieId)
680 nIndex += nLength -
sizeof(processor_register_t);
685 assert(!(nIndex %
sizeof(uintptr_t)));
686 uintptr_t *nInitialLocation =
687 &debugTablePointers[nIndex /
sizeof(uintptr_t)];
688 *nInitialLocation += loadBase;
690 nIndex += nLength -
sizeof(processor_register_t);
701 if (m_pSymbolTable && m_pStringTable)
705 const char *pStrtab =
reinterpret_cast<const char *
>(m_pStringTable);
707 for (
size_t i = 0; i < m_nSymbolTableSize /
sizeof(
ElfSymbol_t); i++)
711 if (ST_TYPE(pSymbol->info) == STT_SECTION)
718 if (!(pSh->flags & SHF_ALLOC))
724 pStr =
reinterpret_cast<const char *
>(m_pShstrtab) + pSh->name;
727 pStr = pStrtab + pSymbol->name;
731 switch (ST_BIND(pSymbol->info))
734 binding = SymbolTable::Local;
737 binding = SymbolTable::Global;
740 binding = SymbolTable::Weak;
743 binding = SymbolTable::Global;
748 if (ST_TYPEOK(pSymbol->info))
752 if (*pStr !=
'\0' && pSymbol->shndx != 0)
756 name, binding,
this, pSymbol->value + loadBase);
757 #ifndef TRACK_HIDDEN_SYMBOLS 758 if (pSymbol->other != STV_HIDDEN)
763 name, binding,
this, pSymbol->value + loadBase);
771 if (pSymbolTableCopy)
777 if (!relocateModinfo(pBuffer, length))
779 ERROR(
"Failed to relocate modinfo!");
786 m_pGotTable[2] =
reinterpret_cast<uintptr_t
>(resolveNeeded);
794 bool bRelocate = relocate(pBuffer, length);
804 for (
size_t i = 0; i < m_nProgramHeaders; ++i)
806 if (m_pProgramHeaders[i].type == PT_LOAD)
808 uintptr_t baseAddr = m_pProgramHeaders[i].vaddr;
809 uintptr_t loadEnd = baseAddr + m_pProgramHeaders[i].memsz;
810 if (loadEnd & pageSzMask)
812 loadEnd = (loadEnd & ~pageSzMask) + pageSz;
817 if (m_pProgramHeaders[i].flags & PF_X)
821 if (m_pProgramHeaders[i].flags & PF_W)
826 for (uintptr_t addr = baseAddr; addr < loadEnd; addr += pageSz)
828 void *virt =
reinterpret_cast<void *
>(addr);
838 uint8_t *pBuffer,
size_t length, uintptr_t &loadBase,
SymbolTable *pSymtab,
839 bool bAllocate,
size_t *pSize)
843 "Elf::allocate: buffer at " 844 <<
Hex << reinterpret_cast<uintptr_t>(pBuffer) <<
", len " << length);
851 uintptr_t start = ~0;
852 for (
size_t i = 0; i < m_nProgramHeaders; i++)
854 if (m_pProgramHeaders[i].type == PT_LOAD)
856 size = m_pProgramHeaders[i].vaddr + m_pProgramHeaders[i].memsz;
857 if (m_pProgramHeaders[i].vaddr < start)
858 start = m_pProgramHeaders[i].vaddr;
866 *pSize = (size + 0x1000) & 0xFFFFF000;
871 if (m_nEntry < 0x100000)
874 (size + 0x1000) & 0xFFFFF000, loadBase))
877 (size + 0x1000) & 0xFFFFF000, loadBase))
891 start, (size + 0x1000) & 0xFFFFF000))
895 m_LoadBase = loadBase;
899 uintptr_t loadAddr = (loadBase == 0) ? start : loadBase;
900 for (uintptr_t j = loadAddr; j < loadAddr + size + 0x1000; j += 0x1000)
902 physical_uintptr_t phys =
906 reinterpret_cast<void *>(
910 WARNING(
"map() failed for address " <<
Hex << j);
916 if (m_pDynamicSymbolTable && m_pDynamicStringTable)
920 const char *pStrtab = m_pDynamicStringTable;
923 while (reinterpret_cast<uintptr_t>(pSymbol) <
924 reinterpret_cast<uintptr_t>(m_pDynamicSymbolTable) +
925 m_nDynamicSymbolTableSize)
927 const char *pStr = pStrtab + pSymbol->name;
930 switch (ST_BIND(pSymbol->info))
933 binding = SymbolTable::Local;
936 binding = SymbolTable::Global;
939 binding = SymbolTable::Weak;
942 binding = SymbolTable::Global;
946 #ifndef TRACK_HIDDEN_SYMBOLS 947 if (pSymbol->other != STV_HIDDEN)
950 if (ST_TYPEOK(pSymbol->info))
954 if (pSymbol->shndx != 0)
959 String(pStr), binding,
this, pSymbol->value);
966 String(pStr), binding,
this,
967 pSymbol->value + loadBase);
974 if (binding == SymbolTable::Weak)
976 Elf_Xword value = pSymbol->value;
982 pSymtab,
String(pStr), binding,
this,
996 "Elf::allocate: no thread or process support, cannot allocate memory");
1002 uint8_t *pBuffer,
size_t length, uintptr_t loadBase,
SymbolTable *pSymtab,
1003 uintptr_t nStart, uintptr_t nEnd,
bool relocate)
1006 for (
size_t i = 0; i < m_nProgramHeaders; i++)
1008 if (m_pProgramHeaders[i].type == PT_LOAD)
1010 uintptr_t loadAddr = m_pProgramHeaders[i].vaddr + loadBase;
1011 NOTICE(
"LOAD[" << i <<
"]: @" <<
Hex << loadAddr <<
".");
1013 if (nStart > (loadAddr + m_pProgramHeaders[i].memsz))
1015 if (nEnd <= loadAddr)
1017 uintptr_t sectionStart = (loadAddr >= nStart) ? loadAddr : nStart;
1020 m_pProgramHeaders[i].offset + (sectionStart - loadAddr);
1022 (loadAddr + m_pProgramHeaders[i].filesz >= nEnd) ?
1023 (nEnd - sectionStart) :
1024 (loadAddr + m_pProgramHeaders[i].filesz - sectionStart);
1025 if (loadAddr + m_pProgramHeaders[i].filesz < nStart)
1028 (loadAddr + m_pProgramHeaders[i].memsz >= nEnd) ?
1029 (nEnd - sectionStart) :
1030 (loadAddr + m_pProgramHeaders[i].memsz - sectionStart);
1034 reinterpret_cast<uint8_t *>(sectionStart), &pBuffer[offset],
1038 reinterpret_cast<uint8_t *>(sectionStart + filesz), 0,
1041 #if defined(PPC_COMMON) || defined(MIPS_COMMON) 1042 Processor::flushDCacheAndInvalidateICache(
1043 loadAddr, loadAddr + m_pProgramHeaders[i].filesz);
1058 pRel < (m_pRelTable + (m_nRelTableSize /
sizeof(
ElfRel_t)));
1061 if ((pRel->offset + loadBase < nStart) ||
1062 (pRel->offset + loadBase >= nEnd))
1073 pRel < (m_pRelaTable + (m_nRelaTableSize /
sizeof(
ElfRela_t)));
1076 if ((pRel->offset + loadBase < nStart) ||
1077 (pRel->offset + loadBase >= nEnd))
1090 for (
size_t i = 0; i < m_nPltSize /
sizeof(
ElfRel_t); i++, pRel++)
1092 if ((pRel->offset + loadBase < nStart) ||
1093 (pRel->offset + loadBase >= nEnd))
1095 uintptr_t *address =
1096 reinterpret_cast<uintptr_t *
>(loadBase + pRel->offset);
1097 *address += loadBase;
1100 if (m_pPltRelaTable)
1104 for (
size_t i = 0; i < m_nPltSize /
sizeof(
ElfRela_t); i++, pRel++)
1106 if ((pRel->offset + loadBase < nStart) ||
1107 (pRel->offset + loadBase >= nEnd))
1109 uintptr_t *address =
1110 reinterpret_cast<uintptr_t *
>(loadBase + pRel->offset);
1111 *address += loadBase;
1126 entry = pHeader->entry;
1132 uint8_t *pBuffer,
size_t length,
size_t &phdrCount,
size_t &phdrEntrySize,
1133 uintptr_t &phdrAddress)
1140 phdrCount = pHeader->phnum;
1141 phdrEntrySize = pHeader->phentsize;
1142 phdrAddress =
reinterpret_cast<uintptr_t
>(pBuffer) + pHeader->phoff;
1155 if (!m_pSymbolTable || !m_pStringTable)
1166 if (!symbolTable || !m_pStringTable)
1171 T *pSymbol = symbolTable;
1173 const char *pStrtab =
reinterpret_cast<const char *
>(m_pStringTable);
1175 for (
size_t i = 0; i < m_nSymbolTableSize /
sizeof(T); i++)
1178 if (ST_TYPE(pSymbol->info) != STT_FUNC &&
1179 ST_TYPE(pSymbol->info) != STT_NOTYPE )
1189 if (ST_BIND(pSymbol->info) != STB_GLOBAL)
1201 Elf_Xword size = pSymbol->size;
1204 if ((addr >= pSymbol->value) && (addr < (pSymbol->value + size)))
1206 const char *pStr = pStrtab + pSymbol->name;
1208 *startAddr = pSymbol->value;
1223 uintptr_t value = m_SymbolTable.
lookup(
String(sym),
this);
1227 return value + loadBase;
1232 return reinterpret_cast<uintptr_t
>(m_pGotTable);
1240 bool Elf::relocate(uint8_t *pBuffer, uintptr_t length)
1243 for (
size_t i = 0; i < m_nSectionHeaders; i++)
1247 if (pSh->type != SHT_REL && pSh->type != SHT_RELA)
1255 reinterpret_cast<const char *
>(m_pShstrtab) + pLink->name;
1256 if (!StringCompare(pStr,
".modinfo"))
1263 if (pSh->type == SHT_REL)
1267 reinterpret_cast<ElfRel_t *>(&pBuffer[pSh->offset]);
1268 pRel < reinterpret_cast<ElfRel_t *>(
1269 &pBuffer[pSh->offset + pSh->size]);
1277 else if (pSh->type == SHT_RELA)
1281 reinterpret_cast<ElfRela_t *>(&pBuffer[pSh->offset]);
1282 pRel < reinterpret_cast<ElfRela_t *>(
1283 &pBuffer[pSh->offset + pSh->size]);
1298 bool Elf::relocateModinfo(uint8_t *pBuffer, uintptr_t length)
1301 for (
size_t i = 0; i < m_nSectionHeaders; i++)
1304 if (pSh->type != SHT_REL && pSh->type != SHT_RELA)
1313 reinterpret_cast<const char *
>(m_pShstrtab) + pLink->name;
1314 if (StringCompare(pStr,
".modinfo"))
1320 if (pSh->type == SHT_REL)
1324 reinterpret_cast<ElfRel_t *>(&pBuffer[pSh->offset]);
1325 pRel < reinterpret_cast<ElfRel_t *>(
1326 &pBuffer[pSh->offset + pSh->size]);
1334 else if (pSh->type == SHT_RELA)
1338 reinterpret_cast<ElfRela_t *>(&pBuffer[pSh->offset]);
1339 pRel < reinterpret_cast<ElfRela_t *>(
1340 &pBuffer[pSh->offset + pSh->size]);
1354 uintptr_t off,
SymbolTable *pSymtab, uintptr_t loadBase,
1361 ElfRel_t *pRel = adjust_pointer(m_pPltRelTable, off);
1365 uintptr_t address = loadBase + pRel->offset;
1367 return *
reinterpret_cast<uintptr_t *
>(address);
1370 if (m_pPltRelaTable)
1376 uintptr_t address = loadBase + pRel.offset;
1378 return *
reinterpret_cast<uintptr_t *
>(address);
1383 uintptr_t Elf::debugFrameTable()
1385 return reinterpret_cast<uintptr_t
>(m_pDebugTable);
1388 uintptr_t Elf::debugFrameTableLength()
1390 return m_nDebugTableSize;
1395 return m_NeededLibraries;
1400 return m_sInterpreter;
1412 if (m_pDynamicSymbolTable && m_pDynamicStringTable)
1416 const char *pStrtab = m_pDynamicStringTable;
1419 while (reinterpret_cast<uintptr_t>(pSymbol) <
1420 reinterpret_cast<uintptr_t>(m_pDynamicSymbolTable) +
1421 m_nDynamicSymbolTableSize)
1423 const char *pStr = pStrtab + pSymbol->name;
1427 if (pSymbol->shndx != 0)
1430 switch (ST_BIND(pSymbol->info))
1433 binding = SymbolTable::Local;
1436 binding = SymbolTable::Global;
1439 binding = SymbolTable::Weak;
1442 binding = SymbolTable::Global;
1446 #ifndef TRACK_HIDDEN_SYMBOLS 1447 if (pSymbol->other != STV_HIDDEN)
1450 if (ST_TYPEOK(pSymbol->info))
1457 String(pStr), binding,
this,
1458 pSymbol->value + loadBase);
1472 if (!pSymtabOverride)
1474 pSymtabOverride = &m_SymbolTable;
1477 size_t numLocal = 0;
1479 size_t numGlobal = 0;
1484 for (
size_t i = 0; i < m_nSymbolTableSize /
sizeof(
ElfSymbol_t); i++)
1486 switch (ST_BIND(m_pSymbolTable[i].info))
1503 if (m_pDynamicSymbolTable)
1506 for (
size_t i = 0; i < m_nDynamicSymbolTableSize /
sizeof(
ElfSymbol_t);
1509 switch (ST_BIND(m_pDynamicSymbolTable[i].info))
1526 if (numLocal || numWeak || numGlobal)
1529 "ELF: preallocating symbol table with " 1530 << numGlobal <<
" global " << numWeak <<
" weak and " << numLocal
1531 <<
" local symbols.");
1532 pSymtabOverride->
preallocate(numGlobal, numWeak,
this, numLocal);
1533 if (pAdditionalSymtab)
1536 numGlobal, numWeak,
this, numLocal);
1546 m_pGotTable = adjust_pointer(m_pGotTable, m_LoadBase);
1550 m_InitFunc += m_LoadBase;
1554 m_FiniFunc += m_LoadBase;
1559 template const char *Elf::lookupSymbol<Elf::ElfSymbol_t>(
1560 uintptr_t addr, uintptr_t *startAddr = 0,
ElfSymbol_t *symbolTable = 0);
1562 template const char *Elf::lookupSymbol<Elf::Elf32Symbol_t>(
1563 uintptr_t addr, uintptr_t *startAddr = 0,
Elf32Symbol_t *symbolTable = 0);
uintptr_t getLastAddress()
void pushBack(const T &value)
uintptr_t EXPORTED_PUBLIC lookup(const HashedStringView &name, Elf *pElf, Policy policy=LocalFirst, Binding *pBinding=0)
void preallocateAdditional(size_t numGlobal, size_t numWeak, Elf *localElf, size_t numLocal)
bool load(uint8_t *pBuffer, size_t length, uintptr_t loadBase, SymbolTable *pSymtab=0, uintptr_t nStart=0, uintptr_t nEnd=~0, bool relocate=true)
static size_t getPageSize() PURE
uintptr_t lookupDynamicSymbolAddress(const char *str, uintptr_t loadBase)
static PhysicalMemoryManager & instance()
virtual void setFlags(void *virtualAddress, size_t newFlags)=0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
virtual bool isMapped(void *virtualAddress)=0
static const size_t Execute
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
static T * elfCopy(uint8_t *, ElfProgramHeader_t *, size_t, T *, size_t)
const char * lookupSymbol(uintptr_t addr, uintptr_t *startAddr, T *symbolTable)
static ProcessorInformation & information()
bool allocate(uint8_t *pBuffer, size_t length, uintptr_t &loadBase, SymbolTable *pSymtab=0, bool bAllocate=true, size_t *pSize=0)
bool allocate(T length, T &address)
static KernelElf & instance()
bool createNeededOnly(uint8_t *pBuffer, size_t length)
static bool extractEntryPoint(uint8_t *pBuffer, size_t length, uintptr_t &entry)
static const size_t Write
static const size_t KernelMode
void insert(const String &name, Binding binding, Elf *pParent, uintptr_t value)
MemoryAllocator & getDynamicSpaceAllocator()
bool allocateSpecific(T address, T length)
bool finaliseModule(uint8_t *pBuffer, uintptr_t length)
uintptr_t applySpecificRelocation(uintptr_t off, SymbolTable *pSymtab, uintptr_t loadBase, SymbolTable::Policy policy=SymbolTable::LocalFirst)
void populateSymbolTable(SymbolTable *pSymtab, uintptr_t loadBase)
uintptr_t getGlobalOffsetTable()
bool create(uint8_t *pBuffer, size_t length)
String & getInterpreter()
static bool extractInformation(uint8_t *pBuffer, size_t length, size_t &phdrCount, size_t &phdrEntrySize, uintptr_t &phdrAddress)
bool loadModule(uint8_t *pBuffer, size_t length, uintptr_t &loadBase, size_t &loadSize, SymbolTable *pSymbolTableCopy=0)
bool applyRelocation(ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst)
void copyTable(Elf *pNewElf, const SymbolTable &newSymtab)
bool validate(uint8_t *pBuffer, size_t length)
void insertMultiple(SymbolTable *pOther, const String &name, Binding binding, Elf *pParent, uintptr_t value)
List< char * > & neededLibraries()
void preallocateSymbols(SymbolTable *pSymtabOverride=nullptr, SymbolTable *pAdditionalSymtab=nullptr)
uintptr_t getEntryPoint()
void preallocate(size_t numGlobal, size_t numWeak, Elf *localElf, size_t numLocal)
MemoryAllocator & getSpaceAllocator()