1/*****************************************************************************/
2/* */
3/* extsyms.c */
4/* */
5/* Handle program external symbols for relocatable output formats */
6/* */
7/* */
8/* */
9/* (C) 1999-2011, Ullrich von Bassewitz */
10/* Roemerstrasse 52 */
11/* D-70794 Filderstadt */
12/* EMail: uz@cc65.org */
13/* */
14/* */
15/* This software is provided 'as-is', without any expressed or implied */
16/* warranty. In no event will the authors be held liable for any damages */
17/* arising from the use of this software. */
18/* */
19/* Permission is granted to anyone to use this software for any purpose, */
20/* including commercial applications, and to alter it and redistribute it */
21/* freely, subject to the following restrictions: */
22/* */
23/* 1. The origin of this software must not be misrepresented; you must not */
24/* claim that you wrote the original software. If you use this software */
25/* in a product, an acknowledgment in the product documentation would be */
26/* appreciated but is not required. */
27/* 2. Altered source versions must be plainly marked as such, and must not */
28/* be misrepresented as being the original software. */
29/* 3. This notice may not be removed or altered from any source */
30/* distribution. */
31/* */
32/*****************************************************************************/
33
34
35
36#include <string.h>
37
38/* common */
39#include "hashfunc.h"
40#include "xmalloc.h"
41
42/* ld65 */
43#include "error.h"
44#include "extsyms.h"
45#include "spool.h"
46
47
48
49/*****************************************************************************/
50/* Data */
51/*****************************************************************************/
52
53
54
55/* Structure holding an external symbol */
56struct ExtSym {
57 unsigned Name; /* Name index */
58 ExtSym* List; /* Next entry in list of all symbols */
59 ExtSym* Next; /* Next entry in hash list */
60 unsigned Flags; /* Generic flags */
61 unsigned Num; /* Number of external symbol */
62};
63
64/* External symbol table structure */
65#define HASHTAB_MASK 0x3FU
66#define HASHTAB_SIZE (HASHTAB_MASK + 1)
67struct ExtSymTab {
68 ExtSym* Root; /* List of symbols */
69 ExtSym* Last; /* Pointer to last symbol */
70 unsigned Count; /* Number of symbols */
71 ExtSym* HashTab[HASHTAB_SIZE];
72};
73
74
75
76/*****************************************************************************/
77/* Code */
78/*****************************************************************************/
79
80
81
82ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
83/* Create a new external symbol and insert it into the table */
84{
85 /* Get the hash value of the string */
86 unsigned Hash = (Name & HASHTAB_MASK);
87
88 /* Check for duplicates */
89 ExtSym* E = GetExtSym (Tab, Name);
90 if (E != 0) {
91 /* We do already have a symbol with this name */
92 Error ("Duplicate external symbol '%s'", GetString (Name));
93 }
94
95 /* Allocate memory for the structure */
96 E = xmalloc (sizeof (ExtSym));
97
98 /* Initialize the structure */
99 E->Name = Name;
100 E->List = 0;
101 E->Flags = 0;
102 E->Num = Tab->Count;
103
104 /* Insert the entry into the list of all symbols */
105 if (Tab->Last == 0) {
106 /* List is empty */
107 Tab->Root = E;
108 } else {
109 /* List not empty */
110 Tab->Last->List = E;
111 }
112 Tab->Last = E;
113 ++Tab->Count;
114
115 /* Insert the symbol into the hash table */
116 E->Next = Tab->HashTab[Hash];
117 Tab->HashTab[Hash] = E;
118
119 /* Done, return the created entry */
120 return E;
121}
122
123
124
125static void FreeExtSym (ExtSym* E)
126/* Free an external symbol structure. Will not unlink the entry, so internal
127** use only.
128*/
129{
130 xfree (E);
131}
132
133
134
135ExtSymTab* NewExtSymTab (void)
136/* Create a new external symbol table */
137{
138 unsigned I;
139
140 /* Allocate memory */
141 ExtSymTab* Tab = xmalloc (sizeof (ExtSymTab));
142
143 /* Initialize the fields */
144 Tab->Root = 0;
145 Tab->Last = 0;
146 Tab->Count = 0;
147 for (I = 0; I < HASHTAB_SIZE; ++I) {
148 Tab->HashTab [I] = 0;
149 }
150
151 /* Done, return the hash table */
152 return Tab;
153}
154
155
156
157void FreeExtSymTab (ExtSymTab* Tab)
158/* Free an external symbol structure */
159{
160 /* Free all entries */
161 while (Tab->Root) {
162 ExtSym* E = Tab->Root;
163 Tab->Root = E->Next;
164 FreeExtSym (E);
165 }
166
167 /* Free the struct itself */
168 xfree (Tab);
169}
170
171
172
173ExtSym* GetExtSym (const ExtSymTab* Tab, unsigned Name)
174/* Return the entry for the external symbol with the given name. Return NULL
175** if there is no such symbol.
176*/
177{
178 /* Hash the name */
179 unsigned Hash = (Name & HASHTAB_MASK);
180
181 /* Check the linked list */
182 ExtSym* E = Tab->HashTab[Hash];
183 while (E) {
184 if (E->Name == Name) {
185 /* Found it */
186 break;
187 }
188 E = E->Next;
189 }
190
191 /* Return the symbol we found */
192 return E;
193}
194
195
196
197unsigned ExtSymCount (const ExtSymTab* Tab)
198/* Return the number of symbols in the table */
199{
200 return Tab->Count;
201}
202
203
204
205const ExtSym* ExtSymList (const ExtSymTab* Tab)
206/* Return the start of the symbol list sorted by symbol number. Call
207** ExtSymNext for the next symbol.
208*/
209{
210 return Tab->Root;
211}
212
213
214
215unsigned ExtSymNum (const ExtSym* E)
216/* Return the number of an external symbol */
217{
218 return E->Num;
219}
220
221
222
223unsigned ExtSymName (const ExtSym* E)
224/* Return the symbol name index */
225{
226 return E->Name;
227}
228
229
230
231const ExtSym* ExtSymNext (const ExtSym* E)
232/* Return the next symbol in the list */
233{
234 return E->List;
235}
236