pmdinfogen: fix null dereference
[dpdk.git] / buildtools / pmdinfogen / pmdinfogen.h
1
2 /* Postprocess pmd object files to export hw support
3  *
4  * Copyright 2016 Neil Horman <nhorman@tuxdriver.com>
5  * Based in part on modpost.c from the linux kernel
6  *
7  * This software may be used and distributed according to the terms
8  * of the GNU General Public License V2, incorporated herein by reference.
9  *
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/mman.h>
19 #ifdef __linux__
20 #include <endian.h>
21 #else
22 #include <sys/endian.h>
23 #endif
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <elf.h>
27 #include <rte_config.h>
28 #include <rte_pci.h>
29
30 /* On BSD-alike OSes elf.h defines these according to host's word size */
31 #undef ELF_ST_BIND
32 #undef ELF_ST_TYPE
33 #undef ELF_R_SYM
34 #undef ELF_R_TYPE
35
36 /*
37  * Define ELF64_* to ELF_*, the latter being defined in both 32 and 64 bit
38  * flavors in elf.h.  This makes our code a bit more generic between arches
39  * and allows us to support 32 bit code in the future should we ever want to
40  */
41 #ifdef RTE_ARCH_64
42 #define Elf_Ehdr    Elf64_Ehdr
43 #define Elf_Shdr    Elf64_Shdr
44 #define Elf_Sym     Elf64_Sym
45 #define Elf_Addr    Elf64_Addr
46 #define Elf_Sword   Elf64_Sxword
47 #define Elf_Section Elf64_Half
48 #define ELF_ST_BIND ELF64_ST_BIND
49 #define ELF_ST_TYPE ELF64_ST_TYPE
50
51 #define Elf_Rel     Elf64_Rel
52 #define Elf_Rela    Elf64_Rela
53 #define ELF_R_SYM   ELF64_R_SYM
54 #define ELF_R_TYPE  ELF64_R_TYPE
55 #else
56 #define Elf_Ehdr    Elf32_Ehdr
57 #define Elf_Shdr    Elf32_Shdr
58 #define Elf_Sym     Elf32_Sym
59 #define Elf_Addr    Elf32_Addr
60 #define Elf_Sword   Elf32_Sxword
61 #define Elf_Section Elf32_Half
62 #define ELF_ST_BIND ELF32_ST_BIND
63 #define ELF_ST_TYPE ELF32_ST_TYPE
64
65 #define Elf_Rel     Elf32_Rel
66 #define Elf_Rela    Elf32_Rela
67 #define ELF_R_SYM   ELF32_R_SYM
68 #define ELF_R_TYPE  ELF32_R_TYPE
69 #endif
70
71
72 /*
73  * Note, it seems odd that we have both a CONVERT_NATIVE and a TO_NATIVE macro
74  * below.  We do this because the values passed to TO_NATIVE may themselves be
75  * macros and need both macros here to get expanded.  Specifically its the width
76  * variable we are concerned with, because it needs to get expanded prior to
77  * string concatenation
78  */
79 #define CONVERT_NATIVE(fend, width, x) ({ \
80 typeof(x) ___x; \
81 if ((fend) == ELFDATA2LSB) \
82         ___x = le##width##toh(x); \
83 else \
84         ___x = be##width##toh(x); \
85         ___x; \
86 })
87
88 #define TO_NATIVE(fend, width, x) CONVERT_NATIVE(fend, width, x)
89
90 enum opt_params {
91         PMD_PARAM_STRING = 0,
92         PMD_KMOD_DEP,
93         PMD_OPT_MAX
94 };
95
96 struct pmd_driver {
97         Elf_Sym *name_sym;
98         const char *name;
99         struct rte_pci_id *pci_tbl;
100         struct pmd_driver *next;
101
102         const char *opt_vals[PMD_OPT_MAX];
103 };
104
105 struct elf_info {
106         unsigned long size;
107         Elf_Ehdr     *hdr;
108         Elf_Shdr     *sechdrs;
109         Elf_Sym      *symtab_start;
110         Elf_Sym      *symtab_stop;
111         char         *strtab;
112
113         /* support for 32bit section numbers */
114
115         unsigned int num_sections; /* max_secindex + 1 */
116         unsigned int secindex_strings;
117         /* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
118          * take shndx from symtab_shndx_start[N] instead
119          */
120         Elf32_Word   *symtab_shndx_start;
121         Elf32_Word   *symtab_shndx_stop;
122
123         struct pmd_driver *drivers;
124 };
125