Export some useful information for startup scripts and debug. For now, only pci drivers are handled.
Example for a static binary: marchand at gloops:~/git/dpdk$ ./build/app/dpdk-obj-info ./build/app/testpmd pci:driver=cxgbe,flags=needmapping,lsc pci:driver=cxgbe,id=vendor=1425,device=5400,subvendor=ffff,subdevice=ffff pci:driver=cxgbe,id=vendor=1425,device=5401,subvendor=ffff,subdevice=ffff pci:driver=cxgbe,id=vendor=1425,device=5402,subvendor=ffff,subdevice=ffff Example for a dso: marchand at gloops:~/git/dpdk$ ./build/app/dpdk-obj-info ./build/lib/librte_pmd_ixgbe.so pci:driver=ixgbe,flags=needmapping,lsc,detachable pci:driver=ixgbe,id=vendor=8086,device=10b6,subvendor=ffff,subdevice=ffff pci:driver=ixgbe,id=vendor=8086,device=1508,subvendor=ffff,subdevice=ffff pci:driver=ixgbe,id=vendor=8086,device=10c6,subvendor=ffff,subdevice=ffff Signed-off-by: David Marchand <david.marchand at 6wind.com> --- app/Makefile | 1 + app/dpdk-obj-info/Makefile | 45 +++++++++ app/dpdk-obj-info/dpdk-obj-info.c | 188 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 app/dpdk-obj-info/Makefile create mode 100644 app/dpdk-obj-info/dpdk-obj-info.c diff --git a/app/Makefile b/app/Makefile index 1151e09..0461a35 100644 --- a/app/Makefile +++ b/app/Makefile @@ -37,5 +37,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test-pipeline DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_test DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info +DIRS-y += dpdk-obj-info include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/app/dpdk-obj-info/Makefile b/app/dpdk-obj-info/Makefile new file mode 100644 index 0000000..b0f4bc7 --- /dev/null +++ b/app/dpdk-obj-info/Makefile @@ -0,0 +1,45 @@ +# BSD LICENSE +# +# Copyright 2016 6WIND S.A. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of 6WIND S.A. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(RTE_SDK)/mk/rte.vars.mk + + +APP = dpdk-obj-info + +SRCS-y += dpdk-obj-info.c + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +LDLIBS += -lbfd --as-needed + +DEPDIRS-y += lib + +include $(RTE_SDK)/mk/rte.app.mk diff --git a/app/dpdk-obj-info/dpdk-obj-info.c b/app/dpdk-obj-info/dpdk-obj-info.c new file mode 100644 index 0000000..23c183d --- /dev/null +++ b/app/dpdk-obj-info/dpdk-obj-info.c @@ -0,0 +1,188 @@ +/*- + * BSD LICENSE + * + * Copyright 2016 6WIND S.A. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND S.A. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <bfd.h> + +#include <rte_pci.h> + +static char * +dump_flags(uint32_t flags) +{ + static char buffer[sizeof("needmapping,lsc,detachable,")]; + int written = 0; + + buffer[0] = '\0'; + + if (flags & RTE_PCI_DRV_NEED_MAPPING) + written += snprintf(&buffer[written], sizeof(buffer) - written, + "%s,", "needmapping"); + if (flags & RTE_PCI_DRV_INTR_LSC) + written += snprintf(&buffer[written], sizeof(buffer) - written, + "%s,", "lsc"); + if (flags & RTE_PCI_DRV_DETACHABLE) + written += snprintf(&buffer[written], sizeof(buffer) - written, + "%s,", "detachable"); + if (written) + buffer[written-1] = '\0'; + + return buffer; +} + +static bfd *cur_bfd; +static void *bin_start; +static asymbol **sym_table; +static long sym_number; + +static asymbol * +find_symbol(const uintptr_t p) +{ + int i; + + for (i = 0; i < sym_number; i++) { + asymbol *sym = sym_table[i]; + + if (bfd_asymbol_value(sym) == p) + return sym; + } + + return NULL; +} + +static off_t +get_sec_vma_offset(const asection *sec) +{ + return (uintptr_t) bin_start + sec->filepos + - bfd_get_section_vma(cur_bfd, sec); +} + +static uintptr_t +get_value(const asymbol *sym) +{ + asection *sec = bfd_get_section(sym); + off_t sec_vma_offset = get_sec_vma_offset(sec); + return bfd_asymbol_value(sym) + sec_vma_offset; +} + +int main(int argc, char *argv[]) +{ + int fd; + struct stat st; + long sym_table_size; + long i; + const char *filename; + const char *filter = NULL; + + /* for now, handle one file, and an optional driver name */ + if (argc < 2 || argc > 3) + return -1; + + filename = argv[1]; + if (argc > 2) + filter = argv[2]; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -1; + if (fstat(fd, &st) < 0) + return -1; + + bin_start = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (bin_start == MAP_FAILED) + return -1; + + bfd_init(); + + cur_bfd = bfd_fdopenr(filename, NULL, fd); + if (!cur_bfd) { + printf("could not init bfd: %s\n", strerror(errno)); + return -1; + } + + if (!bfd_check_format(cur_bfd, bfd_object)) + return -1; + + sym_table_size = bfd_get_symtab_upper_bound(cur_bfd); + if (sym_table_size <= 0) + return -1; + + sym_table = malloc(sym_table_size); + if (!sym_table) + return -1; + + sym_number = bfd_canonicalize_symtab(cur_bfd, sym_table); + if (sym_number < 0) + return -1; + + for (i = 0; i < sym_number; i++) { + asymbol *sym = sym_table[i]; + const struct rte_pci_driver *dr; + asymbol *symid; + const struct rte_pci_id *id; + const char *name; + + if (strncmp(sym->name, RTE_EAL_PCI_DRIVER_PREFIX, + strlen(RTE_EAL_PCI_DRIVER_PREFIX))) + continue; + + name = sym->name + strlen(RTE_EAL_PCI_DRIVER_PREFIX); + if (filter && strcmp(name, filter)) + continue; + + /* pcidriver_* symbols are pointers to real symbol */ + dr = (typeof(dr))get_value(find_symbol(*(uintptr_t *)get_value(sym))); + symid = find_symbol((uintptr_t)dr->id_table); + id = (typeof(id))get_value(symid); + + printf("pci:driver=%s,", name); + printf("flags=%s\n", dump_flags(dr->drv_flags)); + + while (id->vendor_id) { + printf("pci:driver=%s,", name); + printf("id="); + printf("vendor=%4.4x,", id->vendor_id); + printf("device=%4.4x,", id->device_id); + printf("subvendor=%4.4x,", id->subsystem_vendor_id); + printf("subdevice=%4.4x\n", id->subsystem_device_id); + id++; + } + } + + return 0; +} -- 1.9.1