Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / util / fileutil.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: fileutil.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <sys/types.h> // gid_t
25#include <sys/stat.h> // gid_t
26#include <unistd.h> // getuid
27#include <errno.h>
28#include <signal.h>
29
30#include <sys/wait.h>
31#include <stdarg.h>
32
33#include "types.h"
34#include "fileutil.h"
35
36#pragma ident "@(#)1.12 06/05/22 fileutil.cc"
37
38static char buff[256];
39
40
41#ifdef __cplusplus
42extern "C" {
43#endif /* __cplusplus */
44
45typedef void (*sigfunc_t)(int);
46
47#ifdef __cplusplus
48}
49#endif /* __cplusplus */
50
51/*
52 * This routine is used to perform a waitpid() call that will work.
53 * It disables the SIGCHLD signal handler (used by window command)
54 * before the waitpid() and then restores it.
55 */
56int
57fw_waitpid(pid_t pid, int* statusp, int options)
58{
59 pid_t w;
60 /* static void (*sigchld_func)(int); */
61 sigfunc_t sigchld_func;
62
63 /*
64 * Set handling of sigchld to default (ignored) -- needed because we
65 * call waitpid() below.
66 */
67 sigchld_func = signal(SIGCHLD, SIG_DFL);
68
69 /* Wait for child to die. */
70 w = waitpid(pid, statusp, options);
71
72 /* Restore sigchld handling. */
73 signal(SIGCHLD, sigchld_func);
74
75 return w;
76}
77
78/* A safe interface for the wait() routine. */
79int
80fw_wait(int* statusp)
81{
82 pid_t w;
83 /* void (*sigchld_func)(int); */
84 sigfunc_t sigchld_func;
85
86 /* Set handling of sigchld to default (ignored) -- needed because we
87 * call waitpid() below.
88 */
89 sigchld_func = signal(SIGCHLD, SIG_DFL);
90
91 /* Wait for child to die. */
92 w = wait(statusp);
93
94 /* Restore sigchld handling. */
95 signal(SIGCHLD, sigchld_func);
96
97 return w;
98}
99
100
101/*
102 * This routine executes the specified UNIX command and examines the status.
103 * If the command passed, 0 is returned, otherwise 1.
104 */
105int
106system_command(char* cmd)
107{
108 int status;
109 pid_t pid;
110 pid_t w;
111
112#if 0
113 int tty_flags;
114#endif
115
116 /*
117 * Put the tty into blocking mode. This also stops the simulator from
118 * handling SIGIO signals until it gets back into non-blocking
119 * mode.
120 */
121
122#if 0 //////// TODO
123
124 tty_flags = sigio_make_tty_blocking();
125#endif
126
127 if ((pid = fork()) == 0) {
128 (void) execl("/bin/sh", "sh", "-c", cmd, NULL);
129 _exit(127);
130 }
131
132 if (pid == -1) {
133
134#if 0 //// TODO
135 /* Restore the tty mode. */
136 sigio_set_tty_flags(tty_flags);
137#endif
138 printf("Fork for UNIX command %s failed.\n", cmd);
139 perror("fork");
140
141 return 1;
142 }
143
144 /* Wait for child to die. */
145 w = fw_waitpid(pid, &status, 0);
146
147#if 0 ///// TODO
148 /* Restore the tty mode. */
149 sigio_set_tty_flags(tty_flags);
150#endif
151
152 if (w == -1) {
153 if (errno == ECHILD) {
154 printf("Child did not exist for UNIX command %s.\n", cmd);
155 }
156
157 perror("waitpid");
158 return 1;
159 }
160
161 if (WIFSTOPPED(status)) {
162 printf("UNIX command %s stopped by signal %d.\n",
163 cmd, WSTOPSIG(status));
164 printf("May not be enough memory.\n");
165 return 1;
166 }
167
168 if (WIFSIGNALED(status)) {
169 printf("UNIX command %s terminated by signal %d.\n",
170 cmd, WTERMSIG(status));
171 return 1;
172 }
173
174 if (WIFEXITED(status)) {
175 if (WEXITSTATUS(status)) {
176 return 1;
177 }
178
179 return 0;
180 }
181
182 /* Command didn't call exit() so assume it failed. */
183 return 1;
184}
185
186
187
188FILE *fopen_dir_path(const char *dir, const char *a, const char *b,
189 const char *mode)
190{
191 if (b != NULL) {
192 sprintf(buff, "%s%s%s", dir, a, b);
193 } else {
194 sprintf(buff, "%s%s", dir, a);
195 }
196 {
197 FILE *f = fopen(buff, mode);
198 if (f == NULL) {
199 perror(buff);
200 }
201 return f;
202 }
203} /* fopen_dir_path */
204
205FILE *fopen_as_uid(const char *filename, const char *mode)
206{
207 int uid = getuid();
208 FILE *fp = fopen(filename, mode);
209 if (fp == NULL) {
210 perror(filename);
211 } else {
212 if (*mode == 'w') { // change owner if writing a file
213 int fd = fileno(fp);
214 fchown(fd, uid, -1); // change owner to the actual user
215 }
216 }
217 return fp;
218}
219
220// just a template for defining other fns
221static int statTest(const char *dirname)
222{
223 struct stat statbuf;
224 int status = stat(dirname, &statbuf);
225 if (status == 0) {
226 int reg = (S_ISREG(statbuf.st_mode));
227 int fifo = (S_ISFIFO(statbuf.st_mode));
228 int chr = (S_ISCHR(statbuf.st_mode));
229 int dir = (S_ISDIR(statbuf.st_mode));
230 int blk = (S_ISBLK(statbuf.st_mode));
231 int lnk = (S_ISLNK(statbuf.st_mode));
232 }
233 return 0;
234} /* statTest */
235
236int isDir(const char *dirname)
237{
238 struct stat statbuf;
239 int status = stat(dirname, &statbuf);
240 if (status == 0) {
241 int dir = (S_ISDIR(statbuf.st_mode));
242 return dir;
243 }
244 return 0;
245}
246
247int isFile(const char *filename)
248{
249 struct stat statbuf;
250 int status = stat(filename, &statbuf);
251 if (status == 0) {
252 int reg = (S_ISREG(statbuf.st_mode));
253 return reg;
254 }
255 return 0;
256}
257
258int fileExists(const char *filename)
259{
260 struct stat statbuf;
261 int status = stat(filename, &statbuf);
262 return (status == 0) || (errno != ENOENT);
263} /* fileExists */
264
265
266/////////////////////////////////////////////////////////////////
267
268void write_double (FILE *fp, const char * name, double v)
269{
270 fprintf (fp, "%s %f\n", name, v);
271}
272
273
274void write_scalar_64 (FILE *fp, const char * name, uint64_t v)
275{
276 fprintf (fp, "%s 0x%llx\n", name, v);
277}
278
279void write_scalar_2_64 (FILE *fp, const char * name, uint64_t v1, uint64_t v2)
280{
281 fprintf (fp, "%s 2\n", name);
282 fprintf (fp, " 0x%llx\n ", v1);
283 fprintf (fp, " 0x%llx\n", v2);
284}
285
286void write_scalar_32 (FILE *fp, const char * name, uint32_t v)
287{
288 fprintf (fp, "%s 0x%x\n", name, v);
289}
290
291void write_scalar_8 (FILE *fp, const char * name, uint8_t v)
292{
293 fprintf (fp, "%s 0x%x\n", name, v);
294}
295
296
297void write_string (FILE *fp, const char * name, char *s)
298{
299 fprintf (fp, "%s \"%s\"\n", name, s);
300}
301
302void write_vector_64 (FILE *fp, const char * name, int n, uint64_t *v)
303{
304 int i;
305 fprintf (fp, "%s %d\n", name, n);
306 for (i = 0; i < n; i++) {
307 fprintf (fp, " 0x%llx\n", v[i]);
308 }
309}
310
311void write_vector_32 (FILE *fp, const char * name, int n, uint32_t *v)
312{
313 int i;
314 fprintf (fp, "%s %d\n", name, n);
315 for (i = 0; i < n; i++) {
316 fprintf (fp, " 0x%x\n", v[i]);
317 }
318}
319
320///////////////////
321
322void dump_uint32(FILE * fp, uint32_t val)
323{
324 fwrite(&val, sizeof(uint32_t), 1, fp);
325}
326
327void dump_uint64(FILE * fp, uint64_t val)
328{
329 fwrite(&val, sizeof(uint64_t), 1, fp);
330}
331
332uint64_t restore_uint64(FILE * fp)
333{
334 uint64_t val;
335 fread((void*)&val, sizeof(val), 1, fp);
336 return val;
337}
338
339bool_t read_double (FILE *fp, const char * name, double *v)
340{
341 char s[128], sn[128];
342 float ff;
343
344 if (fgets (s, 128, fp) == NULL) {
345 return FALSE;
346 }
347 if (sscanf (s, "%s %f", sn, &ff) != 2) {
348 return FALSE;
349 }
350 *v = ff;
351 if (strcmp(sn, name) != NULL) {
352 return FALSE;
353 }
354 return TRUE;
355}
356
357
358bool_t read_scalar_64 (FILE *fp, const char * name, uint64_t *v)
359{
360 char s[128], sn[128];
361
362 if (fgets (s, 128, fp) == NULL) {
363 return FALSE;
364 }
365
366 if (sscanf (s, "%s %lli", sn, v) != 2) {
367 return FALSE;
368 }
369 if (strcmp(sn, name) != NULL) {
370 return FALSE;
371 }
372 return TRUE;
373}
374
375bool_t read_scalar_32 (FILE *fp, const char * name, uint32_t *v)
376{
377 char s[128], sn[128];
378
379 if (fgets (s, 128, fp) == NULL) {
380 return FALSE;
381 }
382
383 if (sscanf (s, "%s %i", sn, v) != 2) {
384 return FALSE;
385 }
386 if (strcmp(sn, name) != NULL) {
387 return FALSE;
388 }
389 return TRUE;
390}
391
392bool_t read_scalar_8 (FILE *fp, const char * name, Byte *v)
393{
394 int i;
395 char s[128], sn[128];
396
397 if (fgets (s, 128, fp) == NULL) {
398 return FALSE;
399 }
400
401 if (sscanf (s, "%s %i", sn, &i) != 2) {
402 return FALSE;
403 }
404 if (strcmp(sn, name) != NULL) {
405 return FALSE;
406 }
407 *v = (Byte)i;
408 return TRUE;
409}
410
411bool_t read_scalar_2_64 (FILE *fp, const char * name, uint64_t *v1, uint64_t *v2)
412{
413
414 int i;
415 char s[128], sn[128];
416
417 if (fgets (s, 128, fp) == NULL) {
418 return FALSE;
419 }
420
421 if (sscanf (s, "%s %i", sn, &i) != 2) {
422 return FALSE;
423 }
424 if (strcmp(sn, name) != NULL) {
425 return FALSE;
426 }
427
428 if (fgets (s, 128, fp) == NULL) {
429 return FALSE;
430 }
431
432 if (sscanf (s, "%lli", v1) != 1) {
433 return FALSE;
434 }
435
436 if (fgets (s, 128, fp) == NULL) {
437 return FALSE;
438 }
439
440 if (sscanf (s, "%lli", v2) != 1) {
441 return FALSE;
442 }
443 return TRUE;
444}
445
446/////////////////////////////////////////
447
448char * read_string (FILE *fp, const char * name, int n, char *ss)
449{
450 int i = 0;
451 char s[128], sn[128];
452
453 char *ps = ss, *ps1, *ps2;
454
455 if (fgets (s, 128, fp) == NULL)
456 return NULL;
457
458 if (sscanf (s, "%s", sn) != 1) {
459 return NULL;
460 }
461
462 if (strcmp(sn, name) != NULL) {
463 fprintf (stderr, "restore err S = <%s>; pattern <%s>, %d\n", s, name, n);
464 return NULL;
465 }
466
467 ps1 = strchr (s, '"');
468 ps2 = strrchr (s, '"');
469
470 if ((ps1 == NULL) || (ps2 == NULL)) {
471 fprintf (stderr, "restore err <%s> \n", s);
472 return NULL;
473 }
474 ++ps1;
475 for (;ps1 != ps2; ps1++, i++) {
476 if (i >= n)
477 break;
478 *ps++ = *ps1;
479 }
480
481 *ps = '\0';
482 return ps;
483}
484
485char * read_string_2 (FILE *fp, const char * name, const char * alt_name, int n, char *ss)
486{
487 int i = 0;
488 char s[128], sn[128];
489
490 char *ps = ss, *ps1, *ps2;
491
492 if (fgets (s, 128, fp) == NULL)
493 return NULL;
494
495 if (sscanf (s, "%s", sn) != 1) {
496 return NULL;
497 }
498
499 if ((strcmp(sn, name) != NULL) && (strcmp(sn, alt_name) != NULL)) {
500 fprintf (stderr, "restore err S = <%s>; pattern <%s>, %d\n", s, name, n);
501 return NULL;
502 }
503
504 ps1 = strchr (s, '"');
505 ps2 = strrchr (s, '"');
506
507 if ((ps1 == NULL) || (ps2 == NULL)) {
508 fprintf (stderr, "restore err <%s> \n", s);
509 return NULL;
510 }
511 ++ps1;
512 for (;ps1 != ps2; ps1++, i++) {
513 if (i >= n)
514 break;
515 *ps++ = *ps1;
516 }
517
518 *ps = '\0';
519 return ps;
520}
521
522
523bool_t read_vector_64 (FILE *fp, const char * name, int n, uint64_t *v)
524{
525 int i;
526 char s[128], sn[128];
527 if (fgets (s, 128, fp) == NULL)
528 return FALSE;
529
530 if (sscanf (s, "%s %d", sn, &i) != 2) {
531 return FALSE;
532 }
533
534 if ((i != n) || (strcmp(sn, name) != NULL)) {
535 fprintf (stderr, "restore err S = <%s>; pattern <%s>, %d\n", s, name, n);
536 return FALSE;
537 }
538
539 for (i = 0; i < n; i++) {
540 if (fgets (s, 128, fp) == NULL)
541 return FALSE;
542 if (sscanf (s, "%lli", &v[i]) != 1) {
543 return FALSE;
544 }
545 }
546 return TRUE;
547}
548
549bool_t read_vector_32 (FILE *fp, const char * name, int n, uint32_t *v)
550{
551 int i;
552 char s[128], sn[128];
553 if (fgets (s, 128, fp) == NULL)
554 return FALSE;
555
556 if (sscanf (s, "%s %d", sn, &i) != 2) {
557 return FALSE;
558 }
559
560 if ((i != n) || (strcmp(sn, name) != NULL)) {
561 fprintf (stderr, "restore err S = <%s>; pattern <%s>, %d\n", s, name, n);
562 return FALSE;
563 }
564
565 for (i = 0; i < n; i++) {
566 if (fgets (s, 128, fp) == NULL)
567 return FALSE;
568 if (sscanf (s, "%i", &v[i]) != 1) {
569 return FALSE;
570 }
571 }
572 return TRUE;
573}
574
575
576///////////////////////////////////////////
577// Thw following routines borrowed
578// form BLAZE V3 without modifocation
579//
580
581
582/*
583 * This routine converts a pointer into an array into its equivalent integer
584 * index and then writes it to a file. It handles null pointers.
585 * Returns 1 on error, 0 no error.
586
587 * Borrowed from Blaze v3 without changes
588 *
589 */
590int dump_array_ptr (
591 FILE* fp,
592 char* array_base,
593 u_int element_size,
594 char* ptr
595)
596{
597 char is_ptr_null = 0;
598 u_int index = 0;
599
600 if (ptr == NULL) {
601 is_ptr_null = 1;
602 } else {
603 if (ptr < array_base) {
604 /* Address of pointer is less than the base. */
605 return 1;
606 }
607
608 index = ((u_int) (ptr - array_base)) / element_size;
609
610 if (ptr != array_base + index * element_size) {
611 /*
612 * If reconstructing the address from the index
613 * doesn't give the original pointer value, return
614 * with and error. This can happen when the pointer
615 * doesn't point to the start of an element.
616 */
617 return 1;
618 }
619
620 }
621
622 /* Write out flag that indicates if pointer is null. */
623 if (fwrite((char*)&is_ptr_null, sizeof(is_ptr_null), 1, fp) != 1) {
624 return 1;
625 }
626
627 /* Write out index (even if pointer is null). */
628 if (fwrite((char*)&index, sizeof(index), 1, fp) != 1) {
629 return 1;
630 }
631
632 return 0;
633}
634
635int restore_array_ptr (
636 FILE* fp,
637 char* array_base,
638 u_int element_size,
639 char** ptr
640)
641{
642 char is_ptr_null = 0;
643 u_int index = 0;
644
645 /* Read in flag that indicates if pointer is null. */
646 if (fread((char*)&is_ptr_null, sizeof(is_ptr_null), 1, fp) != 1) {
647 return 1;
648 }
649
650 /* Read in index (even if pointer is null). */
651 if (fread((char*)&index, sizeof(index), 1, fp) != 1) {
652 return 1;
653 }
654
655 if (is_ptr_null) {
656 *ptr = NULL;
657 } else {
658 *ptr = array_base + index * element_size;
659 }
660
661 return 0;
662}
663
664
665/*
666 * Remove directory tree recursively by calling "rm -rf <dirname>".
667 * It cannot return status since rm -f doesn't set it.
668 */
669void rm_rf_directory (char* dir_name)
670{
671 char buf[FILENAME_MAX];
672 sprintf(buf, "rm -rf %s", dir_name);
673 system_command(buf);
674}
675
676
677
678
679//
680// 32 vs 64 bit stuff
681//
682void print_addr (FILE *f, void *vp) {
683#if HOST32BIT == 1
684 fprintf (f, "0x%08x", vp);
685#elif HOST64BIT == 1
686 fprintf (f, "0x%016llx", vp);
687#else
688 printf ("Print_addr error: neither HOST32BIT nor HOST64BIT defined\n");
689#endif
690}
691
692
693//
694// DUMP FUNCTIONS
695//
696
697void dumpStructAddr (FILE *f, char *addr, const char *name, int size, int arrlen) {
698 fprintf (f, "StructAddr %d %d ", size, arrlen);
699 print_addr (f, addr);
700 fprintf (f, " %s\n", name);
701}
702
703
704void dumpDynArrDelm (FILE *f, const char *name, int idx, int total) {
705 fprintf (f, "DynArrDelm %d %d %s\n", idx, total, name);
706}
707
708
709void dumpScalar (FILE *f, const char *name, char *data, size_t size) {
710 int i;
711
712 fprintf (f, "%s %d 0x", name, size);
713 for (i = 0; i < size; i++) {
714 fprintf (f, "%02x", *(data + i) & 0xff);
715 }
716 fprintf (f, "\n");
717 fflush(f);
718}
719
720void dumpArr (FILE *f, const char *name, unsigned char *data, size_t num, size_t size) {
721 int i, j;
722
723 for (i = 0; i < num; i++) {
724 fprintf (f, "%s[%d] %d 0x", name, i, size);
725 for (j = 0; j < size; j++) {
726 fprintf (f, "%02x", *(data + size*i + j) & 0xff);
727 }
728 fprintf (f, "\n");
729 }
730}
731
732///////////////////////////////////////////////
733
734char *get_substr_until (char *src, char *tgt, char stop_symbol)
735{
736 char *ps = src, *pt = tgt;
737 *pt = '\0';
738
739 while (*ps == ' ')
740 ps++;
741
742 if (*ps == '\0')
743 return NULL;
744
745 if (*ps == 0xA)
746 return NULL;
747
748 if ((*ps == '#') || (*ps == '!'))
749 return NULL;
750
751 while ((*ps != stop_symbol) && (*ps != ' ')) {
752 *pt++ = *ps;
753 ++ps;
754 }
755
756 *pt = '\0';
757 if (*ps == stop_symbol) {
758 return ps + 1;
759 }
760 else {
761 while ((*ps != stop_symbol) && (*ps != '\0')) {
762 ++ps;
763 }
764 if (*ps == '\0')
765 return ps;
766 else
767 return ps + 1;
768 }
769}
770
771///////////////////////////////////////////////
772
773char * get_quoted_substr (char *src, char *tgt)
774{
775 char *ps = src, *pt = tgt;
776 while (*ps == ' ')
777 ps++;
778
779 if (*ps == '\0')
780 return NULL;
781
782 if (*ps == 0xA)
783 return NULL;
784
785 if ((*ps == '#') || (*ps == '!'))
786 return NULL;
787
788 if (*ps == '\"') {
789 *pt = '\0';
790 }
791 else {
792 return NULL;
793 }
794 ++ps;
795
796 while (*ps != '\"') {
797 *pt++ = *ps++;
798 if (*ps == '\0')
799 return NULL;
800
801 }
802
803 *pt = '\0';
804 return ps + 1;
805}
806
807///////////////////////////////////////////////
808//
809// Microsecs --> cycles
810//
811
812uint64_t usec2cycles (uint64_t usecs, uint64_t sfreq, uint32_t loopticks)
813{
814 double tau = ((double)(1000000.0) / (double) sfreq) / (double) loopticks ;
815 return (uint64_t) ((double) usecs / tau);
816}
817
818///////////////////////////////////////////////
819
820#define NNN 16
821
822AddrPair * eval_mem_image (FILE *fp, int *ret_size)
823{
824 int index = -1, len = NNN;
825 char s[512 + 4], *ps;
826 uint64_t v[4], pa;
827
828 AddrPair *ppp = (AddrPair*) calloc (NNN, sizeof(AddrPair));
829 if (ppp == NULL) {
830 return NULL;
831 }
832
833 *ret_size = 0;
834
835 while (fgets (s, 512, fp)) {
836 if (s[0] == '\0') {
837 continue;
838 }
839 if (s[0] == '@') { /// address
840 ps = &s[1];
841 int ret = sscanf (ps, "%llx", &pa);
842 if (ret != 1) {
843 goto error;
844 }
845 index++;
846 ppp[index].addr = pa;
847 ppp[index].size = 0;
848
849 if (index >= len - 1) {
850 len <<= 1;
851 ppp = (AddrPair*)realloc (ppp, sizeof(AddrPair) * len);
852 }
853 }
854 else {
855 int ret = sscanf (s, "%llx %llx %llx %llx", &v[0], &v[1], &v[2], &v[3]);
856 if (ret != 4) {
857 ret = sscanf (s, "%llx %llx %llx", &v[0], &v[1], &v[2]);
858 if (ret != 3) {
859 ret = sscanf (s, "%llx %llx", &v[0], &v[1]);
860 if (ret != 2) {
861 ret = sscanf (s, "%llx", &v[0]);
862 if (ret != 1) {
863 continue;
864 }
865 }
866 }
867 }
868 ppp[index].size += (ret<<3);
869 }
870 }
871
872 *ret_size = index + 1;
873 return ppp;
874
875error:
876
877 free ((char*) ppp);
878 return NULL;
879
880}
881
882
883
884
885