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