Category : Recently Uploaded Files
Archive   : DOSUIT07.ZIP
Filename : PROTECT.CPP

 
Output of file : PROTECT.CPP contained in archive : DOSUIT07.ZIP

#include "protect.hpp"

#ifndef NOPROTECT
void *Protected::lastnew = 0;
size_t Protected::length = 0;
Protected *Protected::pstack = 0;
Protected *Protected::pheap = 0;
FILE *Protected::dumpfile = stderr;
static unsigned *stacktop;
extern "C" int main(int, char **);

void *mapAddress(void *p)
{
static unsigned long mainSegment = ((long)&main) & 0xffff0000;

if(!p)
return 0;
return (void *)((unsigned long)p - mainSegment);
}

void *Protected::calledFrom() const
{
return mapAddress(caller);
}

void Protected::setNewFlag()
{
static unsigned thisSegment = ((unsigned long)&dumpstack) >> 16;
unsigned a, *stk = &a;

stk += 3;

while(stk[2] == thisSegment)
{
unsigned nextframe = *stk - (unsigned)stk;
stk += nextframe / sizeof(unsigned);
}
caller = *((void **)(stk + 1));
if(lastnew <= this && (char *)lastnew + length >= (char *)this)
{ // was created using new
next = pheap; // add to heap
pheap = this;
newflag = 1; // mark as new'ed
}
else
{ // was static or automatic
next = pstack; // add to stack
pstack = this;
newflag = 0; // mark as not new'ed
}
}

Protected::Protected()
: me(this)
{
setNewFlag();
}

Protected::Protected(const Protected&)
: me(this)
{
setNewFlag();
}

Protected::~Protected()
{
VALIDATE(this); // Ensure not deleted twice !
if(isnew())
{
// Must walk heap until we find this
Protected **prevptr = &pheap, *n = pheap;

while(n != this)
{
if(!n) // this not found in heap - error !
crash("Item not on heap", __FILE__, __LINE__);
prevptr = &n->next;
n = n->next;
}
*prevptr = this->next; // Now remove from heap list
}
else
{
#if 0
// We assume that items are destroyed in reverse order
// to their creation. If this is not the case for your
// compiler, the code for the heap (above) should be used
// instead.
if(this != Protected::pstack) // Should be destroyed in reverse
crash("Item not on top of stack", __FILE__, __LINE__);
pstack = this->next;
#endif
#if 1
if (this == Protected::pstack)
pstack = this->next;
else
{
// Must walk globals until we find this
Protected **prevptr = &pstack, *n = pstack;

while(n != this)
{
if(!n) // this not found in stack - error !
crash("Item not on stack", __FILE__, __LINE__);
prevptr = &n->next;
n = n->next;
}
*prevptr = this->next; // Now remove from globals list
}
#endif
}
me = 0;
next = 0;
}

void Protected::v_dump(FILE *f) const
{
if(f)
fprintf(f,"[email protected]%p from %s caller %p\n",
this,isnew() ? "heap" : "stack", calledFrom());
}

void *Protected::operator new(size_t len)
{
// Register all calls to new
length = len;
return (lastnew = ::operator new(len));
}

void Protected::dumpstack(FILE *f)
{
unsigned a, *stk = &a;

if(!f)
f = dumpfile ? dumpfile : stderr;
fprintf(f,"Dumpstack = %p, top = %p\n", &dumpstack, stacktop);
if(stacktop)
stk += 7;
else
stk = 0;
for(Protected *p = pstack; p; p = p->next)
{
if((void *)stk > (void *)p)
stk = 0;
while(stk && (void *)stk < (void *)p && stk < stacktop)
{
unsigned nextframe = *stk;

if(nextframe < (unsigned)stk)
{
stk = 0;
break;
}
fprintf(f,"Frame : %p -> %04x", stk, nextframe);
stk++;
fprintf(f," from %p", mapAddress(*((void **)stk)));
stk += 2;
if(nextframe > (unsigned)stacktop)
nextframe = (unsigned)stacktop;
while((unsigned)stk < nextframe)
fprintf(f," %04X", *stk++);
fputc('\n', f);
}
if(p->valid())
p->v_dump(f);
else
fprintf(f,"Invalid object @%p\n",p);
}
fflush(dumpfile);
}

void Protected::dumpheap(FILE *f)
{
if(!f)
f = dumpfile ? dumpfile : stderr;
fprintf(f,"\nHeap :-\n");
for(Protected *p = pheap; p; p = p->next)
if(p->valid())
p->v_dump(f);
else
fprintf(f,"Invalid object @%p\n",p);
fflush(dumpfile);
}

void Protected::dumpclose(FILE *f)
{
if(!f)
f = dumpfile ? dumpfile : stderr;
dumpall(f);
if(f != stderr)
fclose(f);
if(f == dumpfile)
dumpfile = 0;
}

void NamedProtected::v_dump(FILE *f) const
{
if(f)
fprintf(f,"%[email protected]%p caller %p\n", name(), this, calledFrom());
}

Function::Function(const char *name, unsigned &frame, const char *file, unsigned line)
: NamedProtected(name), filename(file), lineno(line)
{
if(!stacktop)
stacktop = &frame;
}

void Function::v_dump(FILE *f) const
{
if(f)
fprintf(f,"Function %[email protected]%p in file %s at line %u address %p\n",
name(), this, file(), line(), calledFrom());
}

const char Protected::on = 1;
#else
const char Protected::off = 0;
#endif

NamedProtected::NamedProtected(const char *name)
: namestring(name)
{
}