bool Utilities::Map< EntryType >::Remove( const char* entryName ) { List* tableEntryList = 0; TableEntry* tableEntry = LookupTableEntry( entryName, &tableEntryList ); if( !tableEntry ) return false; tableEntryList->Remove( tableEntry, true ); count--; return true; }
bool Utilities::Map< EntryType >::Lookup( const char* entryName, EntryType* entry /*= 0*/ ) { TableEntry* tableEntry = LookupTableEntry( entryName ); if( tableEntry ) { if( entry ) *entry = tableEntry->entry; return true; } return false; }
bool Utilities::Map< EntryType >::Insert( const char* entryName, EntryType entry ) { List* tableEntryList = 0; int tableEntryHash = 0; TableEntry* tableEntry = LookupTableEntry( entryName, &tableEntryList, &tableEntryHash ); if( tableEntry ) return false; tableEntry = new TableEntry; tableEntry->entry = entry; tableEntry->hash = tableEntryHash; strcpy_s( tableEntry->entryName, sizeof( tableEntry->entryName ), entryName ); tableEntryList->InsertRightOf( tableEntryList->RightMost(), tableEntry ); count++; return true; }
static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int need_unwind_info, void *arg) { const auto *info = (libunwindInfo*)arg; memset(pip, 0, sizeof(*pip)); Ehdr ehdr; if (!info->ReadMemory((void*)info->BaseAddress, &ehdr, sizeof(ehdr))) { ERROR("ELF: reading ehdr %p\n", info->BaseAddress); return -UNW_EINVAL; } Phdr* phdrAddr = reinterpret_cast<Phdr*>(info->BaseAddress + ehdr.e_phoff); int phnum = ehdr.e_phnum; TRACE("ELF: base %p ip %p e_type %d e_phnum %d e_phoff %p\n", info->BaseAddress, ip, ehdr.e_type, ehdr.e_phnum, ehdr.e_phoff); // The eh_frame header Phdr ehPhdr; memset(&ehPhdr, 0, sizeof(ehPhdr)); // Search for the module's dynamic header and unwind frames Dyn* dynamicAddr = nullptr; for (int i = 0; i < phnum; i++, phdrAddr++) { Phdr ph; if (!info->ReadMemory(phdrAddr, &ph, sizeof(ph))) { ERROR("ELF: reading phdrAddr %p\n", phdrAddr); return -UNW_EINVAL; } TRACE("ELF: phdr %p type %d (%x) vaddr %p memsz %016llx paddr %p filesz %016llx offset %p align %016llx\n", phdrAddr, ph.p_type, ph.p_type, ph.p_vaddr, ph.p_memsz, ph.p_paddr, ph.p_filesz, ph.p_offset, ph.p_align); switch (ph.p_type) { case PT_DYNAMIC: if (ehdr.e_type == ET_EXEC) { dynamicAddr = reinterpret_cast<Dyn*>(ph.p_vaddr); } if (ehdr.e_type == ET_DYN) { dynamicAddr = reinterpret_cast<Dyn*>(ph.p_vaddr + info->BaseAddress); } break; case PT_GNU_EH_FRAME: ehPhdr = ph; break; } } if (dynamicAddr != nullptr) { for (;;) { Dyn dyn; if (!info->ReadMemory(dynamicAddr, &dyn, sizeof(dyn))) { ERROR("ELF: reading dynamicAddr %p\n", dynamicAddr); return -UNW_EINVAL; } if (dyn.d_tag == DT_PLTGOT) { TRACE("ELF: dyn %p tag %d (%x) d_ptr %p\n", dynamicAddr, dyn.d_tag, dyn.d_tag, dyn.d_un.d_ptr); pip->gp = dyn.d_un.d_ptr; break; } else if (dyn.d_tag == DT_NULL) { break; } dynamicAddr++; } } unw_word_t ehFrameHdrAddr = ehPhdr.p_offset + info->BaseAddress; eh_frame_hdr ehFrameHdr; if (!info->ReadMemory((PVOID)ehFrameHdrAddr, &ehFrameHdr, sizeof(eh_frame_hdr))) { ERROR("ELF: reading ehFrameHdrAddr %p\n", ehFrameHdrAddr); return -UNW_EINVAL; } TRACE("ehFrameHdrAddr %p version %d eh_frame_ptr_enc %d fde_count_enc %d table_enc %d\n", ehFrameHdrAddr, ehFrameHdr.version, ehFrameHdr.eh_frame_ptr_enc, ehFrameHdr.fde_count_enc, ehFrameHdr.table_enc); if (ehFrameHdr.version != DW_EH_VERSION) { ASSERT("ehFrameHdr version %x not supported\n", ehFrameHdr.version); return -UNW_EBADVERSION; } unw_word_t addr = ehFrameHdrAddr + sizeof(eh_frame_hdr); unw_word_t ehFrameStart; unw_word_t fdeCount; // Decode the eh_frame_hdr info if (!ReadEncodedPointer(info, &addr, ehFrameHdr.eh_frame_ptr_enc, UINTPTR_MAX, &ehFrameStart)) { ERROR("decoding eh_frame_ptr\n"); return -UNW_EINVAL; } if (!ReadEncodedPointer(info, &addr, ehFrameHdr.fde_count_enc, UINTPTR_MAX, &fdeCount)) { ERROR("decoding fde_count_enc\n"); return -UNW_EINVAL; } TRACE("ehFrameStart %p fdeCount %p ip offset %08x\n", ehFrameStart, fdeCount, (int32_t)(ip - ehFrameHdrAddr)); // LookupTableEntry assumes this encoding if (ehFrameHdr.table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) { ASSERT("Table encoding not supported %x\n", ehFrameHdr.table_enc); return -UNW_EINVAL; } // Find the fde using a binary search on the frame table table_entry entry; bool found; if (!LookupTableEntry(info, ip - ehFrameHdrAddr, addr, fdeCount, &entry, &found)) { ERROR("LookupTableEntry\n"); return -UNW_EINVAL; } unw_word_t fdeAddr = entry.fde_offset + ehFrameHdrAddr; TRACE("start_ip %08x fde_offset %08x fdeAddr %p found %d\n", entry.start_ip, entry.fde_offset, fdeAddr, found); // Unwind info not found if (!found) { return -UNW_ENOINFO; } // Now get the unwind info if (!ExtractProcInfoFromFde(info, &fdeAddr, pip, need_unwind_info)) { ERROR("ExtractProcInfoFromFde\n"); return -UNW_EINVAL; } _ASSERTE(ip >= pip->start_ip && ip <= pip->end_ip); return UNW_ESUCCESS; }