source: trunk/third/sysinfo/kvm.c @ 12269

Revision 12269, 4.0 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12268, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 1992-1998 Michael A. Cooper.
3 * This software may be freely used and distributed provided it is not
4 * sold for profit or used in part or in whole for commercial gain
5 * without prior written agreement, and the author is credited
6 * appropriately.
7 */
8
9/*
10 * Frontend functions for kvm_*() functions
11 *
12 * It is assumed we HAVE_NLIST if we HAVE_KVM.
13 */
14
15#include <stdio.h>
16#include "defs.h"
17
18#if     defined(HAVE_KVM)
19
20#include "defs.h"
21#include <fcntl.h>
22
23/*
24 * Perform a kvm_close().  Really just here to be compatible.
25 */
26extern void KVMclose(kd)
27    kvm_t                      *kd;
28{
29    if (kd)
30        (void) kvm_close(kd);
31}
32
33/*
34 * Perform a kvm_open().
35 */
36extern kvm_t *KVMopen()
37{
38    kvm_t                      *kd = NULL;
39    extern char                *ProgramName;
40
41    if ((kd = kvm_open((char *)NULL, (char *)NULL, (char *)NULL, O_RDONLY,
42                       ProgramName)) == NULL) {
43        SImsg(SIM_GERR, "kvm_open failed: %s.", SYSERR);
44        return((kvm_t *) NULL);
45    }
46
47    return(kd);
48}
49
50#if     defined(HAVE_NLIST) || defined(HAVE_KNLIST)
51
52static nlist_t NListTab[] = {
53    { 0 },
54    { 0 },
55};
56
57/*
58 * Perform an nlist on "kd" looking for "Symbol" or "NameList".
59 * Return the a pointer to the found nlist structure.
60 * On failure, return NULL and KVMclos(kd).
61 */
62extern nlist_t *KVMnlist(kd, Symbol, NameList, NumNameList)
63    kvm_t                      *kd;
64    char                       *Symbol;
65    nlist_t                    *NameList;
66    int                         NumNameList;
67    /*ARGSUSED*/
68{
69    nlist_t                    *NLPtr;
70    nlist_t                    *TabPtr;
71    char                       *cp;
72    int                         Status;
73    int                         NumEle;
74
75    if (NameList) {
76        NLPtr = NameList;
77        TabPtr = NameList;
78        NumEle = NumNameList;
79    } else {
80        TabPtr = NListTab;
81        NLPtr = &NListTab[0];
82        NumEle = 1;
83        memset((void *) NLPtr, 0, sizeof(nlist_t));
84        GetNlNamePtr(NLPtr) = Symbol;
85    }
86
87#if     defined(COFF) || defined(ELF)
88    for (NLPtr = TabPtr; GetNlNamePtr(NLPtr); ++NLPtr) {
89        cp = GetNlNamePtr(NLPtr);
90        /*
91         * Skip over initial '_'
92         */
93        if (*cp == '_')
94            GetNlNamePtr(NLPtr) = cp + 1;
95    }
96#endif
97
98#if     defined(HAVE_KNLIST)
99    Status = knlist(TabPtr, NumEle, sizeof(nlist_t));
100#else   /* !HAVE_KNLIST */
101    Status = kvm_nlist(kd, TabPtr);
102#endif  /* HAVE_KNLIST */
103    if (Status == -1) {
104        cp = GetNlNamePtr(NLPtr);
105        SImsg(SIM_GERR, "kvm_nlist name \"%s\" failed (status = %d): %s.",
106                         (cp) ? cp : "(unknown)", Status, SYSERR);
107        KVMclose(kd);
108        return((nlist_t *) NULL);
109    }
110
111    return(&TabPtr[0]);
112}
113#endif  /* HAVE_NLIST || HAVE_KNLIST */
114
115/*
116 * Perform a kvm_read().
117 *
118 * If DataType==KDT_STRING, read 1 byte at a time until '\0' or
119 * NumBytes is reached. This is necessary in order to avoid
120 * reading invalid memory pages from the kernel which can lead
121 * to system crashes.
122 *
123 * If DataType==KDT_DATA then we read NumBytes of data into
124 * Buf all at once.
125 */
126extern int KVMget(kd, Addr, Buf, NumBytes, DataType)
127    kvm_t                      *kd;
128    KVMaddr_t                   Addr;
129    void                       *Buf;
130    size_t                      NumBytes;
131    int                         DataType;
132{
133    char                       *Ptr;
134    char                       *End;
135
136    if (!kd)
137        return(-1);
138
139    switch (DataType) {
140    case KDT_STRING:
141        Ptr = (char *) Buf;
142        End = (char *) &Ptr[NumBytes-1];
143        do {
144            if (kvm_read(kd, Addr++, Ptr, 1) != 1) {
145                SImsg(SIM_GERR, "kvm_read failed prematurely: %s.", SYSERR);
146                return(-1);
147            }
148        } while (Ptr < End && *Ptr++);
149        *Ptr = C_NULL;
150        break;
151
152    case KDT_DATA:
153        if (kvm_read(kd, Addr, Buf, NumBytes) != NumBytes) {
154            SImsg(SIM_GERR, "kvm_read failed (amount=%d): %s.",
155                             NumBytes, SYSERR);
156            return(-1);
157        }
158        break;
159
160    default:
161        SImsg(SIM_UNKN, "Unknown Kernel Data Type: %d.", DataType);
162        return(-1);
163    }
164
165    return(0);
166}
167
168/*
169 * Check to see if PtrNL is valid.
170 */
171extern int _CheckNlist(PtrNL)
172    nlist_t                    *PtrNL;
173{
174    char                       *cp;
175
176    if (!PtrNL)
177        return(-1);
178
179    /*
180     * Should use n_type, but that's not set
181     * correctly on some OS's.
182     */
183    if (!PtrNL->n_value) {
184        cp = GetNlNamePtr(PtrNL);
185        SImsg(SIM_DBG, "Kernel symbol \"%s\" not found.",
186              (cp) ? cp : "(unknown)");
187        return(-1);
188    }
189
190    return(0);
191}
192
193#endif /* HAVE_KVM */
Note: See TracBrowser for help on using the repository browser.