Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}