- void *Addr = getPointerToGlobalIfAvailable(F);
- getJITInfo().emitFunctionStubAtAddr(F, Addr, Stub, *getCodeEmitter());
-}
-
-/// updateDlsymStubTable - Emit the data necessary to relocate the stubs
-/// that were emitted during code generation.
-///
-void JIT::updateDlsymStubTable() {
- assert(isa<JITEmitter>(JCE) && "Unexpected MCE?");
- JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
-
- SmallVector<GlobalValue*, 8> GVs;
- SmallVector<void*, 8> Ptrs;
- const StringMap<void *> &ExtFns = JE->getExternalFnStubs();
-
- JE->getJITResolver().getRelocatableGVs(GVs, Ptrs);
-
- unsigned nStubs = GVs.size() + ExtFns.size();
-
- // If there are no relocatable stubs, return.
- if (nStubs == 0)
- return;
-
- // If there are no new relocatable stubs, return.
- void *CurTable = JE->getMemMgr()->getDlsymTable();
- if (CurTable && (*(unsigned *)CurTable == nStubs))
- return;
-
- // Calculate the size of the stub info
- unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs;
-
- SmallVector<unsigned, 8> Offsets;
- for (unsigned i = 0; i != GVs.size(); ++i) {
- Offsets.push_back(offset);
- offset += GVs[i]->getName().size() + 1;
- }
- for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
- i != e; ++i) {
- Offsets.push_back(offset);
- offset += strlen(i->first()) + 1;
- }
-
- // Allocate space for the new "stub", which contains the dlsym table.
- JE->startGVStub(0, offset, 4);
-
- // Emit the number of records
- JE->emitInt32(nStubs);
-
- // Emit the string offsets
- for (unsigned i = 0; i != nStubs; ++i)
- JE->emitInt32(Offsets[i]);
-
- // Emit the pointers. Verify that they are at least 2-byte aligned, and set
- // the low bit to 0 == GV, 1 == Function, so that the client code doing the
- // relocation can write the relocated pointer at the appropriate place in
- // the stub.
- for (unsigned i = 0; i != GVs.size(); ++i) {
- intptr_t Ptr = (intptr_t)Ptrs[i];
- assert((Ptr & 1) == 0 && "Stub pointers must be at least 2-byte aligned!");
-
- if (isa<Function>(GVs[i]))
- Ptr |= (intptr_t)1;
-
- if (sizeof(Ptr) == 8)
- JE->emitInt64(Ptr);
- else
- JE->emitInt32(Ptr);
- }
- for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
- i != e; ++i) {
- intptr_t Ptr = (intptr_t)i->second | 1;
-
- if (sizeof(Ptr) == 8)
- JE->emitInt64(Ptr);
- else
- JE->emitInt32(Ptr);
- }
-
- // Emit the strings.
- for (unsigned i = 0; i != GVs.size(); ++i)
- JE->emitString(GVs[i]->getName());
- for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
- i != e; ++i)
- JE->emitString(i->first());
-
- // Tell the JIT memory manager where it is. The JIT Memory Manager will
- // deallocate space for the old one, if one existed.
- JE->getMemMgr()->SetDlsymTable(JE->finishGVStub(0));