home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
monitors
/
rsys
/
source.lha
/
src
/
RSysHunks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-09
|
19KB
|
745 lines
/*
***************************************************************************
*
* Datei:
* RSysHunks.c
*
* Inhalt:
* void PrintHunkStruct(char *file);
* void HunkStruct(void);
*
* Bemerkungen:
* Ermittlung der Hunkstruktur einer ausführbaren oder ladbaren Datei.
*
* Erstellungsdatum:
* 07-Jul-93 Rolf Böhme
*
* Änderungen:
* 07-Jul-93 Rolf Böhme Erstellung
*
***************************************************************************
*/
#include "RSysDebug.h"
#include "RSysFunc.h"
static struct hunkentry
{
struct Node denode;
char *name;
struct hunkentry *next;
};
static struct Remember *hekey = NULL;
#define RKEY ((struct Remember **)&hekey)
#define SIZEDE sizeof(struct hunkentry)
extern struct Window *TreeWnd;
extern struct Gadget *TreeGadgets[3],*TreeGList;
extern int decnt,breakit;
extern UBYTE *TreeWdt;
extern UBYTE *TreeWdt1;
enum
{
GD_TreeLV,
GD_SaveGad,
GD_KindCY
};
static struct hunkentry *loop, *firstde;
static struct List Tree;
static enum ext_types1
{
ext_def = 1,
ext_abs,
ext_res
};
static char *ext_names1[] =
{
"dummy ",
"ext_def ",
"ext_abs ",
"ext_res "
};
static enum ext_types2
{
ext_ref32 = 129,
ext_common,
ext_ref16,
ext_ref8,
ext_dref32,
ext_dref16,
ext_dref8
};
static char *ext_names2[] =
{
"ext_ref32 ",
"ext_common ",
"ext_ref16 ",
"ext_ref8 ",
"ext_dref32 ",
"ext_dref16 ",
"ext_dref8 "
};
static enum hunktypes
{
hunk_unit = 0x3e7,
hunk_name, /* 0x3e8 */
hunk_code, /* 0x3e9 */
hunk_data, /* 0x3ea */
hunk_bss, /* 0x3eb */
hunk_reloc32, /* 0x3ec */
hunk_reloc16, /* 0x3ed */
hunk_reloc8, /* 0x3ee */
hunk_ext, /* 0x3ef */
hunk_symbol, /* 0x3f0 */
hunk_debug, /* 0x3f1 */
hunk_end, /* 0x3f2 */
hunk_header, /* 0x3f3 */
dummy, /* 0x3f4 */
hunk_overlay, /* 0x3f5 */
hunk_break, /* 0x3f6 */
dummy1, /* 0x3f7 */
dummy2, /* 0x3f8 */
dummy3, /* 0x3f9 */
hunk_lib, /* 0x3fa */
hunk_libindex /* 0x3fb */
};
char *names[]=
{
"hunk_unit",
"hunk_name",
" hunk_code",
" hunk_data",
" hunk_bss",
" hunk_reloc32",
" hunk_reloc16",
" hunk_reloc8 ",
" hunk_ext",
" hunk_symbol",
" hunk_debug",
"hunk_end",
"hunk_header",
"dummy",
"hunk_overlay",
"hunk_break ",
"dummy",
"dummy",
"dummy",
"lib_hunk",
"lib_index"
};
/*
static char hunkblanks[] =
{
"", "",
" ", " ", " ",
" ", " ", " ", " ", " ", " ",
"", "", "",
" ", " ",
"", "", "",
" ", " "
};
*/
static BPTR file;
/*
* makehunkentry() erzeugt einen Listeneintrag aus einem Hunk
* einer ausführbaren Datei
*/
static struct hunkentry *
makehunkentry(struct hunkentry *last, char *name)
{
DPOS;
if ((last = (struct hunkentry *) AllocRemember(RKEY, SIZEDE,
MEMF_CLEAR | MEMF_ANY)) &&
(last->name = (char *)AllocRemember(RKEY, strlen(name) + 1,
MEMF_CLEAR | MEMF_ANY)))
{
strcpy(last->name, name);
last->next = NULL;
last->denode.ln_Name = last->name;
last->denode.ln_Type = 0;
InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
AddTail(&Tree, &last->denode);
InitListView(TreeWnd,TreeGadgets[GD_TreeLV],&Tree,decnt);
decnt++;
return (last->next);
}
else
ErrorHandle(MEMORY_ERR, ALLOC_FAIL, KILL);
return (NULL);
}
/*
* jumpinfile() setzt den Dateizeiger um eine Anzahl ULONG's
* weiter vor
*/
static int
jumpinfile(ULONG d)
{
int serr;
serr = Seek(file, d * sizeof(ULONG), OFFSET_CURRENT);
if (serr < 0)
return(FALSE);
return(TRUE);
}
/*
* readlong() liest ein ULONG aus einer Datei aus
*/
static int
readlong(ULONG *d)
{
return (Read(file, d, sizeof(ULONG)));
}
/*
* readtext() liest einen Text definierter Länge aus
* einer Datei aus
*/
static int
readtext(char *d,long count)
{
ULONG readdata[MAXSTRLEN];
int ret = 0,i,len = 0;
union {
ULONG ul;
unsigned char ut[4];
} cv;
if(count == 0)
{
strcpy(d, field[NO_FIELD]);
return(ret);
}
ret = Read(file, readdata, count * sizeof(ULONG));
d[0] = STRINGEND;
cv.ul = 0L;
cv.ul = readdata[0];
strncpy(d,(char *)cv.ut,4);
len +=4;
d[len] = STRINGEND;
for(i = 1; i < count; i++)
{
cv.ul = 0L;
cv.ul = readdata[i];
strncat(d,(char *)cv.ut,4);
len += 4;
d[len] = STRINGEND;
}
return (ret);
}
/*
* currentpos() ermittelt die aktuelle Position des Dateizeigers
*/
static long
currentpos(void)
{
return (Seek(file, 0L, OFFSET_CURRENT) - sizeof(ULONG));
}
/*
* ScanHunks() ermittelt alle Hunks eines ausführbaren Files und
* trägt diese in eine interne Liste ein
*/
static void
ScanHunks(char *filename)
{
ULONG data,
data2,
data3,
type,
typeofmem,
type_of_hunk,
lasthunk = hunk_name;
char datatext[120];
int error,
i,
z;
char buffer[MAXFULLNAME],
blanks[10] = " ",
*memtype[3] = {"MEMF_CHIP","MEMF_FAST"};
int ext_type,failure = 0;
DPOS;
sprintf(buffer, "File name : %s", filename);
loop = makehunkentry(loop, buffer);
sprintf(buffer, "File size : %ld", SizeOfFile(filename));
loop = makehunkentry(loop, buffer);
if (file = Open((UBYTE *) filename, MODE_OLDFILE))
{
error = readlong(&data);
while ((error > 0) && NOT(ClickedCloseGadget()))
{
type = data - hunk_unit;
type_of_hunk = ((data << 8) >> 8);
if ((type_of_hunk >= hunk_unit) &&
(type_of_hunk <= hunk_libindex) &&
(type_of_hunk != hunk_end) &&
(type_of_hunk != hunk_break))
{
loop = makehunkentry(loop, (char *)field[BLANK_FIELD]);
sprintf(buffer, "%s (o: \$%lx,\#%ld t: \$%lx,\#%ld)",
names[type], currentpos(),
currentpos(),data,data);
loop = makehunkentry(loop, buffer);
}
switch (type_of_hunk)
{
case hunk_unit:
case hunk_name:
error = readlong(&data);
if((error > 0) && data)
{
error = readtext(datatext,data);
sprintf(buffer, " Name: %s",(char *)datatext);
}
else
strcpy(buffer, " Name: -");
loop = makehunkentry(loop, buffer);
break;
case hunk_code:
case hunk_bss:
case hunk_data:
typeofmem = ((data & (1L<<30)) ? 0 : 1);
error = readlong(&data);
sprintf(buffer, " Size: \$%lx, \#%ld (%s)",
data * 4, data * 4,memtype[typeofmem]);
loop = makehunkentry(loop, buffer);
if (type_of_hunk != hunk_bss)
if (NOT(jumpinfile(data)))
loop = makehunkentry(loop, "Seek() error!");
break;
case hunk_reloc32:
case hunk_reloc16:
case hunk_reloc8:
error = readlong(&data);
while ((error > 0) && data != 0L)
{
data2 = data;
error = readlong(&data3);
sprintf(buffer, " \#%-3ld offsets in Hunk \#%-3ld",
data, data3);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data2)))
{
loop = makehunkentry(loop, "Seek() error!");
break;
}
error = readlong(&data);
}
break;
case hunk_ext:
error = readlong(&data);
z = 0;
while(data && (error > 0))
{
ext_type = (int)(data >> 24);
data = (data << 8) >> 8;
switch(ext_type)
{
case ext_def:
case ext_abs:
case ext_res:
error = readtext(datatext,data);
error = readlong(&data2);
sprintf(buffer, " %s: %-22s val: %ld",
ext_names1[ext_type-ext_def+1],datatext, data2);
loop = makehunkentry(loop, buffer);
break;
case ext_ref32:
case ext_dref32:
error = readtext(datatext,data);
error = readlong(&data2);
sprintf(buffer, " %s: %-22s refs: %ld",
ext_names2[ext_type-ext_ref32],datatext,data2);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data2)))
loop = makehunkentry(loop, "Seek() error!");
break;
case ext_common:
error = readlong(&data);
error = readlong(&data2);
sprintf(buffer, " %s (size): %ld refs: %ld",
ext_names2[ext_type-ext_ref32],data,data2);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data2)))
loop = makehunkentry(loop, "Seek() error!");
break;
case ext_ref16:
case ext_ref8:
case ext_dref16:
case ext_dref8:
error = readtext(datatext,data);
error = readlong(&data2);
sprintf(buffer, " %s: %-22s refs: %ld",
ext_names2[ext_type-ext_ref32],datatext, data2);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data2)))
loop = makehunkentry(loop, "Seek() error!");
break;
default:
loop = makehunkentry(loop, "Unknown external reference!");
break;
}
z++;
error = readlong(&data);
}
sprintf(buffer, " External refs: %ld",z);
loop = makehunkentry(loop, buffer);
break;
case hunk_symbol:
error = readlong(&data);
z=0;
while(data && (error > 0))
{
data = (data << 8) >> 8;
error = readtext(datatext,data);
error = readlong(&data);
sprintf(buffer, " Symbol: %-22s val: %ld",
datatext,data);
loop = makehunkentry(loop, buffer);
error = readlong(&data);
z++;
}
sprintf(buffer, " External symbols: %ld", z);
loop = makehunkentry(loop, buffer);
break;
case hunk_debug:
error = readlong(&data);
sprintf(buffer, " \$%lx, \#%ld",data * 4, data * 4);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data)))
loop = makehunkentry(loop, "Seek() error!");
break;
case hunk_end:
if(lasthunk >= hunk_code && lasthunk <= hunk_debug)
strcpy(blanks," ");
else
strcpy(blanks," ");
sprintf(buffer, "%s%s (o: \$%lx,\#%ld t: \$%lx,\#%ld)",
blanks,names[type], currentpos(), currentpos(),data,data);
loop = makehunkentry(loop, buffer);
break;
case hunk_header:
error = readlong(&data);
while ((error > 0) && data != 0L)
error = readlong(&data);
error = readlong(&data);
sprintf(buffer, " Count hunks : \#%ld",data);
loop = makehunkentry(loop, buffer);
error = readlong(&data2);
sprintf(buffer, " First hunk : \#%ld", data2);
loop = makehunkentry(loop, buffer);
error = readlong(&data3);
sprintf(buffer, " Last hunk : \#%ld", data3);
loop = makehunkentry(loop, buffer);
for (i = data2; error && i <= data3; i++)
{
error = readlong(&data);
if (error > 0)
{
sprintf(buffer, " Hunk \#%ld, Length \$%lx, \#%ld",
i, data * 4, data * 4);
loop = makehunkentry(loop, buffer);
}
else
{
sprintf(buffer, " Hunk \#%ld, Length ??", i);
loop = makehunkentry(loop, buffer);
}
}
break;
case hunk_overlay:
error = readlong(&data);
sprintf(buffer, " Table size: \$%lx, \#%ld",data, data);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data)))
loop = makehunkentry(loop, "Seek() error!");
break;
case hunk_break:
loop = makehunkentry(loop, (char *)field[BLANK_FIELD]);
sprintf(buffer, "%s (o: \$%lx,\#%ld t: \$%lx,\#%ld)",
names[type], currentpos(), currentpos(),data,data);
loop = makehunkentry(loop, buffer);
break;
case hunk_lib:
case hunk_libindex:
error = readlong(&data);
sprintf(buffer, "\$%lx, \#%ld", data * 4, data * 4);
loop = makehunkentry(loop, buffer);
if (NOT(jumpinfile(data)))
loop = makehunkentry(loop, "Seek() error!");
break;
default:
loop = makehunkentry(loop, (char *)field[BLANK_FIELD]);
sprintf(buffer, "%s: \#%ld (\$%lX)", "Unknown hunk type position",
currentpos(),currentpos());
loop = makehunkentry(loop, buffer);
failure++;
if(failure >= 5)
Seek(file, 0L, OFFSET_END);
break;
}
lasthunk = type_of_hunk;
error = readlong(&data);
}
Close(file);
}
return;
}
/*
* MakeHunkList() erzeugt aus einem ausführbaren File eine
* Liste aus den Hunks, aus denen das Executable besteht. Zuvor
* werden die Gadgets deaktiviert
*/
static void
MakeHunkList(char *file)
{
loop = firstde;
if(SysWnd)
PrintInfo("Scanning Hunks", SPEAK, 0);
SetWindowTitles(TreeWnd, (UBYTE *) "<- Cancel reading Hunks...",
NOSCREENTITLECHANGE);
EnableGadget(TreeWnd, TreeGadgets[GD_SaveGad], FALSE);
EnableGadget(TreeWnd, TreeGadgets[GD_KindCY], FALSE);
ScanHunks(file);
SetWindowTitles(TreeWnd, TreeWdt1, NOSCREENTITLECHANGE);
EnableGadget(TreeWnd, TreeGadgets[GD_SaveGad], TRUE);
EnableGadget(TreeWnd, TreeGadgets[GD_KindCY], TRUE);
return;
}
/*
* PrintHunkStruct() bietet eine kleine Benutzeroberfläche an
* und ermittelt die Hunks eines Executables. Diese werden dann
* in einem ListView angezeigt
*/
void
PrintHunkStruct(char *file)
{
struct IntuiMessage *message;
ULONG class,
code;
APTR object;
APTR req;
int id;
DPOS;
Flags.quit_hunk = 0;
NewList(&Tree);
if (NOT(OpenTreeWindow(NULL, TRUE)))
{
if (SysWnd)
{
req = LockWindow(SysWnd);
PrintInfo("Scanning Hunks", SPEAK, 0);
}
decnt = 0;
if(file)
{
InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
breakit = FALSE;
MakeHunkList(file);
}
do
{
Wait(1L << TreeWnd->UserPort->mp_SigBit);
while ((message = (struct IntuiMessage *)
GT_GetIMsg(TreeWnd->UserPort)) != NULL)
{
class = message->Class;
code = message->Code;
object = message->IAddress;
GT_ReplyIMsg(message);
switch(class)
{
case IDCMP_CLOSEWINDOW:
Flags.quit_hunk = 1;
break;
case IDCMP_GADGETUP:
id = ((struct Gadget *)object)->GadgetID;
switch(id)
{
case GD_SaveGad:
if (GetFile(TreeWnd,"RAM:","RSys-Hunk.DAT","#?.dat",
"Select File for saving hunklist","Save"))
SaveList(TreeWnd, (char *)_fullpath,
(char *)"RSys-Hunk.DAT",&Tree, FALSE);
break;
case GD_KindCY:
InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
if (NOT(IsListEmpty(&Tree)))
{
NewList(&Tree);
FreeRemember(RKEY, TRUE);
}
decnt = 0;
breakit = FALSE;
if (GetFile(TreeWnd,NULL,NULL,NULL,
"Select File for Hunk list","Show"))
MakeHunkList((char *)_fullpath);
break;
}
break;
case IDCMP_VANILLAKEY:
if((char)code == ESC)
Flags.quit_hunk = 1;
break;
}
}
}
while (NOT(Flags.quit_hunk));
InitListView(TreeWnd,TreeGadgets[GD_TreeLV],NULL,UNSETLVPOS);
if (NOT(IsListEmpty(&Tree)))
{
NewList(&Tree);
FreeRemember(RKEY, TRUE);
}
CloseASysWindow(&TreeWnd, &TreeGList, NULL);
if (SysWnd)
{
UnlockWindow(req);
RefreshMainWindowPattern();
RefreshList(LastID);
}
}
else
ErrorHandle(WINDOW_ERR, OPEN_FAIL, NO_KILL);
return;
}
/*
* PrintHunkStruct() kann mit einem Parameter aufgerufen werden
* oder ohne. Kommt der Aufruf nicht vom RSysAppIcon, so wird kein
* Filename übergeben und der Aufruf wird von HunkStruct() aus
* getätigt
*/
void
HunkStruct(void)
{
DPOS;
PrintHunkStruct(NULL);
return;
}