lkml.org 
[lkml]   [2011]   [May]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
Date
SubjectRe: [GIT pull] x86 vdso updates
On Sun, May 29, 2011 at 11:10 AM, richard -rw- weinberger
<richard.weinberger@gmail.com> wrote:
> On Sun, May 29, 2011 at 4:57 PM, Andrew Lutomirski <luto@mit.edu> wrote:
>> On Sun, May 29, 2011 at 5:51 AM, richard -rw- weinberger
>> <richard.weinberger@gmail.com> wrote:
>>> Yesterday I had a closer look at 64bit UML.
>>> Glibc is always using vsyscalls because 64bit UML does not support the vDSO.
>>>
>>> On 32bit UML simply scans the ELF auxiliary vector provided by the host to
>>> get the address of the vDSO.
>>> How can I get this address on a 64bit host?
>>
>> I believe it's exactly the same.  There's an auxv entry that points to the vDSO.
>
> I don't think so.
> See:
> http://www.win.tue.nl/~aeb/linux/lk/lk-4.html
> Section "Address space randomization".
> The demo program finds the vDSO only on x86.
>
> UML uses quite the same method to find it.
> arch/um/os-Linux/elf_aux.c

The attached program works for me.

I don't know what this is supposed to mean, though:

/* See if the page is under TASK_SIZE */
if (vsyscall_ehdr < (unsigned long) envp)
vsyscall_ehdr = 0;
First, envp != TASK_SIZE.

Second, the vDSO can be wherever it wants. On current kernels at
least it is *always* mapped below TASK_SIZE (in the unsigned sense)
because it's mapped into user address space.

--Andy
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <elf.h>
#include <stdlib.h>

extern char **environ;

int __captured_argc;
char **__captured_argv;
char **__captured_envp;
Elf64_auxv_t *__captured_auxv;

void _capture_args(int argc, char **argv, char **envp)
{
__captured_argc = argc;
__captured_argv = argv;
__captured_envp = envp;
while(*envp)
envp++;
__captured_auxv = (Elf64_auxv_t*)(envp + 1);
}
static void * initarray_entry __attribute__((section(".preinit_array"), used)) =
(void*)_capture_args;

int main()
{
printf("envp = %p\n", __captured_envp);
for (int i = 0; __captured_auxv[i].a_type != AT_NULL; i++)
{
char *desc = "";
if (__captured_auxv[i].a_type == AT_SYSINFO)
desc = "AT_SYSINFO";
else if (__captured_auxv[i].a_type == AT_SYSINFO_EHDR)
desc = "AT_SYSINFO_EHDR";
printf("aux type %02u = 0x%016lX %s\n",
__captured_auxv[i].a_type, (long)__captured_auxv[i].a_un.a_val,
desc);
}
return 0;
}
\
 
 \ /
  Last update: 2011-05-29 17:31    [from the cache]
©2003-2011 Jasper Spaans