18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file symbol_sort.cpp 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Sorting symbols 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002, 2003 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "symbol_sort.h" 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "symbol_functors.h" 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "name_storage.h" 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_exception.h" 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <algorithm> 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sstream> 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std; 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace { 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool long_filenames; 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint image_compare(image_name_id l, image_name_id r) 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (long_filenames) 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return image_names.name(l).compare(image_names.name(r)); 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return image_names.basename(l).compare(image_names.basename(r)); 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint debug_compare(debug_name_id l, debug_name_id r) 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (long_filenames) 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return debug_names.name(l).compare(debug_names.name(r)); 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return debug_names.basename(l).compare(debug_names.basename(r)); 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint compare_by(sort_options::sort_order order, 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_entry const & lhs, symbol_entry const & rhs) 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd switch (order) { 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case sort_options::sample: 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.sample.counts[0] < rhs.sample.counts[0]) 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 1; 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.sample.counts[0] > rhs.sample.counts[0]) 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -1; 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case sort_options::symbol: 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return symbol_names.demangle(lhs.name).compare( 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_names.demangle(rhs.name)); 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case sort_options::image: 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return image_compare(lhs.image_name, rhs.image_name); 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case sort_options::app_name: 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return image_compare(lhs.app_name, rhs.app_name); 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case sort_options::vma: 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.sample.vma < rhs.sample.vma) 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return -1; 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.sample.vma > rhs.sample.vma) 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 1; 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case sort_options::debug: { 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd file_location const & f1 = lhs.sample.file_loc; 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd file_location const & f2 = rhs.sample.file_loc; 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ret = debug_compare(f1.filename, f2.filename); 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (ret == 0) 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ret = f1.linenr - f2.linenr; 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return ret; 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd default: { 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // static_cast<> to shut up g++ 2.91.66 which warn 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // about ambiguity between <<(int) and <<(long int) 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostringstream os; 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd os << "compare_by(): unknown sort option: " 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << static_cast<int>(order) << endl; 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw op_fatal_error(os.str()); 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct symbol_compare { 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_compare(vector<sort_options::sort_order> const & order, 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool reverse) 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : compare_order(order), reverse_sort(reverse) {} 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool operator()(symbol_entry const * lhs, 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_entry const * rhs) const { 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return operator()(*lhs, *rhs); 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool operator()(symbol_entry const & lhs, 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_entry const & rhs) const; 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprotected: 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<sort_options::sort_order> const & compare_order; 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool reverse_sort; 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool symbol_compare::operator()(symbol_entry const & lhs, 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_entry const & rhs) const 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (size_t i = 0; i < compare_order.size(); ++i) { 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ret = compare_by(compare_order[i], lhs, rhs); 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (reverse_sort) 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ret = -ret; 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (ret != 0) 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return ret < 0; 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // anonymous namespace 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid sort_options:: 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsort(symbol_collection & syms, bool reverse_sort, bool lf) const 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd long_filenames = lf; 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<sort_order> sort_option(options); 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) { 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (find(sort_option.begin(), sort_option.end(), cur) == 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sort_option.end()) 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sort_option.push_back(cur); 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stable_sort(syms.begin(), syms.end(), 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_compare(sort_option, reverse_sort)); 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid sort_options:: 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsort(diff_collection & syms, bool reverse_sort, bool lf) const 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd long_filenames = lf; 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<sort_order> sort_option(options); 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) { 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (find(sort_option.begin(), sort_option.end(), cur) == 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sort_option.end()) 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sort_option.push_back(cur); 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stable_sort(syms.begin(), syms.end(), 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_compare(sort_option, reverse_sort)); 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid sort_options::add_sort_option(string const & name) 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (name == "vma") { 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(vma); 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (name == "sample") { 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(sample); 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (name == "symbol") { 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(symbol); 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (name == "debug") { 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(debug); 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (name == "image") { 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(image); 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (name == "app-name") { 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(app_name); 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostringstream os; 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd os << "unknown sort option: " << name << endl; 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw op_fatal_error(os.str()); 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid sort_options::add_sort_option(sort_options::sort_order order) 1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd options.push_back(order); 1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 191