18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file demangle_symbol.cpp
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Demangle a C++ symbol
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cstdlib>
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "config.h"
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "demangle_symbol.h"
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "demangle_java_symbol.h"
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_regex.h"
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// from libiberty
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*@{\name demangle option parameter */
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef DMGL_PARAMS
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd# define DMGL_PARAMS     (1 << 0)        /**< Include function args */
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef DMGL_ANSI
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd# define DMGL_ANSI       (1 << 1)        /**< Include const, volatile, etc */
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*@}*/
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddextern "C" char * cplus_demangle(char const * mangled, int options);
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std;
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace options {
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	extern demangle_type demangle;
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const demangle_symbol(string const & name)
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (options::demangle == dmt_none)
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return name;
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// Do not try to strip leading underscore, as this leads to many
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// C++ demangling failures. However we strip off a leading '.'
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        // as generated on PPC64
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const & tmp = (name[0] == '.' ? name.substr(1) : name);
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	char * unmangled = cplus_demangle(tmp.c_str(), DMGL_PARAMS | DMGL_ANSI);
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!unmangled) {
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string result = demangle_java_symbol(name);
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (!result.empty())
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return result;
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return name;
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string result(unmangled);
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	free(unmangled);
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (options::demangle == dmt_smart) {
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		static bool init = false;
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		static regular_expression_replace regex;
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (init == false) {
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			setup_regex(regex, OP_DATADIR "/stl.pat");
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			init = true;
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// we don't protect against exception here, pattern must be
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// right and user can easily work-around by using -d
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		regex.execute(result);
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return result;
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
71