From f2980ece06363e584541829bf40d46ad9760d535 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 May 2019 11:59:44 -0600 Subject: sandbox: Quit when hang() is called It doesn't make a lot of sense to hang on sandbox when hang() is called, since the only way out is Ctrl-C. In fact, Ctrl-C does not work if the terminal is in raw mode, which it will be if the command-line has not been reached yet. In that case, Ctrl-Z / kill -9 must be used, which is not very friendly. Avoid all of this by quiting when hang() is called. Signed-off-by: Simon Glass --- lib/hang.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/hang.c b/lib/hang.c index c5a78694be6..4d026a3e64c 100644 --- a/lib/hang.c +++ b/lib/hang.c @@ -9,6 +9,7 @@ #include #include +#include /** * hang - stop processing by staying in an endless loop @@ -26,6 +27,8 @@ void hang(void) puts("### ERROR ### Please RESET the board ###\n"); #endif bootstage_error(BOOTSTAGE_ID_NEED_RESET); + if (IS_ENABLED(CONFIG_SANDBOX)) + os_exit(1); for (;;) ; } -- cgit v1.3.1 From 848e94d0ba7296d81e3c00b01bad1c13741497fb Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 20 May 2019 18:05:04 +0200 Subject: fdtdec: test: Fix memory leak Free the memory allocated to store the test FDT upon test completion to avoid leaking the memory. We don't bother cleaning up on test failure since the code is broken in that case and should be fixed, in which case the leak would also go away. Reported-by: Tom Rini Suggested-by: Heinrich Schuchardt Signed-off-by: Thierry Reding Reviewed-by: Simon Glass --- lib/fdtdec_test.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec_test.c b/lib/fdtdec_test.c index 1f4f2705405..e8bfd1fb1ec 100644 --- a/lib/fdtdec_test.c +++ b/lib/fdtdec_test.c @@ -138,6 +138,7 @@ static int run_test(const char *aliases, const char *nodes, const char *expect) } printf("pass\n"); + free(blob); return 0; } @@ -292,6 +293,7 @@ static int check_carveout(void) CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 2), 0); CHECKOK(check_fdt_carveout(fdt, 2, 2)); + free(fdt); return 0; } -- cgit v1.3.1 From a2fa38da200cbd454bcb8dc7659bde00044302f7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 2 Jun 2019 13:05:08 +0200 Subject: trace: conserve gd register An UEFI application may change the value of the register that gd lives in. But some of our functions like get_ticks() access this register. So we have to set the gd register to the U-Boot value when entering a trace point and set it back to the application value when exiting the trace point. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/trace.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lib') diff --git a/lib/trace.c b/lib/trace.c index 9956442fefe..a13e5bf228b 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -56,6 +56,49 @@ static inline uintptr_t __attribute__((no_instrument_function)) return offset / FUNC_SITE_SIZE; } +#ifdef CONFIG_EFI_LOADER + +/** + * trace_gd - the value of the gd register + */ +static volatile void *trace_gd; + +/** + * trace_save_gd() - save the value of the gd register + */ +static void __attribute__((no_instrument_function)) trace_save_gd(void) +{ + trace_gd = gd; +} + +/** + * trace_swap_gd() - swap between U-Boot and application gd register value + * + * An UEFI application may change the value of the register that gd lives in. + * But some of our functions like get_ticks() access this register. So we + * have to set the gd register to the U-Boot value when entering a trace + * point and set it back to the application value when exiting the trace point. + */ +static void __attribute__((no_instrument_function)) trace_swap_gd(void) +{ + volatile void *temp_gd = trace_gd; + + trace_gd = gd; + gd = temp_gd; +} + +#else + +static void __attribute__((no_instrument_function)) trace_save_gd(void) +{ +} + +static void __attribute__((no_instrument_function)) trace_swap_gd(void) +{ +} + +#endif + static void __attribute__((no_instrument_function)) add_ftrace(void *func_ptr, void *caller, ulong flags) { @@ -100,6 +143,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( if (trace_enabled) { int func; + trace_swap_gd(); add_ftrace(func_ptr, caller, FUNCF_ENTRY); func = func_ptr_to_num(func_ptr); if (func < hdr->func_count) { @@ -111,6 +155,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( hdr->depth++; if (hdr->depth > hdr->depth_limit) hdr->max_depth = hdr->depth; + trace_swap_gd(); } } @@ -126,8 +171,10 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit( void *func_ptr, void *caller) { if (trace_enabled) { + trace_swap_gd(); add_ftrace(func_ptr, caller, FUNCF_EXIT); hdr->depth--; + trace_swap_gd(); } } @@ -284,6 +331,8 @@ int __attribute__((no_instrument_function)) trace_init(void *buff, size_t needed; int was_disabled = !trace_enabled; + trace_save_gd(); + if (!was_disabled) { #ifdef CONFIG_TRACE_EARLY char *end; -- cgit v1.3.1 From da0fb5fdd430abef136bc5e1636f8d1855cf0008 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 2 Jun 2019 13:30:09 +0200 Subject: trace: make call depth limit customizable Up to now we had hard coded values for the call depth up to which trace records are created: 200 for early tracing, 15 thereafter. UEFI applications reach a call depth of 80 or above. Provide customizing settings for the call trace depth limit and the early call trace depth limit. Use the old values as defaults. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/Kconfig | 15 +++++++++++++++ lib/trace.c | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 416e63c1c73..e717eb3de50 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -192,6 +192,13 @@ config TRACE_BUFFER_SIZE the size is too small then 'trace stats' will show a message saying how many records were dropped due to buffer overflow. +config TRACE_CALL_DEPTH_LIMIT + int "Trace call depth limit" + depends on TRACE + default 15 + help + Sets the maximum call depth up to which function calls are recorded. + config TRACE_EARLY bool "Enable tracing before relocation" depends on TRACE @@ -209,6 +216,14 @@ config TRACE_EARLY_SIZE Sets the size of the early trace buffer in bytes. This is used to hold tracing information before relocation. +config TRACE_EARLY_CALL_DEPTH_LIMIT + int "Early trace call depth limit" + depends on TRACE_EARLY + default 200 + help + Sets the maximum call depth up to which function calls are recorded + during early tracing. + config TRACE_EARLY_ADDR hex "Address of early trace buffer in U-Boot" depends on TRACE_EARLY diff --git a/lib/trace.c b/lib/trace.c index a13e5bf228b..04780f59d33 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -376,7 +376,7 @@ int __attribute__((no_instrument_function)) trace_init(void *buff, add_textbase(); puts("trace: enabled\n"); - hdr->depth_limit = 15; + hdr->depth_limit = CONFIG_TRACE_CALL_DEPTH_LIMIT; trace_enabled = 1; trace_inited = 1; @@ -410,7 +410,7 @@ int __attribute__((no_instrument_function)) trace_early_init(void) hdr->ftrace = (struct trace_call *)((char *)hdr + needed); hdr->ftrace_size = (buff_size - needed) / sizeof(*hdr->ftrace); add_textbase(); - hdr->depth_limit = 200; + hdr->depth_limit = CONFIG_TRACE_EARLY_CALL_DEPTH_LIMIT; printf("trace: early enable at %08x\n", CONFIG_TRACE_EARLY_ADDR); trace_enabled = 1; -- cgit v1.3.1 From 2b7a3882e0f70d253fb6a2da5682c94aea4c46f1 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 14 Jun 2019 21:50:55 +0200 Subject: trace: do not limit trace buffer to 2GiB There is no good reason to limit the trace buffer to 2GiB on a 64bit system. Adjust the types of the relevant parameters. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- cmd/trace.c | 10 ++++------ include/trace.h | 6 +++--- lib/trace.c | 14 +++++++------- tools/proftool.c | 4 ++-- 4 files changed, 16 insertions(+), 18 deletions(-) (limited to 'lib') diff --git a/cmd/trace.c b/cmd/trace.c index 26bf0960d49..7d328f88be5 100644 --- a/cmd/trace.c +++ b/cmd/trace.c @@ -30,8 +30,7 @@ static int get_args(int argc, char * const argv[], char **buff, static int create_func_list(int argc, char * const argv[]) { - size_t buff_size, avail, buff_ptr, used; - unsigned int needed; + size_t buff_size, avail, buff_ptr, needed, used; char *buff; int err; @@ -41,7 +40,7 @@ static int create_func_list(int argc, char * const argv[]) avail = buff_size - buff_ptr; err = trace_list_functions(buff + buff_ptr, avail, &needed); if (err) - printf("Error: truncated (%#x bytes needed)\n", needed); + printf("Error: truncated (%#zx bytes needed)\n", needed); used = min(avail, (size_t)needed); printf("Function trace dumped to %08lx, size %#zx\n", (ulong)map_to_sysmem(buff + buff_ptr), used); @@ -54,8 +53,7 @@ static int create_func_list(int argc, char * const argv[]) static int create_call_list(int argc, char * const argv[]) { - size_t buff_size, avail, buff_ptr, used; - unsigned int needed; + size_t buff_size, avail, buff_ptr, needed, used; char *buff; int err; @@ -65,7 +63,7 @@ static int create_call_list(int argc, char * const argv[]) avail = buff_size - buff_ptr; err = trace_list_calls(buff + buff_ptr, avail, &needed); if (err) - printf("Error: truncated (%#x bytes needed)\n", needed); + printf("Error: truncated (%#zx bytes needed)\n", needed); used = min(avail, (size_t)needed); printf("Call list dumped to %08lx, size %#zx\n", (ulong)map_to_sysmem(buff + buff_ptr), used); diff --git a/include/trace.h b/include/trace.h index 99f34f72bcc..606dba97689 100644 --- a/include/trace.h +++ b/include/trace.h @@ -39,7 +39,7 @@ struct trace_output_func { /* A header at the start of the trace output buffer */ struct trace_output_hdr { enum trace_chunk_type type; /* Record type */ - uint32_t rec_count; /* Number of records */ + size_t rec_count; /* Number of records */ }; /* Print statistics about traced function calls */ @@ -57,7 +57,7 @@ void trace_print_stats(void); * @param needed Returns number of bytes used / needed * @return 0 if ok, -1 on error (buffer exhausted) */ -int trace_list_functions(void *buff, int buff_size, unsigned *needed); +int trace_list_functions(void *buff, size_t buff_size, size_t *needed); /* Flags for ftrace_record */ enum ftrace_flags { @@ -77,7 +77,7 @@ struct trace_call { uint32_t flags; /* Flags and timestamp */ }; -int trace_list_calls(void *buff, int buff_size, unsigned int *needed); +int trace_list_calls(void *buff, size_t buff_size, size_t *needed); /** * Turn function tracing on and off diff --git a/lib/trace.c b/lib/trace.c index 04780f59d33..f2402b93593 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -190,12 +190,12 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit( * greater than buff_size if we ran out of space. * @return 0 if ok, -1 if space was exhausted */ -int trace_list_functions(void *buff, int buff_size, unsigned int *needed) +int trace_list_functions(void *buff, size_t buff_size, size_t *needed) { struct trace_output_hdr *output_hdr = NULL; void *end, *ptr = buff; - int func; - int upto; + size_t func; + size_t upto; end = buff ? buff + buff_size : NULL; @@ -206,7 +206,7 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed) /* Add information about each function */ for (func = upto = 0; func < hdr->func_count; func++) { - int calls = hdr->call_accum[func]; + size_t calls = hdr->call_accum[func]; if (!calls) continue; @@ -235,12 +235,12 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed) return 0; } -int trace_list_calls(void *buff, int buff_size, unsigned *needed) +int trace_list_calls(void *buff, size_t buff_size, size_t *needed) { struct trace_output_hdr *output_hdr = NULL; void *end, *ptr = buff; - int rec, upto; - int count; + size_t rec, upto; + size_t count; end = buff ? buff + buff_size : NULL; diff --git a/tools/proftool.c b/tools/proftool.c index c1803fa78a7..fecb9d6e99c 100644 --- a/tools/proftool.c +++ b/tools/proftool.c @@ -205,12 +205,12 @@ static struct func_info *find_caller_by_offset(uint32_t offset) return low >= 0 ? &func_list[low] : NULL; } -static int read_calls(FILE *fin, int count) +static int read_calls(FILE *fin, size_t count) { struct trace_call *call_data; int i; - notice("call count: %d\n", count); + notice("call count: %zu\n", count); call_list = (struct trace_call *)calloc(count, sizeof(*call_data)); if (!call_list) { error("Cannot allocate call_list\n"); -- cgit v1.3.1