1 | /* $Id: wat2map.cmd,v 1.1 2001/04/14 16:24:08 sandervl Exp $ */
|
---|
2 |
|
---|
3 | /* SCCSID = %W% %E% */
|
---|
4 | /****************************************************************************
|
---|
5 | * *
|
---|
6 | * Copyright (c) IBM Corporation 1994 - 1997. *
|
---|
7 | * *
|
---|
8 | * The following IBM OS/2 source code is provided to you solely for the *
|
---|
9 | * the purpose of assisting you in your development of OS/2 device drivers. *
|
---|
10 | * You may use this code in accordance with the IBM License Agreement *
|
---|
11 | * provided in the IBM Device Driver Source Kit for OS/2. *
|
---|
12 | * *
|
---|
13 | ****************************************************************************/
|
---|
14 | /**@internal %W%
|
---|
15 | * WAT2MAP - translate symbol map from Watcom format to MS format.
|
---|
16 | * @version %I%
|
---|
17 | * @context
|
---|
18 | * Unless otherwise noted, all interfaces are Ring-0, 16-bit, kernel stack.
|
---|
19 | * @notes
|
---|
20 | * Usage: WAT2MAP <watcom_mapfile >ms_mapfile
|
---|
21 | * - or -
|
---|
22 | * type watcom_mapfile | WAT2MAP >ms_mapfile
|
---|
23 | *
|
---|
24 | * Reads from stdin, writes to stdout. Will accept the Watcom map filename
|
---|
25 | * as an argument (in place of reading from stdin). Eg.,
|
---|
26 | *
|
---|
27 | * WAT2MAP watcom_mapfile >ms_mapfile
|
---|
28 | *
|
---|
29 | * Notes:
|
---|
30 | * 1.) The symbol handling in the debug kernel won't work for some of the
|
---|
31 | * characters used in the C++ name space. WAT2MAP handles these symbols
|
---|
32 | * as follows.
|
---|
33 | * Scoping operator symbol '::' is translated to '__'.
|
---|
34 | * Destructor symbol '~' is translated to 'd'.
|
---|
35 | * Symbols for operators '::operator' are not provided.
|
---|
36 | *
|
---|
37 | * Eg., for user defined class 'A', the symbol for constructor A::A is
|
---|
38 | * translated to A__A, and the destructor symbol A::~A becomes A__dA, and
|
---|
39 | * the assignment operator, 'A::operator =', is not translated.
|
---|
40 | *
|
---|
41 | * 2.) Bug - C++ provides for defining multiple functions with same fn name
|
---|
42 | * but different function signatures (different parameter lists). This
|
---|
43 | * utility just translates all the address / symbol combinations it finds,
|
---|
44 | * so you can end up with several addresses for a given fn name.
|
---|
45 | * @history
|
---|
46 | */
|
---|
47 | /* <End of helpText> - don't modify this string - used to flag end of help. */
|
---|
48 | /****************************************************************************/
|
---|
49 | CALL RXFUNCADD 'sysloadfuncs','rexxutil','sysloadfuncs'
|
---|
50 | call sysloadfuncs
|
---|
51 |
|
---|
52 | Parse Arg arg1 arg2 rest
|
---|
53 | If (Length( arg1 ) = 0) | (Verify( arg1, '/-?' ) = 0) Then Do;
|
---|
54 | Do i = 1 to 1000
|
---|
55 | helpText = Sourceline(i)
|
---|
56 | If Pos( '<End of helpText>', helpText ) <> 0 Then Leave; /* quit loop */
|
---|
57 | Say helpText
|
---|
58 | End;
|
---|
59 | Return
|
---|
60 | End;
|
---|
61 | If Length( arg2 ) = 0 Then Do;
|
---|
62 | Say " Way to go Beaver... How about an out-put file name ?"
|
---|
63 | Return
|
---|
64 | End;
|
---|
65 | mapFile = arg1 /* Can be Null, in which case we pull from stdin. */
|
---|
66 | outFile = arg2
|
---|
67 |
|
---|
68 | /* erase outfile */ /* kill the old map file */
|
---|
69 | rc=SysFileDelete(outfile)
|
---|
70 |
|
---|
71 |
|
---|
72 | /*--- 1. Find & translate module name. ---*/
|
---|
73 | Do While Lines( mapFile ) <> 0
|
---|
74 | watcomText = LineIn( mapFile )
|
---|
75 | Parse Value watcomText With "Executable Image: " fileName "." fileExt
|
---|
76 |
|
---|
77 | If fileName <> "" Then Do; /* Found match */
|
---|
78 | call lineout outfile ,' '
|
---|
79 | call lineout outfile ,' ' || fileName
|
---|
80 | call lineout outfile ,' '
|
---|
81 | Leave; /* Break from loop. */
|
---|
82 | End;
|
---|
83 | End
|
---|
84 | If Lines( mapFile ) = 0 Then Do; /* If end of file ... */
|
---|
85 | Say "Error: Expected to find line with text 'Executable Image:' "
|
---|
86 | Return
|
---|
87 | End
|
---|
88 |
|
---|
89 | /*--- 2. Skip the group definitions - Rob's notes say we don't need them. -*/
|
---|
90 |
|
---|
91 | /*--- 3. Skip to the start of the segment table. ---*/
|
---|
92 | Do While Lines( mapFile ) <> 0
|
---|
93 | watcomText = LineIn( mapFile )
|
---|
94 | Parse Value watcomText With "Segment" header_2_3 "Address" header_5
|
---|
95 | If Strip( header_5 ) = "Size" Then Leave; /* Found header line for Segment table. */
|
---|
96 | End
|
---|
97 | If Lines( mapFile ) = 0 Then Do; /* If end of file ... */
|
---|
98 | Say "Error: Expected to find line with text 'Segments ... Size' "
|
---|
99 | Return
|
---|
100 | End
|
---|
101 | junk = LineIn( mapFile ) /* Discard a couple lines of formatting. */
|
---|
102 | junk = LineIn( mapFile )
|
---|
103 |
|
---|
104 | /*--- 4. Translate segment table. ---*/
|
---|
105 | call lineout outfile , " Start Length Name Class"
|
---|
106 | Do While Lines( mapFile ) <> 0
|
---|
107 | watcomText = LineIn( mapFile )
|
---|
108 | Parse Value watcomText With segName className groupName address size .
|
---|
109 | If segName = "" Then Leave; /* Empty line, break from loop. */
|
---|
110 | length = Substr( size, 4, 5 ) || 'H '
|
---|
111 | segName = Left( segName, 23 )
|
---|
112 | call lineout outfile ,' ' || address || ' ' || length || segName || className
|
---|
113 | End
|
---|
114 | call lineout outfile ,' ' /* Extra line feed. */
|
---|
115 |
|
---|
116 |
|
---|
117 | /*--- 5. For all remaining lines in the input file: if the line starts
|
---|
118 | with a 16:16 address, assume it's a symbol declaration and translate
|
---|
119 | it into MS format. ---*/
|
---|
120 |
|
---|
121 | call lineout outfile ,' Address Publics by Value'
|
---|
122 | /* call lineout outfile ,' '*/
|
---|
123 |
|
---|
124 | Do While Lines( mapFile ) <> 0
|
---|
125 | watcomText = LineIn( mapFile )
|
---|
126 | Parse Value watcomText With seg ':' ofs 10 . 16 declaration
|
---|
127 | is_Adress = (is_Hex(seg) = 1) & (is_Hex(ofs) = 1)
|
---|
128 | If (is_Adress = 1) Then Do;
|
---|
129 |
|
---|
130 | /*--- Haven't done the work to xlate operator symbols - skip the line. */
|
---|
131 | If Pos( '::operator', declaration ) <> 0 Then Iterate;
|
---|
132 |
|
---|
133 | /*--- Strip any arguement list if this is a function prototype. */
|
---|
134 | declaration = StripMatchedParen( declaration )
|
---|
135 |
|
---|
136 | /*--- Strip array brackets if this is an array. */
|
---|
137 | sqBracket = Pos( '[', declaration )
|
---|
138 | If sqBracket <> 0
|
---|
139 | Then declaration = Substr(declaration, 1, sqBracket-1);
|
---|
140 |
|
---|
141 | /*--- Strip leading tokens from the function name.
|
---|
142 | Eg., remove function return type, near/far, etc. */
|
---|
143 | declaration = Word( declaration, Words(declaration) )
|
---|
144 |
|
---|
145 | /*--- Strip any remaining parens around function name. ---*/
|
---|
146 | declaration = ReplaceSubstr( '(', ' ', declaration )
|
---|
147 | declaration = ReplaceSubstr( ')', ' ', declaration )
|
---|
148 |
|
---|
149 | /*--- Debug kernel doesn't like symbol for scoping operator "::"
|
---|
150 | in symbol names. Replace :: with double underscore "__". ---*/
|
---|
151 | declaration = ReplaceSubstr( '::', '__', declaration )
|
---|
152 |
|
---|
153 | /*--- Debug kernel doesn't like symbol for destructor "~"
|
---|
154 | in symbol names. Replace ~ with character "d" for "destructor.
|
---|
155 | Note destructor for a class will translate "A::~A" -> "A__dA". ---*/
|
---|
156 | declaration = ReplaceSubstr( '~', 'd', declaration )
|
---|
157 |
|
---|
158 | call lineout outfile ,' ' || seg || ':' || ofs || ' ' || declaration
|
---|
159 | End;
|
---|
160 | End; /* End While through symbol section, end of input file. */
|
---|
161 |
|
---|
162 | Return; /* End of program. */
|
---|
163 |
|
---|
164 | /*--- Helper subroutines. ---*/
|
---|
165 |
|
---|
166 | StripMatchedParen:
|
---|
167 | /* Strips matched "( )" from end of string. Returns
|
---|
168 | a substring with the trailing, matched parens deleted. */
|
---|
169 |
|
---|
170 | Parse Arg string
|
---|
171 |
|
---|
172 | ixOpenParen = LastPos( "(", string );
|
---|
173 | ixCloseParen = LastPos( ")", Substr( string, 1, Length(string)-1 ));
|
---|
174 |
|
---|
175 | If (ixOpenParen = 0) /* No match. */
|
---|
176 | Then Return string
|
---|
177 | Else If ixCloseParen < ixOpenParen /* Found match, no imbedded "()". */
|
---|
178 | Then Return Substr( string, 1, ixOpenParen-1 )
|
---|
179 | Else Do; /* Imbedded (), must skip over them. */
|
---|
180 | /* Parse Value string With first ixCloseParen+1 rest */
|
---|
181 | first = Substr( string, 1, ixCloseParen)
|
---|
182 | rest = Substr( string, ixCloseParen+1 )
|
---|
183 | string = StripMatchedParen( first ) || rest
|
---|
184 | Return StripMatchedParen( string )
|
---|
185 | End;
|
---|
186 | End;
|
---|
187 |
|
---|
188 | ReplaceSubstr:
|
---|
189 | /* Replaces oldPat (old pattern) with newPat (new pattern) in string. */
|
---|
190 |
|
---|
191 | Parse Arg oldPat , newPat , string
|
---|
192 |
|
---|
193 | ix = Pos( oldPat, string )
|
---|
194 | if ix <> 0 Then Do;
|
---|
195 | first = Substr( string, 1, ix-1 )
|
---|
196 | rest = Substr( string, ix + Length( oldPat ) )
|
---|
197 | string = first || newPat || rest
|
---|
198 | End;
|
---|
199 | Return string
|
---|
200 | End;
|
---|
201 |
|
---|
202 | is_Hex:
|
---|
203 | /* Returns 1 if String is valid hex number, 0 otherwise. */
|
---|
204 | Parse Arg string
|
---|
205 | Return (Length(string) > 0) & (Verify( string, '0123456789abcdefABCDEF' ) = 0)
|
---|
206 | End;
|
---|