iPXE
Data Structures | Macros | Functions | Variables
fnrec.c File Reference

Function trace recorder for crash and hang debugging. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ipxe/init.h>
#include <ipxe/uaccess.h>
#include <ipxe/io.h>

Go to the source code of this file.

Data Structures

struct  fnrec_entry
 A trace buffer entry. More...
 
struct  fnrec_buffer
 A trace buffer. More...
 

Macros

#define FNREC_MAGIC   ( 'f' << 24 | 'n' << 16 | 'r' << 8 | 'e' )
 Constant for identifying valid trace buffers. More...
 
#define FNREC_NUM_ENTRIES   4096
 Number of trace buffer entries. More...
 
#define FNREC_PHYS_ADDRESS   ( 17 * 1024 * 1024 )
 Trace buffer physical address. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int fnrec_is_valid (void)
 Test whether the trace buffer is valid. More...
 
static void fnrec_invalidate (void)
 Invalidate the trace buffer. More...
 
static void fnrec_reset (void)
 Reset the trace buffer and clear entries. More...
 
static struct fnrec_entryfnrec_append (void *called_fn, void *call_site)
 Append an entry to the trace buffer. More...
 
static void fnrec_dump (void)
 Print the contents of the trace buffer in chronological order. More...
 
static void fnrec_init (void)
 Function tracer initialisation function. More...
 
struct init_fn fnrec_init_fn __init_fn (INIT_NORMAL)
 
void __cyg_profile_func_enter (void *called_fn, void *call_site)
 
void __cyg_profile_func_exit (void *called_fn, void *call_site)
 

Variables

static struct fnrec_bufferfnrec_buffer
 The trace buffer. More...
 

Detailed Description

Function trace recorder for crash and hang debugging.

Definition in file fnrec.c.

Macro Definition Documentation

◆ FNREC_MAGIC

#define FNREC_MAGIC   ( 'f' << 24 | 'n' << 16 | 'r' << 8 | 'e' )

Constant for identifying valid trace buffers.

Definition at line 40 of file fnrec.c.

◆ FNREC_NUM_ENTRIES

#define FNREC_NUM_ENTRIES   4096

Number of trace buffer entries.

Definition at line 43 of file fnrec.c.

◆ FNREC_PHYS_ADDRESS

#define FNREC_PHYS_ADDRESS   ( 17 * 1024 * 1024 )

Trace buffer physical address.

Fixed at 17MB

Definition at line 49 of file fnrec.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ fnrec_is_valid()

static int fnrec_is_valid ( void  )
static

Test whether the trace buffer is valid.

Return values
is_validBuffer is valid

Definition at line 86 of file fnrec.c.

86  {
87  return ( fnrec_buffer && ( fnrec_buffer->magic == FNREC_MAGIC ) );
88 }
A trace buffer.
Definition: fnrec.c:66
#define FNREC_MAGIC
Constant for identifying valid trace buffers.
Definition: fnrec.c:40
uint32_t magic
Constant for identifying valid trace buffers.
Definition: fnrec.c:68

References FNREC_MAGIC, and fnrec_buffer::magic.

Referenced by __cyg_profile_func_enter(), __cyg_profile_func_exit(), and fnrec_init().

◆ fnrec_invalidate()

static void fnrec_invalidate ( void  )
static

Invalidate the trace buffer.

Definition at line 94 of file fnrec.c.

94  {
95  fnrec_buffer->magic = 0;
96 }
A trace buffer.
Definition: fnrec.c:66
uint32_t magic
Constant for identifying valid trace buffers.
Definition: fnrec.c:68

References fnrec_buffer::magic.

Referenced by fnrec_init().

◆ fnrec_reset()

static void fnrec_reset ( void  )
static

Reset the trace buffer and clear entries.

Definition at line 101 of file fnrec.c.

101  {
102  memset ( fnrec_buffer, 0, sizeof ( *fnrec_buffer ) );
104 }
A trace buffer.
Definition: fnrec.c:66
#define FNREC_MAGIC
Constant for identifying valid trace buffers.
Definition: fnrec.c:40
uint32_t magic
Constant for identifying valid trace buffers.
Definition: fnrec.c:68
void * memset(void *dest, int character, size_t len) __nonnull

References FNREC_MAGIC, fnrec_buffer::magic, and memset().

Referenced by fnrec_init().

◆ fnrec_append()

static struct fnrec_entry* fnrec_append ( void *  called_fn,
void *  call_site 
)
static

Append an entry to the trace buffer.

Parameters
called_fnCalled function
call_siteCall site
Return values
entryTrace buffer entry

Definition at line 113 of file fnrec.c.

113  {
114  struct fnrec_entry *entry;
115 
116  /* Re-use existing entry, if possible */
118  if ( ( entry->called_fn == called_fn ) &&
119  ( entry->call_site == call_site ) &&
120  ( entry->entry_count >= entry->exit_count ) ) {
121  return entry;
122  }
123 
124  /* Otherwise, create a new entry */
127  entry->called_fn = called_fn;
128  entry->call_site = call_site;
129  entry->entry_count = 0;
130  entry->exit_count = 0;
131  entry->checksum = ( ( ( unsigned long ) called_fn ) ^
132  ( ( unsigned long ) call_site ) );
133  return entry;
134 }
#define FNREC_NUM_ENTRIES
Number of trace buffer entries.
Definition: fnrec.c:43
A trace buffer entry.
Definition: fnrec.c:52
A trace buffer.
Definition: fnrec.c:66
void * call_site
Call site.
Definition: fnrec.c:56
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
struct fnrec_entry data[FNREC_NUM_ENTRIES]
Trace buffer.
Definition: fnrec.c:74
void * called_fn
Called function address.
Definition: fnrec.c:54
unsigned int idx
Next trace buffer entry to fill.
Definition: fnrec.c:71

References fnrec_entry::call_site, fnrec_entry::called_fn, fnrec_buffer::data, entry, FNREC_NUM_ENTRIES, and fnrec_buffer::idx.

Referenced by __cyg_profile_func_enter(), and __cyg_profile_func_exit().

◆ fnrec_dump()

static void fnrec_dump ( void  )
static

Print the contents of the trace buffer in chronological order.

Definition at line 139 of file fnrec.c.

139  {
140  struct fnrec_entry *entry;
141  unsigned int i;
142  unsigned int idx;
143  unsigned long checksum;
144 
145  printf ( "fnrec buffer dump:\n" );
146  for ( i = 1 ; i <= FNREC_NUM_ENTRIES ; i++ ) {
147  idx = ( ( fnrec_buffer->idx + i ) % FNREC_NUM_ENTRIES );
148  entry = &fnrec_buffer->data[idx];
149  if ( ( entry->entry_count == 0 ) && ( entry->exit_count == 0 ) )
150  continue;
151  checksum = ( ( ( ( unsigned long ) entry->called_fn ) ^
152  ( ( unsigned long ) entry->call_site ) ) +
153  entry->entry_count + entry->exit_count );
154  printf ( "%p %p %d %d", entry->called_fn, entry->call_site,
155  entry->entry_count, entry->exit_count );
156  if ( entry->checksum != checksum ) {
157  printf ( " (checksum wrong at phys %08lx)",
158  virt_to_phys ( entry ) );
159  }
160  printf ( "\n");
161  }
162 }
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
#define FNREC_NUM_ENTRIES
Number of trace buffer entries.
Definition: fnrec.c:43
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
uint8_t checksum
Checksum.
Definition: pnpbios.c:37
A trace buffer entry.
Definition: fnrec.c:52
A trace buffer.
Definition: fnrec.c:66
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
struct fnrec_entry data[FNREC_NUM_ENTRIES]
Trace buffer.
Definition: fnrec.c:74
unsigned int idx
Next trace buffer entry to fill.
Definition: fnrec.c:71

References checksum, fnrec_buffer::data, entry, FNREC_NUM_ENTRIES, fnrec_buffer::idx, printf(), and virt_to_phys().

Referenced by fnrec_init().

◆ fnrec_init()

static void fnrec_init ( void  )
static

Function tracer initialisation function.

Definition at line 167 of file fnrec.c.

167  {
168 
170  if ( fnrec_is_valid() ) {
172  fnrec_dump();
173  } else {
174  printf ( "fnrec buffer not found\n" );
175  }
176  fnrec_reset();
177 }
static int fnrec_is_valid(void)
Test whether the trace buffer is valid.
Definition: fnrec.c:86
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static void fnrec_dump(void)
Print the contents of the trace buffer in chronological order.
Definition: fnrec.c:139
A trace buffer.
Definition: fnrec.c:66
static __always_inline void * phys_to_virt(unsigned long phys_addr)
Convert physical address to a virtual address.
Definition: uaccess.h:299
#define FNREC_PHYS_ADDRESS
Trace buffer physical address.
Definition: fnrec.c:49
static void fnrec_invalidate(void)
Invalidate the trace buffer.
Definition: fnrec.c:94
static void fnrec_reset(void)
Reset the trace buffer and clear entries.
Definition: fnrec.c:101

References fnrec_dump(), fnrec_invalidate(), fnrec_is_valid(), FNREC_PHYS_ADDRESS, fnrec_reset(), phys_to_virt(), and printf().

◆ __init_fn()

struct init_fn fnrec_init_fn __init_fn ( INIT_NORMAL  )

◆ __cyg_profile_func_enter()

void __cyg_profile_func_enter ( void *  called_fn,
void *  call_site 
)

Definition at line 187 of file fnrec.c.

187  {
188  struct fnrec_entry *entry;
189 
190  if ( fnrec_is_valid() ) {
192  entry->entry_count++;
193  entry->checksum++;
194  mb();
195  }
196 }
static struct fnrec_entry * fnrec_append(void *called_fn, void *call_site)
Append an entry to the trace buffer.
Definition: fnrec.c:113
static int fnrec_is_valid(void)
Test whether the trace buffer is valid.
Definition: fnrec.c:86
A trace buffer entry.
Definition: fnrec.c:52
void * call_site
Call site.
Definition: fnrec.c:56
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
void * called_fn
Called function address.
Definition: fnrec.c:54
void mb(void)
Memory barrier.

References fnrec_entry::call_site, fnrec_entry::called_fn, entry, fnrec_append(), fnrec_is_valid(), and mb().

◆ __cyg_profile_func_exit()

void __cyg_profile_func_exit ( void *  called_fn,
void *  call_site 
)

Definition at line 198 of file fnrec.c.

198  {
199  struct fnrec_entry *entry;
200 
201  if ( fnrec_is_valid() ) {
203  entry->exit_count++;
204  entry->checksum++;
205  mb();
206  }
207 }
static struct fnrec_entry * fnrec_append(void *called_fn, void *call_site)
Append an entry to the trace buffer.
Definition: fnrec.c:113
static int fnrec_is_valid(void)
Test whether the trace buffer is valid.
Definition: fnrec.c:86
A trace buffer entry.
Definition: fnrec.c:52
void * call_site
Call site.
Definition: fnrec.c:56
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
void * called_fn
Called function address.
Definition: fnrec.c:54
void mb(void)
Memory barrier.

References fnrec_entry::call_site, fnrec_entry::called_fn, entry, fnrec_append(), fnrec_is_valid(), and mb().

Variable Documentation

◆ fnrec_buffer

struct fnrec_buffer* fnrec_buffer
static

The trace buffer.

Definition at line 79 of file fnrec.c.