On Tue, 2013-01-22 at 17:03 +0100, Jan Kratochvil wrote:
On Tue, 22 Jan 2013 16:46:48 +0100, Mark Wielaard wrote:
> Yeah, good catch. And although first_global was initialized to -1 that
> was really unnecessary (as you point out below load_symtab now always
> sets it), because we don't use that as marker anymore. I have updated
> the comment and removed that -1 initialization.
- search_table (mod->first_global < 0 ? 1 : mod->first_global, syments);
+ int first_global = mod->first_global + mod->aux_first_global - 1;
+ search_table (first_global < 0 ? 1 : first_global, syments);
Now there is "- 1" with no reason, in fact a bug although not exploitable.
Sigh, I seem to have tricked myself in "cleverness". So how about we
just express the "globals first", "locals second" simply as follows
expanded the comment to make clear what zero means when we get here):
/* First go through global symbols. mod->first_global and
mod->aux_first_global are setup by dwfl_module_getsymtab to the
index of the first global symbol in the module's symbol table.
Both are zero when unknown. All symbols with local binding come
first in the symbol table, then all globals. The zeroth, null
entry, in the auxiliary table is always skipped. If we get here
and the main symbol table first_global is zero we loaded it
through phdrs and don't know what the first global is. The
auxiliary table if it exists always has aux_first_global set
correctly because it is looked up and loaded through shdrs. */
int first_global = mod->first_global;
if (first_global > 0 && mod->aux_symdata != NULL)
first_global += mod->aux_first_global - 1;
search_table (first_global == 0 ? 1 : first_global, syments);
/* If we found nothing searching the global symbols, then try the locals.
Unless we have a global sizeless symbol that matches exactly. */
if (closest_name == NULL && first_global > 1
&& (sizeless_name == NULL || sizeless_sym.st_value != addr))
search_table (1, first_global);