Name Mangling

From STRIDE Wiki
Jump to: navigation, search

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.