/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* interface used by unwind support to query frame descriptor info
*/
#ifndef _LIBCRUN_
#include "lint.h"
#endif
#include <limits.h>
#include "stack_unwind.h"
#include "unwind_context.h"
#include <dlfcn.h>
/*
* CIE:
* UNUM32 length
* UNUM32 ID
* UNUM8 version
* ZTSTRING augmentation
* ULEB128 Code Align Factor
* SLEB128 Data Align Factor
* UNUM8 RA
* ULEB128 length
* UNUM8 personality enc
* ADDR personality
* UNUM8 code_enc
* UNUM8 lsda_enc
*
* FDE:
* UNUM32 length
* UNUM32 ID
* ADDR initial loc
* SIZE size
* ULEB128 length
* ADDR lsda
*/
struct eh_frame_fields *
{
void *fde_end;
void *data;
void *cie_end;
void *cdata;
int lsda_enc = 0;
int per_enc = 0;
int code_enc = 0;
char *p;
void* lsda = 0;
/* here is where data mapping would happen ??REMOTE?? */
reloc = 0;
creloc = 0;
/* data mapping has happened */
f->cie_ops_end = cie_end;
f->fde_ops_end = fde_end;
/* LINTED alignment */
if (augment[0] == 'z' &&
for (p = &(augment[1]); *p != 0; p++) {
switch (*p) {
case 'P':
if (per_enc == 0)
per_enc = 0x4;
break;
case 'R':
break;
case 'L':
break;
}
}
}
if (code_enc == 0)
code_enc = 0x4;
return (0);
if (augment[0] == 'z') {
/*
* without the two work-arounds test would be
* (scratch > 0 & lsda_enc)
*/
} else if (scratch == 4) {
/*
* 11/24/04 compiler is sometimes not outputing
* lsda_enc
*/
} else if (scratch == 8) {
/*
* 11/12/04 - compiler is putting out relative
* encoding byte and absolute data - inconsistancy
* is caught here.
*/
}
}
if (pfn)
if (lsda)
return (f);
}
static int
{
int res;
switch (val) {
case 0x3:
res = 3;
break;
case 0x04:
res = 4;
break;
case 0x0b:
res = 3;
break;
case 0x0c:
res = 4;
break;
default:
break;
}
return (res);
}
static void
{
void *fde;
switch (val) {
case 0x3:
/* LINTED alignment */
second += 4;
/* LINTED alignment */
third += 8;
/* LINTED alignment */
break;
case 0x04:
/* LINTED alignment */
second += 8;
/* LINTED alignment */
third += 16;
/* LINTED alignment */
break;
case 0x0b:
/* LINTED alignment */
second += 4;
/* LINTED alignment */
third += 8;
/* LINTED alignment */
break;
case 0x0c:
/* LINTED alignment */
second += 8;
/* LINTED alignment */
third += 16;
/* LINTED alignment */
break;
}
switch (rel) {
case 0:
break;
case 1:
break;
case 3:
break;
default:
/* remainder not implemented */
break;
}
*next_codep = next_code;
}
static void *
/*
* Search the eh_frame info with a given pc. Return a pointer to a
* FDE. The search is performed in two stages.
* First rtld.so identifies the load module containing the target location.
* This returns the appropiate eh_frame_hdr, and a binary search is
* then performed on the eh_frame_hdr to locate the entry with
* a matching pc value.
*/
void *
{
void* data;
void* data_end;
/* Locate the appropiate exception_range_entry table first */
return (0);
}
/*
* you now know size and position of block of data needed for
* binary search ??REMOTE??
*/
if (0 == data)
return (0);
reloc = 0;
/* ??REMOTE?? */
}
static void *
{
void* fde;
/*
* Invariant -- if there is a containing range,
* it must lie in the interval [pi,pj). That is,
* pi <= p < pj, if p exists.
*/
unsigned char *pr =
/* Don't use (pi+pj)>>1 */
/* Return fde if tpc is in this range. */
return ((void*) fde);
}
if (range_start < pc)
else
}
return (0);
}