diff --git a/include/nuttx/allsyms.h b/include/nuttx/allsyms.h new file mode 100644 index 00000000000..46272c04bcb --- /dev/null +++ b/include/nuttx/allsyms.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * include/nuttx/allsyms.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_ALLSYMS_H +#define __INCLUDE_NUTTX_ALLSYMS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: allsyms_findbyname + * + * Description: + * Find the symbol in the symbol table with the matching name. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s *allsyms_findbyname(FAR const char *name, + FAR size_t *size); + +/**************************************************************************** + * Name: symtab_findbyvalue + * + * Description: + * Find the symbol in the symbol table whose value closest (but not greater + * than), the provided value. This version assumes that table is not + * ordered with respect to symbol value and, hence, access time will be + * linear with respect to nsyms. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s *allsyms_findbyvalue(FAR void *value, + FAR size_t *size); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_ALLSYMS_H */ diff --git a/libs/libc/Kconfig b/libs/libc/Kconfig index 1ffde33ff8d..963c974d07c 100644 --- a/libs/libc/Kconfig +++ b/libs/libc/Kconfig @@ -29,3 +29,4 @@ source "libs/libc/wqueue/Kconfig" source "libs/libc/hex2bin/Kconfig" source "libs/libc/userfs/Kconfig" source "libs/libc/builtin/Kconfig" +source "libs/libc/symtab/Kconfig" diff --git a/libs/libc/symtab/Kconfig b/libs/libc/symtab/Kconfig new file mode 100644 index 00000000000..fd024589448 --- /dev/null +++ b/libs/libc/symtab/Kconfig @@ -0,0 +1,12 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config ALLSYMS + bool "Load all symbols for debugging" + default n + help + Say Y here to let the nuttx print out symbolic crash information and + symbolic stack backtraces. This increases the size of the nuttx + somewhat, as all symbols have to be loaded into the nuttx image. diff --git a/libs/libc/symtab/Make.defs b/libs/libc/symtab/Make.defs index cb00ccaba75..021d49d80b4 100644 --- a/libs/libc/symtab/Make.defs +++ b/libs/libc/symtab/Make.defs @@ -22,6 +22,12 @@ CSRCS += symtab_findbyname.c symtab_findbyvalue.c symtab_sortbyname.c +# Symbolic information support + +ifeq ($(CONFIG_ALLSYMS),y) +CSRCS += symtab_allsyms.c +endif + # Add the symtab directory to the build DEPPATH += --dep-path symtab diff --git a/libs/libc/symtab/symtab_allsyms.c b/libs/libc/symtab/symtab_allsyms.c new file mode 100644 index 00000000000..021528ea252 --- /dev/null +++ b/libs/libc/symtab/symtab_allsyms.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * libs/libc/symtab/symtab_allsyms.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct symtab_s g_allsyms[1]; +extern const int g_nallsyms; + +/**************************************************************************** + * Name: allsyms_lookup + * + * Description: + * Find the symbol in the symbol table with the matching name. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +static FAR const struct symtab_s * +allsyms_lookup(FAR const char *name, FAR void *value, + FAR size_t *size) +{ + FAR const struct symtab_s *symbol = NULL; + + if (name) + { + symbol = symtab_findbyname(g_allsyms, name, g_nallsyms); + } + else if (value) + { + symbol = symtab_findbyvalue(g_allsyms, value, g_nallsyms); + } + + if (symbol && symbol != &g_allsyms[g_nallsyms - 1]) + { + *size = (symbol + 1)->sym_value - symbol->sym_value; + } + else + { + *size = 0; + } + + return symbol; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: allsyms_findbyname + * + * Description: + * Find the symbol in the symbol table with the matching name. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s *allsyms_findbyname(FAR const char *name, + FAR size_t *size) +{ + return allsyms_lookup(name, NULL, size); +} + +/**************************************************************************** + * Name: symtab_findbyvalue + * + * Description: + * Find the symbol in the symbol table whose value closest (but not greater + * than), the provided value. This version assumes that table is not + * ordered with respect to symbol value and, hence, access time will be + * linear with respect to nsyms. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s *allsyms_findbyvalue(FAR void *value, + FAR size_t *size) +{ + return allsyms_lookup(NULL, value, size); +} diff --git a/tools/mkallsyms.sh b/tools/mkallsyms.sh new file mode 100755 index 00000000000..8b6de5c7258 --- /dev/null +++ b/tools/mkallsyms.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +############################################################################ +# tools/mkallsyms.sh +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +export LC_ALL=C + +usage="Usage: $0 " + +# Get the symbol table + +# Extract all of the symbols from the ELF files and create a +# list of sorted, unique undefined variable names. + +# Now output the symbol table as a structure in a C source file. All +# undefined symbols are declared as void* types. If the toolchain does +# any kind of checking for function vs. data objects, then this could +# failed + +nm="${2}nm" +filt="${2}c++filt" +if [ -f "${1}" ];then + count=`${nm} -n ${1} | grep -E " [T|t] " | uniq | wc -l` +else + count=0 +fi + +echo "#include " +echo "#include " +echo "" +echo "const int g_nallsyms = ${count} + 2;" +echo "const struct symtab_s g_allsyms[${count} + 2] = " +echo "{" + +# Add start address boundary + +echo " { \"Unknown\", (FAR const void *)0x00000000 }," + +if [ -f "${1}" ];then + ${nm} -n ${1} | grep -E " [T|t] " | uniq | \ + while read addr type name + do + echo " { \"`${filt} -p $name`\", (FAR const void *)0x$addr }," + done +fi + +# Add end address boundary + +echo " { \"Unknown\", (FAR const void *)0xffffffff }," + +echo "};"