This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Re: vdso handling
- From: Pedro Alves <palves at redhat dot com>
- To: Mark Wielaard <mjw at redhat dot com>, Cary Coutant <ccoutant at google dot com>, Doug Evans <dje at google dot com>, "Metzger, Markus T" <markus dot t dot metzger at intel dot com>, "gdb at sourceware dot org" <gdb at sourceware dot org>, "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Thu, 13 Mar 2014 14:59:20 +0000
- Subject: Re: vdso handling
- Authentication-results: sourceware.org; auth=none
- References: <A78C989F6D9628469189715575E55B230AA884EB at IRSMSX104 dot ger dot corp dot intel dot com> <20140312071701 dot GW26922 at bubble dot grove dot modra dot org> <CADPb22SAmK5JB3muW_nCvuHN5L-aOcdyzYNR+OtnM3bA1x_OJg at mail dot gmail dot com> <CAHACq4o=HmdCo1FPFL-96raf2UN805jvM=VZM-9dbKrmzJFJTw at mail dot gmail dot com> <20140313010147 dot GZ26922 at bubble dot grove dot modra dot org> <1394704336 dot 11818 dot 115 dot camel at bordewijk dot wildebeest dot org> <20140313130322 dot GA3384 at bubble dot grove dot modra dot org>
On 03/13/2014 01:03 PM, Alan Modra wrote:
> On Thu, Mar 13, 2014 at 10:52:16AM +0100, Mark Wielaard wrote:
>> On Thu, 2014-03-13 at 11:31 +1030, Alan Modra wrote:
>>> It wouldn't
>>> help in the vdso case anyway, since the problem there is that you only
>>> have the loaded part of the original ELF file.
>>
>> Note that the vdso is often special, compared to other ELF dsos, because
>> the loaded part is just the complete ELF image in memory. Since they are
>> very simple they will just have one PT_LOAD at offset zero and if the
>> image is smaller than the page size then the whole file is just simply
>> mapped into memory completely. So by fetching the vdso ELF image from
>> remote memory you should be able to get the section headers and the
>> not-allocated sections too.
>
> Yes, but if the vdso does not fit in a page (which incidentally is
> inferred by program header p_align), then you may lose the section
> headers. I was assuming this was the case.
Hmm. How so? On x86 (arch/x86/vdso/vdso.S), the kernel just does:
.globl vdso_start, vdso_end
.align PAGE_SIZE
vdso_start:
.incbin "arch/x86/vdso/vdso.so"
vdso_end:
.align PAGE_SIZE /* extra data here leaks to userspace. */
And then arch/x86/vdso/vma.c has:
static int __init init_vdso(void)
{
int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE;
int i;
patch_vdso64(vdso_start, vdso_end - vdso_start);
vdso_size = npages << PAGE_SHIFT;
for (i = 0; i < npages; i++)
vdso_pages[i] = virt_to_page(vdso_start + i*PAGE_SIZE);
#ifdef CONFIG_X86_X32_ABI
patch_vdsox32(vdsox32_start, vdsox32_end - vdsox32_start);
npages = (vdsox32_end - vdsox32_start + PAGE_SIZE - 1) / PAGE_SIZE;
vdsox32_size = npages << PAGE_SHIFT;
for (i = 0; i < npages; i++)
vdsox32_pages[i] = virt_to_page(vdsox32_start + i*PAGE_SIZE);
#endif
return 0;
}
And patch_vdso64 _relies_ on sections being present at runtime:
static void __init patch_vdso64(void *vdso, size_t len)
{
Elf64_Ehdr *hdr = vdso;
Elf64_Shdr *sechdrs, *alt_sec = 0;
char *secstrings;
void *alt_data;
int i;
BUG_ON(len < sizeof(Elf64_Ehdr));
BUG_ON(memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0);
sechdrs = (void *)hdr + hdr->e_shoff;
secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
for (i = 1; i < hdr->e_shnum; i++) {
Elf64_Shdr *shdr = &sechdrs[i];
if (!strcmp(secstrings + shdr->sh_name, ".altinstructions")) {
alt_sec = shdr;
goto found;
}
}
/* If we get here, it's probably a bug. */
pr_warning("patch_vdso64: .altinstructions not found\n");
return; /* nothing to patch */
found:
alt_data = (void *)hdr + alt_sec->sh_offset;
apply_alternatives(alt_data, alt_data + alt_sec->sh_size);
}
On e.g., arch/powerpc/kernel/vdso.c, I see even a lot more
code looking at the sections of the vdso.
--
Pedro Alves