Errors and omissions
Borland Open Architecture Handbook for Pascal
Chapter 4 Symbol table format  (Turbo Debug Information)

Andy McFarland [71055,2743]

p 51  This chapter describes the format of the symbol table that
      appears at the END of an .EXE file.

p 51  Observed VersionIDs for BP7 : $208 (real mode without objects),
      $209 (real mode with objects), $300 (protected mode).

p 51  GlobalsCount is optional -- 0 for Pascal EXE's

p 52  TDebugHeader.ImageSize is 0 for Pascal EXE's  Need to calculate
      this using information from EXE header (real mode), or CodeView
      trailer (protected mode).

p 52  DataCount = length of DataPool.  DataPool contains untyped
      constant strings and extended constants where Symbol.Offset =
      offset in DataPool. Untyped constant sets do not appear in the
      data pool.

p 52  If ExtensionSize = 16, CoverageOffsetCount and the first word
      of NamePoolOffset are filler.

p 53  'memory map' is not a section in the debug information.

p 53  There are 16 bytes from the CodeView header to the start of Turbo
      Debug information.  First two bytes are 'NB' (Protected mode)

p 53  Names are NOT stored uniquely. (Pascal)

p 54  Observed values for TSymbolRecord.Info :
        0 : Assembler subroutines with no stack frame
            Interrupt procedures
            Global variables
            Typed Constants
            Absolute <identifier>
        1 : Absolute segment:offset
        2 : Local variables
        3 : Function result returned on the stack -- string
            Self
        5 : Untyped constants
        6 : Type
       10 : Value parameter
       11 : Var parameter
       24 : Subroutines with a stack frame

p 54  Symbols are sorted, but the main criterion is not 'address order'.

p 56  Return_address_word_offset is not used by Pascal

p 56  Type ModuleHeader, reorder fields : Language then Flags

p 56  Memory_model := Flags and 7 ;

p 57  For Pascal only : Symbols_index is the first global symbol in
      the implementation, Symbols_count is the number of symbols in
      the implementation.

      For each unit, all symbols in the interface precede the symbols
      in the implementation.

p 59  'Only unique offset have line numbers stored.'  If several lines
      have the same offset, only the one which generates code is stored.

p 59  'When a statement spans several lines' ...  I have not found
      any example of more than one line record for one source line.

p 59  Function_symbol = $FFFF (UnitScope) :
         Autos_index is the first symbol in a unit.
         Autos_count is the number of symbols in the interface.
         Parent_Scope is ScopeIndex of the first UsesScope.
         Scope_Offset, Scope_Length is of unit initialization, if any.

      Function_Symbol = $FFFE (UsesScope) :
         Autos_Index is the index to the UnitScope.
         Parent_Scope is the index to the next UsesScope.

p 59  Function_parent should be Function_symbol

p 60  Scope_parent should be Parent_scope.

p 61  Typedef makes no sense here, Correlation would be better.

p 61  TypeIndex = 0 for Protected mode System.RealModeRegisters.
      TDX can not access RealModeRegisters.

p 61  Interrupt Procedures generate Type 30 (near Pascal procedure)
      not Type 32 (Interrupt Procedure)

p 62  tid_sQuad tid_uQuad  are not ranges.
p 66  tid_Bool, tid_Tbyte are not ranges.
p 68  tid_WordBool, tid_LongBool
      The type record is 8 bytes : Type_id, Type_name, Type_size,
      3 bytes filler

p 63  Pointers Extra_Info is not documented. Extra_Info = 2 for PChar

p 65  Functions, Language see table on p 66.  Language and $40 <> 0
      means nested subroutine -- see TDUMP -v.

p 65  Functions, Accepts var.args.  At least one parameter is passed
      by reference, a 'var' parameter.

p 65  'Accepts var.args' works for Pascal functions but not procedures

p 65  For 'small' sets  offset 5 is 1.

p 67  Special functions Byte_15 = $90 for dymanic methods, $10 all
      other methods.  Byte_14 = 0 in all observations.

p 71  New_Offset : Word ;  last two bytes in Struct_Offset_Rec not used

p 71  Offset_rec := (Info = $40)  see p 72 last paragraph.

p 72  Member_rec is a variant record (union).  SizeOf(Member_rec)
      = 5.  see p 73 last paragraph, p 74 for the Info field.

p 73  End_of_structure  (Info and $80) <> 0

p 73  TParentTable is the identifier used for parents p 74

p 73  If object does not have a VMT, Virtual_ptr = $FFFF.

p 73  Info = $10 in all observations

p 74  Special cases : 'Member_record' refers to the Info field in the
      member_record.

p 74  If a Record type is smart linked, the record's fields do show as
      members.

p 75  'If any scope class records are needed, there must be one record
      for each scope record'.  BP7 has one scope class record for each
      module record.

      ScopeExtension Class_Index, Class_Count are for objects in
      Interface.

p 75  Class_Index is NOT the first Object in the Implementation.

      Module class table
      Type
         LocalClass =
         Record
            Overload_index,           { 0 for BP7 }
            Overload_count : Word ;   { 0 for BP7 }
            Class_index,          { ??? }
            Class_count : Word ;  { number of objects in Implementation }
         End ;

p 76  Coverage is not used in BP7 or when DebugHeader.ExtensionSize = 16