Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / libxref / datafile.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: datafile.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * @(#)datafile.c 1.1 02/05/02
46 * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved
47 * Copyright Use is subject to license terms.
48 */
49#include <stdio.h>
50#include <stdlib.h>
51#include <unistd.h>
52#include <string.h>
53
54#include "xref.h"
55
56static void
57write_4bytes(int n, FILE *fd)
58{
59 fwrite(&n, 1, 4, fd);
60}
61
62static int
63read_4bytes(FILE *fd)
64{
65 uint32_t ival;
66 fread(&ival, 1, 4, fd);
67 return (ival);
68}
69
70#ifdef LOAD_DEBUG
71#define LPRINTF(x) printf x
72#else
73#define LPRINTF(x)
74#endif
75
76static xref_t *
77load_symbol_from_file(xref_state_t *state, int *sindex, int n, FILE *fd)
78{
79 xref_t *sym;
80 char tag[4];
81 int j, fid, bytes;
82 int *calls_ptr = NULL;
83 int *called_ptr = NULL;
84 xref_t *new;
85 xref_file_t *file;
86
87 LPRINTF(("Loading symbol: %d ", n));
88 sym = state->xref_cache[n];
89 if (sym != NULL) {
90 LPRINTF((" [cached] %x\n", sym));
91 return (sym);
92 }
93 LPRINTF((" from file\n"));
94
95 new = malloc(sizeof (xref_t));
96 memset(new, 0, sizeof (xref_t));
97
98 fseek(fd, sindex[n], 0);
99 fread(tag, 1, 3, fd);
100 if (strncmp(tag, "SYM", 3) != 0) {
101 printf("Corrupted xref data file\n");
102 return (NULL);
103 }
104
105 new->id = read_4bytes(fd);
106 new->flags = read_4bytes(fd);
107
108 /* we have the name */
109 bytes = fgetc(fd);
110 new->name = malloc(bytes + 1);
111 fread(new->name, 1, bytes, fd);
112 new->name[bytes] = 0;
113 LPRINTF(("....name: %s\n", new->name));
114
115 /* get the file it was defined in */
116 fid = read_4bytes(fd);
117 new->file = file = state->file_cache[fid];
118 new->linenum = read_4bytes(fd);
119
120 LPRINTF(("....File(%d) : %s:%d\n", fid, file->name, new->linenum));
121 xref_add_definition(file->defs, new);
122
123 /* prepare the data structures for the call refs */
124 new->calls.insert = read_4bytes(fd);
125 new->called_by.insert = read_4bytes(fd);
126 new->calls.size = new->calls.insert;
127 new->called_by.size = new->called_by.insert + 10;
128
129 if (new->calls.size) {
130 new->calls.ptr = malloc(new->calls.size * sizeof (xref_t *));
131 }
132
133 LPRINTF(("....Calls: %d\n", new->calls.insert));
134
135 bytes = new->calls.insert * sizeof (int);
136 if (bytes) {
137 calls_ptr = malloc(bytes);
138 fread(calls_ptr, 1, bytes, fd);
139 }
140
141 /* prepare the data structures for the called_by refs */
142 bytes = new->called_by.size * sizeof (xref_t);
143 new->called_by.ptr = malloc(bytes);
144
145 LPRINTF(("....Called by: %d\n", new->called_by.insert));
146 bytes = new->called_by.insert * sizeof (int);
147 if (bytes) {
148 called_ptr = malloc(bytes);
149 fread(called_ptr, 1, bytes, fd);
150 }
151
152 state->xref_cache[new->id] = new;
153 xref_add_definition(state->all_refs, new);
154 for (j = 0; j < new->calls.insert; j++) {
155 new->calls.ptr[j] = load_symbol_from_file(state,
156 sindex, calls_ptr[j], fd);
157 }
158
159 for (j = 0; j < new->called_by.insert; j++) {
160 new->called_by.ptr[j] = load_symbol_from_file(state,
161 sindex, called_ptr[j], fd);
162 }
163#ifdef LOAD_DEBUG
164 printf(": %s(%d) ", new->name, new->id);
165 for (j = 0; j < new->calls.insert; j++) {
166 printf("%s(%d) ", new->calls.ptr[j]->name,
167 new->calls.ptr[j]->id);
168 }
169 printf(";\n");
170#endif
171 if (calls_ptr != NULL)
172 free(calls_ptr);
173 if (called_ptr != NULL)
174 free(called_ptr);
175 return (new);
176}
177
178xref_state_t *
179xref_load_file(char *filename, int verbose)
180{
181 int fid = 0;
182 int sid = 0;
183 int i, rebuild;
184 FILE *fd;
185 int *index, *findex, *sindex, bytes;
186 xref_file_t *newf;
187 xref_state_t *state;
188
189 state = xref_create_state();
190
191 fd = fopen(filename, "rb");
192 if (fd == NULL) {
193 printf("failed to open Xref data file %s\n", filename);
194 return (NULL);
195 }
196
197 rebuild = read_4bytes(fd);
198 fid = read_4bytes(fd);
199 sid = read_4bytes(fd);
200
201 if (verbose) {
202 printf("loading xref data file %s, %d files, %d refs\n",
203 filename, fid, sid);
204 }
205
206 fseek(fd, 0, 0);
207 bytes = sizeof (int) * (fid + sid + 3);
208 index = malloc(bytes);
209 memset(index, 0, bytes);
210 fread(index, 1, bytes, fd);
211
212 /* We have the index */
213 findex = &index[3];
214 sindex = &index[fid+3];
215
216 state->file_cache = malloc(sizeof (xref_file_t *)*fid);
217 memset(state->file_cache, 0, sizeof (xref_file_t *) * fid);
218
219 state->xref_cache = malloc(sizeof (xref_t *) * sid);
220 memset(state->xref_cache, 0, sizeof (xref_t *) * sid);
221
222 i = 0;
223 while (fid--) {
224 int len;
225 char nameptr[256];
226
227 fseek(fd, findex[i], 0);
228 len = fgetc(fd);
229 fread(nameptr, 1, len, fd);
230 nameptr[len] = 0;
231 newf = xref_create_file_reference(nameptr);
232#if 0
233 printf("File: %d: %s\n", i, nameptr);
234#endif
235 newf->next = state->sources;
236 state->sources = newf;
237 state->file_cache[i] = newf;
238 i++;
239 }
240 /*
241 * Now weve loaded the file names and created the file->sym
242 * structures fill in the references.
243 */
244 i = 0;
245 while (sid--) {
246 xref_t *sym;
247 sym = load_symbol_from_file(state, sindex, i++, fd);
248 }
249
250 fclose(fd);
251 return (state);
252}
253
254void
255xref_save_file(char *filename, xref_state_t *state)
256{
257 xref_file_t *fptr = state->sources;
258 xref_t *rptr;
259 int fid = 0;
260 int wid = 0;
261 int i;
262 FILE *fd;
263 int *index, *findex, *sindex, bytes;
264
265 /* allocate a unique file ID */
266 while (fptr != NULL) {
267 fptr->id = fid++;
268 fptr = fptr->next;
269 }
270
271 /* Allocate a unique symbol ID */
272 for (i = 0; i < 128; i++) {
273 rptr = state->all_refs[i];
274 while (rptr != NULL) {
275 rptr->id = wid++;
276 rptr = rptr->next_def;
277 }
278 }
279
280 /* Now write the binary file */
281 fd = fopen(filename, "wb");
282 if (fd == NULL) {
283 printf("failed to open Xref database %s\n", filename);
284 return;
285 }
286
287 bytes = sizeof (int) * (wid + fid + 3);
288 index = malloc(bytes);
289 memset(index, 0, bytes);
290 index[0] = 0;
291 index[1] = fid;
292 index[2] = wid;
293 findex = &index[3];
294 sindex = &index[fid+3];
295 fseek(fd, bytes, 0); /* skip the index */
296 fptr = state->sources;
297 while (fptr != NULL) {
298 int len = strlen(fptr->name);
299
300 findex[fptr->id] = ftell(fd);
301 fputc(len, fd);
302 fputs(fptr->name, fd);
303 fptr = fptr->next;
304 }
305 for (i = 0; i < 128; i++) {
306 int len;
307 int j;
308 xref_t *cptr;
309 rptr = state->all_refs[i];
310 while (rptr != NULL) {
311#if 0
312 printf("Saving: %s (%d)\n", rptr->name, rptr->id);
313#endif
314 len = strlen(rptr->name);
315 sindex[rptr->id] = ftell(fd);
316 fputs("SYM", fd);
317 write_4bytes(rptr->id, fd);
318 write_4bytes(rptr->flags, fd);
319 fputc(len, fd);
320 fputs(rptr->name, fd);
321 write_4bytes(rptr->file->id, fd);
322 write_4bytes(rptr->linenum, fd);
323 write_4bytes(rptr->calls.insert, fd);
324 write_4bytes(rptr->called_by.insert, fd);
325 for (j = 0; j < rptr->calls.insert; j++) {
326 cptr = rptr->calls.ptr[j];
327 write_4bytes(cptr->id, fd);
328 }
329 for (j = 0; j < rptr->called_by.insert; j++) {
330 cptr = rptr->called_by.ptr[j];
331 write_4bytes(cptr->id, fd);
332 }
333 rptr = rptr->next_def;
334 }
335 }
336 fseek(fd, 0, 0);
337 fwrite(index, 1, bytes, fd);
338 fclose(fd);
339}