1178525Sjb/* 2178525Sjb * CDDL HEADER START 3178525Sjb * 4178525Sjb * The contents of this file are subject to the terms of the 5178525Sjb * Common Development and Distribution License, Version 1.0 only 6178525Sjb * (the "License"). You may not use this file except in compliance 7178525Sjb * with the License. 8178525Sjb * 9178525Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10178525Sjb * or http://www.opensolaris.org/os/licensing. 11178525Sjb * See the License for the specific language governing permissions 12178525Sjb * and limitations under the License. 13178525Sjb * 14178525Sjb * When distributing Covered Code, include this CDDL HEADER in each 15178525Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16178525Sjb * If applicable, add the following below this CDDL HEADER, with the 17178525Sjb * fields enclosed by brackets "[]" replaced with your own identifying 18178525Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 19178525Sjb * 20178525Sjb * CDDL HEADER END 21178525Sjb */ 22178525Sjb/* 23178525Sjb * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24178525Sjb * Use is subject to license terms. 25178525Sjb */ 26178525Sjb 27178525Sjb#pragma ident "%Z%%M% %I% %E% SMI" 28178525Sjb 29178525Sjb#include <ctf_impl.h> 30178525Sjb 31178525Sjb/* 32178525Sjb * Simple doubly-linked list append routine. This implementation assumes that 33178525Sjb * each list element contains an embedded ctf_list_t as the first member. 34178525Sjb * An additional ctf_list_t is used to store the head (l_next) and tail 35178525Sjb * (l_prev) pointers. The current head and tail list elements have their 36178525Sjb * previous and next pointers set to NULL, respectively. 37178525Sjb */ 38178525Sjbvoid 39178525Sjbctf_list_append(ctf_list_t *lp, void *new) 40178525Sjb{ 41178525Sjb ctf_list_t *p = lp->l_prev; /* p = tail list element */ 42178525Sjb ctf_list_t *q = new; /* q = new list element */ 43178525Sjb 44178525Sjb lp->l_prev = q; 45178525Sjb q->l_prev = p; 46178525Sjb q->l_next = NULL; 47178525Sjb 48178525Sjb if (p != NULL) 49178525Sjb p->l_next = q; 50178525Sjb else 51178525Sjb lp->l_next = q; 52178525Sjb} 53178525Sjb 54178525Sjb/* 55178525Sjb * Prepend the specified existing element to the given ctf_list_t. The 56178525Sjb * existing pointer should be pointing at a struct with embedded ctf_list_t. 57178525Sjb */ 58178525Sjbvoid 59178525Sjbctf_list_prepend(ctf_list_t *lp, void *new) 60178525Sjb{ 61178525Sjb ctf_list_t *p = new; /* p = new list element */ 62178525Sjb ctf_list_t *q = lp->l_next; /* q = head list element */ 63178525Sjb 64178525Sjb lp->l_next = p; 65178525Sjb p->l_prev = NULL; 66178525Sjb p->l_next = q; 67178525Sjb 68178525Sjb if (q != NULL) 69178525Sjb q->l_prev = p; 70178525Sjb else 71178525Sjb lp->l_prev = p; 72178525Sjb} 73178525Sjb 74178525Sjb/* 75178525Sjb * Delete the specified existing element from the given ctf_list_t. The 76178525Sjb * existing pointer should be pointing at a struct with embedded ctf_list_t. 77178525Sjb */ 78178525Sjbvoid 79178525Sjbctf_list_delete(ctf_list_t *lp, void *existing) 80178525Sjb{ 81178525Sjb ctf_list_t *p = existing; 82178525Sjb 83178525Sjb if (p->l_prev != NULL) 84178525Sjb p->l_prev->l_next = p->l_next; 85178525Sjb else 86178525Sjb lp->l_next = p->l_next; 87178525Sjb 88178525Sjb if (p->l_next != NULL) 89178525Sjb p->l_next->l_prev = p->l_prev; 90178525Sjb else 91178525Sjb lp->l_prev = p->l_prev; 92178525Sjb} 93178525Sjb 94178525Sjb/* 95178525Sjb * Convert an encoded CTF string name into a pointer to a C string by looking 96178525Sjb * up the appropriate string table buffer and then adding the offset. 97178525Sjb */ 98178525Sjbconst char * 99178525Sjbctf_strraw(ctf_file_t *fp, uint_t name) 100178525Sjb{ 101178525Sjb ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)]; 102178525Sjb 103178525Sjb if (ctsp->cts_strs != NULL && CTF_NAME_OFFSET(name) < ctsp->cts_len) 104178525Sjb return (ctsp->cts_strs + CTF_NAME_OFFSET(name)); 105178525Sjb 106178525Sjb /* string table not loaded or corrupt offset */ 107178525Sjb return (NULL); 108178525Sjb} 109178525Sjb 110178525Sjbconst char * 111178525Sjbctf_strptr(ctf_file_t *fp, uint_t name) 112178525Sjb{ 113178525Sjb const char *s = ctf_strraw(fp, name); 114178525Sjb return (s != NULL ? s : "(?)"); 115178525Sjb} 116178525Sjb 117178525Sjb/* 118178525Sjb * Same strdup(3C), but use ctf_alloc() to do the memory allocation. 119178525Sjb */ 120178525Sjbchar * 121178525Sjbctf_strdup(const char *s1) 122178525Sjb{ 123178525Sjb char *s2 = ctf_alloc(strlen(s1) + 1); 124178525Sjb 125178525Sjb if (s2 != NULL) 126178525Sjb (void) strcpy(s2, s1); 127178525Sjb 128178525Sjb return (s2); 129178525Sjb} 130178525Sjb 131178525Sjb/* 132178525Sjb * Store the specified error code into errp if it is non-NULL, and then 133178525Sjb * return NULL for the benefit of the caller. 134178525Sjb */ 135178525Sjbctf_file_t * 136178525Sjbctf_set_open_errno(int *errp, int error) 137178525Sjb{ 138178525Sjb if (errp != NULL) 139178525Sjb *errp = error; 140178525Sjb return (NULL); 141178525Sjb} 142178525Sjb 143178525Sjb/* 144178525Sjb * Store the specified error code into the CTF container, and then return 145178525Sjb * CTF_ERR for the benefit of the caller. 146178525Sjb */ 147178525Sjblong 148178525Sjbctf_set_errno(ctf_file_t *fp, int err) 149178525Sjb{ 150178525Sjb fp->ctf_errno = err; 151178525Sjb return (CTF_ERR); 152178525Sjb} 153