home *** CD-ROM | disk | FTP | other *** search
- /*
- ***************************************************************************
- *
- * 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;
- }
-
-