Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/12886/?format=api
http://patches.dpdk.org/api/patches/12886/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/1463605687-649-2-git-send-email-nhorman@tuxdriver.com/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<1463605687-649-2-git-send-email-nhorman@tuxdriver.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1463605687-649-2-git-send-email-nhorman@tuxdriver.com", "date": "2016-05-18T21:08:04", "name": "[dpdk-dev,PATCHv2,1/4] pmdinfogen: Add buildtools and pmdinfogen utility", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "ff88ab9839c371726890986a55c900b8681d204c", "submitter": { "id": 32, "url": "http://patches.dpdk.org/api/people/32/?format=api", "name": "Neil Horman", "email": "nhorman@tuxdriver.com" }, "delegate": { "id": 1, "url": "http://patches.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/1463605687-649-2-git-send-email-nhorman@tuxdriver.com/mbox/", "series": [], "comments": "http://patches.dpdk.org/api/patches/12886/comments/", "check": "pending", "checks": "http://patches.dpdk.org/api/patches/12886/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 5D7BB95D3;\n\tWed, 18 May 2016 23:08:39 +0200 (CEST)", "from smtp.tuxdriver.com (charlotte.tuxdriver.com [70.61.120.58])\n\tby dpdk.org (Postfix) with ESMTP id 1441B68FC\n\tfor <dev@dpdk.org>; Wed, 18 May 2016 23:08:38 +0200 (CEST)", "from hmsreliant.think-freely.org\n\t([2001:470:8:a08:7aac:c0ff:fec2:933b] helo=localhost)\n\tby smtp.tuxdriver.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.63)\n\t(envelope-from <nhorman@tuxdriver.com>)\n\tid 1b38hh-0001IQ-Me; Wed, 18 May 2016 17:08:35 -0400" ], "From": "Neil Horman <nhorman@tuxdriver.com>", "To": "dev@dpdk.org", "Cc": "Neil Horman <nhorman@tuxdriver.com>,\n\tBruce Richardson <bruce.richardson@intel.com>,\n\tThomas Monjalon <thomas.monjalon@6wind.com>,\n\tStephen Hemminger <stephen@networkplumber.org>,\n\tPanu Matilainen <pmatilai@redhat.com>", "Date": "Wed, 18 May 2016 17:08:04 -0400", "Message-Id": "<1463605687-649-2-git-send-email-nhorman@tuxdriver.com>", "X-Mailer": "git-send-email 2.5.5", "In-Reply-To": "<1463605687-649-1-git-send-email-nhorman@tuxdriver.com>", "References": "<1463431287-4551-1-git-send-email-nhorman@tuxdriver.com>\n\t<1463605687-649-1-git-send-email-nhorman@tuxdriver.com>", "X-Spam-Score": "-1.0 (-)", "X-Spam-Status": "No", "Subject": "[dpdk-dev] [PATCHv2 1/4] pmdinfogen: Add buildtools and pmdinfogen\n\tutility", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "pmdinfogen is a tool used to parse object files and build json strings for use in\nlater determining hardware support in a dso or application binary. pmdinfo\nlooks for the non-exported symbol names this_pmd_name<n> and this_pmd_tbl<n>\n(where n is a integer counter). It records the name of each of these tuples,\nusing the later to find the symbolic name of the pci_table for physical devices\nthat the object supports. With this information, it outputs a C file with a\nsingle line of the form:\n\nstatic char *<pmd_name>_driver_info[] __attribute__((used)) = \" \\\n\tPMD_DRIVER_INFO=<json string>\";\n\nWhere <pmd_name> is the arbitrary name of the pmd, and <json_string> is the json\nencoded string that hold relevant pmd information, including the pmd name, type\nand optional array of pci device/vendor ids that the driver supports.\n\nThis c file is suitable for compiling to object code, then relocatably linking\ninto the parent file from which the C was generated. This creates an entry in\nthe string table of the object that can inform a later tool about hardware\nsupport.\n\nSigned-off-by: Neil Horman <nhorman@tuxdriver.com>\nCC: Bruce Richardson <bruce.richardson@intel.com>\nCC: Thomas Monjalon <thomas.monjalon@6wind.com>\nCC: Stephen Hemminger <stephen@networkplumber.org>\nCC: Panu Matilainen <pmatilai@redhat.com>\n---\n GNUmakefile | 2 +-\n buildtools/Makefile | 36 ++++\n buildtools/pmdinfogen/Makefile | 48 +++++\n buildtools/pmdinfogen/pmdinfogen.c | 430 +++++++++++++++++++++++++++++++++++++\n buildtools/pmdinfogen/pmdinfogen.h | 83 +++++++\n mk/rte.buildtools.mk | 148 +++++++++++++\n mk/rte.sdkbuild.mk | 3 +-\n 7 files changed, 748 insertions(+), 2 deletions(-)\n create mode 100644 buildtools/Makefile\n create mode 100644 buildtools/pmdinfogen/Makefile\n create mode 100644 buildtools/pmdinfogen/pmdinfogen.c\n create mode 100644 buildtools/pmdinfogen/pmdinfogen.h\n create mode 100644 mk/rte.buildtools.mk", "diff": "diff --git a/GNUmakefile b/GNUmakefile\nindex b59e4b6..00fe0db 100644\n--- a/GNUmakefile\n+++ b/GNUmakefile\n@@ -40,6 +40,6 @@ export RTE_SDK\n # directory list\n #\n \n-ROOTDIRS-y := lib drivers app\n+ROOTDIRS-y := buildtools lib drivers app\n \n include $(RTE_SDK)/mk/rte.sdkroot.mk\ndiff --git a/buildtools/Makefile b/buildtools/Makefile\nnew file mode 100644\nindex 0000000..eb565eb\n--- /dev/null\n+++ b/buildtools/Makefile\n@@ -0,0 +1,36 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+# * Redistributions of source code must retain the above copyright\n+# notice, this list of conditions and the following disclaimer.\n+# * Redistributions in binary form must reproduce the above copyright\n+# notice, this list of conditions and the following disclaimer in\n+# the documentation and/or other materials provided with the\n+# distribution.\n+# * Neither the name of Intel Corporation nor the names of its\n+# contributors may be used to endorse or promote products derived\n+# from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+DIRS-y += pmdinfogen\n+\n+include $(RTE_SDK)/mk/rte.subdir.mk\ndiff --git a/buildtools/pmdinfogen/Makefile b/buildtools/pmdinfogen/Makefile\nnew file mode 100644\nindex 0000000..4de9506\n--- /dev/null\n+++ b/buildtools/pmdinfogen/Makefile\n@@ -0,0 +1,48 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+# * Redistributions of source code must retain the above copyright\n+# notice, this list of conditions and the following disclaimer.\n+# * Redistributions in binary form must reproduce the above copyright\n+# notice, this list of conditions and the following disclaimer in\n+# the documentation and/or other materials provided with the\n+# distribution.\n+# * Neither the name of Intel Corporation nor the names of its\n+# contributors may be used to endorse or promote products derived\n+# from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+#\n+# library name\n+#\n+APP = pmdinfogen\n+\n+#\n+# all sources are stored in SRCS-y\n+#\n+SRCS-y += pmdinfogen.c\n+\n+#CFLAGS += $(WERROR_FLAGS) -g\n+CFLAGS += -g\n+\n+include $(RTE_SDK)/mk/rte.buildtools.mk\n+\ndiff --git a/buildtools/pmdinfogen/pmdinfogen.c b/buildtools/pmdinfogen/pmdinfogen.c\nnew file mode 100644\nindex 0000000..9183937\n--- /dev/null\n+++ b/buildtools/pmdinfogen/pmdinfogen.c\n@@ -0,0 +1,430 @@\n+/* Postprocess pmd object files to export hw support \n+ *\n+ * Copyright 2016 Neil Horman <nhorman@tuxdriver.com>\n+ * Based in part on modpost.c from the linux kernel\n+ *\n+ * This software may be used and distributed according to the terms\n+ * of the GNU General Public License V2, incorporated herein by reference.\n+ *\n+ */\n+\n+#define _GNU_SOURCE\n+#include <stdio.h>\n+#include <ctype.h>\n+#include <string.h>\n+#include <limits.h>\n+#include <stdbool.h>\n+#include <errno.h>\n+#include \"pmdinfogen.h\"\n+\n+\n+static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)\n+{\n+\tif (sym)\n+\t\treturn elf->strtab + sym->st_name;\n+\telse\n+\t\treturn \"(unknown)\";\n+}\n+\n+void *grab_file(const char *filename, unsigned long *size)\n+{\n+\tstruct stat st;\n+\tvoid *map = MAP_FAILED;\n+\tint fd;\n+\n+\tfd = open(filename, O_RDONLY);\n+\tif (fd < 0)\n+\t\treturn NULL;\n+\tif (fstat(fd, &st))\n+\t\tgoto failed;\n+\n+\t*size = st.st_size;\n+\tmap = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);\n+\n+failed:\n+\tclose(fd);\n+\tif (map == MAP_FAILED)\n+\t\treturn NULL;\n+\treturn map;\n+}\n+\n+/**\n+ * Return a copy of the next line in a mmap'ed file.\n+ * spaces in the beginning of the line is trimmed away.\n+ * Return a pointer to a static buffer.\n+ **/\n+void release_file(void *file, unsigned long size)\n+{\n+\tmunmap(file, size);\n+}\n+\n+\n+static void *get_sym_value(struct elf_info *info, const Elf_Sym *sym)\n+{\n+\tvoid *ptr = (void *)info->hdr + info->sechdrs[sym->st_shndx].sh_offset;\n+\n+\treturn (void *)(ptr + sym->st_value);\n+}\n+\n+static Elf_Sym *find_sym_in_symtab(struct elf_info *info, \n+\t\t\t\t const char *name, Elf_Sym *last)\n+{\n+\tElf_Sym *idx;\n+\tif (last)\n+\t\tidx = last+1;\n+\telse\n+\t\tidx = info->symtab_start;\n+\n+\tfor(; idx < info->symtab_stop; idx++) {\n+\t\tconst char *n = sym_name(info, idx);\n+\t\tif (!strncmp(n, name, strlen(name)))\n+\t\t\treturn idx;\n+\t}\n+\treturn NULL;\n+}\n+\n+static int parse_elf(struct elf_info *info, const char *filename)\n+{\n+\tunsigned int i;\n+\tElf_Ehdr *hdr;\n+\tElf_Shdr *sechdrs;\n+\tElf_Sym *sym;\n+\tconst char *secstrings;\n+\tunsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;\n+\n+\thdr = grab_file(filename, &info->size);\n+\tif (!hdr) {\n+\t\tperror(filename);\n+\t\texit(1);\n+\t}\n+\tinfo->hdr = hdr;\n+\tif (info->size < sizeof(*hdr)) {\n+\t\t/* file too small, assume this is an empty .o file */\n+\t\treturn 0;\n+\t}\n+\t/* Is this a valid ELF file? */\n+\tif ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||\n+\t (hdr->e_ident[EI_MAG1] != ELFMAG1) ||\n+\t (hdr->e_ident[EI_MAG2] != ELFMAG2) ||\n+\t (hdr->e_ident[EI_MAG3] != ELFMAG3)) {\n+\t\t/* Not an ELF file - silently ignore it */\n+\t\treturn 0;\n+\t}\n+\t/* Fix endianness in ELF header */\n+\thdr->e_type = TO_NATIVE(hdr->e_type);\n+\thdr->e_machine = TO_NATIVE(hdr->e_machine);\n+\thdr->e_version = TO_NATIVE(hdr->e_version);\n+\thdr->e_entry = TO_NATIVE(hdr->e_entry);\n+\thdr->e_phoff = TO_NATIVE(hdr->e_phoff);\n+\thdr->e_shoff = TO_NATIVE(hdr->e_shoff);\n+\thdr->e_flags = TO_NATIVE(hdr->e_flags);\n+\thdr->e_ehsize = TO_NATIVE(hdr->e_ehsize);\n+\thdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);\n+\thdr->e_phnum = TO_NATIVE(hdr->e_phnum);\n+\thdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);\n+\thdr->e_shnum = TO_NATIVE(hdr->e_shnum);\n+\thdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);\n+\tsechdrs = (void *)hdr + hdr->e_shoff;\n+\tinfo->sechdrs = sechdrs;\n+\n+\t/* Check if file offset is correct */\n+\tif (hdr->e_shoff > info->size) {\n+\t\tfprintf(stderr, \"section header offset=%lu in file '%s' is bigger than \"\n+\t\t \"filesize=%lu\\n\", (unsigned long)hdr->e_shoff,\n+\t\t filename, info->size);\n+\t\treturn 0;\n+\t}\n+\n+\tif (hdr->e_shnum == SHN_UNDEF) {\n+\t\t/*\n+\t\t * There are more than 64k sections,\n+\t\t * read count from .sh_size.\n+\t\t */\n+\t\tinfo->num_sections = TO_NATIVE(sechdrs[0].sh_size);\n+\t}\n+\telse {\n+\t\tinfo->num_sections = hdr->e_shnum;\n+\t}\n+\tif (hdr->e_shstrndx == SHN_XINDEX) {\n+\t\tinfo->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);\n+\t}\n+\telse {\n+\t\tinfo->secindex_strings = hdr->e_shstrndx;\n+\t}\n+\n+\t/* Fix endianness in section headers */\n+\tfor (i = 0; i < info->num_sections; i++) {\n+\t\tsechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);\n+\t\tsechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);\n+\t\tsechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);\n+\t\tsechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);\n+\t\tsechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);\n+\t\tsechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);\n+\t\tsechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);\n+\t\tsechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);\n+\t\tsechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);\n+\t\tsechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);\n+\t}\n+\t/* Find symbol table. */\n+\tsecstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;\n+\tfor (i = 1; i < info->num_sections; i++) {\n+\t\tconst char *secname;\n+\t\tint nobits = sechdrs[i].sh_type == SHT_NOBITS;\n+\n+\t\tif (!nobits && sechdrs[i].sh_offset > info->size) {\n+\t\t\tfprintf(stderr, \"%s is truncated. sechdrs[i].sh_offset=%lu > \"\n+\t\t\t \"sizeof(*hrd)=%zu\\n\", filename,\n+\t\t\t (unsigned long)sechdrs[i].sh_offset,\n+\t\t\t sizeof(*hdr));\n+\t\t\treturn 0;\n+\t\t}\n+\t\tsecname = secstrings + sechdrs[i].sh_name;\n+\t\tif (strcmp(secname, \".modinfo\") == 0) {\n+\t\t\tif (nobits)\n+\t\t\t\tfprintf(stderr, \"%s has NOBITS .modinfo\\n\", filename);\n+\t\t\tinfo->modinfo = (void *)hdr + sechdrs[i].sh_offset;\n+\t\t\tinfo->modinfo_len = sechdrs[i].sh_size;\n+\t\t} else if (strcmp(secname, \"__ksymtab\") == 0)\n+\t\t\tinfo->export_sec = i;\n+\t\telse if (strcmp(secname, \"__ksymtab_unused\") == 0)\n+\t\t\tinfo->export_unused_sec = i;\n+\t\telse if (strcmp(secname, \"__ksymtab_gpl\") == 0)\n+\t\t\tinfo->export_gpl_sec = i;\n+\t\telse if (strcmp(secname, \"__ksymtab_unused_gpl\") == 0)\n+\t\t\tinfo->export_unused_gpl_sec = i;\n+\t\telse if (strcmp(secname, \"__ksymtab_gpl_future\") == 0)\n+\t\t\tinfo->export_gpl_future_sec = i;\n+\n+\t\tif (sechdrs[i].sh_type == SHT_SYMTAB) {\n+\t\t\tunsigned int sh_link_idx;\n+\t\t\tsymtab_idx = i;\n+\t\t\tinfo->symtab_start = (void *)hdr +\n+\t\t\t sechdrs[i].sh_offset;\n+\t\t\tinfo->symtab_stop = (void *)hdr +\n+\t\t\t sechdrs[i].sh_offset + sechdrs[i].sh_size;\n+\t\t\tsh_link_idx = sechdrs[i].sh_link;\n+\t\t\tinfo->strtab = (void *)hdr +\n+\t\t\t sechdrs[sh_link_idx].sh_offset;\n+\t\t}\n+\n+\t\t/* 32bit section no. table? (\"more than 64k sections\") */\n+\t\tif (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {\n+\t\t\tsymtab_shndx_idx = i;\n+\t\t\tinfo->symtab_shndx_start = (void *)hdr +\n+\t\t\t sechdrs[i].sh_offset;\n+\t\t\tinfo->symtab_shndx_stop = (void *)hdr +\n+\t\t\t sechdrs[i].sh_offset + sechdrs[i].sh_size;\n+\t\t}\n+\t}\n+\tif (!info->symtab_start)\n+\t\tfprintf(stderr, \"%s has no symtab?\\n\", filename);\n+\n+\t/* Fix endianness in symbols */\n+\tfor (sym = info->symtab_start; sym < info->symtab_stop; sym++) {\n+\t\tsym->st_shndx = TO_NATIVE(sym->st_shndx);\n+\t\tsym->st_name = TO_NATIVE(sym->st_name);\n+\t\tsym->st_value = TO_NATIVE(sym->st_value);\n+\t\tsym->st_size = TO_NATIVE(sym->st_size);\n+\t}\n+\n+\tif (symtab_shndx_idx != ~0U) {\n+\t\tElf32_Word *p;\n+\t\tif (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)\n+\t\t\tfprintf(stderr, \"%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\\n\",\n+\t\t\t filename, sechdrs[symtab_shndx_idx].sh_link,\n+\t\t\t symtab_idx);\n+\t\t/* Fix endianness */\n+\t\tfor (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;\n+\t\t p++)\n+\t\t\t*p = TO_NATIVE(*p);\n+\t}\n+\n+\treturn 1;\n+}\n+\n+static void parse_elf_finish(struct elf_info *info)\n+{\n+\tstruct pmd_driver *tmp, *idx = info->drivers;\n+\trelease_file(info->hdr, info->size);\n+\twhile (idx) {\n+\t\ttmp = idx->next;\n+\t\tfree(idx);\n+\t\tidx = tmp;\n+\t}\n+}\n+\n+static const char *sec_name(struct elf_info *elf, int secindex)\n+{\n+\tElf_Shdr *sechdrs = elf->sechdrs;\n+\treturn (void *)elf->hdr +\n+\t\telf->sechdrs[elf->secindex_strings].sh_offset +\n+\t\tsechdrs[secindex].sh_name;\n+}\n+\n+static int get_symbol_index(struct elf_info *info, Elf64_Sym *sym)\n+{\n+\tconst char *name = sym_name(info, sym);\n+\tconst char *idx;\n+\n+\tidx = name;\n+\twhile (idx) {\n+\t\tif (isdigit(*idx))\n+\t\t\treturn atoi(idx);\n+\t\tidx++;\n+\t}\n+\treturn -1;\n+}\n+\n+struct opt_tag {\n+\tconst char* suffix;\n+\tconst char* json_id;\n+};\n+\n+static const struct opt_tag opt_tags[] = {\n+\t{\"_param_string_export\", \"params\"},\n+};\n+\n+static int complete_pmd_entry(struct elf_info *info, struct pmd_driver *drv)\n+{\n+\tconst char *tname;\n+\tint i;\n+\tchar tmpsymname[128];\n+\tElf_Sym *tmpsym;\n+\t\n+\n+\tdrv->name = get_sym_value(info, drv->name_sym);\n+\n+\tfor (i=0; i<PMD_OPT_MAX; i++) {\n+\t\tmemset(tmpsymname, 0, 128);\n+\t\tsprintf(tmpsymname, \"%s%s\", drv->name, opt_tags[i].suffix);\n+\t\ttmpsym = find_sym_in_symtab(info, tmpsymname, NULL);\n+\t\tif (!tmpsym)\n+\t\t\tcontinue;\n+\t\tdrv->opt_vals[i] = get_sym_value(info, tmpsym);\n+\t}\n+\n+\tmemset(tmpsymname, 0, 128);\n+\tsprintf(tmpsymname, \"%s_pci_tbl_export\", drv->name);\n+\n+\ttmpsym = find_sym_in_symtab(info, tmpsymname, NULL);\n+\n+\n+\t/*\n+ \t * If this returns NULL, then this is a PMD_VDEV, because\n+ \t * it has no pci table reference\n+ \t */\n+\tif (!tmpsym) {\n+\t\tdrv->pci_tbl = NULL;\n+\t\treturn 0;\n+\t}\n+\n+\ttname = get_sym_value(info, tmpsym);\n+\ttmpsym = find_sym_in_symtab(info, tname, NULL);\n+\tif (!tmpsym)\n+\t\treturn -ENOENT;\n+\n+\tdrv->pci_tbl = (struct rte_pci_id *)get_sym_value(info, tmpsym);\n+\tif (!drv->pci_tbl)\n+\t\treturn -ENOENT;\n+\n+\n+\treturn 0;\n+\t\n+}\n+\n+static int locate_pmd_entries(struct elf_info *info)\n+{\n+\tElf_Sym *last = NULL;\n+\tstruct pmd_driver *new;\n+\n+\tinfo->drivers = NULL;\n+\n+\tdo {\n+\t\tnew = calloc(sizeof(struct pmd_driver), 1);\n+\t\tnew->name_sym = find_sym_in_symtab(info, \"this_pmd_name\", last);\n+\t\tlast = new->name_sym;\n+\t\tif (!new->name_sym)\n+\t\t\tfree(new);\n+\t\telse {\n+\t\t\tif (complete_pmd_entry(info, new)) {\n+\t\t\t\tfprintf(stderr, \"Failed to complete pmd entry\\n\");\n+\t\t\t\tfree(new);\n+\t\t\t} else {\n+\t\t\t\tnew->next = info->drivers;\n+\t\t\t\tinfo->drivers = new;\n+\t\t\t}\n+\t\t}\n+\t} while (last);\n+}\n+\n+static void output_pmd_info_string(struct elf_info *info, char *outfile)\n+{\n+\tFILE *ofd;\n+\tstruct pmd_driver *drv;\n+\tstruct rte_pci_id *pci_ids;\n+\tint idx = 0;\n+\n+\tofd = fopen(outfile, \"w+\");\n+\tif (!ofd) {\n+\t\tfprintf(stderr, \"Unable to open output file\\n\");\n+\t\treturn;\n+\t}\n+\n+\tdrv = info->drivers;\n+\n+\twhile (drv) {\n+\t\tfprintf(ofd, \"const char %s_pmd_info[] __attribute__((used)) = \\\"PMD_INFO_STRING= {\",\n+\t\t\tdrv->name);\n+\t\tfprintf(ofd,\"\\\\\\\"name\\\\\\\" : \\\\\\\"%s\\\\\\\", \", drv->name);\n+\t\tfprintf(ofd,\"\\\\\\\"type\\\\\\\" : \\\\\\\"%s\\\\\\\", \", drv->pci_tbl ? \"PMD_PDEV\" : \"PMD_VDEV\");\n+\n+\t\tfor(idx=0; idx<PMD_OPT_MAX; idx++) {\n+\t\t\tif (drv->opt_vals[idx])\n+\t\t\t\tfprintf(ofd,\"\\\\\\\"%s\\\\\\\" : \\\\\\\"%s\\\\\\\", \", opt_tags[idx].json_id,\n+\t\t\t\t\tdrv->opt_vals[idx]);\n+\t\t}\n+\n+\t\tpci_ids = drv->pci_tbl;\n+\t\tfprintf(ofd, \"\\\\\\\"pci_ids\\\\\\\" : [\");\n+\n+\t\twhile (pci_ids && pci_ids->device_id) {\n+\t\t\tfprintf(ofd, \"[%d, %d, %d, %d]\",\n+\t\t\t\tpci_ids->vendor_id, pci_ids->device_id,\n+\t\t\t\tpci_ids->subsystem_vendor_id,\n+\t\t\t\tpci_ids->subsystem_device_id);\n+\t\t\tpci_ids++;\n+\t\t\tif (pci_ids->device_id)\n+\t\t\t\tfprintf(ofd, \",\");\n+\t\t\telse\n+\t\t\t\tfprintf(ofd, \" \");\n+\t\t}\n+\t\tfprintf(ofd, \"]}\\\";\");\n+\t\tdrv = drv->next;\n+\t}\n+\n+\tfclose(ofd);\n+}\n+\n+int main(int argc, char **argv)\n+{\n+\tstruct elf_info info;\n+\tint rc = 1;\n+\n+\tif (argc < 3) {\n+\t\tfprintf(stderr, \"usage: pmdinfo <object file> <c output file>\\n\");\n+\t\texit(127);\n+\t}\n+\tparse_elf(&info, argv[1]);\n+\n+\tlocate_pmd_entries(&info);\n+\n+\tif (info.drivers) {\n+\t\toutput_pmd_info_string(&info, argv[2]);\n+\t\trc = 0;\n+\t} else {\n+\t\tfprintf(stderr, \"Hmm, Appears to be a driver but no drivers registered\\n\");\n+\t}\n+\n+\tparse_elf_finish(&info);\n+\texit(rc);\n+}\ndiff --git a/buildtools/pmdinfogen/pmdinfogen.h b/buildtools/pmdinfogen/pmdinfogen.h\nnew file mode 100644\nindex 0000000..580ed9f\n--- /dev/null\n+++ b/buildtools/pmdinfogen/pmdinfogen.h\n@@ -0,0 +1,83 @@\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <stdarg.h>\n+#include <string.h>\n+#include <sys/types.h>\n+#include <sys/stat.h>\n+#include <sys/mman.h>\n+#include <fcntl.h>\n+#include <unistd.h>\n+#include <elf.h>\n+\n+\n+/* On BSD-alike OSes elf.h defines these according to host's word size */\n+#undef ELF_ST_BIND\n+#undef ELF_ST_TYPE\n+#undef ELF_R_SYM\n+#undef ELF_R_TYPE\n+\n+#define Elf_Ehdr Elf64_Ehdr\n+#define Elf_Shdr Elf64_Shdr\n+#define Elf_Sym Elf64_Sym\n+#define Elf_Addr Elf64_Addr\n+#define Elf_Sword Elf64_Sxword\n+#define Elf_Section Elf64_Half\n+#define ELF_ST_BIND ELF64_ST_BIND\n+#define ELF_ST_TYPE ELF64_ST_TYPE\n+\n+#define Elf_Rel Elf64_Rel\n+#define Elf_Rela Elf64_Rela\n+#define ELF_R_SYM ELF64_R_SYM\n+#define ELF_R_TYPE ELF64_R_TYPE\n+\n+#define TO_NATIVE(x) (x)\n+\n+\n+struct rte_pci_id {\n+\tuint16_t vendor_id; /**< Vendor ID or PCI_ANY_ID. */\n+\tuint16_t device_id; /**< Device ID or PCI_ANY_ID. */\n+\tuint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */\n+\tuint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */\n+};\n+\n+enum opt_params {\n+\tPMD_PARAM_STRING = 0,\n+\tPMD_OPT_MAX\n+};\n+\n+struct pmd_driver {\n+\tElf_Sym *name_sym;\n+\tconst char *name;\n+\tstruct rte_pci_id *pci_tbl;\n+\tstruct pmd_driver *next;\n+\n+\tconst char* opt_vals[PMD_OPT_MAX];\n+};\n+\n+struct elf_info {\n+\tunsigned long size;\n+\tElf_Ehdr *hdr;\n+\tElf_Shdr *sechdrs;\n+\tElf_Sym *symtab_start;\n+\tElf_Sym *symtab_stop;\n+\tElf_Section export_sec;\n+\tElf_Section export_unused_sec;\n+\tElf_Section export_gpl_sec;\n+\tElf_Section export_unused_gpl_sec;\n+\tElf_Section export_gpl_future_sec;\n+\tchar *strtab;\n+\tchar\t *modinfo;\n+\tunsigned int modinfo_len;\n+\n+\t/* support for 32bit section numbers */\n+\n+\tunsigned int num_sections; /* max_secindex + 1 */\n+\tunsigned int secindex_strings;\n+\t/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,\n+\t * take shndx from symtab_shndx_start[N] instead */\n+\tElf32_Word *symtab_shndx_start;\n+\tElf32_Word *symtab_shndx_stop;\n+\n+\tstruct pmd_driver *drivers;\n+};\n+\ndiff --git a/mk/rte.buildtools.mk b/mk/rte.buildtools.mk\nnew file mode 100644\nindex 0000000..e8bfcef\n--- /dev/null\n+++ b/mk/rte.buildtools.mk\n@@ -0,0 +1,148 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.\n+# Copyright(c) 2014-2015 6WIND S.A.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+# * Redistributions of source code must retain the above copyright\n+# notice, this list of conditions and the following disclaimer.\n+# * Redistributions in binary form must reproduce the above copyright\n+# notice, this list of conditions and the following disclaimer in\n+# the documentation and/or other materials provided with the\n+# distribution.\n+# * Neither the name of Intel Corporation nor the names of its\n+# contributors may be used to endorse or promote products derived\n+# from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/internal/rte.compile-pre.mk\n+include $(RTE_SDK)/mk/internal/rte.install-pre.mk\n+include $(RTE_SDK)/mk/internal/rte.clean-pre.mk\n+include $(RTE_SDK)/mk/internal/rte.build-pre.mk\n+include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk\n+\n+# VPATH contains at least SRCDIR\n+VPATH += $(SRCDIR)\n+\n+_BUILD = $(APP)\n+_INSTALL = $(INSTALL-FILES-y) $(SYMLINK-FILES-y)\n+_INSTALL += $(RTE_OUTPUT)/buildtools/$(APP) $(RTE_OUTPUT)/buildtools/$(APP).map\n+POSTINSTALL += target-appinstall\n+_CLEAN = doclean\n+POSTCLEAN += target-appclean\n+\n+.PHONY: all\n+all: install\n+\n+.PHONY: install\n+install: build _postinstall\n+\n+_postinstall: build\n+\n+.PHONY: build\n+build: _postbuild\n+\n+exe2cmd = $(strip $(call dotfile,$(patsubst %,%.cmd,$(1))))\n+\n+ifeq ($(LINK_USING_CC),1)\n+override EXTRA_LDFLAGS := $(call linkerprefix,$(EXTRA_LDFLAGS))\n+O_TO_EXE = $(CC) $(CFLAGS) $(LDFLAGS_$(@)) \\\n+\t-Wl,-Map=$(@).map,--cref -o $@ $(OBJS-y) $(call linkerprefix,$(LDFLAGS)) \\\n+\t$(EXTRA_LDFLAGS) $(call linkerprefix,$(LDLIBS))\n+else\n+O_TO_EXE = $(LD) $(LDFLAGS) $(LDFLAGS_$(@)) $(EXTRA_LDFLAGS) \\\n+\t-Map=$(@).map --cref -o $@ $(OBJS-y) $(LDLIBS)\n+endif\n+O_TO_EXE_STR = $(subst ','\\'',$(O_TO_EXE)) #'# fix syntax highlight\n+O_TO_EXE_DISP = $(if $(V),\"$(O_TO_EXE_STR)\",\" LD $(@)\")\n+O_TO_EXE_CMD = \"cmd_$@ = $(O_TO_EXE_STR)\"\n+O_TO_EXE_DO = @set -e; \\\n+\techo $(O_TO_EXE_DISP); \\\n+\t$(O_TO_EXE) && \\\n+\techo $(O_TO_EXE_CMD) > $(call exe2cmd,$(@))\n+\n+-include .$(APP).cmd\n+\n+# path where libraries are retrieved\n+LDLIBS_PATH := $(subst -Wl$(comma)-L,,$(filter -Wl$(comma)-L%,$(LDLIBS)))\n+LDLIBS_PATH += $(subst -L,,$(filter -L%,$(LDLIBS)))\n+\n+# list of .a files that are linked to this application\n+LDLIBS_NAMES := $(patsubst -l%,lib%.a,$(filter -l%,$(LDLIBS)))\n+LDLIBS_NAMES += $(patsubst -Wl$(comma)-l%,lib%.a,$(filter -Wl$(comma)-l%,$(LDLIBS)))\n+\n+# list of found libraries files (useful for deps). If not found, the\n+# library is silently ignored and dep won't be checked\n+LDLIBS_FILES := $(wildcard $(foreach dir,$(LDLIBS_PATH),\\\n+\t$(addprefix $(dir)/,$(LDLIBS_NAMES))))\n+\n+#\n+# Compile executable file if needed\n+#\n+$(APP): $(OBJS-y) $(LDLIBS_FILES) $(DEP_$(APP)) $(LDSCRIPT) FORCE\n+\t@[ -d $(dir $@) ] || mkdir -p $(dir $@)\n+\t$(if $(D),\\\n+\t\t@echo -n \"$< -> $@ \" ; \\\n+\t\techo -n \"file_missing=$(call boolean,$(file_missing)) \" ; \\\n+\t\techo -n \"cmdline_changed=$(call boolean,$(call cmdline_changed,$(O_TO_EXE_STR))) \" ; \\\n+\t\techo -n \"depfile_missing=$(call boolean,$(depfile_missing)) \" ; \\\n+\t\techo \"depfile_newer=$(call boolean,$(depfile_newer)) \")\n+\t$(if $(or \\\n+\t\t$(file_missing),\\\n+\t\t$(call cmdline_changed,$(O_TO_EXE_STR)),\\\n+\t\t$(depfile_missing),\\\n+\t\t$(depfile_newer)),\\\n+\t\t$(O_TO_EXE_DO))\n+\n+#\n+# install app in $(RTE_OUTPUT)/app\n+#\n+$(RTE_OUTPUT)/buildtools/$(APP): $(APP)\n+\t@echo \" INSTALL-APP $(APP)\"\n+\t@[ -d $(RTE_OUTPUT)/buildtools ] || mkdir -p $(RTE_OUTPUT)/buildtools\n+\t$(Q)cp -f $(APP) $(RTE_OUTPUT)/buildtools\n+\n+#\n+# install app map file in $(RTE_OUTPUT)/app\n+#\n+$(RTE_OUTPUT)/buildtools/$(APP).map: $(APP)\n+\t@echo \" INSTALL-MAP $(APP).map\"\n+\t@[ -d $(RTE_OUTPUT)/buildtools ] || mkdir -p $(RTE_OUTPUT)/buildtools\n+\t$(Q)cp -f $(APP).map $(RTE_OUTPUT)/buildtools\n+\n+#\n+# Clean all generated files\n+#\n+.PHONY: clean\n+clean: _postclean\n+\t$(Q)rm -f $(_BUILD_TARGETS) $(_INSTALL_TARGETS) $(_CLEAN_TARGETS)\n+\n+.PHONY: doclean\n+doclean:\n+\t$(Q)rm -rf $(APP) $(OBJS-all) $(DEPS-all) $(DEPSTMP-all) \\\n+\t $(CMDS-all) $(INSTALL-FILES-all) .$(APP).cmd\n+\n+\n+include $(RTE_SDK)/mk/internal/rte.compile-post.mk\n+include $(RTE_SDK)/mk/internal/rte.install-post.mk\n+include $(RTE_SDK)/mk/internal/rte.clean-post.mk\n+include $(RTE_SDK)/mk/internal/rte.build-post.mk\n+include $(RTE_SDK)/mk/internal/rte.depdirs-post.mk\n+\n+.PHONY: FORCE\n+FORCE:\ndiff --git a/mk/rte.sdkbuild.mk b/mk/rte.sdkbuild.mk\nindex eec5241..fb68af2 100644\n--- a/mk/rte.sdkbuild.mk\n+++ b/mk/rte.sdkbuild.mk\n@@ -64,7 +64,8 @@ build: $(ROOTDIRS-y)\n clean: $(CLEANDIRS)\n \t@rm -rf $(RTE_OUTPUT)/include $(RTE_OUTPUT)/app \\\n \t\t$(RTE_OUTPUT)/hostapp $(RTE_OUTPUT)/lib \\\n-\t\t$(RTE_OUTPUT)/hostlib $(RTE_OUTPUT)/kmod\n+\t\t$(RTE_OUTPUT)/hostlib $(RTE_OUTPUT)/kmod \\\n+\t\t$(RTE_OUTPUT)/buildtools\n \t@[ -d $(RTE_OUTPUT)/include ] || mkdir -p $(RTE_OUTPUT)/include\n \t@$(RTE_SDK)/scripts/gen-config-h.sh $(RTE_OUTPUT)/.config \\\n \t\t> $(RTE_OUTPUT)/include/rte_config.h\n", "prefixes": [ "dpdk-dev", "PATCHv2", "1/4" ] }{ "id": 12886, "url": "