11bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata/* 21bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * This file is part of ltrace. 31bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * Copyright (C) 2012 Petr Machata, Red Hat Inc. 41bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * 51bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * This program is free software; you can redistribute it and/or 61bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * modify it under the terms of the GNU General Public License as 71bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * published by the Free Software Foundation; either version 2 of the 81bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * License, or (at your option) any later version. 91bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * 101bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * This program is distributed in the hope that it will be useful, but 111bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 121bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 131bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * General Public License for more details. 141bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * 151bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * You should have received a copy of the GNU General Public License 161bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * along with this program; if not, write to the Free Software 171bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 181bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata * 02110-1301 USA 191bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata */ 201bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 210b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata#include <stdlib.h> 221bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata#include <assert.h> 23cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <stdio.h> 24cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <string.h> 251bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 261bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata#include "filter.h" 271bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata#include "library.h" 28a24021c5abfa8c2482e3224f14ac191cd0826a8fPetr Machata#include "callback.h" 291bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 301bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 311bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_init(struct filter *filt) 321bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 331bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata filt->rules = NULL; 3435c8814db9e7d41811cc4620c1bda084f4ff4c7bPetr Machata filt->next = NULL; 351bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 361bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 371bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 381bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_destroy(struct filter *filt) 391bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 401bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata struct filter_rule *it; 411bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata for (it = filt->rules; it != NULL; ) { 421bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata struct filter_rule *next = it->next; 431bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata filter_rule_destroy(it); 441bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata it = next; 451bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata } 461bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 471bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 481bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 491bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_rule_init(struct filter_rule *rule, enum filter_rule_type type, 501bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata struct filter_lib_matcher *matcher, 511bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata regex_t symbol_re) 521bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 531bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata rule->type = type; 541bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata rule->lib_matcher = matcher; 551bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata rule->symbol_re = symbol_re; 561bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata rule->next = NULL; 571bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 581bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 591bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 601bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_rule_destroy(struct filter_rule *rule) 611bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 621bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata filter_lib_matcher_destroy(rule->lib_matcher); 631bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata regfree(&rule->symbol_re); 641bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 651bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 661bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 671bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_add_rule(struct filter *filt, struct filter_rule *rule) 681bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 690e44da35a9d783318f936cce8a4f81f18193ab23Petr Machata struct filter_rule **rulep; 700e44da35a9d783318f936cce8a4f81f18193ab23Petr Machata for (rulep = &filt->rules; *rulep != NULL; rulep = &(*rulep)->next) 710e44da35a9d783318f936cce8a4f81f18193ab23Petr Machata ; 720e44da35a9d783318f936cce8a4f81f18193ab23Petr Machata *rulep = rule; 731bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 741bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 751bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 761bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_lib_matcher_name_init(struct filter_lib_matcher *matcher, 770b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata enum filter_lib_matcher_type type, 781bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata regex_t libname_re) 791bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 800b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata switch (type) { 810b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_MAIN: 820b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata assert(type != type); 830b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata abort(); 840b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata 850b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_SONAME: 860b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_PATHNAME: 870b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata matcher->type = type; 880b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata matcher->libname_re = libname_re; 890b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata } 901bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 911bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 921bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 931bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_lib_matcher_main_init(struct filter_lib_matcher *matcher) 941bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 951bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata matcher->type = FLM_MAIN; 961bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 971bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 981bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatavoid 991bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_lib_matcher_destroy(struct filter_lib_matcher *matcher) 1001bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 1011bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata switch (matcher->type) { 1020b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_SONAME: 1030b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_PATHNAME: 1041bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata regfree(&matcher->libname_re); 1051bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata break; 1061bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata case FLM_MAIN: 1071bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata break; 1081bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata } 1091bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 1101bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 1111bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatastatic int 1121bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatare_match_or_error(regex_t *re, const char *name, const char *what) 1131bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 1141bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata int status = regexec(re, name, 0, NULL, 0); 1151bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata if (status == 0) 1161bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata return 1; 1171bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata if (status == REG_NOMATCH) 1181bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata return 0; 1191bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 1201bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata char buf[200]; 1211bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata regerror(status, re, buf, sizeof buf); 122cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata fprintf(stderr, "Error when matching %s: %s\n", name, buf); 1231bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 1241bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata return 0; 1251bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 1261bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 1271bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatastatic int 1281bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatamatcher_matches_library(struct filter_lib_matcher *matcher, struct library *lib) 1291bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 1301bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata switch (matcher->type) { 1310b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_SONAME: 1320b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata return re_match_or_error(&matcher->libname_re, lib->soname, 1330b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata "library soname"); 1340b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata case FLM_PATHNAME: 1350b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata return re_match_or_error(&matcher->libname_re, lib->pathname, 1360b55b5852b9fe2ed6cceada004db303fe6efe6cePetr Machata "library pathname"); 1371bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata case FLM_MAIN: 138b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata return lib->type == LT_LIBTYPE_MAIN; 1391bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata } 1401bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata assert(matcher->type != matcher->type); 1411bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata abort(); 1421bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 1431bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 1441bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machataint 1451bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machatafilter_matches_library(struct filter *filt, struct library *lib) 1461bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 14735c8814db9e7d41811cc4620c1bda084f4ff4c7bPetr Machata if (filt == NULL) 14835c8814db9e7d41811cc4620c1bda084f4ff4c7bPetr Machata return 0; 14935c8814db9e7d41811cc4620c1bda084f4ff4c7bPetr Machata 1501054c90aa71875610fda43365a8e74086eb2bd66Petr Machata for (; filt != NULL; filt = filt->next) { 1511054c90aa71875610fda43365a8e74086eb2bd66Petr Machata struct filter_rule *it; 1521054c90aa71875610fda43365a8e74086eb2bd66Petr Machata for (it = filt->rules; it != NULL; it = it->next) 1531054c90aa71875610fda43365a8e74086eb2bd66Petr Machata switch (it->type) { 1541054c90aa71875610fda43365a8e74086eb2bd66Petr Machata case FR_ADD: 1551054c90aa71875610fda43365a8e74086eb2bd66Petr Machata if (matcher_matches_library(it->lib_matcher, lib)) 1561054c90aa71875610fda43365a8e74086eb2bd66Petr Machata return 1; 1571054c90aa71875610fda43365a8e74086eb2bd66Petr Machata case FR_SUBTRACT: 1581054c90aa71875610fda43365a8e74086eb2bd66Petr Machata continue; 1591054c90aa71875610fda43365a8e74086eb2bd66Petr Machata }; 1601054c90aa71875610fda43365a8e74086eb2bd66Petr Machata } 1611bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata return 0; 1621bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 1631bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata 1641bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machataint 165b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machatafilter_matches_symbol(struct filter *filt, 166b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata const char *sym_name, struct library *lib) 1671bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata{ 168391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata for (; filt != NULL; filt = filt->next) { 169c631abfeeb063952f63533fd2c261567a297eeb1Petr Machata int matches = 0; 170391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata struct filter_rule *it; 171391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata for (it = filt->rules; it != NULL; it = it->next) { 172391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata switch (it->type) { 173391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata case FR_ADD: 174391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata if (matches) 175391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata continue; 176391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata break; 177391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata case FR_SUBTRACT: 178391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata if (!matches) 179391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata continue; 180391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata } 181391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata 182391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata if (matcher_matches_library(it->lib_matcher, lib) 183391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata && re_match_or_error(&it->symbol_re, sym_name, 184391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata "symbol name")) 185391318fb9b1f0f0f67b642309f5c9e94557f8568Petr Machata matches = !matches; 1861bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata } 187c631abfeeb063952f63533fd2c261567a297eeb1Petr Machata if (matches) 188c631abfeeb063952f63533fd2c261567a297eeb1Petr Machata return 1; 1891bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata } 190c631abfeeb063952f63533fd2c261567a297eeb1Petr Machata return 0; 1911bbfbc6c6a7b7706bf4e8bf152d7ffc28453c3bdPetr Machata} 192