death to trailing whitespace
[openafs.git] / src / export / symtab.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * symtab -     symbol table routines
12  */
13 #include <afsconfig.h>
14 #include <afs/param.h>
15
16
17 #include "sys/types.h"
18 #include "sym.h"
19
20 /*
21  * using the toc_syment structure, that we fabricate:
22  *      sym->n_offset is the string pointer
23  */
24 #ifdef __XCOFF64__
25 #define sym_str(sym) ((char *) (sym)->n_nptr)
26 #else
27 #define sym_off(sym)    ((sym)->n_offset)
28 #define sym_str(sym)    \
29         ((sym)->n_zeroes == 0 ? (char *) sym_off(sym) : (sym)->n_name)
30 #endif
31
32 sym_t *
33 sym_lookup(name, value)
34      char *name;
35 {
36     static sym_t *symsrch(), *search();
37     char buf[64];
38     sym_t *sym;
39
40     if (name) {
41         /*
42          * Heuristic:
43          * first, try just the name. if that fails, try with a
44          * prefix '.', and failing that, a prefix '_'.
45          */
46         if (sym = symsrch(name))
47             return sym;
48         memcpy(buf + 1, name, sizeof(buf) - 2);
49         buf[0] = '.';
50
51         if (sym = symsrch(buf))
52             return sym;
53
54         buf[0] = '_';
55
56         return symsrch(buf);
57     } else
58         return search(value);
59 }
60
61 static sym_t *
62 search(addr)
63      unsigned addr;
64 {
65     sym_t *sp;
66     sym_t *save;
67     unsigned value;
68
69     value = 0;
70     save = 0;
71
72     for (sp = toc_syms; sp < &toc_syms[toc_nsyms]; ++sp) {
73         if (sp->n_value <= addr && sp->n_value >= value) {
74             value = sp->n_value;
75             save = sp;
76             if (sp->n_value == addr)
77                 break;
78         }
79     }
80     return save ? sym_flex(save) : 0;
81 }
82
83 static sym_t *
84 symsrch(s)
85      char *s;
86 {
87     sym_t *sp;
88     sym_t *found;
89     int len;
90     char *p;
91
92     /*
93      * determine length of symbol
94      */
95     for (len = 0, p = s; *p; ++p)
96         ++len;
97
98     found = 0;
99     for (sp = toc_syms; sp < &toc_syms[toc_nsyms]; ++sp) {
100         /*
101          * exact matches preferred
102          */
103         if (strcmp(sym_str(sp), s) == 0) {
104             found = sp;
105             break;
106         }
107         /*
108          * otherwise, prefices might interest us.
109          */
110         if (!found && (strncmp(sym_str(sp), s, len) == 0)) {
111             found = sp;
112             continue;
113         }
114     }
115
116     return found ? sym_flex(found) : 0;
117 }
118
119 /*
120  * sym_flex -   convert a symbol so that there is no distinction between
121  *              flex-string and non flex-string format.
122  *
123  * Input:
124  *      sym     -       ^ to symbol table entry
125  *
126  * Returns:
127  *      ^ to static location containing modified symbol.
128  */
129 sym_t *
130 sym_flex(sym)
131      sym_t *sym;
132 {
133     static sym_t symbol;
134     static char name[48];
135
136     strncpy(name, sym_str(sym), sizeof(name) - 1);
137
138 #ifndef __XCOFF64__
139     if (sym->n_zeroes != 0)
140         name[8] = 0;            /* make sure that we truncate correctly */
141     symbol.n_zeroes = 0;
142 #endif
143
144     symbol = *sym;
145     symbol.n_nptr = name;
146
147     return &symbol;
148 }