150 lines
4.2 KiB
C
150 lines
4.2 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2011 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "gtm_string.h"
|
||
|
#include "gtm_stat.h"
|
||
|
#include "gtm_limits.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
|
||
|
#include "zroutines.h"
|
||
|
#include "eintr_wrappers.h"
|
||
|
#include "error.h"
|
||
|
#include "lv_val.h" /* needed for "fgncal.h" */
|
||
|
#include "fgncal.h"
|
||
|
|
||
|
error_def (ERR_ZFILENMTOOLONG);
|
||
|
error_def (ERR_SYSCALL);
|
||
|
|
||
|
/*
|
||
|
* mstr *objstr; if NULL, do not search for object, else pointer to object file text string
|
||
|
* zro_ent **objdir; NULL if objstr is NULL, otherwise, return pointer to associated object directory
|
||
|
* objdir is NULL if object directory is not found
|
||
|
* mstr *srcstr; like objstr, except for associated source program
|
||
|
* zro_ent **srcdir; like objdir, except for associated source program directory
|
||
|
* boolean_t skip; if TRUE, skip over shared libraries. If FALSE, probe shared libraries.
|
||
|
*/
|
||
|
void zro_search (mstr *objstr, zro_ent **objdir, mstr *srcstr, zro_ent **srcdir, boolean_t skip)
|
||
|
{
|
||
|
uint4 status;
|
||
|
zro_ent *op, *sp, *op_result, *sp_result;
|
||
|
char objfn[PATH_MAX], srcfn[PATH_MAX], *obp, *sbp;
|
||
|
int objcnt, srccnt;
|
||
|
struct stat outbuf;
|
||
|
int stat_res;
|
||
|
mstr rtnname;
|
||
|
DCL_THREADGBL_ACCESS;
|
||
|
|
||
|
SETUP_THREADGBL_ACCESS;
|
||
|
if (!TREF(zro_root))
|
||
|
zro_init();
|
||
|
assert(objstr || srcstr); /* must search for object or source or both */
|
||
|
assert(!objstr || objdir); /* if object text, then must have pointer for result */
|
||
|
assert(!srcstr || srcdir); /* if source text, then must have pointer for result */
|
||
|
assert(ZRO_TYPE_COUNT == (TREF(zro_root))->type);
|
||
|
op_result = sp_result = NULL;
|
||
|
objcnt = (TREF(zro_root))->count;
|
||
|
assert(objcnt);
|
||
|
for (op = TREF(zro_root) + 1; !op_result && !sp_result && objcnt-- > 0; )
|
||
|
{
|
||
|
assert((ZRO_TYPE_OBJECT == op->type) || (ZRO_TYPE_OBJLIB == op->type));
|
||
|
if (objstr)
|
||
|
{
|
||
|
if (ZRO_TYPE_OBJLIB == op->type)
|
||
|
{
|
||
|
if (!skip)
|
||
|
{
|
||
|
assert(op->shrlib);
|
||
|
rtnname.len = objstr->len - (int)STR_LIT_LEN(DOTOBJ);
|
||
|
memcpy(objfn, objstr->addr, rtnname.len);
|
||
|
objfn[rtnname.len] = 0;
|
||
|
rtnname.addr = objfn;
|
||
|
if (NULL != (op->shrsym = (void *)fgn_getrtn(op->shrlib, &rtnname, SUCCESS)))
|
||
|
/* Note assignment above */
|
||
|
op_result = op;
|
||
|
}
|
||
|
op++;
|
||
|
continue;
|
||
|
}
|
||
|
if ((op->str.len + objstr->len + 2) > SIZEOF(objfn))
|
||
|
rts_error(VARLSTCNT(4) ERR_ZFILENMTOOLONG, 2, op->str.len, op->str.addr);
|
||
|
obp = &objfn[0];
|
||
|
if (op->str.len)
|
||
|
{
|
||
|
memcpy(obp, op->str.addr, op->str.len);
|
||
|
obp += op->str.len;
|
||
|
*obp++ = '/';
|
||
|
}
|
||
|
memcpy(obp, objstr->addr, objstr->len);
|
||
|
obp += objstr->len;
|
||
|
*obp++ = 0;
|
||
|
STAT_FILE(objfn, &outbuf, stat_res);
|
||
|
if (-1 == stat_res)
|
||
|
{
|
||
|
if (errno != ENOENT)
|
||
|
rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("stat"), CALLFROM, errno);
|
||
|
} else
|
||
|
op_result = op;
|
||
|
}
|
||
|
if (srcstr)
|
||
|
{
|
||
|
sp = op + 1;
|
||
|
if (ZRO_TYPE_OBJLIB == op->type)
|
||
|
{
|
||
|
op = sp;
|
||
|
continue;
|
||
|
}
|
||
|
assert(ZRO_TYPE_COUNT == sp->type);
|
||
|
srccnt = (sp++)->count;
|
||
|
for ( ; !sp_result && srccnt-- > 0; sp++)
|
||
|
{
|
||
|
assert(sp->type == ZRO_TYPE_SOURCE);
|
||
|
if (sp->str.len + srcstr->len + 2 > SIZEOF(srcfn)) /* extra 2 for '/' & null */
|
||
|
rts_error(VARLSTCNT(4) ERR_ZFILENMTOOLONG, 2, sp->str.len, sp->str.addr);
|
||
|
sbp = &srcfn[0];
|
||
|
if (sp->str.len)
|
||
|
{
|
||
|
memcpy (sbp, sp->str.addr, sp->str.len);
|
||
|
sbp += sp->str.len;
|
||
|
*sbp++ = '/';
|
||
|
}
|
||
|
memcpy(sbp, srcstr->addr, srcstr->len);
|
||
|
sbp += srcstr->len;
|
||
|
*sbp++ = 0;
|
||
|
STAT_FILE(srcfn, &outbuf, stat_res);
|
||
|
if (-1 == stat_res)
|
||
|
{
|
||
|
if (ENOENT != errno)
|
||
|
rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("stat"), CALLFROM, errno);
|
||
|
} else
|
||
|
{
|
||
|
sp_result = sp;
|
||
|
op_result = op;
|
||
|
}
|
||
|
}
|
||
|
op = sp;
|
||
|
} else
|
||
|
{
|
||
|
op++;
|
||
|
assert(ZRO_TYPE_COUNT == op->type);
|
||
|
op += op->count;
|
||
|
op++;
|
||
|
}
|
||
|
}
|
||
|
if (objdir)
|
||
|
*objdir = op_result;
|
||
|
if (srcdir)
|
||
|
*srcdir = sp_result;
|
||
|
return;
|
||
|
}
|