use-dollar-cc-not-cc-for-aix-exporter-20010305
[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 "sys/types.h"
14 #include "sym.h"
15
16 /*
17  * using the toc_syment structure, that we fabricate:
18  *      sym->n_offset is the string pointer
19  */
20 #define sym_off(sym)    ((sym)->n_offset)
21 #define sym_str(sym)    \
22         ((sym)->n_zeroes == 0 ? (char *) sym_off(sym) : (sym)->n_name)
23
24 sym_t *
25 sym_lookup(name, value)
26 char *name; {
27         static sym_t *symsrch(), *search();
28         char buf[64];
29         register sym_t *sym;
30
31         if (name) {
32                 /*
33                  * Heuristic:
34                  * first, try just the name. if that fails, try with a
35                  * prefix '.', and failing that, a prefix '_'.
36                  */
37                 if (sym = symsrch(name))
38                         return sym;
39                 bcopy(name, buf+1, sizeof (buf) - 2);
40                 buf[0] = '.';
41
42                 if (sym = symsrch(buf))
43                         return sym;
44
45                 buf[0] = '_';
46
47                 return symsrch(buf);
48         } else
49                 return search(value);
50 }
51
52 static sym_t *
53 search(addr)
54 unsigned addr; {
55         register sym_t *sp;
56         register sym_t *save;
57         unsigned value;
58
59         value = 0;
60         save  = 0;
61
62         for (sp = toc_syms; sp < &toc_syms[toc_nsyms]; ++sp) {
63                 if (sp->n_value <= addr && sp->n_value >= value) {
64                         value = sp->n_value;
65                         save  = sp;
66                         if (sp->n_value == addr)
67                                 break;
68                 }
69         }
70         return save ? sym_flex(save) : 0;
71 }
72
73 static sym_t *
74 symsrch(s)
75 register char *s; {
76         register sym_t *sp;
77         register sym_t *found;
78         register len;
79         register char *p;
80
81         /*
82          * determine length of symbol
83          */
84         for (len = 0, p = s; *p; ++p)
85                 ++len;
86
87         found = 0;
88         for (sp = toc_syms; sp < &toc_syms[toc_nsyms]; ++sp) {
89                 /*
90                  * exact matches preferred
91                  */
92                 if (strcmp(sym_str(sp), s) == 0) {
93                         found = sp;
94                         break;
95                 }
96                 /*
97                  * otherwise, prefices might interest us.
98                  */
99                 if (!found && (strncmp(sym_str(sp), s, len) == 0)) {
100                         found = sp;
101                         continue;
102                 }
103         }
104
105         return found ? sym_flex(found) : 0;
106 }
107
108 /*
109  * sym_flex -   convert a symbol so that there is no distinction between
110  *              flex-string and non flex-string format.
111  *
112  * Input:
113  *      sym     -       ^ to symbol table entry
114  *
115  * Returns:
116  *      ^ to static location containing modified symbol.
117  */
118 sym_t *
119 sym_flex(sym)
120 register sym_t *sym; {
121         static sym_t symbol;
122         static char name[48];
123
124         strncpy(name, sym_str(sym), sizeof (name) - 1);
125
126         if (sym->n_zeroes != 0)
127                 name[8] = 0;    /* make sure that we truncate correctly */
128
129         symbol          = *sym;
130         symbol.n_zeroes = 0;
131         symbol.n_nptr   = name;
132
133         return &symbol;
134 }