1 /****************************************************************************
2 *
3 * Open Watcom Project
4 *
5 * Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6 *
7 * ========================================================================
8 *
9 * This file contains Original Code and/or Modifications of Original
10 * Code as defined in and that are subject to the Sybase Open Watcom
11 * Public License version 1.0 (the 'License'). You may not use this file
12 * except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13 * ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14 * provided with the Original Code and Modifications, and is also
15 * available at www.sybase.com/developer/opensource.
16 *
17 * The Original Code and all software distributed under the License are
18 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19 * EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22 * NON-INFRINGEMENT. Please see the License for the specific language
23 * governing rights and limitations under the License.
24 *
25 * ========================================================================
26 *
27 * Description: Symbol name mangling routines.
28 *
29 ****************************************************************************/
30
31 #include <ctype.h>
32
33 #include "globals.h"
34 #include "memalloc.h"
35 #include "parser.h"
36 #include "mangle.h"
37
38 #if MANGLERSUPP
39 #if !defined(__GNUC__) && !defined(__POCC__)
40 #define tolower(c) ((c >= 'A' && c <= 'Z') ? c | 0x20 : c )
41 #endif
42 #endif
43
44 typedef int (*mangle_func)( const struct asym *, char * );
45
46 static int ms32_decorate( const struct asym *sym, char *buffer );
47 #if OWFC_SUPPORT
48 static int ow_decorate( const struct asym *sym, char *buffer );
49 #endif
50 #if AMD64_SUPPORT
51 static int ms64_decorate( const struct asym *sym, char *buffer );
52 #endif
53
54 /* table of FASTCALL types.
55 * order must match the one of enum fastcall_type
56 * also see proc.c and invoke.c!
57 */
58
59 static const mangle_func fcmanglers[] = {
60 ms32_decorate, /* FCT_MSC */
61 #if OWFC_SUPPORT
62 ow_decorate, /* FCT_WATCOMC */
63 #endif
64 #if AMD64_SUPPORT
65 ms64_decorate /* FCT_WIN64 */
66 #endif
67 };
68
69 /* VoidMangler: no change to symbol name */
70
VoidMangler(const struct asym * sym,char * buffer)71 static int VoidMangler( const struct asym *sym, char *buffer )
72 /************************************************************/
73 {
74 memcpy( buffer, sym->name, sym->name_size + 1 );
75 return( sym->name_size );
76 }
77
78 /* UCaseMangler: convert symbol name to upper case */
79
UCaseMangler(const struct asym * sym,char * buffer)80 static int UCaseMangler( const struct asym *sym, char *buffer )
81 /*************************************************************/
82 {
83 memcpy( buffer, sym->name, sym->name_size + 1 );
84 _strupr( buffer );
85 return( sym->name_size );
86 }
87
88 /* UScoreMangler: add '_' prefix to symbol name */
89
UScoreMangler(const struct asym * sym,char * buffer)90 static int UScoreMangler( const struct asym *sym, char *buffer )
91 /**************************************************************/
92 {
93 buffer[0] = '_';
94 memcpy( buffer+1, sym->name, sym->name_size + 1 );
95 return( sym->name_size + 1 );
96 }
97
98 /* StdcallMangler: add '_' prefix and '@size' suffix to proc names */
99 /* add '_' prefix to other symbols */
100
StdcallMangler(const struct asym * sym,char * buffer)101 static int StdcallMangler( const struct asym *sym, char *buffer )
102 /***************************************************************/
103 {
104 const struct dsym *dir = (struct dsym *)sym;
105
106 if( Options.stdcall_decoration == STDCALL_FULL && sym->isproc ) {
107 return( sprintf( buffer, "_%s@%d", sym->name, dir->e.procinfo->parasize ) );
108 } else {
109 return( UScoreMangler( sym, buffer ) );
110 }
111 }
112
113 /* MS FASTCALL 32bit */
114
ms32_decorate(const struct asym * sym,char * buffer)115 static int ms32_decorate( const struct asym *sym, char *buffer )
116 /**************************************************************/
117 {
118 return ( sprintf( buffer, "@%s@%u", sym->name, ((struct dsym *)sym)->e.procinfo->parasize ) );
119 }
120
121 #if OWFC_SUPPORT
122
123 /* flag values used by the OW fastcall name mangler ( changes ) */
124 enum changes {
125 NORMAL = 0,
126 USCORE_FRONT = 1,
127 USCORE_BACK = 2
128 };
129
130 /* FASTCALL OW style:
131 * add '_' suffix to proc names and labels
132 * add '_' prefix to other symbols
133 */
134
ow_decorate(const struct asym * sym,char * buffer)135 static int ow_decorate( const struct asym *sym, char *buffer )
136 /************************************************************/
137 {
138 char *name;
139 enum changes changes = NORMAL;
140
141 if( sym->isproc ) {
142 changes |= USCORE_BACK;
143 } else {
144 switch( sym->mem_type ) {
145 case MT_NEAR:
146 case MT_FAR:
147 case MT_EMPTY:
148 changes |= USCORE_BACK;
149 break;
150 default:
151 changes |= USCORE_FRONT;
152 }
153 }
154
155 name = buffer;
156
157 if( changes & USCORE_FRONT )
158 *name++ = '_';
159 memcpy( name, sym->name, sym->name_size + 1 );
160 name += sym->name_size;
161 if( changes & USCORE_BACK ) {
162 *name++ = '_';
163 *name = NULLC;
164 }
165 return( name - buffer );
166 }
167 #endif
168
169 #if AMD64_SUPPORT
170
171 /* MS FASTCALL 64bit */
172
ms64_decorate(const struct asym * sym,char * buffer)173 static int ms64_decorate( const struct asym *sym, char *buffer )
174 /**************************************************************/
175 {
176 memcpy( buffer, sym->name, sym->name_size + 1 );
177 return( sym->name_size );
178 }
179 #endif
180
181 #if MANGLERSUPP
CMangler(const struct asym * sym,char * buffer)182 static char *CMangler( const struct asym *sym, char *buffer )
183 /***********************************************************/
184 {
185 if( Options.naming_convention == NC_ADD_USCORES ) {
186 return( UScoreMangler( sym, buffer ) );
187 } else {
188 return( VoidMangler( sym, buffer ) );
189 }
190 }
191
GetMangler(const char * mangle_type)192 static mangle_func GetMangler( const char *mangle_type )
193 /******************************************************/
194 {
195 if( mangle_type != NULL && mangle_type[1] == NULLC ) {
196 switch ( tolower( *mangle_type ) ) {
197 case 'c':
198 return( Options.xxx ? CMangler : ow_decorate );
199 case 'n':
200 return( VoidMangler );
201 }
202 }
203 if ( mangle_type )
204 EmitErr( UNKNOWN_MANGLER, mangle_type );
205
206 return( NULL );
207 }
208 #endif
209
Mangle(struct asym * sym,char * buffer)210 int Mangle( struct asym *sym, char *buffer )
211 /******************************************/
212 {
213 mangle_func mangler;
214
215 switch( sym->langtype ) {
216 case LANG_C:
217 /* leading underscore for C? */
218 mangler = Options.no_cdecl_decoration ? VoidMangler : UScoreMangler;
219 break;
220 case LANG_SYSCALL:
221 mangler = VoidMangler;
222 break;
223 case LANG_STDCALL:
224 mangler = ( Options.stdcall_decoration == STDCALL_NONE ) ? VoidMangler : StdcallMangler;
225 break;
226 case LANG_PASCAL:
227 case LANG_FORTRAN:
228 case LANG_BASIC:
229 mangler = UCaseMangler;
230 break;
231 case LANG_FASTCALL: /* registers passing parameters */
232 mangler = fcmanglers[ModuleInfo.fctype];
233 break;
234 default: /* LANG_NONE */
235 #if MANGLERSUPP
236 mangler = sym->mangler;
237 if( mangler == NULL )
238 mangler = GetMangler( Options.default_name_mangler );
239 if( mangler == NULL )
240 #endif
241 mangler = VoidMangler;
242 break;
243 }
244 #if MANGLERSUPP
245 sym->mangler = mangler;
246 #endif
247 return( mangler( sym, buffer ) );
248 }
249
250 /* the "mangle_type" is an extension inherited from OW Wasm
251 * accepted are "C" and "N". It's NULL if MANGLESUPP == 0 (standard)
252 */
SetMangler(struct asym * sym,int langtype,const char * mangle_type)253 void SetMangler( struct asym *sym, int langtype, const char *mangle_type )
254 /************************************************************************/
255 {
256 #if MANGLERSUPP
257 mangle_func mangler;
258 #endif
259
260 if( langtype != LANG_NONE )
261 sym->langtype = langtype;
262
263 #if MANGLERSUPP
264 mangler = GetMangler( mangle_type );
265 if( mangler == NULL ) {
266 /* nothing to do */
267 } else if( sym->mangler == NULL ) {
268 sym->mangler = mangler;
269 } else if( sym->mangler != mangler ) {
270 EmitErr( CONFLICTING_MANGLER, sym->name );
271 }
272 #endif
273 }
274