+2010-05-20 Roland McGrath <roland@redhat.com>
+
+ * linux-proc-maps.c (find_sysinfo_ehdr): Renamed to ...
+ (grovel_auxv): ... this. Take DWFL argument.
+ (dwfl_linux_proc_report): Update caller.
+
+ * dwfl_module_getdwarf.c (open_elf): Calculate alignment for bias
+ based on dwfl->segment_align or manifest alignment of MOD->low_addr.
+
2010-05-19 Roland McGrath <roland@redhat.com>
* linux-kernel-modules.c (intuit_kernel_bounds): Rewritten.
goto elf_error;
if (ph->p_type == PT_LOAD)
{
- file->bias = ((mod->low_addr & -ph->p_align)
- - (ph->p_vaddr & -ph->p_align));
+ GElf_Addr align = mod->dwfl->segment_align;
+ if (align <= 1)
+ {
+ if ((mod->low_addr & (ph->p_align - 1)) == 0)
+ align = ph->p_align;
+ else
+ align = ((GElf_Addr) 1 << ffsll (mod->low_addr)) >> 1;
+ }
+
+ file->bias = ((mod->low_addr & -align) - (ph->p_vaddr & -align));
break;
}
}
/* Standard libdwfl callbacks for debugging a live Linux process.
- Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
+ Copyright (C) 2005-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag. */
static int
-find_sysinfo_ehdr (pid_t pid, GElf_Addr *sysinfo_ehdr)
+grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
{
char *fname;
if (asprintf (&fname, PROCAUXVFMT, pid) < 0)
if (d.a32[i].a_type == AT_SYSINFO_EHDR)
{
*sysinfo_ehdr = d.a32[i].a_un.a_val;
- nread = 0;
- break;
+ if (dwfl->segment_align > 1)
+ {
+ nread = 0;
+ break;
+ }
}
+ else if (d.a32[i].a_type == AT_PAGESZ
+ && dwfl->segment_align <= 1)
+ dwfl->segment_align = d.a32[i].a_un.a_val;
break;
case 8:
for (size_t i = 0; (char *) &d.a64[i] < &d.buffer[nread]; ++i)
if (d.a64[i].a_type == AT_SYSINFO_EHDR)
{
*sysinfo_ehdr = d.a64[i].a_un.a_val;
- nread = 0;
- break;
+ if (dwfl->segment_align > 1)
+ {
+ nread = 0;
+ break;
+ }
}
+ else if (d.a64[i].a_type == AT_PAGESZ
+ && dwfl->segment_align <= 1)
+ dwfl->segment_align = d.a64[i].a_un.a_val;
break;
default:
abort ();
/* We'll notice the AT_SYSINFO_EHDR address specially when we hit it. */
GElf_Addr sysinfo_ehdr = 0;
- int result = find_sysinfo_ehdr (pid, &sysinfo_ehdr);
+ int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr);
if (result != 0)
return result;