bindings.c revision 883492d5a933deb34cd27521e7f2756773cd27af
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <link.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <synch.h>
#include <string.h>
#include "bindings.h"
#include "env.h"
static Elist *bindto_list = 0;
static Elist *bindfrom_list = 0;
static unsigned int current_map_len = 0;
static char *buffer_name;
/*
* This routine was stolen from libelf.so.1
*/
static unsigned long
{
register unsigned int g, h = 0;
while (*nm != '\0') {
h = (h << 4) + *nm++;
/* LINTED */
if ((g = (unsigned int)(h & MASK)) != 0)
h ^= g >> 24;
h &= ~MASK;
}
return ((unsigned long)h);
}
static void
output_err_message(const char *msg)
{
int fd;
perror("open");
}
}
/*
* common mutex locking & unlocking routines for this module. This is to
* control the setting of 'lock_held'.
*/
static void
{
if (_lwp_mutex_lock(lock) != 0) {
output_err_message("bt_lock failed!!\n");
perror("_lwp_mutex_lock");
}
}
static void
{
if (_lwp_mutex_unlock(lock) != 0) {
output_err_message("bt_unlock failed!!\n");
perror("_lwp_mutex_unlock");
}
}
/*
* It's always possible that another process sharing our buffer
* has caused it to grow. If this is the case we must adjust our
* mappings to compensate.
*/
static void
remap_buffer(int fd)
{
void * new_bhp;
perror("mmap");
exit(1);
}
/*
* clean up old mapping
*/
}
static void
grow_buffer(void)
{
int fd;
"bidings: grow_buffer: open failed: %s\n",
perror("open");
exit(1);
}
perror("ftruncate");
exit(1);
}
}
static void
get_new_strbuf(void)
{
grow_buffer();
}
static unsigned int
{
char *sptr;
unsigned int bptr;
unsigned int slen;
/* LINTED */
/*
* will string fit into our current string buffer?
*/
return (bptr);
}
static unsigned int
get_new_entry(void)
{
unsigned int new_ent;
grow_buffer();
return (new_ent);
}
static void
init_locks(void)
{
int i;
for (i = 0; i < DEFBKTS; i++)
sizeof (lwp_mutex_t));
}
{
int fd;
if (version < LAV_CURRENT) {
"bindings.so: unexpected link_audit version: %d\n",
version);
return (0);
}
perror("ftruncate");
return (0);
}
/* LINTED */
perror("bindings.so: mmap");
return (0);
}
init_locks();
/*
* Lock our structure and then initialize the data
*/
/*
* Set up our initial string buffer
*/
int i;
for (i = 0; i < 4; i++) {
(void) sleep(1);
continue;
}
(void) sleep(1);
continue;
}
/* LINTED */
MAP_FAILED) {
"bindings: mmap failed\n");
perror("mmap");
return (0);
}
/* LINTED */
}
"bindings: buffer mapping timed out\n");
return (0);
}
for (i = 0; i < 4; i++) {
(void) sleep(1);
continue;
}
}
"bindings: %s not initialized\n", buffer_name);
return (0);
}
} else {
perror("open");
return (0);
}
return (LAV_CURRENT);
}
/* ARGSUSED 0 */
{
if ((bindto_list == 0) ||
else
flags = 0;
if ((bindfrom_list == 0) ||
flags |= LA_FLG_BINDFROM;
return (flags);
}
/* ARGSUSED 1 */
#if defined(__sparcv9)
const char *sym_name)
const char *sym_name)
#endif
{
unsigned long bktno;
const char *lib_name;
#if !defined(_LP64)
#endif
if (sym_name == 0) {
output_err_message("null symname\n");
}
/*
* The buffer has been grown (by another process) and
* we need to remap it into memory.
*/
int fd;
"bidings: plt_enter: open failed: %s\n",
perror("open");
exit(1);
}
}
binding_entry * bep;
unsigned int be_off;
unsigned int sym_off;
unsigned int lib_off;
be_off = get_new_entry();
/* LINTED */
} else {
int strcmp_res;
unsigned int prev_off = 0;
unsigned int cur_off;
unsigned int lib_off = 0;
/*
* Once we get to the bucket, we do a two tiered
* search. First we search for a library match, then
* we search for a symbol match.
*/
/* LINTED */
cur_off);
/* LINTED */
cur_off);
}
if (cur_off && (strcmp_res == 0)) {
/*
* This is a small optimization. For
* each bucket we will only record a library
* name once. Once it has been recorded in
* a bucket we will just re-use the same
* string.
*/
/* LINTED */
cur_off);
}
}
if (strcmp_res == 0) {
/*
* We've got a match
*/
} else {
unsigned int new_off;
unsigned int sym_off;
new_off = get_new_entry();
if (lib_off == 0)
/* LINTED */
new_off);
if (prev_off) {
/* LINTED */
prev_off);
} else
/*
* Insert at head of list.
*/
}
}
}