1 /* SPDX-License-Identifier: GPL-2.0-only */
16 #define SEEK_SET 0 /* Seek from beginning of file. */
18 #define DIR_SEPARATOR '/'
19 #define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
20 #define HAS_DRIVE_SPEC(f) (0)
22 #define COVERAGE_SIZE (32*1024)
24 #define COVERAGE_MAGIC 0x584d4153
26 static FILE *current_file
= NULL
;
27 static FILE *previous_file
= NULL
;
29 static FILE *fopen(const char *path
, const char *mode
)
31 #if CONFIG(DEBUG_COVERAGE)
32 printk(BIOS_DEBUG
, "fopen %s with mode %s\n",
36 current_file
= cbmem_add(CBMEM_ID_COVERAGE
, 32*1024);
38 previous_file
= current_file
;
40 (FILE *)(ALIGN(((unsigned long)previous_file
->data
41 + previous_file
->len
), 16));
44 // TODO check if we're at the end of the CBMEM region (ENOMEM)
46 current_file
->magic
= COVERAGE_MAGIC
;
47 current_file
->next
= NULL
;
49 previous_file
->next
= current_file
;
50 current_file
->filename
= (char *)¤t_file
[1];
51 strcpy(current_file
->filename
, path
);
53 (char *)ALIGN(((unsigned long)current_file
->filename
54 + strlen(path
) + 1), 16);
55 current_file
->offset
= 0;
56 current_file
->len
= 0;
62 static int fclose(FILE *stream
)
64 #if CONFIG(DEBUG_COVERAGE)
65 printk(BIOS_DEBUG
, "fclose %s\n", stream
->filename
);
70 static int fseek(FILE *stream
, long offset
, int whence
)
72 /* fseek should only be called with offset==0 and whence==SEEK_SET
73 * to a freshly opened file. */
74 gcc_assert(offset
== 0 && whence
== SEEK_SET
);
75 #if CONFIG(DEBUG_COVERAGE)
76 printk(BIOS_DEBUG
, "fseek %s offset=%ld whence=%d\n",
77 stream
->filename
, offset
, whence
);
82 static long ftell(FILE *stream
)
84 /* ftell should currently not be called */
86 #if CONFIG(DEBUG_COVERAGE)
87 printk(BIOS_DEBUG
, "ftell %s\n", stream
->filename
);
92 static size_t fread(void *ptr
, size_t size
, size_t nmemb
, FILE *stream
)
94 #if CONFIG(DEBUG_COVERAGE)
95 printk(BIOS_DEBUG
, "fread: ptr=%p size=%zd nmemb=%zd FILE*=%p\n",
96 ptr
, size
, nmemb
, stream
);
101 static size_t fwrite(const void *ptr
, size_t size
, size_t nmemb
, FILE *stream
)
103 #if CONFIG(DEBUG_COVERAGE)
104 printk(BIOS_DEBUG
, "fwrite: %zd * %zd bytes to file %s\n",
105 nmemb
, size
, stream
->filename
);
107 // TODO check if file is last opened file and fail otherwise.
109 memcpy(stream
->data
+ stream
->offset
, ptr
, size
* nmemb
);
110 stream
->len
+= (nmemb
* size
) - (stream
->len
- stream
->offset
);
111 stream
->offset
+= nmemb
* size
;
115 static void setbuf(FILE *stream
, char *buf
)
117 gcc_assert(buf
== 0);
120 static void coverage_init(void *unused
)
122 extern long __CTOR_LIST__
;
123 typedef void (*func_ptr
)(void);
124 func_ptr
*ctor
= (func_ptr
*) &__CTOR_LIST__
;
128 for (; *ctor
!= (func_ptr
) 0; ctor
++)
132 void __gcov_flush(void);
133 static void coverage_exit(void *unused
)
135 #if CONFIG(DEBUG_COVERAGE)
136 printk(BIOS_DEBUG
, "Syncing coverage data.\n");
141 BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE
, BS_ON_ENTRY
, coverage_init
, NULL
);
142 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME
, BS_ON_ENTRY
, coverage_exit
, NULL
);
143 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD
, BS_ON_EXIT
, coverage_exit
, NULL
);