diff options
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/libunwind')
4 files changed, 60 insertions, 30 deletions
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp index b34f93f50c6..c4425b47a0d 100644 --- a/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp +++ b/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp @@ -44,6 +44,8 @@ namespace lldb_private class AssemblyParse_x86 { public: + enum { kMaxInstructionByteSize = 32 }; + AssemblyParse_x86 (RemoteProcInfo& procinfo, unw_accessors_t *acc, unw_addr_space_t as, void *arg) : fArg(arg), fAccessors(acc), fAs(as), fRemoteProcInfo(procinfo) { fRegisterMap = fRemoteProcInfo.getRegisterMap(); if (fRemoteProcInfo.getTargetArch() == UNW_TARGET_X86_64) { @@ -76,7 +78,7 @@ public: private: void *fArg; - uint8_t* fCurInsnByteBuf; + uint8_t fCurInsnByteBuf[kMaxInstructionByteSize]; int fCurInsnSize; RemoteProcInfo& fRemoteProcInfo; RemoteRegisterMap *fRegisterMap; @@ -285,7 +287,7 @@ bool AssemblyParse_x86::profileFunction (uint64_t start, uint64_t end, RemoteUnw /* An error parsing the instruction; stop scanning. */ break; } - fCurInsnByteBuf = (uint8_t *) malloc (fCurInsnSize); + assert (fCurInsnSize <= kMaxInstructionByteSize); if (fRemoteProcInfo.getBytes (cur_addr, fCurInsnSize, fCurInsnByteBuf, fArg) == 0) return false; next_addr = cur_addr + fCurInsnSize; diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp index 3640dc6195c..e9ec886bf5b 100644 --- a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp +++ b/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp @@ -173,7 +173,7 @@ public: void addImage (uint64_t mh, uint64_t text_start, uint64_t text_end, uint64_t eh_frame, uint64_t eh_frame_len, uint64_t compact_unwind_start, uint64_t compact_unwind_len); bool addProfile (RemoteProcInfo* procinfo, unw_accessors_t *acc, unw_addr_space_t as, uint64_t start, uint64_t end, void *arg); RemoteUnwindProfile* findProfileByTextAddr (uint64_t pc); - void addMemBlob (RemoteMemoryBlob *blob); + bool addMemBlob (RemoteMemoryBlob *blob); uint8_t *getMemBlobMemory (uint64_t addr, int len); private: RemoteImages(); @@ -312,14 +312,25 @@ bool RemoteImages::findFuncBounds (uint32_t pc, uint32_t &startAddr, uint32_t &e // as this is used today, the only duplication will be with the same // start address. -void RemoteImages::addMemBlob (RemoteMemoryBlob *blob) { - std::vector<RemoteMemoryBlob *>::iterator i; - for (i = fMemBlobs.begin(); i != fMemBlobs.end(); ++i) { - if (blob->getStartAddr() == (*i)->getStartAddr()) - return; +bool +RemoteImages::addMemBlob (RemoteMemoryBlob *blob) { + + if (fMemBlobs.empty()) + { + fMemBlobs.push_back(blob); + } + else + { + std::vector<RemoteMemoryBlob *>::iterator pos; + + pos = std::lower_bound (fMemBlobs.begin(), fMemBlobs.end(), blob); + + if (pos != fMemBlobs.end() && (*pos)->getStartAddr() == blob->getStartAddr()) + return false; + + fMemBlobs.insert (pos, blob); } - fMemBlobs.push_back(blob); - std::sort(fMemBlobs.begin(), fMemBlobs.end()); + return true; } uint8_t *RemoteImages::getMemBlobMemory (uint64_t addr, int len) { @@ -702,7 +713,7 @@ public: unw_addr_space_t wrap () { return (unw_addr_space_t) &fWrapper; } bool remoteIsLittleEndian () { return fLittleEndian; } unw_log_level_t getDebugLoggingLevel() { return fLogLevel; } - void addMemBlob (RemoteMemoryBlob *blob) { fImages.addMemBlob(blob); } + bool addMemBlob (RemoteMemoryBlob *blob) { return fImages.addMemBlob(blob); } unw_caching_policy_t getCachingPolicy() { return fCachingPolicy; } private: @@ -742,14 +753,16 @@ bool RemoteProcInfo::haveImageEntry (uint64_t pc, void *arg) { uint8_t *buf = (uint8_t*) malloc (compact_unwind_len); if (this->getBytes (compact_unwind, compact_unwind_len, buf, arg)) { RemoteMemoryBlob *b = new RemoteMemoryBlob(buf, free, compact_unwind, compact_unwind_len, mh, NULL); - fImages.addMemBlob (b); + if (fImages.addMemBlob (b) == false) + delete b; } } else if (eh_frame_len != 0) { logVerbose ("Creating RemoteMemoryBlob of eh_frame for image at mh 0x%llx, %lld bytes", mh, (uint64_t) compact_unwind_len); uint8_t *buf = (uint8_t*) malloc (eh_frame_len); if (this->getBytes (eh_frame, eh_frame_len, buf, arg)) { RemoteMemoryBlob *b = new RemoteMemoryBlob(buf, free, eh_frame, eh_frame_len, mh, NULL); - fImages.addMemBlob (b); + if (fImages.addMemBlob (b) == false) + delete b; } } } diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp index e940b8b8bf1..d7df99b64d7 100644 --- a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp +++ b/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp @@ -1168,9 +1168,13 @@ int RemoteUnwindCursor<A,R>::step() // thing anyway so we might as well save it. uint8_t *eh_buf = (uint8_t *)malloc (eh_frame_len); if (UnwindCursor<A,R>::fAddressSpace.getBytes (eh_frame_start, eh_frame_len, eh_buf) == 0) - return UNW_EUNSPEC; + { + free (eh_buf); + return UNW_EUNSPEC; + } RemoteMemoryBlob *ehmem = new RemoteMemoryBlob(eh_buf, free, eh_frame_start, eh_frame_len, mh, NULL); - procinfo->addMemBlob (ehmem); + if (procinfo->addMemBlob (ehmem) == false) + delete ehmem; } if (CFI_Parser<A>::functionFuncBoundsViaFDE(UnwindCursor<A,R>::fAddressSpace, eh_frame_start, eh_frame_len, func_bounds)) { @@ -1271,9 +1275,13 @@ int RemoteUnwindCursor<A,R>::endOfPrologueInsns (unw_word_t start, unw_word_t en // thing anyway so we might as well save it. uint8_t *eh_buf = (uint8_t *)malloc (eh_frame_len); if (UnwindCursor<A,R>::fAddressSpace.getBytes (eh_frame_start, eh_frame_len, eh_buf) == 0) - return UNW_EUNSPEC; + { + free (eh_buf); + return UNW_EUNSPEC; + } RemoteMemoryBlob *ehmem = new RemoteMemoryBlob(eh_buf, free, eh_frame_start, eh_frame_len, mh, NULL); - procinfo->addMemBlob (ehmem); + if (procinfo->addMemBlob (ehmem) == false) + delete ehmem; } if (CFI_Parser<A>::functionFuncBoundsViaFDE(UnwindCursor<A,R>::fAddressSpace, eh_frame_start, eh_frame_len, func_bounds)) { procinfo->addFuncBounds(mh, func_bounds); diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx b/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx index e7e66a452f0..d841677db37 100644 --- a/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx +++ b/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx @@ -235,25 +235,32 @@ EXPORT int unw_init_remote(unw_cursor_t *cursor, unw_addr_space_t as, void *arg) // with the rest of the code here. switch ( remote->ras->getTargetArch() ) { case UNW_TARGET_I386: - { - Registers_x86 *r = new Registers_x86; + { + Registers_x86 r; + // LEAK: "addrSpace" is being leaked every time here with no easy solution. + // The address space is in the cursor and the cursor may get + // duplicated, though if it does get duplicated, it will just be + // memcpy'ed since unw_cursor_t is just a bunch of uint64_t types... OtherAddressSpace<Pointer32<LittleEndian> > *addrSpace = new OtherAddressSpace<Pointer32<LittleEndian> >(as, arg); - getRemoteContext (remote->ras, *r, arg); - unw_context_t *context = (unw_context_t*) r; + getRemoteContext (remote->ras, r, arg); + unw_context_t *context = (unw_context_t*) &r; new ((void*)cursor) RemoteUnwindCursor<OtherAddressSpace<Pointer32<LittleEndian> >, Registers_x86>(*addrSpace, context, arg); - break; - } + } break; case UNW_TARGET_X86_64: - { - Registers_x86_64 *r = new Registers_x86_64; + { + Registers_x86_64 r; + // LEAK: "addrSpace" is being leaked every time here with no easy solution. + // The address space is in the cursor and the cursor may get + // duplicated, though if it does get duplicated, it will just be + // memcpy'ed since unw_cursor_t is just a bunch of uint64_t types... OtherAddressSpace<Pointer64<LittleEndian> > *addrSpace = new OtherAddressSpace<Pointer64<LittleEndian> >(as, arg); - getRemoteContext (remote->ras, *r, arg); - unw_context_t *context = (unw_context_t*) r; + getRemoteContext (remote->ras, r, arg); + unw_context_t *context = (unw_context_t*) &r; new ((void*)cursor) RemoteUnwindCursor<OtherAddressSpace<Pointer64<LittleEndian> >, Registers_x86_64>(*addrSpace, context, arg); - break; - } - + } + break; + case UNW_TARGET_PPC: ABORT("ppc not supported for remote unwinds"); break; |

