[dpdk-dev,PATCHv6,1/7] pmdinfogen: Add buildtools and pmdinfogen utility

Message ID 1464703068-2924-2-git-send-email-nhorman@tuxdriver.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers

Commit Message

Neil Horman May 31, 2016, 1:57 p.m. UTC
pmdinfogen is a tool used to parse object files and build json strings for use in
later determining hardware support in a dso or application binary.  pmdinfo
looks for the non-exported symbol names this_pmd_name<n> and this_pmd_tbl<n>
(where n is a integer counter).  It records the name of each of these tuples,
using the later to find the symbolic name of the pci_table for physical devices
that the object supports.  With this information, it outputs a C file with a
single line of the form:

static char *<pmd_name>_driver_info[] __attribute__((used)) = " \
	PMD_DRIVER_INFO=<json string>";

Where <pmd_name> is the arbitrary name of the pmd, and <json_string> is the json
encoded string that hold relevant pmd information, including the pmd name, type
and optional array of pci device/vendor ids that the driver supports.

This c file is suitable for compiling to object code, then relocatably linking
into the parent file from which the C was generated.  This creates an entry in
the string table of the object that can inform a later tool about hardware
support.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Bruce Richardson <bruce.richardson@intel.com>
CC: Thomas Monjalon <thomas.monjalon@6wind.com>
CC: Stephen Hemminger <stephen@networkplumber.org>
CC: Panu Matilainen <pmatilai@redhat.com>
---
 GNUmakefile                        |   2 +-
 buildtools/Makefile                |  36 ++++
 buildtools/pmdinfogen/Makefile     |  49 +++++
 buildtools/pmdinfogen/pmdinfogen.c | 410 +++++++++++++++++++++++++++++++++++++
 buildtools/pmdinfogen/pmdinfogen.h |  94 +++++++++
 mk/rte.buildtools.mk               | 148 +++++++++++++
 mk/rte.sdkbuild.mk                 |   3 +-
 7 files changed, 740 insertions(+), 2 deletions(-)
 create mode 100644 buildtools/Makefile
 create mode 100644 buildtools/pmdinfogen/Makefile
 create mode 100644 buildtools/pmdinfogen/pmdinfogen.c
 create mode 100644 buildtools/pmdinfogen/pmdinfogen.h
 create mode 100644 mk/rte.buildtools.mk
  

Comments

Thomas Monjalon June 7, 2016, 9:57 a.m. UTC | #1
2016-05-31 09:57, Neil Horman:
> +++ b/buildtools/Makefile
> @@ -0,0 +1,36 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> +#   All rights reserved.

I really think it is a strange copyright for a new empty file.

> +#if __x86_64__ || __aarch64__

Better to use CONFIG_RTE_ARCH_64.

> +#define TO_NATIVE(x) (x)

We already have some functions for endianness in
lib/librte_eal/common/include/generic/rte_byteorder.h

> +struct elf_info {
> +	unsigned long size;
> +	Elf_Ehdr     *hdr;
> +	Elf_Shdr     *sechdrs;
> +	Elf_Sym      *symtab_start;
> +	Elf_Sym      *symtab_stop;
> +	Elf_Section  export_sec;
> +	Elf_Section  export_unused_sec;
> +	Elf_Section  export_gpl_sec;
> +	Elf_Section  export_unused_gpl_sec;
> +	Elf_Section  export_gpl_future_sec;
> +	char         *strtab;

The export_* fields are not used.

> --- /dev/null
> +++ b/mk/rte.buildtools.mk

I'm sorry I really do not agree it is a good practice to create a new
makefile type just for a new directory.
My opinion is that you should use and improve rte.hostapp.mk to make
it usable for possible other host apps.
  
Neil Horman June 7, 2016, 12:04 p.m. UTC | #2
On Tue, Jun 07, 2016 at 11:57:42AM +0200, Thomas Monjalon wrote:
> 2016-05-31 09:57, Neil Horman:
> > +++ b/buildtools/Makefile
> > @@ -0,0 +1,36 @@
> > +#   BSD LICENSE
> > +#
> > +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > +#   All rights reserved.
> 
> I really think it is a strange copyright for a new empty file.
> 
Its not empty, It lists the subdirectories to build.  And given that the DPDK is
licensed under multiple licenses (BSD/GPL/LGPL), it introduces confusion to not
call out the license in a specific file, file size is really irrelevant to that.

> > +#if __x86_64__ || __aarch64__
> 
> Better to use CONFIG_RTE_ARCH_64.
> 
I'm not sure why, given that every supported compiler defines the arches I use,
but sure, fine.

> > +#define TO_NATIVE(x) (x)
> 
> We already have some functions for endianness in
> lib/librte_eal/common/include/generic/rte_byteorder.h
> 
Very well, I'll use the rte byteorder macros.

> > +struct elf_info {
> > +	unsigned long size;
> > +	Elf_Ehdr     *hdr;
> > +	Elf_Shdr     *sechdrs;
> > +	Elf_Sym      *symtab_start;
> > +	Elf_Sym      *symtab_stop;
> > +	Elf_Section  export_sec;
> > +	Elf_Section  export_unused_sec;
> > +	Elf_Section  export_gpl_sec;
> > +	Elf_Section  export_unused_gpl_sec;
> > +	Elf_Section  export_gpl_future_sec;
> > +	char         *strtab;
> 
> The export_* fields are not used.
> 
Fine, I'll remove them.

> > --- /dev/null
> > +++ b/mk/rte.buildtools.mk
> 
> I'm sorry I really do not agree it is a good practice to create a new
> makefile type just for a new directory.
> My opinion is that you should use and improve rte.hostapp.mk to make
> it usable for possible other host apps.
> 
I am so exhausted by this argument.

They are the same file Thomas.  I'm not sure how you don't see that.  I've
explained to you that they are, with the exception of whitespace noise,
identical.  buildtools is a better nomenclature because it more closely
describes what is being built at the moment.  The only reason we still have
hostapp is because you didn't remove it when you removed the applications that,
in your own words from the commit log, are "useless".  The argument that we
should keep the build file, and its naming convention on the off chance that
someone might use it in the future really doesn't hold water with me, at least
not to the point that, when we have something that duplicates its function we
should do anything other than take the path of least resistance to make it work.
I'm not sure how you expected anyone to know there is a makefile in place in the
DPDK to build local application, when there are currently no applications in
place, but asking people to use it after the fact is really just the height of
busywork.  If it was already building other utilities, I'd feel differently, but
given that its just sitting there, a vestigual file, makes this all just silly.

But clearly, this isn't going to be done until I do what you want, regardless of
what either of us think of it, So I'll make the change.

Neil
  
Thomas Monjalon June 7, 2016, 12:53 p.m. UTC | #3
2016-06-07 08:04, Neil Horman:
> On Tue, Jun 07, 2016 at 11:57:42AM +0200, Thomas Monjalon wrote:
> > 2016-05-31 09:57, Neil Horman:
> > > +++ b/buildtools/Makefile
> > > @@ -0,0 +1,36 @@
> > > +#   BSD LICENSE
> > > +#
> > > +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > > +#   All rights reserved.
> > 
> > I really think it is a strange copyright for a new empty file.
> > 
> Its not empty, It lists the subdirectories to build.  And given that the DPDK is
> licensed under multiple licenses (BSD/GPL/LGPL), it introduces confusion to not
> call out the license in a specific file, file size is really irrelevant to that.

Neil, please take a drink :)
I'm not talking about license but about copyright.
Don't you think it's strange to put "2010-2014 Intel" copyright on top of
the few lines you wrote?
 
> > > +#if __x86_64__ || __aarch64__
> > 
> > Better to use CONFIG_RTE_ARCH_64.
> > 
> I'm not sure why, given that every supported compiler defines the arches I use,
> but sure, fine.

Because it will work for every 64-bit arch in DPDK.

> > > --- /dev/null
> > > +++ b/mk/rte.buildtools.mk
> > 
> > I'm sorry I really do not agree it is a good practice to create a new
> > makefile type just for a new directory.
> > My opinion is that you should use and improve rte.hostapp.mk to make
> > it usable for possible other host apps.
> > 
> I am so exhausted by this argument.
> 
> They are the same file Thomas.  I'm not sure how you don't see that.  I've
> explained to you that they are, with the exception of whitespace noise,
> identical.  buildtools is a better nomenclature because it more closely
> describes what is being built at the moment.  The only reason we still have
> hostapp is because you didn't remove it when you removed the applications that,
> in your own words from the commit log, are "useless".  The argument that we
> should keep the build file, and its naming convention on the off chance that
> someone might use it in the future really doesn't hold water with me, at least
> not to the point that, when we have something that duplicates its function we
> should do anything other than take the path of least resistance to make it work.
> I'm not sure how you expected anyone to know there is a makefile in place in the
> DPDK to build local application, when there are currently no applications in
> place, but asking people to use it after the fact is really just the height of
> busywork.  If it was already building other utilities, I'd feel differently, but
> given that its just sitting there, a vestigual file, makes this all just silly.
> 
> But clearly, this isn't going to be done until I do what you want, regardless of
> what either of us think of it, So I'll make the change.

You can keep it as is if you find someone else to say that having a makefile
template named and specific to only the buildtools usage is fine.
And no, it is not identical to rte.hostapp.mk.
But I was probably not clear enough:
I do not like rte.hostapp.mk. I just like its explicit name.
I see the same issue in rte.hostapp.mk and rte.buildtools.mk: they should be
build in the app/ subdir like any other app.

So my suggestion is to replace rte.hostapp.mk with your implementation in
a separate patch with the build path changed to app/ instead of hostapp/ or
buildtools/.
  
Neil Horman June 7, 2016, 1:03 p.m. UTC | #4
On Tue, Jun 07, 2016 at 02:53:36PM +0200, Thomas Monjalon wrote:
> 2016-06-07 08:04, Neil Horman:
> > On Tue, Jun 07, 2016 at 11:57:42AM +0200, Thomas Monjalon wrote:
> > > 2016-05-31 09:57, Neil Horman:
> > > > +++ b/buildtools/Makefile
> > > > @@ -0,0 +1,36 @@
> > > > +#   BSD LICENSE
> > > > +#
> > > > +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > > > +#   All rights reserved.
> > > 
> > > I really think it is a strange copyright for a new empty file.
> > > 
> > Its not empty, It lists the subdirectories to build.  And given that the DPDK is
> > licensed under multiple licenses (BSD/GPL/LGPL), it introduces confusion to not
> > call out the license in a specific file, file size is really irrelevant to that.
> 
> Neil, please take a drink :)
> I'm not talking about license but about copyright.
> Don't you think it's strange to put "2010-2014 Intel" copyright on top of
> the few lines you wrote?
>  
Ah, yes, I copied the file, so the copyright years are wrong, so that should be
fixed.

That said, you asked if it was strange to put a copyright on an empty file, and
the answer is no, because its not empty, and it nees a copyright for clarity :)

> > > > +#if __x86_64__ || __aarch64__
> > > 
> > > Better to use CONFIG_RTE_ARCH_64.
> > > 
> > I'm not sure why, given that every supported compiler defines the arches I use,
> > but sure, fine.
> 
> Because it will work for every 64-bit arch in DPDK.
> 
Ok, fair enough.

> > > > --- /dev/null
> > > > +++ b/mk/rte.buildtools.mk
> > > 
> > > I'm sorry I really do not agree it is a good practice to create a new
> > > makefile type just for a new directory.
> > > My opinion is that you should use and improve rte.hostapp.mk to make
> > > it usable for possible other host apps.
> > > 
> > I am so exhausted by this argument.
> > 
> > They are the same file Thomas.  I'm not sure how you don't see that.  I've
> > explained to you that they are, with the exception of whitespace noise,
> > identical.  buildtools is a better nomenclature because it more closely
> > describes what is being built at the moment.  The only reason we still have
> > hostapp is because you didn't remove it when you removed the applications that,
> > in your own words from the commit log, are "useless".  The argument that we
> > should keep the build file, and its naming convention on the off chance that
> > someone might use it in the future really doesn't hold water with me, at least
> > not to the point that, when we have something that duplicates its function we
> > should do anything other than take the path of least resistance to make it work.
> > I'm not sure how you expected anyone to know there is a makefile in place in the
> > DPDK to build local application, when there are currently no applications in
> > place, but asking people to use it after the fact is really just the height of
> > busywork.  If it was already building other utilities, I'd feel differently, but
> > given that its just sitting there, a vestigual file, makes this all just silly.
> > 
> > But clearly, this isn't going to be done until I do what you want, regardless of
> > what either of us think of it, So I'll make the change.
> 
> You can keep it as is if you find someone else to say that having a makefile
> template named and specific to only the buildtools usage is fine.
> And no, it is not identical to rte.hostapp.mk.
> But I was probably not clear enough:
> I do not like rte.hostapp.mk. I just like its explicit name.
> I see the same issue in rte.hostapp.mk and rte.buildtools.mk: they should be
> build in the app/ subdir like any other app.
> 
> So my suggestion is to replace rte.hostapp.mk with your implementation in
> a separate patch with the build path changed to app/ instead of hostapp/ or
> buildtools/.
> 
Soo, I'm confused now.  You don't want rte.buildtools.mk, and you don't really
want rte.hostapp.mk, you want a different makefile, that just builds to the /app
subdirectory?

Neil
  
Thomas Monjalon June 7, 2016, 1:24 p.m. UTC | #5
2016-06-07 09:03, Neil Horman:
> On Tue, Jun 07, 2016 at 02:53:36PM +0200, Thomas Monjalon wrote:
> > 2016-06-07 08:04, Neil Horman:
> > > On Tue, Jun 07, 2016 at 11:57:42AM +0200, Thomas Monjalon wrote:
> > > > 2016-05-31 09:57, Neil Horman:
> > > > > +++ b/buildtools/Makefile
> > > > > @@ -0,0 +1,36 @@
> > > > > +#   BSD LICENSE
> > > > > +#
> > > > > +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > > > > +#   All rights reserved.
> > > > 
> > > > I really think it is a strange copyright for a new empty file.
> > > > 
> > > Its not empty, It lists the subdirectories to build.  And given that the DPDK is
> > > licensed under multiple licenses (BSD/GPL/LGPL), it introduces confusion to not
> > > call out the license in a specific file, file size is really irrelevant to that.
> > 
> > Neil, please take a drink :)
> > I'm not talking about license but about copyright.
> > Don't you think it's strange to put "2010-2014 Intel" copyright on top of
> > the few lines you wrote?
> >  
> Ah, yes, I copied the file, so the copyright years are wrong, so that should be
> fixed.

Not only the years, the copyright holder should be you or your company.

> That said, you asked if it was strange to put a copyright on an empty file, and
> the answer is no, because its not empty, and it nees a copyright for clarity :)

Of course, yes.

> > > > > --- /dev/null
> > > > > +++ b/mk/rte.buildtools.mk
> > > > 
> > > > I'm sorry I really do not agree it is a good practice to create a new
> > > > makefile type just for a new directory.
> > > > My opinion is that you should use and improve rte.hostapp.mk to make
> > > > it usable for possible other host apps.
> > > > 
> > > I am so exhausted by this argument.
> > > 
> > > They are the same file Thomas.  I'm not sure how you don't see that.  I've
> > > explained to you that they are, with the exception of whitespace noise,
> > > identical.  buildtools is a better nomenclature because it more closely
> > > describes what is being built at the moment.  The only reason we still have
> > > hostapp is because you didn't remove it when you removed the applications that,
> > > in your own words from the commit log, are "useless".  The argument that we
> > > should keep the build file, and its naming convention on the off chance that
> > > someone might use it in the future really doesn't hold water with me, at least
> > > not to the point that, when we have something that duplicates its function we
> > > should do anything other than take the path of least resistance to make it work.
> > > I'm not sure how you expected anyone to know there is a makefile in place in the
> > > DPDK to build local application, when there are currently no applications in
> > > place, but asking people to use it after the fact is really just the height of
> > > busywork.  If it was already building other utilities, I'd feel differently, but
> > > given that its just sitting there, a vestigual file, makes this all just silly.
> > > 
> > > But clearly, this isn't going to be done until I do what you want, regardless of
> > > what either of us think of it, So I'll make the change.
> > 
> > You can keep it as is if you find someone else to say that having a makefile
> > template named and specific to only the buildtools usage is fine.
> > And no, it is not identical to rte.hostapp.mk.
> > But I was probably not clear enough:
> > I do not like rte.hostapp.mk. I just like its explicit name.
> > I see the same issue in rte.hostapp.mk and rte.buildtools.mk: they should be
> > build in the app/ subdir like any other app.
> > 
> > So my suggestion is to replace rte.hostapp.mk with your implementation in
> > a separate patch with the build path changed to app/ instead of hostapp/ or
> > buildtools/.
> > 
> Soo, I'm confused now.  You don't want rte.buildtools.mk, and you don't really
> want rte.hostapp.mk, you want a different makefile, that just builds to the /app
> subdirectory?

The apps and examples use rte.app.mk to build a DPDK app.
Here you make a standard app, without DPDK dependency, to run on the host.
So you cannot use rte.app.mk. I think rte.hostapp.mk is not a so bad name
(I have no better one).
About the build directory, the app/ one looks OK, no need to put a reference
to buildtools which is just the user of this makefile.
Except these considerations, the content of your makefile is probably good.
  
Neil Horman June 7, 2016, 1:49 p.m. UTC | #6
On Tue, Jun 07, 2016 at 03:24:55PM +0200, Thomas Monjalon wrote:
> 2016-06-07 09:03, Neil Horman:
> > On Tue, Jun 07, 2016 at 02:53:36PM +0200, Thomas Monjalon wrote:
> > > 2016-06-07 08:04, Neil Horman:
> > > > On Tue, Jun 07, 2016 at 11:57:42AM +0200, Thomas Monjalon wrote:
> > > > > 2016-05-31 09:57, Neil Horman:
> > > > > > +++ b/buildtools/Makefile
> > > > > > @@ -0,0 +1,36 @@
> > > > > > +#   BSD LICENSE
> > > > > > +#
> > > > > > +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > > > > > +#   All rights reserved.
> > > > > 
> > > > > I really think it is a strange copyright for a new empty file.
> > > > > 
> > > > Its not empty, It lists the subdirectories to build.  And given that the DPDK is
> > > > licensed under multiple licenses (BSD/GPL/LGPL), it introduces confusion to not
> > > > call out the license in a specific file, file size is really irrelevant to that.
> > > 
> > > Neil, please take a drink :)
> > > I'm not talking about license but about copyright.
> > > Don't you think it's strange to put "2010-2014 Intel" copyright on top of
> > > the few lines you wrote?
> > >  
> > Ah, yes, I copied the file, so the copyright years are wrong, so that should be
> > fixed.
> 
> Not only the years, the copyright holder should be you or your company.
> 
> > That said, you asked if it was strange to put a copyright on an empty file, and
> > the answer is no, because its not empty, and it nees a copyright for clarity :)
> 
> Of course, yes.
> 
> > > > > > --- /dev/null
> > > > > > +++ b/mk/rte.buildtools.mk
> > > > > 
> > > > > I'm sorry I really do not agree it is a good practice to create a new
> > > > > makefile type just for a new directory.
> > > > > My opinion is that you should use and improve rte.hostapp.mk to make
> > > > > it usable for possible other host apps.
> > > > > 
> > > > I am so exhausted by this argument.
> > > > 
> > > > They are the same file Thomas.  I'm not sure how you don't see that.  I've
> > > > explained to you that they are, with the exception of whitespace noise,
> > > > identical.  buildtools is a better nomenclature because it more closely
> > > > describes what is being built at the moment.  The only reason we still have
> > > > hostapp is because you didn't remove it when you removed the applications that,
> > > > in your own words from the commit log, are "useless".  The argument that we
> > > > should keep the build file, and its naming convention on the off chance that
> > > > someone might use it in the future really doesn't hold water with me, at least
> > > > not to the point that, when we have something that duplicates its function we
> > > > should do anything other than take the path of least resistance to make it work.
> > > > I'm not sure how you expected anyone to know there is a makefile in place in the
> > > > DPDK to build local application, when there are currently no applications in
> > > > place, but asking people to use it after the fact is really just the height of
> > > > busywork.  If it was already building other utilities, I'd feel differently, but
> > > > given that its just sitting there, a vestigual file, makes this all just silly.
> > > > 
> > > > But clearly, this isn't going to be done until I do what you want, regardless of
> > > > what either of us think of it, So I'll make the change.
> > > 
> > > You can keep it as is if you find someone else to say that having a makefile
> > > template named and specific to only the buildtools usage is fine.
> > > And no, it is not identical to rte.hostapp.mk.
> > > But I was probably not clear enough:
> > > I do not like rte.hostapp.mk. I just like its explicit name.
> > > I see the same issue in rte.hostapp.mk and rte.buildtools.mk: they should be
> > > build in the app/ subdir like any other app.
> > > 
> > > So my suggestion is to replace rte.hostapp.mk with your implementation in
> > > a separate patch with the build path changed to app/ instead of hostapp/ or
> > > buildtools/.
> > > 
> > Soo, I'm confused now.  You don't want rte.buildtools.mk, and you don't really
> > want rte.hostapp.mk, you want a different makefile, that just builds to the /app
> > subdirectory?
> 
> The apps and examples use rte.app.mk to build a DPDK app.
> Here you make a standard app, without DPDK dependency, to run on the host.
> So you cannot use rte.app.mk. I think rte.hostapp.mk is not a so bad name
> (I have no better one).
> About the build directory, the app/ one looks OK, no need to put a reference
> to buildtools which is just the user of this makefile.
> Except these considerations, the content of your makefile is probably good.
> 

Sooo....you do actually want to just use the hostapp makefile, because you like
the name, and don't like mine, and you want to just dump the output into the
same app directory that all the dpdk examples get written to, because it looks
ok to you? 

Fine, whatever, I'm tired of arguing.
Neil
  
Thomas Monjalon June 7, 2016, 2:09 p.m. UTC | #7
2016-06-07 09:49, Neil Horman:
> On Tue, Jun 07, 2016 at 03:24:55PM +0200, Thomas Monjalon wrote:
> > 2016-06-07 09:03, Neil Horman:
> > > On Tue, Jun 07, 2016 at 02:53:36PM +0200, Thomas Monjalon wrote:
> > > > 2016-06-07 08:04, Neil Horman:
> > > > > On Tue, Jun 07, 2016 at 11:57:42AM +0200, Thomas Monjalon wrote:
> > > > > > 2016-05-31 09:57, Neil Horman:
> > > > > > > +++ b/buildtools/Makefile
> > > > > > > @@ -0,0 +1,36 @@
> > > > > > > +#   BSD LICENSE
> > > > > > > +#
> > > > > > > +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> > > > > > > +#   All rights reserved.
> > > > > > 
> > > > > > I really think it is a strange copyright for a new empty file.
> > > > > > 
> > > > > Its not empty, It lists the subdirectories to build.  And given that the DPDK is
> > > > > licensed under multiple licenses (BSD/GPL/LGPL), it introduces confusion to not
> > > > > call out the license in a specific file, file size is really irrelevant to that.
> > > > 
> > > > Neil, please take a drink :)
> > > > I'm not talking about license but about copyright.
> > > > Don't you think it's strange to put "2010-2014 Intel" copyright on top of
> > > > the few lines you wrote?
> > > >  
> > > Ah, yes, I copied the file, so the copyright years are wrong, so that should be
> > > fixed.
> > 
> > Not only the years, the copyright holder should be you or your company.
> > 
> > > That said, you asked if it was strange to put a copyright on an empty file, and
> > > the answer is no, because its not empty, and it nees a copyright for clarity :)
> > 
> > Of course, yes.
> > 
> > > > > > > --- /dev/null
> > > > > > > +++ b/mk/rte.buildtools.mk
> > > > > > 
> > > > > > I'm sorry I really do not agree it is a good practice to create a new
> > > > > > makefile type just for a new directory.
> > > > > > My opinion is that you should use and improve rte.hostapp.mk to make
> > > > > > it usable for possible other host apps.
> > > > > > 
> > > > > I am so exhausted by this argument.
> > > > > 
> > > > > They are the same file Thomas.  I'm not sure how you don't see that.  I've
> > > > > explained to you that they are, with the exception of whitespace noise,
> > > > > identical.  buildtools is a better nomenclature because it more closely
> > > > > describes what is being built at the moment.  The only reason we still have
> > > > > hostapp is because you didn't remove it when you removed the applications that,
> > > > > in your own words from the commit log, are "useless".  The argument that we
> > > > > should keep the build file, and its naming convention on the off chance that
> > > > > someone might use it in the future really doesn't hold water with me, at least
> > > > > not to the point that, when we have something that duplicates its function we
> > > > > should do anything other than take the path of least resistance to make it work.
> > > > > I'm not sure how you expected anyone to know there is a makefile in place in the
> > > > > DPDK to build local application, when there are currently no applications in
> > > > > place, but asking people to use it after the fact is really just the height of
> > > > > busywork.  If it was already building other utilities, I'd feel differently, but
> > > > > given that its just sitting there, a vestigual file, makes this all just silly.
> > > > > 
> > > > > But clearly, this isn't going to be done until I do what you want, regardless of
> > > > > what either of us think of it, So I'll make the change.
> > > > 
> > > > You can keep it as is if you find someone else to say that having a makefile
> > > > template named and specific to only the buildtools usage is fine.
> > > > And no, it is not identical to rte.hostapp.mk.
> > > > But I was probably not clear enough:
> > > > I do not like rte.hostapp.mk. I just like its explicit name.
> > > > I see the same issue in rte.hostapp.mk and rte.buildtools.mk: they should be
> > > > build in the app/ subdir like any other app.
> > > > 
> > > > So my suggestion is to replace rte.hostapp.mk with your implementation in
> > > > a separate patch with the build path changed to app/ instead of hostapp/ or
> > > > buildtools/.
> > > > 
> > > Soo, I'm confused now.  You don't want rte.buildtools.mk, and you don't really
> > > want rte.hostapp.mk, you want a different makefile, that just builds to the /app
> > > subdirectory?
> > 
> > The apps and examples use rte.app.mk to build a DPDK app.
> > Here you make a standard app, without DPDK dependency, to run on the host.
> > So you cannot use rte.app.mk. I think rte.hostapp.mk is not a so bad name
> > (I have no better one).
> > About the build directory, the app/ one looks OK, no need to put a reference
> > to buildtools which is just the user of this makefile.
> > Except these considerations, the content of your makefile is probably good.
> > 
> 
> Sooo....you do actually want to just use the hostapp makefile, because you like
> the name, and don't like mine, and you want to just dump the output into the
> same app directory that all the dpdk examples get written to, because it looks
> ok to you? 

No.
Your Makefile is fine. I just suggest to rename it to rte.hostapp.mk.
The examples are not built in the app/ directory.
But you can do what you want. I'm just suggesting.

By the way, please use checkpatch.sh.
  

Patch

diff --git a/GNUmakefile b/GNUmakefile
index b59e4b6..00fe0db 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -40,6 +40,6 @@  export RTE_SDK
 # directory list
 #
 
-ROOTDIRS-y := lib drivers app
+ROOTDIRS-y := buildtools lib drivers app
 
 include $(RTE_SDK)/mk/rte.sdkroot.mk
diff --git a/buildtools/Makefile b/buildtools/Makefile
new file mode 100644
index 0000000..eb565eb
--- /dev/null
+++ b/buildtools/Makefile
@@ -0,0 +1,36 @@ 
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   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 Intel Corporation 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
+
+DIRS-y += pmdinfogen
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/buildtools/pmdinfogen/Makefile b/buildtools/pmdinfogen/Makefile
new file mode 100644
index 0000000..223f50c
--- /dev/null
+++ b/buildtools/pmdinfogen/Makefile
@@ -0,0 +1,49 @@ 
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   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 Intel Corporation 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
+
+#
+# library name
+#
+APP = pmdinfogen
+
+#
+# all sources are stored in SRCS-y
+#
+SRCS-y += pmdinfogen.c
+
+CFLAGS += -g
+
+DEPDIRS-y += lib/librte_eal
+
+include $(RTE_SDK)/mk/rte.buildtools.mk
+
diff --git a/buildtools/pmdinfogen/pmdinfogen.c b/buildtools/pmdinfogen/pmdinfogen.c
new file mode 100644
index 0000000..ee2b606
--- /dev/null
+++ b/buildtools/pmdinfogen/pmdinfogen.c
@@ -0,0 +1,410 @@ 
+/* Postprocess pmd object files to export hw support 
+ *
+ * Copyright 2016 Neil Horman <nhorman@tuxdriver.com>
+ * Based in part on modpost.c from the linux kernel
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License V2, incorporated herein by reference.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <errno.h>
+#include "pmdinfogen.h"
+
+
+static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
+{
+	if (sym)
+		return elf->strtab + sym->st_name;
+	else
+		return "(unknown)";
+}
+
+void *grab_file(const char *filename, unsigned long *size)
+{
+	struct stat st;
+	void *map = MAP_FAILED;
+	int fd;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
+		return NULL;
+	if (fstat(fd, &st))
+		goto failed;
+
+	*size = st.st_size;
+	map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+
+failed:
+	close(fd);
+	if (map == MAP_FAILED)
+		return NULL;
+	return map;
+}
+
+/**
+  * Return a copy of the next line in a mmap'ed file.
+  * spaces in the beginning of the line is trimmed away.
+  * Return a pointer to a static buffer.
+  **/
+void release_file(void *file, unsigned long size)
+{
+	munmap(file, size);
+}
+
+
+static void *get_sym_value(struct elf_info *info, const Elf_Sym *sym)
+{
+	void *ptr = (void *)info->hdr + info->sechdrs[sym->st_shndx].sh_offset;
+
+	return (void *)(ptr + sym->st_value);
+}
+
+static Elf_Sym *find_sym_in_symtab(struct elf_info *info, 
+				   const char *name, Elf_Sym *last)
+{
+	Elf_Sym *idx;
+	if (last)
+		idx = last+1;
+	else
+		idx = info->symtab_start;
+
+	for(; idx < info->symtab_stop; idx++) {
+		const char *n = sym_name(info, idx);
+		if (!strncmp(n, name, strlen(name)))
+			return idx;
+	}
+	return NULL;
+}
+
+static int parse_elf(struct elf_info *info, const char *filename)
+{
+	unsigned int i;
+	Elf_Ehdr *hdr;
+	Elf_Shdr *sechdrs;
+	Elf_Sym  *sym;
+	const char *secstrings;
+	unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
+
+	hdr = grab_file(filename, &info->size);
+	if (!hdr) {
+		perror(filename);
+		exit(1);
+	}
+	info->hdr = hdr;
+	if (info->size < sizeof(*hdr)) {
+		/* file too small, assume this is an empty .o file */
+		return 0;
+	}
+	/* Is this a valid ELF file? */
+	if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
+	    (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
+	    (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
+	    (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
+		/* Not an ELF file - silently ignore it */
+		return 0;
+	}
+	/* Fix endianness in ELF header */
+	hdr->e_type      = TO_NATIVE(hdr->e_type);
+	hdr->e_machine   = TO_NATIVE(hdr->e_machine);
+	hdr->e_version   = TO_NATIVE(hdr->e_version);
+	hdr->e_entry     = TO_NATIVE(hdr->e_entry);
+	hdr->e_phoff     = TO_NATIVE(hdr->e_phoff);
+	hdr->e_shoff     = TO_NATIVE(hdr->e_shoff);
+	hdr->e_flags     = TO_NATIVE(hdr->e_flags);
+	hdr->e_ehsize    = TO_NATIVE(hdr->e_ehsize);
+	hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
+	hdr->e_phnum     = TO_NATIVE(hdr->e_phnum);
+	hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
+	hdr->e_shnum     = TO_NATIVE(hdr->e_shnum);
+	hdr->e_shstrndx  = TO_NATIVE(hdr->e_shstrndx);
+	sechdrs = (void *)hdr + hdr->e_shoff;
+	info->sechdrs = sechdrs;
+
+	/* Check if file offset is correct */
+	if (hdr->e_shoff > info->size) {
+		fprintf(stderr, "section header offset=%lu in file '%s' is bigger than "
+		      "filesize=%lu\n", (unsigned long)hdr->e_shoff,
+		      filename, info->size);
+		return 0;
+	}
+
+	if (hdr->e_shnum == SHN_UNDEF) {
+		/*
+		 * There are more than 64k sections,
+		 * read count from .sh_size.
+		 */
+		info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
+	}
+	else {
+		info->num_sections = hdr->e_shnum;
+	}
+	if (hdr->e_shstrndx == SHN_XINDEX) {
+		info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
+	}
+	else {
+		info->secindex_strings = hdr->e_shstrndx;
+	}
+
+	/* Fix endianness in section headers */
+	for (i = 0; i < info->num_sections; i++) {
+		sechdrs[i].sh_name      = TO_NATIVE(sechdrs[i].sh_name);
+		sechdrs[i].sh_type      = TO_NATIVE(sechdrs[i].sh_type);
+		sechdrs[i].sh_flags     = TO_NATIVE(sechdrs[i].sh_flags);
+		sechdrs[i].sh_addr      = TO_NATIVE(sechdrs[i].sh_addr);
+		sechdrs[i].sh_offset    = TO_NATIVE(sechdrs[i].sh_offset);
+		sechdrs[i].sh_size      = TO_NATIVE(sechdrs[i].sh_size);
+		sechdrs[i].sh_link      = TO_NATIVE(sechdrs[i].sh_link);
+		sechdrs[i].sh_info      = TO_NATIVE(sechdrs[i].sh_info);
+		sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
+		sechdrs[i].sh_entsize   = TO_NATIVE(sechdrs[i].sh_entsize);
+	}
+	/* Find symbol table. */
+	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
+	for (i = 1; i < info->num_sections; i++) {
+		int nobits = sechdrs[i].sh_type == SHT_NOBITS;
+
+		if (!nobits && sechdrs[i].sh_offset > info->size) {
+			fprintf(stderr, "%s is truncated. sechdrs[i].sh_offset=%lu > "
+			      "sizeof(*hrd)=%zu\n", filename,
+			      (unsigned long)sechdrs[i].sh_offset,
+			      sizeof(*hdr));
+			return 0;
+		}
+
+		if (sechdrs[i].sh_type == SHT_SYMTAB) {
+			unsigned int sh_link_idx;
+			symtab_idx = i;
+			info->symtab_start = (void *)hdr +
+			    sechdrs[i].sh_offset;
+			info->symtab_stop  = (void *)hdr +
+			    sechdrs[i].sh_offset + sechdrs[i].sh_size;
+			sh_link_idx = sechdrs[i].sh_link;
+			info->strtab       = (void *)hdr +
+			    sechdrs[sh_link_idx].sh_offset;
+		}
+
+		/* 32bit section no. table? ("more than 64k sections") */
+		if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
+			symtab_shndx_idx = i;
+			info->symtab_shndx_start = (void *)hdr +
+			    sechdrs[i].sh_offset;
+			info->symtab_shndx_stop  = (void *)hdr +
+			    sechdrs[i].sh_offset + sechdrs[i].sh_size;
+		}
+	}
+	if (!info->symtab_start)
+		fprintf(stderr, "%s has no symtab?\n", filename);
+
+	/* Fix endianness in symbols */
+	for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
+		sym->st_shndx = TO_NATIVE(sym->st_shndx);
+		sym->st_name  = TO_NATIVE(sym->st_name);
+		sym->st_value = TO_NATIVE(sym->st_value);
+		sym->st_size  = TO_NATIVE(sym->st_size);
+	}
+
+	if (symtab_shndx_idx != ~0U) {
+		Elf32_Word *p;
+		if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
+			fprintf(stderr, "%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
+			      filename, sechdrs[symtab_shndx_idx].sh_link,
+			      symtab_idx);
+		/* Fix endianness */
+		for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
+		     p++)
+			*p = TO_NATIVE(*p);
+	}
+
+	return 1;
+}
+
+static void parse_elf_finish(struct elf_info *info)
+{
+	struct pmd_driver *tmp, *idx = info->drivers;
+	release_file(info->hdr, info->size);
+	while (idx) {
+		tmp = idx->next;
+		free(idx);
+		idx = tmp;
+	}
+}
+
+static const char *sec_name(struct elf_info *elf, int secindex)
+{
+	Elf_Shdr *sechdrs = elf->sechdrs;
+	return (void *)elf->hdr +
+		elf->sechdrs[elf->secindex_strings].sh_offset +
+		sechdrs[secindex].sh_name;
+}
+
+static int get_symbol_index(struct elf_info *info, Elf64_Sym *sym)
+{
+	const char *name =  sym_name(info, sym);
+	const char *idx;
+
+	idx = name;
+	while (idx) {
+		if (isdigit(*idx))
+			return atoi(idx);
+		idx++;
+	}
+	return -1;
+}
+
+struct opt_tag {
+	const char* suffix;
+	const char* json_id;
+};
+
+static const struct opt_tag opt_tags[] = {
+	{"_param_string_export", "params"},
+};
+
+static int complete_pmd_entry(struct elf_info *info, struct pmd_driver *drv)
+{
+	const char *tname;
+	int i;
+	char tmpsymname[128];
+	Elf_Sym *tmpsym;
+	
+
+	drv->name = get_sym_value(info, drv->name_sym);
+
+	for (i=0; i<PMD_OPT_MAX; i++) {
+		memset(tmpsymname, 0, 128);
+		sprintf(tmpsymname, "__%s%s", drv->name, opt_tags[i].suffix);
+		tmpsym = find_sym_in_symtab(info, tmpsymname, NULL);
+		if (!tmpsym)
+			continue;
+		drv->opt_vals[i] = get_sym_value(info, tmpsym);
+	}
+
+	memset(tmpsymname, 0, 128);
+	sprintf(tmpsymname, "__%s_pci_tbl_export", drv->name);
+
+	tmpsym = find_sym_in_symtab(info, tmpsymname, NULL);
+
+
+	/*
+ 	 * If this returns NULL, then this is a PMD_VDEV, because
+ 	 * it has no pci table reference
+ 	 */
+	if (!tmpsym) {
+		drv->pci_tbl = NULL;
+		return 0;
+	}
+
+	tname = get_sym_value(info, tmpsym);
+	tmpsym = find_sym_in_symtab(info, tname, NULL);
+	if (!tmpsym)
+		return -ENOENT;
+
+	drv->pci_tbl = (struct rte_pci_id *)get_sym_value(info, tmpsym);
+	if (!drv->pci_tbl)
+		return -ENOENT;
+
+	return 0;
+}
+
+static int locate_pmd_entries(struct elf_info *info)
+{
+	Elf_Sym *last = NULL;
+	struct pmd_driver *new;
+
+	info->drivers = NULL;
+
+	do {
+		new = calloc(sizeof(struct pmd_driver), 1);
+		new->name_sym = find_sym_in_symtab(info, "this_pmd_name", last);
+		last = new->name_sym;
+		if (!new->name_sym)
+			free(new);
+		else {
+			if (complete_pmd_entry(info, new)) {
+				fprintf(stderr, "Failed to complete pmd entry\n");
+				free(new);
+			} else {
+				new->next = info->drivers;
+				info->drivers = new;
+			}
+		}
+	} while (last);
+}
+
+static void output_pmd_info_string(struct elf_info *info, char *outfile)
+{
+	FILE *ofd;
+	struct pmd_driver *drv;
+	struct rte_pci_id *pci_ids;
+	int idx = 0;
+
+	ofd = fopen(outfile, "w+");
+	if (!ofd) {
+		fprintf(stderr, "Unable to open output file\n");
+		return;
+	}
+
+	drv = info->drivers;
+
+	while (drv) {
+		fprintf(ofd, "const char %s_pmd_info[] __attribute__((used)) = \"PMD_INFO_STRING= {",
+			drv->name);
+		fprintf(ofd,"\\\"name\\\" : \\\"%s\\\", ", drv->name);
+
+		for(idx=0; idx<PMD_OPT_MAX; idx++) {
+			if (drv->opt_vals[idx])
+				fprintf(ofd,"\\\"%s\\\" : \\\"%s\\\", ", opt_tags[idx].json_id,
+					drv->opt_vals[idx]);
+		}
+
+		pci_ids = drv->pci_tbl;
+		fprintf(ofd, "\\\"pci_ids\\\" : [");
+
+		while (pci_ids && pci_ids->device_id) {
+			fprintf(ofd, "[%d, %d, %d, %d]",
+				pci_ids->vendor_id, pci_ids->device_id,
+				pci_ids->subsystem_vendor_id,
+				pci_ids->subsystem_device_id);
+			pci_ids++;
+			if (pci_ids->device_id)
+				fprintf(ofd, ",");
+			else
+				fprintf(ofd, " ");
+		}
+		fprintf(ofd, "]}\";");
+		drv = drv->next;
+	}
+
+	fclose(ofd);
+}
+
+int main(int argc, char **argv)
+{
+	struct elf_info info;
+	int rc = 1;
+
+	if (argc < 3) {
+		fprintf(stderr, "usage: pmdinfo <object file> <c output file>\n");
+		exit(127);
+	}
+	parse_elf(&info, argv[1]);
+
+	locate_pmd_entries(&info);
+
+	if (info.drivers) {
+		output_pmd_info_string(&info, argv[2]);
+		rc = 0;
+	} else {
+		fprintf(stderr, "Hmm, Appears to be a driver but no drivers registered\n");
+	}
+
+	parse_elf_finish(&info);
+	exit(rc);
+}
diff --git a/buildtools/pmdinfogen/pmdinfogen.h b/buildtools/pmdinfogen/pmdinfogen.h
new file mode 100644
index 0000000..7b158c9
--- /dev/null
+++ b/buildtools/pmdinfogen/pmdinfogen.h
@@ -0,0 +1,94 @@ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+#include <rte_pci.h>
+
+/* On BSD-alike OSes elf.h defines these according to host's word size */
+#undef ELF_ST_BIND
+#undef ELF_ST_TYPE
+#undef ELF_R_SYM
+#undef ELF_R_TYPE
+
+/*
+ * Define ELF64_* to ELF_*, the latter being defined in both 32 and 64 bit
+ * flavors in elf.h.  This makes our code a bit more generic between arches
+ * and allows us to support 32 bit code in the future should we ever want to
+ */
+#if __x86_64__ || __aarch64__
+#define Elf_Ehdr    Elf64_Ehdr
+#define Elf_Shdr    Elf64_Shdr
+#define Elf_Sym     Elf64_Sym
+#define Elf_Addr    Elf64_Addr
+#define Elf_Sword   Elf64_Sxword
+#define Elf_Section Elf64_Half
+#define ELF_ST_BIND ELF64_ST_BIND
+#define ELF_ST_TYPE ELF64_ST_TYPE
+
+#define Elf_Rel     Elf64_Rel
+#define Elf_Rela    Elf64_Rela
+#define ELF_R_SYM   ELF64_R_SYM
+#define ELF_R_TYPE  ELF64_R_TYPE
+#else
+#define Elf_Ehdr    Elf32_Ehdr
+#define Elf_Shdr    Elf32_Shdr
+#define Elf_Sym     Elf32_Sym
+#define Elf_Addr    Elf32_Addr
+#define Elf_Sword   Elf32_Sxword
+#define Elf_Section Elf32_Half
+#define ELF_ST_BIND ELF32_ST_BIND
+#define ELF_ST_TYPE ELF32_ST_TYPE
+
+#define Elf_Rel     Elf32_Rel
+#define Elf_Rela    Elf32_Rela
+#define ELF_R_SYM   ELF32_R_SYM
+#define ELF_R_TYPE  ELF32_R_TYPE
+#endif
+
+#define TO_NATIVE(x) (x)
+
+enum opt_params {
+	PMD_PARAM_STRING = 0,
+	PMD_OPT_MAX
+};
+
+struct pmd_driver {
+	Elf_Sym *name_sym;
+	const char *name;
+	struct rte_pci_id *pci_tbl;
+	struct pmd_driver *next;
+
+	const char* opt_vals[PMD_OPT_MAX];
+};
+
+struct elf_info {
+	unsigned long size;
+	Elf_Ehdr     *hdr;
+	Elf_Shdr     *sechdrs;
+	Elf_Sym      *symtab_start;
+	Elf_Sym      *symtab_stop;
+	Elf_Section  export_sec;
+	Elf_Section  export_unused_sec;
+	Elf_Section  export_gpl_sec;
+	Elf_Section  export_unused_gpl_sec;
+	Elf_Section  export_gpl_future_sec;
+	char         *strtab;
+
+	/* support for 32bit section numbers */
+
+	unsigned int num_sections; /* max_secindex + 1 */
+	unsigned int secindex_strings;
+	/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
+	 * take shndx from symtab_shndx_start[N] instead */
+	Elf32_Word   *symtab_shndx_start;
+	Elf32_Word   *symtab_shndx_stop;
+
+	struct pmd_driver *drivers;
+};
+
diff --git a/mk/rte.buildtools.mk b/mk/rte.buildtools.mk
new file mode 100644
index 0000000..e8bfcef
--- /dev/null
+++ b/mk/rte.buildtools.mk
@@ -0,0 +1,148 @@ 
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+#   Copyright(c) 2014-2015 6WIND S.A.
+#   All rights reserved.
+#
+#   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 Intel Corporation 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/internal/rte.compile-pre.mk
+include $(RTE_SDK)/mk/internal/rte.install-pre.mk
+include $(RTE_SDK)/mk/internal/rte.clean-pre.mk
+include $(RTE_SDK)/mk/internal/rte.build-pre.mk
+include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk
+
+# VPATH contains at least SRCDIR
+VPATH += $(SRCDIR)
+
+_BUILD = $(APP)
+_INSTALL = $(INSTALL-FILES-y) $(SYMLINK-FILES-y)
+_INSTALL += $(RTE_OUTPUT)/buildtools/$(APP) $(RTE_OUTPUT)/buildtools/$(APP).map
+POSTINSTALL += target-appinstall
+_CLEAN = doclean
+POSTCLEAN += target-appclean
+
+.PHONY: all
+all: install
+
+.PHONY: install
+install: build _postinstall
+
+_postinstall: build
+
+.PHONY: build
+build: _postbuild
+
+exe2cmd = $(strip $(call dotfile,$(patsubst %,%.cmd,$(1))))
+
+ifeq ($(LINK_USING_CC),1)
+override EXTRA_LDFLAGS := $(call linkerprefix,$(EXTRA_LDFLAGS))
+O_TO_EXE = $(CC) $(CFLAGS) $(LDFLAGS_$(@)) \
+	-Wl,-Map=$(@).map,--cref -o $@ $(OBJS-y) $(call linkerprefix,$(LDFLAGS)) \
+	$(EXTRA_LDFLAGS) $(call linkerprefix,$(LDLIBS))
+else
+O_TO_EXE = $(LD) $(LDFLAGS) $(LDFLAGS_$(@)) $(EXTRA_LDFLAGS) \
+	-Map=$(@).map --cref -o $@ $(OBJS-y) $(LDLIBS)
+endif
+O_TO_EXE_STR = $(subst ','\'',$(O_TO_EXE)) #'# fix syntax highlight
+O_TO_EXE_DISP = $(if $(V),"$(O_TO_EXE_STR)","  LD $(@)")
+O_TO_EXE_CMD = "cmd_$@ = $(O_TO_EXE_STR)"
+O_TO_EXE_DO = @set -e; \
+	echo $(O_TO_EXE_DISP); \
+	$(O_TO_EXE) && \
+	echo $(O_TO_EXE_CMD) > $(call exe2cmd,$(@))
+
+-include .$(APP).cmd
+
+# path where libraries are retrieved
+LDLIBS_PATH := $(subst -Wl$(comma)-L,,$(filter -Wl$(comma)-L%,$(LDLIBS)))
+LDLIBS_PATH += $(subst -L,,$(filter -L%,$(LDLIBS)))
+
+# list of .a files that are linked to this application
+LDLIBS_NAMES := $(patsubst -l%,lib%.a,$(filter -l%,$(LDLIBS)))
+LDLIBS_NAMES += $(patsubst -Wl$(comma)-l%,lib%.a,$(filter -Wl$(comma)-l%,$(LDLIBS)))
+
+# list of found libraries files (useful for deps). If not found, the
+# library is silently ignored and dep won't be checked
+LDLIBS_FILES := $(wildcard $(foreach dir,$(LDLIBS_PATH),\
+	$(addprefix $(dir)/,$(LDLIBS_NAMES))))
+
+#
+# Compile executable file if needed
+#
+$(APP): $(OBJS-y) $(LDLIBS_FILES) $(DEP_$(APP)) $(LDSCRIPT) FORCE
+	@[ -d $(dir $@) ] || mkdir -p $(dir $@)
+	$(if $(D),\
+		@echo -n "$< -> $@ " ; \
+		echo -n "file_missing=$(call boolean,$(file_missing)) " ; \
+		echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(O_TO_EXE_STR))) " ; \
+		echo -n "depfile_missing=$(call boolean,$(depfile_missing)) " ; \
+		echo "depfile_newer=$(call boolean,$(depfile_newer)) ")
+	$(if $(or \
+		$(file_missing),\
+		$(call cmdline_changed,$(O_TO_EXE_STR)),\
+		$(depfile_missing),\
+		$(depfile_newer)),\
+		$(O_TO_EXE_DO))
+
+#
+# install app in $(RTE_OUTPUT)/app
+#
+$(RTE_OUTPUT)/buildtools/$(APP): $(APP)
+	@echo "  INSTALL-APP $(APP)"
+	@[ -d $(RTE_OUTPUT)/buildtools ] || mkdir -p $(RTE_OUTPUT)/buildtools
+	$(Q)cp -f $(APP) $(RTE_OUTPUT)/buildtools
+
+#
+# install app map file in $(RTE_OUTPUT)/app
+#
+$(RTE_OUTPUT)/buildtools/$(APP).map: $(APP)
+	@echo "  INSTALL-MAP $(APP).map"
+	@[ -d $(RTE_OUTPUT)/buildtools ] || mkdir -p $(RTE_OUTPUT)/buildtools
+	$(Q)cp -f $(APP).map $(RTE_OUTPUT)/buildtools
+
+#
+# Clean all generated files
+#
+.PHONY: clean
+clean: _postclean
+	$(Q)rm -f $(_BUILD_TARGETS) $(_INSTALL_TARGETS) $(_CLEAN_TARGETS)
+
+.PHONY: doclean
+doclean:
+	$(Q)rm -rf $(APP) $(OBJS-all) $(DEPS-all) $(DEPSTMP-all) \
+	  $(CMDS-all) $(INSTALL-FILES-all) .$(APP).cmd
+
+
+include $(RTE_SDK)/mk/internal/rte.compile-post.mk
+include $(RTE_SDK)/mk/internal/rte.install-post.mk
+include $(RTE_SDK)/mk/internal/rte.clean-post.mk
+include $(RTE_SDK)/mk/internal/rte.build-post.mk
+include $(RTE_SDK)/mk/internal/rte.depdirs-post.mk
+
+.PHONY: FORCE
+FORCE:
diff --git a/mk/rte.sdkbuild.mk b/mk/rte.sdkbuild.mk
index eec5241..fb68af2 100644
--- a/mk/rte.sdkbuild.mk
+++ b/mk/rte.sdkbuild.mk
@@ -64,7 +64,8 @@  build: $(ROOTDIRS-y)
 clean: $(CLEANDIRS)
 	@rm -rf $(RTE_OUTPUT)/include $(RTE_OUTPUT)/app \
 		$(RTE_OUTPUT)/hostapp $(RTE_OUTPUT)/lib \
-		$(RTE_OUTPUT)/hostlib $(RTE_OUTPUT)/kmod
+		$(RTE_OUTPUT)/hostlib $(RTE_OUTPUT)/kmod \
+		$(RTE_OUTPUT)/buildtools
 	@[ -d $(RTE_OUTPUT)/include ] || mkdir -p $(RTE_OUTPUT)/include
 	@$(RTE_SDK)/scripts/gen-config-h.sh $(RTE_OUTPUT)/.config \
 		> $(RTE_OUTPUT)/include/rte_config.h