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