This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 0/2] libc: Fix __dl_iterate_phdr to work from audit context
- From: Jiri Olsa <jolsa at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Tue, 26 Jul 2011 12:34:52 +0200
- Subject: [PATCH 0/2] libc: Fix __dl_iterate_phdr to work from audit context
hi,
if __dl_iterate_phdr is called from audit context, it will not
provide all the info the callback. Some of the fields are just
zero. The test audit library source is attached.
The reason is, that inside the audit namespace the dynamic loader
link_map object is just a mirror of the real one. And it does not
have all the info filled in.
I prepared 2 fixies for this, since I'm not sure which way
you'll like more.. maybe neither ;)
attached patches:
1/2 - "libc: Fix _dl_map_object_from_fd to update ld.so link_map mirror object"
filling in needed values for dynamic loader mirror link_map object
2/2 - "libc: Fix __dl_iterate_phdr to take values from real link_map object"
using l_real link_map to get the values for __dl_iterate_phdr callback
The justification for this change is that libunwind is using
__dl_iterate_phdr to locate all the unwind info. So with current
behaviour, the stack that unwinds from audit context will stop at
the dynamic loader and does not continue through the application
itself. It works properly with either of above fixies.
thanks,
jirka
---
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>
#include <sys/time.h>
#include <execinfo.h>
#include <link.h>
static int callback(struct dl_phdr_info *info, size_t size, void *data)
{
printf("AUDIT got %s, base=0x%lx, dlpi_phnum %d\n",
info->dlpi_name,
(long) info->dlpi_addr,
info->dlpi_phnum);
return 0;
}
unsigned int la_version (unsigned int v)
{
return v;
}
unsigned int la_objopen(struct link_map *l, Lmid_t a, uintptr_t *cookie)
{
return 3;
}
uintptr_t la_symbind32(Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
{
*flags = 0;
return sym->st_value;
}
uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
{
*flags = 0;
return sym->st_value;
}
Elf64_Addr la_x86_64_gnu_pltenter (Elf64_Sym *__sym,
unsigned int __ndx,
uintptr_t *__refcook,
uintptr_t *__defcook,
La_x86_64_regs *__regs,
unsigned int *__flags,
const char *__symname,
long int *__framesizep)
{
printf("entry %s\n", __symname);
*__framesizep = 100;
dl_iterate_phdr(callback, NULL);
return __sym->st_value;
}
unsigned int la_x86_64_gnu_pltexit (Elf64_Sym *__sym,
unsigned int __ndx,
uintptr_t *__refcook,
uintptr_t *__defcook,
const La_x86_64_regs *__inregs,
La_x86_64_retval *__outregs,
const char *__symname)
{
return 0;
}
void la_activity(uintptr_t *cookie, unsigned int act)
{
}
char* la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
{
return (char*) name;
}
void la_preinit(uintptr_t *__cookie)
{
}
unsigned int la_objclose(uintptr_t *__cookie)
{
return 0;
}