From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755615AbbDNPEL (ORCPT ); Tue, 14 Apr 2015 11:04:11 -0400 Received: from mail.skyhub.de ([78.46.96.112]:33471 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753527AbbDNPED (ORCPT ); Tue, 14 Apr 2015 11:04:03 -0400 Date: Tue, 14 Apr 2015 17:01:42 +0200 From: Borislav Petkov To: Arnaldo Carvalho de Melo , Masami Hiramatsu , Namhyung Kim Cc: lkml Subject: 2c241bd35e6f ("perf symbols: Make sym->end be the first address after the symbol range") Message-ID: <20150414150142.GD14069@pd.tnic> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi guys, so I'm looking at 2c241bd35e6f ("perf symbols: Make sym->end be the first address after the symbol range") Do I see it correctly that with it, we cannot find zero-sized symbols in symbols__find() or was it never meant to do so? symbols__find(): ... while (n) { struct symbol *s = rb_entry(n, struct symbol, rb_node); if (ip < s->start) n = n->rb_left; else if (ip >= s->end) n = n->rb_right; else return s; } Imagine ip == s->start == s->end: ... symbols__find: looking at 0xffffffff81000000, 0xffffffff81000000, st_size: 0 ... I'm playing with this in my own project and this way of doing the comparison above won't find ELF objects like the one above in vmlinux, for example. Btw, there are more than one objects on that address: $ readelf -a vmlinux | grep ffffffff81000000 1: ffffffff81000000 0 SECTION LOCAL DEFAULT 1 46550: ffffffff81000000 0 NOTYPE GLOBAL DEFAULT 1 _text 67061: ffffffff81000000 0 NOTYPE GLOBAL DEFAULT 1 startup_64 And I think you'd probably want to have some way of restarting the traversal through the rbtree to find all and have the higher level callers filter out the symbols depending on what they're looking for, i.e. NOTYPE, FUNC, OBJECT, range or exact match, etc, etc... I've done this here locally and it seems to work so far, need to hammer on it longer. But basically I'm passing through @cur the element I've just found so that it can give me the next one at that @ip. Hmmm... /* * @cur is the current symbol from which to start searching */ static struct symbol *sym_find(struct rb_root *root, u64 ip, struct symbol *cur) { struct rb_node *n; if (!root) return NULL; n = root->rb_node; while (n) { u64 sym_start, sym_end; struct symbol *s = rb_entry(n, struct symbol, rb_node); if (cur && s == cur) { n = rb_next(n); continue; } sym_start = SYM_START(s); sym_end = SYM_END(s); if (ip < sym_start) n = n->rb_left; else if (ip > sym_end) n = n->rb_right; else return s; } return NULL; } -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. --