Documentation of HunkLab V2.34 by Michael Mutschler 24.7.93 ****************************************************************************** First of all: This program is SHAREWARE. If you want the full working program with the ARexx-port active and without this annoying slow Requester, please send US$10 or DM15 to the following address: Michael Mutschler Somborer Weg 11 71067 Sindelfingen Germany Or if you live in Germany you can do the following: Es ist ebenfalls möglich die Gebühr von DM10 auf mein Konto zu überweisen: Konto Nr: 3684791 BLZ: 603 501 30 Kreissparkasse Böblingen Bitte die eigene Adresse bei der Überweisung nicht vergessen! After this you will be shipped a disk with the latest Version of the HunkLab, along with your personal Keyfile. If you find any bugs, or if you have some good ideas, or if you have a good icon, I would be very pleased if you send them to me. You can reach me by EMail via one of the following addresses: Fido: 2:246/1115.1 Internet: amiinfo5@rusmv1.rus.uni-stuttgart.de The newest versions can be downloaded through the following: Mailbox: The Abyss Tel: +49-711-617291 Fido - FileRequest: The Abyss - 2:246/1115; File: "hunklab.lha" Internet anonymous FTP: rusmv1.rus.uni-stuttgart.de dir: soft/amiga/misc/hunklab.lha I would appreciate, if anybody would make a catalog in a not supported language. Please send me a mail (email preferred) first ****************************************************************************** Copyright: The Program may be spread, as long as the following files stay together: hl HunkLab2.doc Hunklab.rexx.doc locale/catalogs/deutsch/hl.catalog locale/catalogs/hl_str.cd locale/catalogs/hl_str_deutsch.ct and as long as no changes are made! The detaching-routines may be used in your programs, as long as they stay public domain. Every other commercially released program, which uses the detaching-routines needs the permission of the author. ***************************************************************************** Difference of the demo-version: - You can load (and process) only one file! - The ARexx-interface is disabled (the document shows what can be done with the normal version) - The Requester at the beginning (and the About-Requester) is very slow. It comes up too when you specify a file in the command line. This is not when you register. ***************************************************************************** ***************************************************************************** *** W A R N I N G ! *** *** There aren't any security-checks in the program. So you should *** *** always work on a backup. I am NOT responsible for any damaged *** *** file or program! *** ***************************************************************************** ***************************************************************************** Now the Documentation: see hunkLab.rexx.doc for the documentation of the AREXX-functions. This program is designed to shorten executables without crunching. This can be done by working with the hunk-structure of a program. You can merge equal hunks, remove symbol- & debug-hunks, remove the hunk-ends ... There are all standard function of some crunchers (PowerPacker: Hunks to chip, remove symbols and debugs; Imploder: merge) and several functions for programmers, e.g. people programming in assembler (such as me) can now get in the advantage of using BSS-parts of a CODE/DATA-hunks such as C-compilers do. Another feature is the ARexx interface, which can control the complete HunkLab. Starting the program: You can start either from Workbench or from CLI. When starting from CLI you can pass a file which will automatically be loaded. If no name is given, such as from the Workbench, you must click in the requester and a filerequester will appear, and you must select a file; otherwise, the program ends. The Filerequester depends on whether you are using Kick20 or not. If Kick20 is used, you get the ASL-requester or whatever it is patched (e.g. MFR), and when running on Kick13/12, you'll get the builtin filerequester.(I was too lazy to work on it anymore, because of ASL and the great MFR) You can also use the option '-NOFILE': No file is loaded, and no requester appears. This is useful when starting the program from AREXX-scripts. ( e.g. 'address command "hl -NOFILE"' ). If you're running under Kick2.0 then there is the possibility to drop an icon in the window, and the file will be automatically loaded. Another Command-line-option since V2.27 is '-NoWin'. This works only if Arexx is running, and doesn't open a window, so you can ONLY control it via ARexx. To use this, you need to register. Now you should have loaded an executeable or object file (others aren't accepted). Note: when loading a link-lib, it can take it can take a while to walk through the structure, because they sometimes have many many hunks. (e.g amiga.lib has 994 hunks and takes 8s to process on my unaccelerated A500.) You can use the arrows and the scrollbar to see the complete hunk-structure. Klicking with both mousebuttons (first LMB then RMB) on the arrows, and you can scroll faster. This is for example AmigaBASIC after merging: Hunk Nr 1: hunk_code 14796 bytes hunk_reloc32 308 entries hunk_end Hunk Nr 2: hunk_data 80 bytes (CHIP) hunk_end Hunk Nr 3: hunk_data 5612 bytes hunk_reloc32 186 entries hunk_end Hunk Nr 4: hunk_bss 632 bytes hunk_end The lines are to be interpreted as follows: CODE/DATA/BSS/overlay/debug: Hunk Nr 1: Hunk_data 80 Bytes (48 bss) (CHIP) | | | | | | | | | memory type: CHIP/FAST | | | | else public | | | | | | | difference of the lengths of Header and Hunk | | | works like BSS; if equal (=0) nothing is | | | displayed | | | | | Length of Hunk; if zero nothing is displayed | hunk type hunk number (only when CODE/DATA/BSS) relocs/symbol: Hunk_reloc32 308 entries | | | number of entries hunk type Header (in Overlay-part): Hunk_header 1 entry from 22 bis 22 | | | | | | | last hunk | | first hunk | number of hunks hunk type break/end Hunk_end | hunk type At the top of the window, there is a status line which shows what is currently done, or errors are displayed. The bottom shows some information about the program loaded. Now you can start manipulating the program: Therefore I'll explain the menus: PROJECT Load load a new file Reload load the old file again Save save over the old file. The file is saved directly without confirmation. Be careful, some function can damage the program. Save as save after selecting a new name Save raw This function is only available if the program has one hunk and no relocs. Then you can save only the program without header. Useful if you are writing a bootblock, or something like that. Print print out the hunk-structure (PRT: is used) more info This brings up a requester with additional information about the file. You get more detailed information how many hunks of a type there are, and about the memory usage of the file. The memory usage is calculated after the real usage after a LoadSeg()-call; this means every hunk needs 8 bytes more than the length of the hunk, and it is bounded to 8-bytes, because exec-memory-management handles it this way. Click in the requester to end. About brings up a requester Quit should I say anything to this? Yes: amiga.lib with its 994 Hunks takes 6s to quit, because there are more than 5000 Memory-Chunks to free. CHANGE HUNKS with this menu you can say where to load the Hunk: In CHIP, FAST or public memory. Usually you don't need it. But some (very) old programs were written for a 512k-CHIP_Mem-only A500, which loaded the program always in CHIP-Mem, and which could have problems on machines with FAST-mem. Be careful when using the function "to fast" it wouldn't work on Machines which have only CHIP-Mem. Always use "to public"! It is only for completeness integrated. Maybe someone want to use it? Using the menu "special/..." you can change a single hunk. You will be prompted to enter a hunk-number and this one is performed. SPECIAL FUNCTIONS Merge multiple reloc32 If there is more than one reloc32 for a hunk, they can be merged together with this function. Useful for those who want to crunch compiled GFABASIC programs. This function is deactivated if no reloc32 exist. Merge Hunks normal First you must enter a limit for the length of a hunk, so you can prevent the hunks from getting to large and cause DOS error 103. But you can switch the limit off by simply entering zero or just press return or klicking "OK" without entering anything. Now the following functions are executed: merge multiple reloc32 Remove Hunk_ends Remove Hunk_Symbol Remove Hunk_Debug Remove unused Hunks now the merging is done Check Hunk_Ends sort reloc32 The merging works as follows: The hunk which are from the same type are merged together. This is a very complex operation, and takes some time. e.g. 491 Hunks take 49.1 sec to merge. (for comparison: Imploder takes about 3:20 min, while it needs 30s to load and is less effective ...) WARNING: If a hunk (CODE or DATA) has a BSS-part, this part will be erased. This means the program, when executed, will use free (not allocated) memory, and the amiga will possibly crash. To avoid this you can call previously the function "BSS to Zeros". If there is only one hunk with a BSS-part, and this one is the last of that type (e.g. the last CODE-hunk) then you can call the funtion "Zeros to BSS" and check if the BSS-value of the hunk is the same as before. (You can try this with MED3.10.) This function is deactivated if no reloc32 exist. DATA -> CODE The same as normal with the feature that DATA-hunks are converted to CODE-hunks and then merged. This function is deactivated if no reloc32 exist. one-hunk-merge This function merges everything into one hunk: DATA and CODE are merged together, CHIP and public hunks too, so everything is in CHIP if there is one. BSS-hunks are added to the first hunk. This can cause trouble, because the memory of CODE- and DATA-hunks isn't cleared, so be careful. If you aren't sure, you can use "BSS to Zeros". This function is deactivated if no reloc32 exist. Remove empty hunks All empty hunks (with length of zero) are removed. Remove unused hunks This function is more powerful than the previous one because it searches the relocs for pointers to the hunks. Those who haven't got a pointer normally can't be accessed from the program and therefore can be deleted. Generally these are the empty hunks. But there are many programs which have a unused BSS-hunk with the length of 4 bytes (e.g. arp.library) which isn't used. I don't have any problems with the arp.library processed with this function. This function is deactivated if no reloc32 exist. Remove Hunk_Debugs All Hunk_Debugs are removed. Remove Hunk_Symbols All Hunk_Symbols are removed. Hunk_Symbols and Hunk_Debugs aren't used when a program is running. They are for debugging a program, and very useful. Remove Hunk_Ends All Hunk_Ends are removed except the last one, which is necessary for DOS to load the prg. Hunk_End aren't required too, but some Crunchers need them such as PowerPacker and Imploder. Therefore the next function is there: Check hunk_Ends This function checks if there is a Hunk_End after each hunk. It inserts one if it is missing and removes them if there is more than one. Sort Reloc32 If a reloc32 has more than one "group" pointing to the same hunk, the can be put together. This is mainly for the "Merge" functions and called from them. This function is deactivated if no reloc32 exist. FURTHER FUNCTIONS Zeros to BSS Select "single" to process only a specific hunk; "all" processes all hunks. This function checks if a hunk contains zeros at the end. If it has found something, they are are declared as BSS-parts of that hunk. This function is mainly for assembler-freaks who put their Variables at the End of a Hunk. »»»»»»»»»»»»»»»»»»»»»»»»»»»»» WARNING «««««««««««««««««««««««««««««««« After declaring it to BSS this part contains junk. that means you must clean it by yourself. This is fixed with Kick20. »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»««««««««««««««««««««««««««««««««««««« What's the difference to a real BSS-hunk? Well you can use PC-relative addressing for shorter and faster programs. But clear the Variables! BSS to Zeros The opposite of the function above. Maybe you want to use it if you want to merge. extra Hunks »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» ATTENTION ««««««««««««««««««««««««««««««« »» use these functions only when processing a normal executable file «« »» libraries, devices & co will be damaged!!!! «« »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»«««««««««««««««««««««««««««««««««««« add chpri You can add a Hunk to the beginning of a file, which just performs a SetTaskPri(FindTask(0),xxx), where xxx ist the priority, which you will be asked for. This way, you can start your programs with a predefined priority. If you want to delete it, you have to kill the first hunk (which should have a legth of 28 bytes, and 1 reloc-entry). add small detach This function adds an auto-detach-routine to the program. This means, the program detaches itself from the CLI and redirects its in- and output to NIL:. This means you needn't RUN or RUNBACK the program anymore. And you can close the CLI-window. If the program is started from WB, then no detaching is done. »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» ATTENTION ««««««««««««««««««««««««««««««« You can't process any CLI-commands. It behaves like a program starting like 'RUN NIL: prg'. So there are no INPUTS AND OUTPUTS via the CON-window possible. ==> Programs aren't pure anymore. That's because the detaching is done by splitting the SegList, and I don't know when a program is run from a resident file. »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»«««««««««««««««««««««««««««««««««««« add normal detach This function works like the above one, but uses a different routine. As it is called "normal", it is a bit longer, and a few more parameters from the CLI-structure are passed to the program: small-v v-normal small-v v-normal n cli_Result2 s n pr_CurrentDir n cli_SetName cli_CommandDir s n pr_CIS n cli_ReturnCode s n pr_COS n cli_CommandName n cli_FailLevel n pr_Result2 n cli_Prompt s n cli_StandardInput only when Kick20, else ignored: s n cli_CurrentInput s n pr_HomeDir cli_CommandFile s n pr_Arguments n cli_Interactive s n cli_Background s n cli_CurrentOutput n cli_DefaultStack s n cli_StandardOutput n cli_Module e.g. cli_Result2 is copied when using the normal routine, and left to zero, when the small routine is used. pr_CIS is initialized by both detach routines. These function add two hunks to the current program. The first MUST stand alone, the second can be merged. The merge function will take care of this but don't merge with Imploder! If the second is merged, it can't be removed anymore! That's because of the Seglist-splitting. The first hunk does the detaching and initializations such as the cli-Structure, and the second only inits the rest and does the cleanup. The funtions are disabled, if there is already a detach-hunk found. remove detach this function removes the detach-hunks, if it is possible. edit Hunk_Name This function is for creating/editing/deleting a Hunk_Name. The Hunk_Name before the first Hunk will be used. If none exists, one will be added, else you can edit the old text in the requester. This is good for putting the version-string of a program, because it is not often used by the program itself. Therefore if you put the string in the Hunk_Name, it isn't loaded, and doesn't use any memory. Could cause problems with future Versions of the version command, because the executeables are loaded with LoadSeg(). Delete hunk Very, very dangerous. A GURU is garanteed if you start the file afterwards by DOS. So, don't use it if you don't know what you are doing. I only implemented it to shorten programs for better disassembling and killing the detach-routines if possible. This are the menu-function of the HunkLab. Now I have to add a few more things: Some functions require the reloc32 of a program. If there aren't any in the program, they are disabled, and you should be careful. Typically these are BCPL or crunched programs. But you can use "Remove Hunk_Ends" very safely. Another feature is when you are interested in the hunk-structure and you haven't got enough memory to load the whole file into memory, only the structure is created and displayed. This takes a little more time. And the most functions are disabled. Another tip at least: You cannot only process executeable files, you can process libraries, devices and handlers too; everything which is loaded by the DOS-function LoadSeg(). Some programs with Overlays are supported too, but they have to look as follows: . : hunk_overlay 116 bytes hunk_header 1 entry from 4 to 4 <- one entry Hunk Nr 4: hunk_code 4208 bytes <- only one hunk hunk_end <- hunk_end hunk_break <- hunk_break hunk_header 1 entry from 5 to 5 Hunk Nr 5: hunk_code 9100 bytes hunk_end hunk_break hunk_header 1 entry from 6 to 6 Hunk Nr 6: hunk_code 9852 bytes hunk_end hunk_break . : Many Programs look like this (e.g. Butcher) and can be processed. If they look different, the most functions won't work correct. Note: always work on a copy of a program. FOR DAMAGED PROGRAMS WHICH WERE CAUSED BY HUNKLAB, THE USER IS RESPONSIBLE AND NOT THE PROGRAMMER. ******************************************************************************** Program history V2.34 (24.7.93) - bug fix: -nowin didn't work on Kick3.0. fixed. V2.33 (20.7.93) - added the "add chpri" option. Finally I'll release it... V2.32 (15.12.92) - Added CacheClearU() after decoding. V2.31 (27.9.92) - Bug fixed: when -nowin option specified no file was loaded. - when no file was loaded, ADD DETACH would crash. fixed. V2.3 (23.9.92) - no demo version anymore. You need a Keyfile to use all function of the program. V2.28 (6.9.92) - localization in DEMO too. Why not? WB2.1 is coming soon ... - added localized numbers for length and Number of hunks. - Fixed the routine when creating the HunkStructure without loading the file a bit. - Now quits when BREAK_C or BREAK_D recieved when waiting. Thanks Jens. - The Input-window doesn't look like a slider anymore. Hi Jens. - Bug fix: the length of a hunk_debug is now shown. - Bug fix: When running on Kick1.2 the Amiga was hanging after quitting. Fixed. V2.27 - detach-routines now take care of pr_Arguments (Kick20) (V1.11/2.11) - disabled Menu3+4 when object-file loaded. It's view only! - fixed bug in print routine - implemented the option '-NOWIN': doesn't open the window if ARexx is runnning - better handling of the command line: supports quotes. - changed the detach-routines: take care of pr_HomeDir if running on Kick20 [V1.1/2.1] - Bug fixed: no longer leaves 64 Bytes allocated. V2.26 - faster scrolling, if you have many hunks. - CreateName() rewritten: Better code. - added the new hunk-types: DREL32, DREL16, DREL8. I don't know how HUNK_LIB and HUNK_INDEX are built. So only their name is displayed. - if a Hunk_Name is displayed, the name itself is also shown. e.g. ("name"). - added the feature of loading object-files. View-only yet. - Filerequester: uses ASL on Kick20. - added 'edit Hunk_Name' function. - added AppWindow-feature for Kick20 - InitHunkStructure rewritten: shorter, faster (a bit). - fixed Bug: When the file doesn't exists, the load-routine would crash. - better cleanup: all outstanding messages are replied. V2.23 - fixed bug in requester - fixed bug in scrolling-routine. - few optimizations V2.21 first written history: - fixed bug on counting relocs/symbols: Previously I used the same routine. To process them, it's OK, but counting is different! Thanks FT. - The Filerequester didn't free its files. Oops. - Delete Hunk did always cancel. Fixed. ******************************************************************************** Future ideas: - Amigaguide documentation - german doc - font independent - 2.0-Style layout will be V3.0, depends on the feedback. - remove of possible enforcer hits... still using a A500 7Mhz :-( ******************************************************************************** Thats all.