The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My work

  • My badges

  • Twitter Updates

  • My Flickr Stream

    20140508-Delphi-2007--Project-Options--Cannot-Edit-Application-Title-HelpFile-Icon-Theming

    20140430-Fiddler-Filter-Actions-Button-Run-Filterset-now

    20140424-Windows-7-free-disk-space

    More Photos
  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,751 other followers

Batch file to get a (non-sorted non-unique) list of units from a Delphi compiled map file

Posted by jpluimers on 2017/01/10

A few weeks ago in When you get “TfsScript.Execute” throwing a “Unregistered version of FastScript.” I wrote about “a process that explains any modules in the MAP file not resulting in DCU files”.

The below batch file aids in that process.

It takes a MAP file from your Delphi compiled executable that has debug information in text format which means you need to set your project linker options to generate detailed MAP files.

The Map Debug File (*.map) – RAD Studio documentation hasn’t much information but points to Detailed-Segments Map File – RAD Studio which has a bit more. Neither contain information on Delphi units as they focus too much on the C++ side of things. Then there is a tiny bit information in Understanding Delphi MAP File – Stack Overflow.

So I did some spelunking and came up with this batch-file which will likely work back until about the Delphi 7 era:

@echo off
  if ["%*"]==[] goto :help
:logic
  if not exist %1 goto :notExist
  setlocal
:: do not use periods (.) in delims as unit names may contain them!
:: it might be that the segment (%%a) for C=CODE/S=.text/G=(none)/M=*/ACBP=A9 is always 0001
:: it might be that the segment (%%a) for C=ICODE/S=.itext/G=(none)/M=*/ACBP=A9 is always 0002
:: it might be that the segment (%%a) for C=DATA/S=.data/G=DGROUP/M=*/ACBP=A9 is always 0003
:: it might be that the segment (%%a) for C=BSS/S=.bss/G=DGROUP/M=*/ACBP=A9 is always 0004
:: it might be that the segment (%%a) for C=TLS/S=.tls/G=(none)/M=*/ACBP=A9 is always 0005
:: the `if ["%%h"]==["(none)"] ` trick is to prevent this error:
:: ) was unexpected at this time.
  for /f "tokens=1,2,3,4,5,6,7,8,9,10,11,12,13,14,* delims=()= " %%a IN (%1) do (
    if   [%%c]==[C]     if [%%e]==[S]      if [%%g]==[G]          if [%%i]==[M] if [%%k]==[ACBP] if [%%l]==[A9] if [%%m]==[] (
      if [%%d]==[CODE]  if [%%f]==[.text]  if ["%%h"]==["(none)"] echo %%j
      if [%%d]==[ICODE] if [%%f]==[.itext] if ["%%h"]==["(none)"] echo %%j
      if [%%d]==[DATA]  if [%%f]==[.data]  if ["%%h"]==["DGROUP"] echo %%j
      if [%%d]==[BSS]   if [%%f]==[.bss]   if ["%%h"]==["DGROUP"] echo %%j
      if [%%d]==[TLS]   if [%%f]==[.tls]   if ["%%h"]==["(none)"] echo %%j
    )
    if   [%%a]==[line] if [%%b]==[numbers] if [%%c]==[for] if [%%f]==[segment] if [%%g]==[.text] if [%%h]==[] (
      echo %%d
    )
  )
  endlocal
  goto :eof

  echo a=%%a;b=%%b;b=%%b;c=%%c;d=%%d;e=%%e;f=%%f;g=%%g;h=%%h;i=%%i;j=%%j;k=%%k;l=%%l;m=%%m;n=%%n
  if [%%c]==[C] if [%%d]==[CODE]  if [%%e]==[S] if [%%f]==[.text]  if [%%g]==[G] if ["%%h"]==["(none)"] if [%%i]==[M] if [%%k]==[ACBP] if [%%l]==[A9] if [%%m]==[] echo %%j

:notExist
  echo %* does not exist.
:help
  echo syntax: %0 MAP-file
  echo will list all the Delphi units that got compiled into your EXE in a non-sorted non-unique way
  goto :eof

Pipe it through sort and then to some sort of uniq script like this PowerShell one.

Then check it against the sorted list of .DCU files the Delphi compiler produced for your project (ensure you cleaned the .DCU directory before compiling).

I usually use Beyond Compare to do this comparison for me.

–jeroen

One Response to “Batch file to get a (non-sorted non-unique) list of units from a Delphi compiled map file”

  1. Delphi version of it (independent implementation): https://sourceforge.net/p/dzlib/code/HEAD/tree/dzlib/trunk/src/u_dzMapFileReader.pas

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: