

    ObjPatch 0.2.0.x (beta)

      Copyright (c) 1998, Stefan Hoffmeister

            Stefan.Hoffmeister@PoBoxes.com

        All rights reserved



Licence
-------

  In plain English, this licence agreement
  tells you that

  - you may use this software free of charge;

  - you use it entirely at your own risk;

  - you can distribute it to anyone interested
    provided you don't charge for it;

  - there is no way to sue me if this software
    does not do what you and I want to see it
    to do it.



  The legalese version:

  USE OF THE ENCLOSED SOFTWARE INDICATES YOUR
  ASSENT TO THE FOLLOWING LICENCE CONDITIONS.


  This licence agreement is exclusively governed
  by the laws and rules of the Federal Republic
  of Germany.

  Non-acceptance or violation of any of the terms
  laid out in this agreement immediately and
  unconditionally terminate any existing licence
  and constitutes a violation of national and
  international copyright law.


  You are granted a non-exclusive, personal
  right to install and use this software on
  any number of machines.

  You may redistribute this software freely,
  if you distribute the original distribution
  archive without any modifications.

  You must not charge for distribution of
  this software except for covering the
  cost of distribution itself.

  The source code of this software, in case
  you received it, must not be distributed.


  You finally agree that:

  THE AUTHOR OF THIS SOFTWARE CANNOT BE
  HELD LIABLE FOR ANY DIRECT OR INDIRECT
  DAMAGE THAT MAY ARISIE THROUGH
  INSTALLATION OR USE OF THIS SOFTWARE.

  ANY USE OF THIS SOFTWARE IS COMPLETELY
  AT YOUR OWN RISK.



Warranty
--------

  There is no warranty at all. Use at
  your own risk.

  This software is still in BETA state,
  a state which can roughly be circumscribed
  as "experimental".

  Expect bugs, failures, crashes. In the case of
  this happening

  - please accept the author's sincerest apologies

and,

  - please, do contact the author at any one of
    the above addresses.

  The problem will be fixed as soon as possible.



Credits
-------

  Hallvard Vassbotn triggered development of
  this tool by showing an interesting technique
  and saying:

    It should be relatively easy to create a
    tool that fixes up OBJ files like this.
    That is left as an exercise for the reader <g>!

  Well, this IS the tool.


  Paul D. DeRocco suggested that a post-processor
  could scan for prefix bytes and correct the
  instruction stream for this.



Motivation
----------

  Both Delphi 3 and Delphi 4 have a problem
  linking perfectly valid OBJ files created
  by Turbo Assembler (TASM).

  Not much of a problem, you would believe,
  but this issue makes it virtually impossible
  to use any of the more advanced CPU opcodes
  in Delphi-created applications.

  This software processes those OBJ files created
  by TASM, tries to find the offending locations
  and patch the OBJ file in a way such that it
  will be accepted by the Delphi linker.

  A very simple pattern matching algorithm is
  employed to detect those special cases where
  the Delphi linker fails. There is no need
  to modify your assembler source code.


  Additionally this software can be used
  to work around a serious ILINK32 3.0x
  bug. This bug is uncovered by the same
  OBJ files, but otherwise completely
  unrelated to the Delphi linker issue.

  Follow the usage instructions below
  to make this tool pose as TASM32 and
  and Borland C++ Builder will build the
  correct instruction sequence from your
  OBJ files.


  Finally, assembler macro libraries that
  provide instruction emulation through the
  use of the ORG directive have a problem
  correctly handling prefixes to the
  patched instructions.

  This software hopefully will remove these
  problems without having to bother with
  it in the macro library.


Installation
------------

  Extract all files in the archives
  to a folder of your choice.

  Run.

  Optionally read the section on
  TASM32 integration below.


Deinstallation
--------------

  In the system registry completely
  delete this key

    HKEY_CURRENT_USER\Software\Econos\Dumper


Usage notes
-----------

  For the GUI interface everything is quite
  simple: select one or more OBJ files and
  get them patched.  The GUI also supports
  file drag-and-drop operations.


  The command line version of this software
  is a little bit more complex:

  - The program will assume that TASM32 is in
    the same directory as this software.

  - It assumes that the "real" TASM32 executable
    has the same name as this program, only
    with a "p" in front of it.

  - Any program with that name will be assumed
    to be TASM32 and will be called as this.

  Algorithmically this can be expressed as:

     Execute := ExtractFilePath(ParamStr(0))
                + 'p'
                + ExtractFileName(ParamStr(0));

  where ParamStr(0) is the complete path to the
  TASM in-between found in this archive.

    Example:

      - This program is called TASM32.EXE

      - Rename your ORIGINAL copy of TASM32.EXE
        (the assembler) to pTASM32.EXE

      - Copy the program you found in this archive
        to the same folder as pTASM32.EXE

      - Execute TASM32.EXE (this software) which
        in turn will call pTASM32.EXE


  The command line version of this software
  adds switches to the TASM command line.

  If the switch

      /nopatch      (case-insensitive)

  is present, it will be filtered out and no
  OBJ-patching at all will be done.


  If the switch

      /noprefixes   (case-insensitive)

  is present, it will be filtered out and
  the prefix correction logic will not be
  used.

  You can set up a default file for these
  command line parameters. <ExeName>.INI
  - for instance TASM32.INI - is always
  checked and has these default
  parameters:

    [Patch settings]
    DoPatch=1
    CorrectForPrefixes=1

  If you need to override any of these
  defaults, then create a Windows-style
  INI file in the same directory as the
  in-between (TASM32.EXE) and change any
  of the setting from 1 to 0.


Known problems / limitations
----------------------------


  There is MAJOR PROBLEM with all compilers
  that generate OMF records like this

      006C78 LEDATA  Segment: '__tpdsc__[forms::tform*]'Offset: 0000  Length: 001B
          0000: 04 00 00 00 90 00 0C 00  00 00 00 00 46 6F 72 6D   ............Form
          0010: 73 3A 3A 54 46 6F 72 6D  20 2A 00                  s::TForm *.
      006C9B FIXU32
          FixUp: 008  Mode: Seg  Loc: Offset32    Frame: GI[1]   Target: VEI[72]
      006CA5 LEDATA  Segment: '__tpdsc__[tform1*]'Offset: 0000  Length: 0015
          0000: 04 00 00 00 90 00 0C 00  00 00 00 00 54 46 6F 72   ............TFor
          0010: 6D 31 20 2A 00                                     m1 *.

  The patcher (at this time) is too dumb to
  read and parse the FIXU?? data.

  THIS IS DANGEROUS and the only safe-guard
  against patching this is the requirement
  that

  -> patch data is EXACTLY ONE BYTE LARGE <-

  It is quite hard to imagine a situation
  where you have a LEDATA record with a size
  of 1 byte that falls into the previous
  LEDATA record - except if you use the
  ORG directive.

  This patcher works perfectly for my needs
  (mainly to patch ORG-emulated F[U]COM[I]
  instructions), thus my motiviation to build
  a saner, more reasonable logic is quite
  low, I am afraid.


  The command line parser that tries to figure
  out which OBJ files to patch is quite limited.

  The TASM command line can be pretty complex
  and this version of the patcher only handles
  one case: one assembler file, no wildcards ('*')
  or jokers ('?'). No concatenation ('+'). No
  multiple source files (';').

  If you do not understand what the previous
  paragraph is all about, then you probably will
  not experience any problems with the implemented
  command line parser. Just forget about it.

  In case you still need a better command line
  parser, please send a routine (Pascal or C++)
  that, given the original command line, will
  return a list of all OBJ files to be patched
  with their destination.

  Again, the command line parser works for me
  just fine, it works well when used as an
  in-between for C++ Builder 3.0, so my motivation
  to write a more comprehensive parser myself
  is quite low.



  The patcher only checks for FIXUPP or FIXU32
  records between LEDATA records. It is not certain
  at this time whether this a limitation or
  problem at all. Theoretically, all should be fine.
  More test cases are needed.



  The patcher will only combine _two_ LEDATA records.
  This means that if you use the ORG directive more
  than once to overwrite bytes in a _single_ CPU
  instruction, patching will succeed only partially.

  There is no work-around for this limitation at
  this time.

  There is no problem with using ORG more than once,
  it is only a problem if you reposition the byte
  stream locator more than once on one atomic CPU
  instruction. But this will hardly ever happen.



  The amount of testing this software has seen
  is still limited. Expect problems.



Still to do...

  Contributions and feedback are very welcome!

  - Test, test, test...

  - Verify that this runs properly on Windows 95
    and Windows 98 (nothing specific to Windows
    NT 4.0 has been used, though). Testing on
    Win95 has been limited, on Win98 non-existent.

  - More tests with 16 bit segments and with 16 bit
    compilers (Delphi 1 does not appear to
    have a problem with ORG, though).
    Should not be a problem.

  - Verify that everything keeps working with
    weird paths, long path names, or files
    where no complete path name is given.

  - Perhaps add another switch "/backupobj" that
    creates a backup copy of the original,
    unpatched OBJ file? Is this useful?




Version history


  0.2.0.0:  First public release


  0.1.0.x:  First, privately circled, release

            Fixes:
              - ObjPatch now deletes OBJ in
                case of an internal error

              - Changed message to get it into BCB 3

              - New requirement: ONLY one byte
                  must be patched into the
                  previous record

                  This is a pretty restrictive
                  assumption, but for the moment
                  the only way to achieve
                  compatibility with the way
                  BCB 3 generates assembler files
                  for C(++) source code.

