// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: fileutil.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
#include <sys/types.h> // gid_t
#include <sys/stat.h> // gid_t
#include <unistd.h> // getuid
#pragma ident "@(#)1.12 06/05/22 fileutil.cc"
typedef void (*sigfunc_t
)(int);
* This routine is used to perform a waitpid() call that will work.
* It disables the SIGCHLD signal handler (used by window command)
* before the waitpid() and then restores it.
fw_waitpid(pid_t pid
, int* statusp
, int options
)
/* static void (*sigchld_func)(int); */
* Set handling of sigchld to default (ignored) -- needed because we
sigchld_func
= signal(SIGCHLD
, SIG_DFL
);
/* Wait for child to die. */
w
= waitpid(pid
, statusp
, options
);
/* Restore sigchld handling. */
signal(SIGCHLD
, sigchld_func
);
/* A safe interface for the wait() routine. */
/* void (*sigchld_func)(int); */
/* Set handling of sigchld to default (ignored) -- needed because we
sigchld_func
= signal(SIGCHLD
, SIG_DFL
);
/* Wait for child to die. */
/* Restore sigchld handling. */
signal(SIGCHLD
, sigchld_func
);
* This routine executes the specified UNIX command and examines the status.
* If the command passed, 0 is returned, otherwise 1.
system_command(char* cmd
)
* Put the tty into blocking mode. This also stops the simulator from
* handling SIGIO signals until it gets back into non-blocking
tty_flags
= sigio_make_tty_blocking();
if ((pid
= fork()) == 0) {
(void) execl("/bin/sh", "sh", "-c", cmd
, NULL
);
/* Restore the tty mode. */
sigio_set_tty_flags(tty_flags
);
printf("Fork for UNIX command %s failed.\n", cmd
);
/* Wait for child to die. */
w
= fw_waitpid(pid
, &status
, 0);
/* Restore the tty mode. */
sigio_set_tty_flags(tty_flags
);
printf("Child did not exist for UNIX command %s.\n", cmd
);
if (WIFSTOPPED(status
)) {
printf("UNIX command %s stopped by signal %d.\n",
printf("May not be enough memory.\n");
if (WIFSIGNALED(status
)) {
printf("UNIX command %s terminated by signal %d.\n",
if (WEXITSTATUS(status
)) {
/* Command didn't call exit() so assume it failed. */
FILE *fopen_dir_path(const char *dir
, const char *a
, const char *b
,
sprintf(buff
, "%s%s%s", dir
, a
, b
);
sprintf(buff
, "%s%s", dir
, a
);
FILE *f
= fopen(buff
, mode
);
FILE *fopen_as_uid(const char *filename
, const char *mode
)
FILE *fp
= fopen(filename
, mode
);
if (*mode
== 'w') { // change owner if writing a file
fchown(fd
, uid
, -1); // change owner to the actual user
// just a template for defining other fns
static int statTest(const char *dirname
)
int status
= stat(dirname
, &statbuf
);
int reg
= (S_ISREG(statbuf
.st_mode
));
int fifo
= (S_ISFIFO(statbuf
.st_mode
));
int chr
= (S_ISCHR(statbuf
.st_mode
));
int dir
= (S_ISDIR(statbuf
.st_mode
));
int blk
= (S_ISBLK(statbuf
.st_mode
));
int lnk
= (S_ISLNK(statbuf
.st_mode
));
int isDir(const char *dirname
)
int status
= stat(dirname
, &statbuf
);
int dir
= (S_ISDIR(statbuf
.st_mode
));
int isFile(const char *filename
)
int status
= stat(filename
, &statbuf
);
int reg
= (S_ISREG(statbuf
.st_mode
));
int fileExists(const char *filename
)
int status
= stat(filename
, &statbuf
);
return (status
== 0) || (errno
!= ENOENT
);
/////////////////////////////////////////////////////////////////
void write_double (FILE *fp
, const char * name
, double v
)
fprintf (fp
, "%s %f\n", name
, v
);
void write_scalar_64 (FILE *fp
, const char * name
, uint64_t v
)
fprintf (fp
, "%s 0x%llx\n", name
, v
);
void write_scalar_2_64 (FILE *fp
, const char * name
, uint64_t v1
, uint64_t v2
)
fprintf (fp
, "%s 2\n", name
);
fprintf (fp
, " 0x%llx\n ", v1
);
fprintf (fp
, " 0x%llx\n", v2
);
void write_scalar_32 (FILE *fp
, const char * name
, uint32_t v
)
fprintf (fp
, "%s 0x%x\n", name
, v
);
void write_scalar_8 (FILE *fp
, const char * name
, uint8_t v
)
fprintf (fp
, "%s 0x%x\n", name
, v
);
void write_string (FILE *fp
, const char * name
, char *s
)
fprintf (fp
, "%s \"%s\"\n", name
, s
);
void write_vector_64 (FILE *fp
, const char * name
, int n
, uint64_t *v
)
fprintf (fp
, "%s %d\n", name
, n
);
for (i
= 0; i
< n
; i
++) {
fprintf (fp
, " 0x%llx\n", v
[i
]);
void write_vector_32 (FILE *fp
, const char * name
, int n
, uint32_t *v
)
fprintf (fp
, "%s %d\n", name
, n
);
for (i
= 0; i
< n
; i
++) {
fprintf (fp
, " 0x%x\n", v
[i
]);
void dump_uint32(FILE * fp
, uint32_t val
)
fwrite(&val
, sizeof(uint32_t), 1, fp
);
void dump_uint64(FILE * fp
, uint64_t val
)
fwrite(&val
, sizeof(uint64_t), 1, fp
);
uint64_t restore_uint64(FILE * fp
)
fread((void*)&val
, sizeof(val
), 1, fp
);
bool_t
read_double (FILE *fp
, const char * name
, double *v
)
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%s %f", sn
, &ff
) != 2) {
if (strcmp(sn
, name
) != NULL
) {
bool_t
read_scalar_64 (FILE *fp
, const char * name
, uint64_t *v
)
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%s %lli", sn
, v
) != 2) {
if (strcmp(sn
, name
) != NULL
) {
bool_t
read_scalar_32 (FILE *fp
, const char * name
, uint32_t *v
)
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%s %i", sn
, v
) != 2) {
if (strcmp(sn
, name
) != NULL
) {
bool_t
read_scalar_8 (FILE *fp
, const char * name
, Byte
*v
)
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%s %i", sn
, &i
) != 2) {
if (strcmp(sn
, name
) != NULL
) {
bool_t
read_scalar_2_64 (FILE *fp
, const char * name
, uint64_t *v1
, uint64_t *v2
)
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%s %i", sn
, &i
) != 2) {
if (strcmp(sn
, name
) != NULL
) {
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%lli", v1
) != 1) {
if (fgets (s
, 128, fp
) == NULL
) {
if (sscanf (s
, "%lli", v2
) != 1) {
/////////////////////////////////////////
char * read_string (FILE *fp
, const char * name
, int n
, char *ss
)
char *ps
= ss
, *ps1
, *ps2
;
if (fgets (s
, 128, fp
) == NULL
)
if (sscanf (s
, "%s", sn
) != 1) {
if (strcmp(sn
, name
) != NULL
) {
fprintf (stderr
, "restore err S = <%s>; pattern <%s>, %d\n", s
, name
, n
);
if ((ps1
== NULL
) || (ps2
== NULL
)) {
fprintf (stderr
, "restore err <%s> \n", s
);
for (;ps1
!= ps2
; ps1
++, i
++) {
char * read_string_2 (FILE *fp
, const char * name
, const char * alt_name
, int n
, char *ss
)
char *ps
= ss
, *ps1
, *ps2
;
if (fgets (s
, 128, fp
) == NULL
)
if (sscanf (s
, "%s", sn
) != 1) {
if ((strcmp(sn
, name
) != NULL
) && (strcmp(sn
, alt_name
) != NULL
)) {
fprintf (stderr
, "restore err S = <%s>; pattern <%s>, %d\n", s
, name
, n
);
if ((ps1
== NULL
) || (ps2
== NULL
)) {
fprintf (stderr
, "restore err <%s> \n", s
);
for (;ps1
!= ps2
; ps1
++, i
++) {
bool_t
read_vector_64 (FILE *fp
, const char * name
, int n
, uint64_t *v
)
if (fgets (s
, 128, fp
) == NULL
)
if (sscanf (s
, "%s %d", sn
, &i
) != 2) {
if ((i
!= n
) || (strcmp(sn
, name
) != NULL
)) {
fprintf (stderr
, "restore err S = <%s>; pattern <%s>, %d\n", s
, name
, n
);
for (i
= 0; i
< n
; i
++) {
if (fgets (s
, 128, fp
) == NULL
)
if (sscanf (s
, "%lli", &v
[i
]) != 1) {
bool_t
read_vector_32 (FILE *fp
, const char * name
, int n
, uint32_t *v
)
if (fgets (s
, 128, fp
) == NULL
)
if (sscanf (s
, "%s %d", sn
, &i
) != 2) {
if ((i
!= n
) || (strcmp(sn
, name
) != NULL
)) {
fprintf (stderr
, "restore err S = <%s>; pattern <%s>, %d\n", s
, name
, n
);
for (i
= 0; i
< n
; i
++) {
if (fgets (s
, 128, fp
) == NULL
)
if (sscanf (s
, "%i", &v
[i
]) != 1) {
///////////////////////////////////////////
// Thw following routines borrowed
// form BLAZE V3 without modifocation
* This routine converts a pointer into an array into its equivalent integer
* index and then writes it to a file. It handles null pointers.
* Returns 1 on error, 0 no error.
* Borrowed from Blaze v3 without changes
/* Address of pointer is less than the base. */
index
= ((u_int
) (ptr
- array_base
)) / element_size
;
if (ptr
!= array_base
+ index
* element_size
) {
* If reconstructing the address from the index
* doesn't give the original pointer value, return
* with and error. This can happen when the pointer
* doesn't point to the start of an element.
/* Write out flag that indicates if pointer is null. */
if (fwrite((char*)&is_ptr_null
, sizeof(is_ptr_null
), 1, fp
) != 1) {
/* Write out index (even if pointer is null). */
if (fwrite((char*)&index
, sizeof(index
), 1, fp
) != 1) {
/* Read in flag that indicates if pointer is null. */
if (fread((char*)&is_ptr_null
, sizeof(is_ptr_null
), 1, fp
) != 1) {
/* Read in index (even if pointer is null). */
if (fread((char*)&index
, sizeof(index
), 1, fp
) != 1) {
*ptr
= array_base
+ index
* element_size
;
* Remove directory tree recursively by calling "rm -rf <dirname>".
* It cannot return status since rm -f doesn't set it.
void rm_rf_directory (char* dir_name
)
sprintf(buf
, "rm -rf %s", dir_name
);
void print_addr (FILE *f
, void *vp
) {
fprintf (f
, "0x%08x", vp
);
fprintf (f
, "0x%016llx", vp
);
printf ("Print_addr error: neither HOST32BIT nor HOST64BIT defined\n");
void dumpStructAddr (FILE *f
, char *addr
, const char *name
, int size
, int arrlen
) {
fprintf (f
, "StructAddr %d %d ", size
, arrlen
);
fprintf (f
, " %s\n", name
);
void dumpDynArrDelm (FILE *f
, const char *name
, int idx
, int total
) {
fprintf (f
, "DynArrDelm %d %d %s\n", idx
, total
, name
);
void dumpScalar (FILE *f
, const char *name
, char *data
, size_t size
) {
fprintf (f
, "%s %d 0x", name
, size
);
for (i
= 0; i
< size
; i
++) {
fprintf (f
, "%02x", *(data
+ i
) & 0xff);
void dumpArr (FILE *f
, const char *name
, unsigned char *data
, size_t num
, size_t size
) {
for (i
= 0; i
< num
; i
++) {
fprintf (f
, "%s[%d] %d 0x", name
, i
, size
);
for (j
= 0; j
< size
; j
++) {
fprintf (f
, "%02x", *(data
+ size
*i
+ j
) & 0xff);
///////////////////////////////////////////////
char *get_substr_until (char *src
, char *tgt
, char stop_symbol
)
char *ps
= src
, *pt
= tgt
;
if ((*ps
== '#') || (*ps
== '!'))
while ((*ps
!= stop_symbol
) && (*ps
!= ' ')) {
if (*ps
== stop_symbol
) {
while ((*ps
!= stop_symbol
) && (*ps
!= '\0')) {
///////////////////////////////////////////////
char * get_quoted_substr (char *src
, char *tgt
)
char *ps
= src
, *pt
= tgt
;
if ((*ps
== '#') || (*ps
== '!'))
///////////////////////////////////////////////
uint64_t usec2cycles (uint64_t usecs
, uint64_t sfreq
, uint32_t loopticks
)
double tau
= ((double)(1000000.0) / (double) sfreq
) / (double) loopticks
;
return (uint64_t) ((double) usecs
/ tau
);
///////////////////////////////////////////////
AddrPair
* eval_mem_image (FILE *fp
, int *ret_size
)
int index
= -1, len
= NNN
;
AddrPair
*ppp
= (AddrPair
*) calloc (NNN
, sizeof(AddrPair
));
while (fgets (s
, 512, fp
)) {
if (s
[0] == '@') { /// address
int ret
= sscanf (ps
, "%llx", &pa
);
ppp
= (AddrPair
*)realloc (ppp
, sizeof(AddrPair
) * len
);
int ret
= sscanf (s
, "%llx %llx %llx %llx", &v
[0], &v
[1], &v
[2], &v
[3]);
ret
= sscanf (s
, "%llx %llx %llx", &v
[0], &v
[1], &v
[2]);
ret
= sscanf (s
, "%llx %llx", &v
[0], &v
[1]);
ret
= sscanf (s
, "%llx", &v
[0]);
ppp
[index
].size
+= (ret
<<3);