20 #include "DynamicLinker.h" 21 #include "modules/Module.h" 22 #include "modules/system/vfs/File.h" 24 #include "modules/system/vfs/Symlink.h" 25 #include "modules/system/vfs/VFS.h" 26 #include "pedigree/kernel/Log.h" 27 #include "pedigree/kernel/linker/Elf.h" 28 #include "pedigree/kernel/linker/SymbolTable.h" 29 #include "pedigree/kernel/process/Process.h" 30 #include "pedigree/kernel/process/Thread.h" 31 #include "pedigree/kernel/processor/KernelCoreSyscallManager.h" 32 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 33 #include "pedigree/kernel/processor/Processor.h" 34 #include "pedigree/kernel/processor/ProcessorInformation.h" 35 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 36 #include "pedigree/kernel/processor/state.h" 37 #include "pedigree/kernel/utilities/Iterator.h" 38 #include "pedigree/kernel/utilities/List.h" 39 #include "pedigree/kernel/utilities/Result.h" 40 #include "pedigree/kernel/utilities/utility.h" 50 state.getSyscallParameter(0), state.getSyscallParameter(1));
54 : m_pProgramElf(0), m_ProgramStart(0), m_ProgramSize(0), m_ProgramBuffer(0),
55 m_LoadedObjects(), m_Objects()
60 : m_pProgramElf(other.m_pProgramElf), m_ProgramStart(other.m_ProgramStart),
61 m_ProgramSize(other.m_ProgramSize),
62 m_ProgramBuffer(other.m_ProgramBuffer),
63 m_LoadedObjects(other.m_LoadedObjects), m_Objects()
65 m_pProgramElf =
new Elf(*other.m_pProgramElf);
67 it != other.m_Objects.end(); it++)
69 uintptr_t key = it.key();
73 new Elf(*pSo->elf), pSo->file, pSo->buffer, pSo->address,
78 DynamicLinker::~DynamicLinker()
84 it != m_Objects.end(); it++)
95 File *pFile,
bool bDryRun,
bool bInterpreter,
String *sInterpreter)
100 uintptr_t buffer = 0;
102 pFile, buffer, pFile->getSize(), MemoryMappedObject::Read);
106 #ifdef VERBOSE_KERNEL 107 NOTICE(
"DynamicLinker::loadProgram(" << fileName <<
")");
110 Elf *programElf =
new Elf();
114 delete m_pProgramElf;
115 m_pProgramElf = programElf;
116 if (!m_pProgramElf->
create(
117 reinterpret_cast<uint8_t *>(buffer), pFile->getSize()))
120 "DynamicLinker: Main program ELF failed to create: `" 121 << fileName <<
"' at " << buffer);
124 delete m_pProgramElf;
130 reinterpret_cast<uint8_t *>(buffer), pFile->getSize(),
131 m_ProgramStart, 0,
false, &m_ProgramSize))
134 "DynamicLinker: Main program ELF failed to load: `" << fileName
138 delete m_pProgramElf;
143 m_ProgramBuffer = buffer;
148 reinterpret_cast<uint8_t *>(buffer), pFile->getSize()))
151 "DynamicLinker: Main program ELF failed to create: `" 152 << fileName <<
"' at " << buffer);
157 delete m_pProgramElf;
171 bool hasInterpreter = sInterpreter->length() > 0;
181 return hasInterpreter;
188 it != dependencies.
end(); it++)
195 WARNING(
"Object `" << *it <<
"' has already been loaded");
200 filename +=
"root»/libraries/";
203 if (!pDependencyFile)
205 ERROR(
"DynamicLinker: Dependency `" << filename <<
"' not found!");
208 delete m_pProgramElf;
215 while (pDependencyFile && pDependencyFile->
isSymlink())
217 if (!pDependencyFile || !
loadObject(pDependencyFile, bDryRun))
220 "DynamicLinker: Dependency `" << filename
221 <<
"' failed to load!");
224 delete m_pProgramElf;
235 m_LoadedObjects.
insert(
String(*it), reinterpret_cast<void *>(1));
248 uintptr_t buffer = 0;
250 uintptr_t loadBase = 0;
252 pFile, buffer, pFile->getSize(), MemoryMappedObject::Read);
259 NOTICE(
"DynamicLinker::loadObject(" << fileName <<
")");
264 reinterpret_cast<uint8_t *>(buffer), pFile->getSize()))
267 "DynamicLinker: ELF creation failed for file `" 274 reinterpret_cast<uint8_t *>(buffer), pFile->getSize(), loadBase,
275 m_pProgramElf->getSymbolTable(),
false, &size))
278 "DynamicLinker: ELF allocate failed for file `" 284 pSo =
new SharedObject(pElf, pMmFile, buffer, loadBase, size);
286 m_Objects.insert(loadBase, pSo);
291 reinterpret_cast<uint8_t *>(buffer), pFile->getSize()))
294 "DynamicLinker: ELF creation failed for file `" 305 it != dependencies.
end(); it++)
312 WARNING(
"Object `" << *it <<
"' has already been loaded");
317 filename +=
"root»/libraries/";
322 ERROR(
"DynamicLinker: Dependency `" << filename <<
"' not found!");
327 m_Objects.remove(loadBase);
339 "DynamicLinker: Dependency `" << filename
340 <<
"' failed to load!");
345 m_Objects.remove(loadBase);
356 m_LoadedObjects.
insert(
String(*it), reinterpret_cast<void *>(1));
370 uintptr_t offset = 0;
371 uintptr_t buffer = 0;
374 if (address >= m_ProgramStart && address < m_ProgramStart + m_ProgramSize)
376 pElf = m_pProgramElf;
378 buffer = m_ProgramBuffer;
379 size = m_ProgramSize;
384 it != m_Objects.end(); it++)
389 #ifdef ADDITIONAL_CHECKS 392 ERROR(
"A null shared object was in the object list.");
397 if (address >= pSo->address && address < pSo->address + pSo->size)
400 offset = pSo->address;
401 buffer = pSo->buffer;
419 p, reinterpret_cast<void *>(v),
422 WARNING(
"IMAGE: map() failed in ElfImage::trap(): vaddr: " << v);
428 reinterpret_cast<uint8_t *>(buffer), size, offset,
429 m_pProgramElf->getSymbolTable(), v,
432 WARNING(
"LINKER: load() failed in DynamicLinker::trap()");
441 return m_pProgramElf->getSymbolTable()->
lookup(name, m_pProgramElf);
454 InterruptState &state, uintptr_t address,
bool bIsWrite)
460 return pL->
trap(address);
470 static void destroy()
474 MODULE_INFO(
"linker", &init, &destroy,
"vfs");
File * find(const String &path, File *pStartNode=0)
uintptr_t EXPORTED_PUBLIC lookup(const HashedStringView &name, Elf *pElf, Policy policy=LocalFirst, Binding *pBinding=0)
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
static PhysicalMemoryManager & instance()
int followLink(char *pBuffer, size_t bufLen)
bool loadProgram(File *pFile, bool bDryRun=false, bool bInterpreter=false, String *sInterpreter=0)
virtual bool trap(InterruptState &state, uintptr_t address, bool bIsWrite)
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
static const size_t Execute
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
void insert(const String &key, const T &value)
static ProcessorInformation & information()
bool allocate(uint8_t *pBuffer, size_t length, uintptr_t &loadBase, SymbolTable *pSymtab=0, bool bAllocate=true, size_t *pSize=0)
void unmap(MemoryMappedObject *pObj)
bool createNeededOnly(uint8_t *pBuffer, size_t length)
uintptr_t registerSyscall(Function_t function, SyscallCallback func)
static PageFaultHandler & instance()
static const size_t Write
Result< T, bool > lookup(const String &key) const
uintptr_t resolvePltSymbol(uintptr_t libraryId, uintptr_t symIdx)
Memory-mapped file interface.
static MemoryMapManager & instance()
bool loadObject(File *pFile, bool bDryRun=false)
static KernelCoreSyscallManager & instance()
bool create(uint8_t *pBuffer, size_t length)
static uintptr_t resolvePlt(SyscallState &state)
MemoryMappedObject * mapFile(File *pFile, uintptr_t &address, size_t length, MemoryMappedObject::Permissions perms, size_t offset=0, bool bCopyOnWrite=true)
void registerHandler(MemoryTrapHandler *pHandler)
static Symlink * fromFile(File *pF)
String & getInterpreter()
uintptr_t resolve(String name)
bool trap(uintptr_t address)
An iterator applicable for many data structures.
List< char * > & neededLibraries()
void initPlt(Elf *pElf, uintptr_t value)