Name Mangling: Difference between revisions

From STRIDE Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(37 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= Intercept Module Terminology: Understanding Name Mangling<br> =
== What is Name Mangling? ==


=== What is Name Mangling?  ===
Name mangling describes the automatic source transformation required for an interceptor to insert itself between caller and callee. There are two options for handling name mangling, one of which must be chosen when using interceptors:


Name mangling describes the automatic source transformation required for a delegate to insert itself between caller and callee. There are two options for handling name mangling, one of which must be chosen when using delegates:&nbsp;<br>
*A call to a function f() is transformed to "__im_f()” to allow interception the call. This is referred to as '''reference mangling'''.


#A call to a function f() is transformed to "__im_f()” to allow the delegate to intercept the call. This is referred to as '''user mangling'''.&lt;br&gt;
*The implemention of f() can be transformed to "__im_f()”. This is referred to as '''definition mangling'''.
#The implemention of f() can be transformed to "__im_f()”. This is referred to as '''owner mangling'''.


Name mangling is necessary in order for the delegate to insert itself between caller and callee. For example, to use a delegate to trace all calls to a function, f():  
For example, to use a interceptor to trace all calls to a function, f():


*If we use '''user mangling''', all calls to f() are transformed to be calls to __im_f(). The delegate is implemented as __im_f(). The original implementation of f() remains unchanged. This allows the delegate to intercept all calls and take the appropriate action.
*If we use '''reference mangling''', all calls to f() are transformed to be calls to __im_f(). The interceptor is implemented as __im_f(). The original implementation of f() remains unchanged. This allows interception of all calls and takes the appropriate action.
*If we use '''owner mangling''', the implementation of f() is changed from f(){...} to __im_f(){...}. The delegate is implemented as f() in order to intercept all calls.


<br>
*If we use '''definition mangling''', the implementation of f() is changed from f(){...} to __im_f(){...}. The interceptor is implemented as f() in order to intercept all calls.


==== Name Mangling Conflicts ====


A mangling conflict applies only to delegates. It exists when the name of a routine requires mangling, but there also exists other references to the same name within the same source file. The other references will inadvertently be mangled by the preprocessor.  
The name mangling is either done '''implicitly''' or '''explicitly''' during the compile process. By default, '''implicit''' mangling is used; this means that selected routines will be mangled by using a chosen [[Intercept_Module#Group_ID|Group ID]] and including the Intercept Module header file. Where '''explicit''' mangling requires the additional step of adding a macro.


'''Explicit mangling''' is used to resolve these type of name mangling conflicts. Explicit mangling uses the '''explicit macro''' "'''imDELEGATE('''&lt;function_name&gt;''')'''", which explicitly mangles the name of "f()" to "__im_f()". The explicit macro is defined in the Intercept Module delegate mangling header file (xxxIM.h). Explicit mangling requires Group ID(s) to be defined (#define MyGroupID) in the source file of the caller/callee of the routine to protect against the inclusion of unnecessary defined types.
== Name Mangling Conflicts  ==


The following examples demonstrate situations where explicit mangling can be used to resolve mangling conflicts:
A mangling conflict applies only to interceptors. It exists when the name of a routine requires mangling, but there also exists other references to the same name within the same source file. The other references will inadvertently be mangled by the preprocessor.


#The owner and the user of the same routine, f(), exist in the same source file  
<span id="Explicit_Mangling">'''Explicit mangling'''</span> is used to resolve these type of name mangling conflicts. Explicit mangling uses the explicit macro "'''srTEST_INTERCEPT('''&lt;function_name&gt;''')'''", which explicitly mangles the name of "f()" to "__im_f()". The explicit macro is defined in the Intercept Module name mangling header file (xxxIM.h). Explicit mangling requires [[Intercept Module#Group ID|Group ID(s)]] to be defined (#define MyGroupID) in the source file of the caller/callee of the routine to protect against the inclusion of unnecessary defined types.
#Two users of a routine, f(), exist in the same source file, but only one is a user delegate


==== ''Mangling Conflict Example 1: The owner and the user of the same routine, f(), exist in the same source file'' ====
The following examples demonstrate situations where explicit mangling can be used to resolve mangling conflicts:
 
If the owner and the user of the same routine, f(), exist in the same source file, the use of explicit mangling is required to resolve the mangling conflict. If the conflict is not resolved, the user will bypass the delegate by using the mangled name when making the call to the routine.
 
==== ''Mangling Conflict Example 2: Two users of a routine, f(), exist in the same source file, but only one is a user delegate'' ====
 
By default, delegates are owner-focused. An owner-focused delegate is used to mangle the actual routine; thus, every user (caller) of the routine goes through the delegate. There are use cases when source code for the routines cannot be accessed (i.e., as with libraries). A user-focused delegate can be used to mangle the caller instead of the routine to be called (callee). User-focused delegates typically do not have mangling conflicts, except when multiple users exist in the same source file, but only a subset is targeted to go through the delegate. Explicit mangling is used to avoid this type of mangling conflict.
 
The Group ID(s) must be defined before including the Intercept Module delegate mangling header file (xxxIM.h) and after all defined types (additional header files) in the source file(s) of the caller/callee of the routine.


#include "MyHeader.h”
==== ''The reference and the definition of the same routine, f(), exist in the same source file'' ====


#define &lt;MyGroupID&gt;
If the reference and the definition of the same routine, f(), exist in the same source file, the use of explicit mangling is required to resolve the mangling conflict. If the conflict is not resolved, the user will bypass the interceptor by using the mangled name when making the call to the routine.


#include "xxxIM.h”
==== ''Two (or more) references of a routine, f(), exist in the same source file, but only one is a reference interceptor'' ====


To enable Intercept Modules to be regenerated continuously and to allow the user the option to add and/or remove delegates, an explicit macro is generated for each routine. If a routine is not selected as a delegate, an explicit macro will be generated so that name mangling will not occur. Also, if use of the Intercept Module is turned off via the source file (e.g., #undef srIMON), the macros will not perform name mangling. This allows users to leave explicit macros in their source code, even if the Intercept Module is not being used.  
By default, interceptors are definition-focused. An referenced-focused interceptor is used to mangle the actual routine; thus, every caller of the routine goes through the interceptor. There are use cases when source code for the routines cannot be accessed (i.e., as with libraries). A referenced-focused interceptor can be used to mangle the caller instead of the routine to be called (callee). Reference-focused interceptors typically do not have mangling conflicts, except when multiple callers exist in the same source file, but only a subset is targeted to go through the interceptor. Explicit mangling is used to avoid this type of mangling conflict.  


<br> '''See also'''
The Group ID(s) must be defined before including the Intercept Module name mangling header file (xxxIM.h) and after all defined types (additional header files) in the source file(s) of the caller/callee of the routine.<br>  
<source lang="c">
#include "MyHeader.h"
#define MyGroupID
#include "xxxIM.h"
</source>


*[[Intercept Module|Intercept Module Overview]]
To enable Intercept Modules to be regenerated continuously and to allow the user the option to add and/or remove interceptors, an [[#Explicit_Mangling|explicit macro]] is generated for each routine. If a routine is not selected as an interceptor, an explicit macro will be generated so that name mangling will not occur. Also, if use of the Intercept Module is turned off via the source file (e.g., <tt>#undef STRIDE_ENABLED</tt> or <tt>#define STRIDE_ENABLED 0</tt>), the macros will not perform name mangling. This allows users to leave explicit macros in their source code, even if the Intercept Module is not being used.
*[[S2sinstrument|Using s2sinstrument.exe to generate an Intercept Module]]

Latest revision as of 20:12, 6 July 2015

What is Name Mangling?

Name mangling describes the automatic source transformation required for an interceptor to insert itself between caller and callee. There are two options for handling name mangling, one of which must be chosen when using interceptors:

  • A call to a function f() is transformed to "__im_f()” to allow interception the call. This is referred to as reference mangling.
  • The implemention of f() can be transformed to "__im_f()”. This is referred to as definition mangling.

For example, to use a interceptor to trace all calls to a function, f():

  • If we use reference mangling, all calls to f() are transformed to be calls to __im_f(). The interceptor is implemented as __im_f(). The original implementation of f() remains unchanged. This allows interception of all calls and takes the appropriate action.
  • If we use definition mangling, the implementation of f() is changed from f(){...} to __im_f(){...}. The interceptor is implemented as f() in order to intercept all calls.


The name mangling is either done implicitly or explicitly during the compile process. By default, implicit mangling is used; this means that selected routines will be mangled by using a chosen Group ID and including the Intercept Module header file. Where explicit mangling requires the additional step of adding a macro.

Name Mangling Conflicts

A mangling conflict applies only to interceptors. It exists when the name of a routine requires mangling, but there also exists other references to the same name within the same source file. The other references will inadvertently be mangled by the preprocessor.

Explicit mangling is used to resolve these type of name mangling conflicts. Explicit mangling uses the explicit macro "srTEST_INTERCEPT(<function_name>)", which explicitly mangles the name of "f()" to "__im_f()". The explicit macro is defined in the Intercept Module name mangling header file (xxxIM.h). Explicit mangling requires Group ID(s) to be defined (#define MyGroupID) in the source file of the caller/callee of the routine to protect against the inclusion of unnecessary defined types.

The following examples demonstrate situations where explicit mangling can be used to resolve mangling conflicts:

The reference and the definition of the same routine, f(), exist in the same source file

If the reference and the definition of the same routine, f(), exist in the same source file, the use of explicit mangling is required to resolve the mangling conflict. If the conflict is not resolved, the user will bypass the interceptor by using the mangled name when making the call to the routine.

Two (or more) references of a routine, f(), exist in the same source file, but only one is a reference interceptor

By default, interceptors are definition-focused. An referenced-focused interceptor is used to mangle the actual routine; thus, every caller of the routine goes through the interceptor. There are use cases when source code for the routines cannot be accessed (i.e., as with libraries). A referenced-focused interceptor can be used to mangle the caller instead of the routine to be called (callee). Reference-focused interceptors typically do not have mangling conflicts, except when multiple callers exist in the same source file, but only a subset is targeted to go through the interceptor. Explicit mangling is used to avoid this type of mangling conflict.

The Group ID(s) must be defined before including the Intercept Module name mangling header file (xxxIM.h) and after all defined types (additional header files) in the source file(s) of the caller/callee of the routine.

#include "MyHeader.h"
#define MyGroupID
#include "xxxIM.h"

To enable Intercept Modules to be regenerated continuously and to allow the user the option to add and/or remove interceptors, an explicit macro is generated for each routine. If a routine is not selected as an interceptor, an explicit macro will be generated so that name mangling will not occur. Also, if use of the Intercept Module is turned off via the source file (e.g., #undef STRIDE_ENABLED or #define STRIDE_ENABLED 0), the macros will not perform name mangling. This allows users to leave explicit macros in their source code, even if the Intercept Module is not being used.