diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index 0d7851d4..0edd4085 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -297,6 +297,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params) //1 - because we're trapping usage if (!pHandler->HandleNative(name, native, 1)) { + amx->usertags[UT_NATIVE] = (void *)native; LogError(amx, AMX_ERR_INVNATIVE, NULL); return 0; } diff --git a/amxmodx/debugger.cpp b/amxmodx/debugger.cpp index 4bf32c55..a787b6a5 100755 --- a/amxmodx/debugger.cpp +++ b/amxmodx/debugger.cpp @@ -363,53 +363,6 @@ bool Debugger::ErrorExists() return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE); } -#define FLAG_INDIRECT (1<<0) - -//vaddr - the address of our current index vector -//base - the base address of which the array is offset to -//dim - the current dimension to search -//dimNum - the number of dimensions total -//sizes[] - an array containing the dimension sizes -//Indexes[] - an output array to contain each dimension's index -int WalkArray(cell *vaddr, unsigned char *base, cell *addr, int dim, int dimNum, int &flags, int sizes[], int Indexes[]) -{ - cell *my_addr; - int idx = 0; - - //if we are the second to last walker, we only need to check the ranges of our vector. - if (dim == dimNum - 2) - { - my_addr = vaddr; - //first check the actual vectors themselves - for (int i=0; ihdr->symbols; - int index = 0; - tagAMX_DBG_SYMBOL **pSymbols = pDbg->symboltbl; - tagAMX_DBG_SYMBOL *pSymbol, *pLastSymbol=NULL; - const tagAMX_DBG_SYMDIM *pDims; - ucell addr = 0; - int flags = 0; - char v_class, i_dent; - cell *arr_addr=NULL, *p_addr=NULL; - unsigned char *data = m_pAmx->base + ((AMX_HEADER *)m_pAmx->base)->dat; - bool valid=false; - //we can't really browse the assembly because - // we've no idea what the peephole optimizer did. - // so we're gonna try to go out on a limb and guess. - if (m_pAmx->alt < 0) - { - //take a guess that it's local - addr = m_pAmx->alt - pTrace->frm; - v_class = 1; - } else { - //take a guess that it's a global - //it won't be global if it's passed in from the stack frame, however - // doing this with a hardcoded array size is quite rare, and is probably passed - // as iREFARRAY not iARRAY! - addr = m_pAmx->alt; - v_class = 0; - } - bool found = false; - bool _found = true; - static char _msgbuf[255]; - size_t _size = 0; - //take a pre-emptive guess at the v_class! - //are we GLOBAL (0) or LOCAL (1) ? - if (m_pAmx->alt < 0) - { - v_class = 1; - i_dent = iARRAY; - arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt); - } else { - //it's greater than 0, check other things! - if (m_pAmx->alt >= m_pAmx->hlw && - m_pAmx->alt <= m_pAmx->stp) - { - //it's in the stack somewhere... guess that it's a local! - v_class = 1; - //relocate it - m_pAmx->alt -= pTrace->frm; - //alt cannot be zero - if (m_pAmx->alt < 0) - i_dent = iARRAY; - else - i_dent = iREFARRAY; - arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt); - } else { - //guess that it's DAT - v_class = 0; - i_dent = iARRAY; - arr_addr = (cell *)(data + m_pAmx->alt); - } - } - for (index = 0; index < symbols; index++) - { - pSymbol = pSymbols[index]; - if (pSymbol->codestart <= (ucell)cip && - pSymbol->codeend >= (ucell)cip && - (pSymbol->ident == iARRAY || pSymbol->ident == iREFARRAY)) - { - amx_err = dbg_GetArrayDim(pDbg, pSymbol, &pDims); - if (amx_err != AMX_ERR_NONE) - continue; - //calculate the size of the array. this is important! - ucell size = pDims[0].size; - ucell aggre = pDims[0].size; - valid = false; - for (int16_t i=1; idim; i++) - { - aggre *= pDims[i].size; - size += aggre; - } - if (pSymbol->vclass != v_class) - continue; - if (pSymbol->ident != i_dent) - continue; - if (v_class == 1) - { - if (i_dent == iARRAY) - { - p_addr = (cell *)(data + pTrace->frm + pSymbol->address); - } else if (i_dent == iREFARRAY) { - //get the variable off the stack, by reference - ucell _addr = (ucell)*((cell *)(data + pTrace->frm + pSymbol->address)); - p_addr = (cell *)(data + _addr); - } - } else if (v_class == 0) { - p_addr = (cell *)(data + pSymbol->address); - } - //make sure our address is in bounds! - if (arr_addr < p_addr || arr_addr > (p_addr + size)) - continue; - int *sizes = new int[pSymbol->dim]; - int *indexes = new int[pSymbol->dim]; - for (int i=0; idim; i++) - { - sizes[i] = pDims[i].size; - indexes[i] = -1; - } - flags = 0; - if (pSymbol->dim >= 2) - { - int dims = pSymbol->dim; - indexes[0] = WalkArray(p_addr, data, arr_addr, 0, pSymbol->dim, flags, sizes, indexes); - if (indexes[0] == -1) - { - while (indexes[0] == -1 && --dims > 0) - { - flags = 0; - indexes[0] = WalkArray(p_addr, data, arr_addr, 0, dims, flags, sizes, indexes); - } - } - //find the last known good dimension - for (dims=pSymbol->dim-1; dims>=0; dims--) - { - if (indexes[dims] != -1) - break; - } - //check for the "impossible" case. - //if we have [X][-1], and X is zero, the array did not walk properly. - if (dims >= 0 - && indexes[dims] == 0 - && !(flags & FLAG_INDIRECT) - && dims < pSymbol->dim - 1) - { - //here we have the dreaded MIXED CASE. we don't know whether - //[-][X] or [0][-] (where - is a bad input) was intended. - //first, we take a guess by checking the bounds. - cell *_cip = (cell *)_CipAsVa(cip); - _cip -= 1; - cell bounds = *_cip; - if (sizes[dims] != sizes[dims+1]) - { - //we were checking initial bounds - if (bounds == sizes[dims] - 1) - { - indexes[dims] = m_pAmx->pri; - } else if (bounds == sizes[dims+1] - 1) { - indexes[dims + 1] = m_pAmx->pri; - indexes[dims] = 0; - } else { - //this should really never happen... - _found = false; - } - } else { - _found = false; - } - if (!_found) - { - //we still don't have a good approximation. - //the user did something like: - //new X[40][40] - //we could do some really complicated and random guesswork - // but fact is, we have no way of deterministically knowing - // what the user intended. - } - } else { - //set the last know index to our culprit - indexes[dims + 1] = m_pAmx->pri; - } - } else { - indexes[0] = m_pAmx->pri; - } - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "(array \"%s", pSymbol->name); - for (int i=0; idim; i++) - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", pDims[i].size); - if (_found) - { - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (indexed \""); - for (int i=0; idim; i++) - { - if (indexes[i] == -1) - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[]"); - else - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", indexes[i]); - } - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\")"); - } else { - _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (unknown index \"%d\")", m_pAmx->pri); - } - found = true; - delete [] indexes; - delete [] sizes; - break; - } /* symbol validation */ - } /* is in valid ranges */ - if (!found) - _msgbuf[0] = '\0'; - - size += _snprintf(buffer, maxLength, "%s", _msgbuf); -#endif //0 - NOT USED! } return size;