Lines Matching +full:qemu +full:- +full:user +full:- +full:static

1 //===----------------------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 //===----------------------------------------------------------------------===//
25 #include <mach-o/dyld.h>
52 #include "Unwind-EHABI.h"
57 // MinGW-w64 has always provided this struct.
99 static constexpr pint_t kSearchAll = static_cast<pint_t>(-1);
100 static pint_t findFDE(pint_t mh, pint_t pc);
101 static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
102 static void removeAllIn(pint_t mh);
103 static void iterateCacheEntries(void (*func)(unw_word_t ip_start,
116 // These fields are all static to avoid needing an initializer.
118 static RWMutex _lock;
120 static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide);
121 static bool _registeredForDyldUnloads;
123 static entry *_buffer;
124 static entry *_bufferUsed;
125 static entry *_bufferEnd;
126 static entry _initialBuffer[64];
157 if ((mh == p->mh) || (mh == kSearchAll)) { in findFDE()
158 if ((p->ip_start <= pc) && (pc < p->ip_end)) { in findFDE()
159 result = p->fde; in findFDE()
174 size_t oldSize = (size_t)(_bufferEnd - _buffer); in add()
185 _bufferUsed->mh = mh; in add()
186 _bufferUsed->ip_start = ip_start; in add()
187 _bufferUsed->ip_end = ip_end; in add()
188 _bufferUsed->fde = fde; in add()
205 if (s->mh != mh) { in removeAllIn()
227 (*func)(p->ip_start, p->ip_end, p->fde, p->mh); in iterateCacheEntries()
484 /// an unwind. This is normally stack-allocated inside a unw_cursor_t.
522 static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } in operator new()
536 pc -= 1; in lookUpSEHUnwindInfo()
664 _msContext.D[i - UNW_ARM_D0] = d.w; in UnwindCursor()
668 _msContext.X[i - UNW_AARCH64_X0] = r.getRegister(i); in UnwindCursor()
672 _msContext.V[i - UNW_AARCH64_V0].D[0] = r.getFloatRegister(i); in UnwindCursor()
750 default: return _msContext.X[regNum - UNW_AARCH64_X0]; in getReg()
831 case UNW_AARCH64_LR: _msContext.X[regNum - UNW_ARM64_X0] = value; break; in setReg()
859 d.w = _msContext.S[regNum - UNW_ARM_S0]; in getFloatReg()
867 d.w = _msContext.D[regNum - UNW_ARM_D0]; in getFloatReg()
872 return _msContext.V[regNum - UNW_AARCH64_V0].D[0]; in getFloatReg()
888 _msContext.S[regNum - UNW_ARM_S0] = d.w; in setFloatReg()
896 _msContext.D[regNum - UNW_ARM_D0] = d.w; in setFloatReg()
900 _msContext.V[regNum - UNW_AARCH64_V0].D[0] = value; in setFloatReg()
963 static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } in operator new()
1023 _addressSpace, (pint_t)this->getReg(UNW_REG_IP), in stepWithDwarfFDE()
1305 return stepWithTBTable(reinterpret_cast<pint_t>(this->getReg(UNW_REG_IP)), in stepWithTBTableData()
1411 static _Self begin(A& addressSpace, const UnwindInfoSections& sects) { in begin()
1414 static _Self end(A& addressSpace, const UnwindInfoSections& sects) { in end()
1424 _Self& operator--() { assert(_i > 0); --_i; return *this; } in operator --()
1425 _Self& operator-=(size_t a) { assert(_i >= a); _i -= a; return *this; } in operator -=()
1428 _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; } in operator -()
1430 size_t operator-(const _Self& other) const { return _i - other._i; } in operator -()
1447 typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof( in functionAddress()
1449 return indexAddr + signExtendPrel31(_addressSpace->get32(indexAddr)); in functionAddress()
1453 typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof( in dataAddress()
1471 size_t len = last - first; in EHABISectionUpperBound()
1479 len -= l2 + 1; in EHABISectionUpperBound()
1501 EHABISectionIterator<A> itThisPC = itNextPC - 1; in getInfoFromEHABISection()
1537 // exceptionTableAddr -- exception handler table entry. in getInfoFromEHABISection()
1538 // exceptionTableData -- the data inside the first word of the eht entry. in getInfoFromEHABISection()
1539 // isSingleWordEHT -- whether the entry is in the index. in getInfoFromEHABISection()
1588 // +---- ehtp in getInfoFromEHABISection()
1590 // +--------------------------------------+ in getInfoFromEHABISection()
1591 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1593 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1594 // | | N | unwind opcodes | | <-- UnwindData in getInfoFromEHABISection()
1595 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1597 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1599 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1601 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1602 // | | LSDA | | <-- lsda in getInfoFromEHABISection()
1604 // | +--------+--------+--------+-------+ | in getInfoFromEHABISection()
1605 // +--------------------------------------+ in getInfoFromEHABISection()
1727 pint_t targetFunctionOffset = pc - sects.dso_base; in getInfoFromCompactEncodingSection()
1733 uint32_t last = high - 1; in getInfoFromCompactEncodingSection()
1787 if (mid == (uint32_t)(pageHeader.entryCount() - 1)) { in getInfoFromCompactEncodingSection()
1829 (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset); in getInfoFromCompactEncodingSection()
1837 last = pageHeader.entryCount() - 1; in getInfoFromCompactEncodingSection()
1885 encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount(); in getInfoFromCompactEncodingSection()
1900 uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base); in getInfoFromCompactEncodingSection()
1902 high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) / in getInfoFromCompactEncodingSection()
1932 --personalityIndex; // change 1-based to zero-based index in getInfoFromCompactEncodingSection()
1986 _info.start_ip = base + unwindEntry->BeginAddress; in getInfoFromSEH()
1988 _info.end_ip = base + unwindEntry->EndAddress; in getInfoFromSEH()
1991 UNWIND_INFO *xdata = reinterpret_cast<UNWIND_INFO *>(base + unwindEntry->UnwindData); in getInfoFromSEH()
1992 if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) { in getInfoFromSEH()
1996 // N.B. UNWIND_INFO structs are DWORD-aligned. in getInfoFromSEH()
1997 uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; in getInfoFromSEH()
1998 const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); in getInfoFromSEH()
2039 static __xlcxx_personality_v0_t *xlcPersonalityV0;
2040 static RWMutex xlcPersonalityV0InitLock;
2065 if (!TBTable->tb.has_tboff) in getInfoFromTBTable()
2069 p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext); in getInfoFromTBTable()
2072 if (TBTable->tb.fixedparms || TBTable->tb.floatparms) in getInfoFromTBTable()
2077 reinterpret_cast<unw_word_t>(TBTable) - *p - sizeof(uint32_t); in getInfoFromTBTable()
2086 if (TBTable->tb.int_hndl) in getInfoFromTBTable()
2093 if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl) { in getInfoFromTBTable()
2105 if (TBTable->tb.name_present) { in getInfoFromTBTable()
2111 if (TBTable->tb.uses_alloca) in getInfoFromTBTable()
2146 // clobbers the value of errno from the user code. This is an AIX in getInfoFromTBTable()
2172 } else if (TBTable->tb.longtbtable) { in getInfoFromTBTable()
2203 // unsigned vr_saved:6; /* Number of non-volatile vector regs saved in getInfoFromTBTable()
2206 // /* 32 - vr_saved */ in getInfoFromTBTable()
2227 if (TBTable->tb.name_present) { in getInfoFromTBTable()
2233 if (TBTable->tb.uses_alloca) in getInfoFromTBTable()
2237 if (TBTable->tb.has_vec) in getInfoFromTBTable()
2256 // The pointer is 4-byte aligned. in getInfoFromTBTable()
2258 charPtr += 4 - reinterpret_cast<uintptr_t>(charPtr) % 4; in getInfoFromTBTable()
2311 reinterpret_cast<void *>(registers.getSP()), TBTable->tb.saves_lr, in stepWithTBTable()
2312 TBTable->tb.stores_bc); in stepWithTBTable()
2337 if (!TBTable->tb.stores_bc) in stepWithTBTable()
2349 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar; in stepWithTBTable()
2356 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar; in stepWithTBTable()
2373 newRegisters.setCR(sigContext->sc_jmpbuf.jmp_context.cr); in stepWithTBTable()
2378 newRegisters.setLR(sigContext->sc_jmpbuf.jmp_context.lr); in stepWithTBTable()
2381 reinterpret_cast<void *>(sigContext->sc_jmpbuf.jmp_context.lr)); in stepWithTBTable()
2385 newRegisters.setRegister(i, sigContext->sc_jmpbuf.jmp_context.gpr[i]); in stepWithTBTable()
2390 sigContext->sc_jmpbuf.jmp_context.fpr[i]); in stepWithTBTable()
2394 if (sigContext->sc_jmpbuf.jmp_context.msr & __EXTCTX) { in stepWithTBTable()
2396 if (uContext->__extctx->__extctx_magic == __EXTCTX_MAGIC) { in stepWithTBTable()
2400 &(uContext->__extctx->__vmx.__vr[i])))); in stepWithTBTable()
2406 if (!TBTable->tb.saves_lr && registers.getLR()) { in stepWithTBTable()
2425 TBTable->tb.fpr_saved, TBTable->tb.gpr_saved, in stepWithTBTable()
2426 TBTable->tb.saves_cr); in stepWithTBTable()
2431 ptrToRegs - (TBTable->tb.fpr_saved * sizeof(double))); in stepWithTBTable()
2432 for (int i = 0; i < TBTable->tb.fpr_saved; ++i) in stepWithTBTable()
2434 32 - TBTable->tb.fpr_saved + i + unwPPCF0Index, FPRegs[i]); in stepWithTBTable()
2439 ptrToRegs - (TBTable->tb.gpr_saved * sizeof(uintptr_t))); in stepWithTBTable()
2440 for (int i = 0; i < TBTable->tb.gpr_saved; ++i) in stepWithTBTable()
2441 newRegisters.setRegister(32 - TBTable->tb.gpr_saved + i, GPRegs[i]); in stepWithTBTable()
2449 if (_info.flags == frameType::frameWithEHInfo && TBTable->tb.has_vec) { in stepWithTBTable()
2452 uint32_t *p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext); in stepWithTBTable()
2455 if (TBTable->tb.fixedparms || TBTable->tb.floatparms) in stepWithTBTable()
2459 if (TBTable->tb.has_tboff) in stepWithTBTable()
2463 if (TBTable->tb.int_hndl) in stepWithTBTable()
2467 if (TBTable->tb.has_ctl) { in stepWithTBTable()
2477 if (TBTable->tb.name_present) { in stepWithTBTable()
2483 if (TBTable->tb.uses_alloca) in stepWithTBTable()
2488 _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d", vec_ext->vr_saved); in stepWithTBTable()
2491 if (vec_ext->vr_saved) { in stepWithTBTable()
2492 // Saved vector registers are 16-byte aligned. in stepWithTBTable()
2494 ptrToRegs -= reinterpret_cast<uintptr_t>(ptrToRegs) % 16; in stepWithTBTable()
2495 v128 *VecRegs = reinterpret_cast<v128 *>(ptrToRegs - vec_ext->vr_saved * in stepWithTBTable()
2497 for (int i = 0; i < vec_ext->vr_saved; ++i) { in stepWithTBTable()
2499 32 - vec_ext->vr_saved + i + unwPPCV0Index, VecRegs[i]); in stepWithTBTable()
2503 if (TBTable->tb.saves_cr) { in stepWithTBTable()
2564 pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); in setInfoBasedOnIPRegister()
2584 // PC needs to be a 4-byte aligned address to be able to look for a in setInfoBasedOnIPRegister()
2587 pc -= 4; in setInfoBasedOnIPRegister()
2589 --pc; in setInfoBasedOnIPRegister()
2595 // handler points to first non-executed instruction, while FDE/CIE expects IP in setInfoBasedOnIPRegister()
2596 // to be after the first non-executed instruction. in setInfoBasedOnIPRegister()
2607 if (this->getInfoFromCompactEncodingSection(pc, sects)) { in setInfoBasedOnIPRegister()
2612 if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) { in setInfoBasedOnIPRegister()
2629 if (this->getInfoFromSEH(pc)) in setInfoBasedOnIPRegister()
2635 if (this->getInfoFromTBTable(pc, _registers)) in setInfoBasedOnIPRegister()
2642 if (this->getInfoFromDwarfSection(pc, sects)) { in setInfoBasedOnIPRegister()
2651 if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects)) in setInfoBasedOnIPRegister()
2657 // There is no static unwind info for this pc. Look to see if an FDE was in setInfoBasedOnIPRegister()
2700 // own restorer function, though, or user-mode QEMU might write a trampoline in setInfoForSigReturn()
2707 // - The PC points at a function compiled without unwind info, and which is in setInfoForSigReturn()
2708 // part of an execute-only mapping (e.g. using -Wl,--execute-only). in setInfoForSigReturn()
2709 // - The PC is invalid and happens to point to unreadable or unmapped memory. in setInfoForSigReturn()
2712 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); in setInfoForSigReturn()
2732 // - 128-byte siginfo struct in stepThroughSigReturn()
2733 // - ucontext struct: in stepThroughSigReturn()
2734 // - 8-byte long (uc_flags) in stepThroughSigReturn()
2735 // - 8-byte pointer (uc_link) in stepThroughSigReturn()
2736 // - 24-byte stack_t in stepThroughSigReturn()
2737 // - 128-byte signal set in stepThroughSigReturn()
2738 // - 8 bytes of padding because sigcontext has 16-byte alignment in stepThroughSigReturn()
2739 // - sigcontext/mcontext_t in stepThroughSigReturn()
2791 // - 128-byte siginfo struct in stepThroughSigReturn()
2792 // - ucontext_t struct: in stepThroughSigReturn()
2793 // - 8-byte long (__uc_flags) in stepThroughSigReturn()
2794 // - 8-byte pointer (*uc_link) in stepThroughSigReturn()
2795 // - 24-byte uc_stack in stepThroughSigReturn()
2796 // - 8-byte uc_sigmask in stepThroughSigReturn()
2797 // - 120-byte of padding to allow sigset_t to be expanded in the future in stepThroughSigReturn()
2798 // - 8 bytes of padding because sigcontext has 16-byte alignment in stepThroughSigReturn()
2799 // - struct sigcontext uc_mcontext in stepThroughSigReturn()
2823 // own restorer function, though, or user-mode QEMU might write a trampoline in setInfoForSigReturn()
2825 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); in setInfoForSigReturn()
2844 const pint_t sp = static_cast<pint_t>(this->getReg(UNW_REG_SP)); in stepThroughSigReturn()
2850 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); in stepThroughSigReturn()
2857 // "svc __NR_sigreturn" uses a non-RT signal trampoline frame. in stepThroughSigReturn()
2859 // Layout of a non-RT signal trampoline frame, starting at the CFA: in stepThroughSigReturn()
2860 // - 8-byte signal mask in stepThroughSigReturn()
2861 // - 8-byte pointer to sigcontext, followed by signo in stepThroughSigReturn()
2862 // - 4-byte signo in stepThroughSigReturn()
2870 // - 8-byte retcode (+ alignment) in stepThroughSigReturn()
2871 // - 128-byte siginfo struct (starts with signo) in stepThroughSigReturn()
2872 // - ucontext struct: in stepThroughSigReturn()
2873 // - 8-byte long (uc_flags) in stepThroughSigReturn()
2874 // - 8-byte pointer (uc_link) in stepThroughSigReturn()
2875 // - 24-byte stack_t in stepThroughSigReturn()
2876 // - 8 bytes of padding because sigcontext has 16-byte alignment in stepThroughSigReturn()
2877 // - sigcontext/mcontext_t in stepThroughSigReturn()
2897 static const int fpr[16] = { in stepThroughSigReturn()
2930 result = this->stepThroughSigReturn(); in step()
2935 result = this->stepWithCompactEncoding(stage2); in step()
2937 result = this->stepWithSEHData(); in step()
2939 result = this->stepWithTBTableData(); in step()
2941 result = this->stepWithDwarfFDE(stage2); in step()
2943 result = this->stepWithEHABI(); in step()
2954 this->setInfoBasedOnIPRegister(true); in step()
2973 return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP), in getFunctionName()
3000 assert(Result == -1); in isReadableAddr()
3011 return co->get_registers(); in __libunwind_cet_get_registers()