1  /* SPDX-License-Identifier: GPL-2.0 */
2  #include <byteswap.h>
3  #include <stdbool.h>
4  #include <stdio.h>
5  #include <stdlib.h>
6  #include <stdarg.h>
7  #include <string.h>
8  #include <sys/types.h>
9  #include <sys/stat.h>
10  #include <sys/mman.h>
11  #include <fcntl.h>
12  #include <unistd.h>
13  #include <elf.h>
14  #include "../../include/linux/module_symbol.h"
15  
16  #include <list_types.h>
17  #include "elfconfig.h"
18  
19  /* On BSD-alike OSes elf.h defines these according to host's word size */
20  #undef ELF_ST_BIND
21  #undef ELF_ST_TYPE
22  #undef ELF_R_SYM
23  #undef ELF_R_TYPE
24  
25  #if KERNEL_ELFCLASS == ELFCLASS32
26  
27  #define Elf_Ehdr    Elf32_Ehdr
28  #define Elf_Shdr    Elf32_Shdr
29  #define Elf_Sym     Elf32_Sym
30  #define Elf_Addr    Elf32_Addr
31  #define Elf_Section Elf32_Half
32  #define ELF_ST_BIND ELF32_ST_BIND
33  #define ELF_ST_TYPE ELF32_ST_TYPE
34  
35  #define Elf_Rel     Elf32_Rel
36  #define Elf_Rela    Elf32_Rela
37  #define ELF_R_SYM   ELF32_R_SYM
38  #define ELF_R_TYPE  ELF32_R_TYPE
39  #else
40  
41  #define Elf_Ehdr    Elf64_Ehdr
42  #define Elf_Shdr    Elf64_Shdr
43  #define Elf_Sym     Elf64_Sym
44  #define Elf_Addr    Elf64_Addr
45  #define Elf_Section Elf64_Half
46  #define ELF_ST_BIND ELF64_ST_BIND
47  #define ELF_ST_TYPE ELF64_ST_TYPE
48  
49  #define Elf_Rel     Elf64_Rel
50  #define Elf_Rela    Elf64_Rela
51  #define ELF_R_SYM   ELF64_R_SYM
52  #define ELF_R_TYPE  ELF64_R_TYPE
53  #endif
54  
55  #define bswap(x) \
56  ({ \
57  	_Static_assert(sizeof(x) == 1 || sizeof(x) == 2 || \
58  		       sizeof(x) == 4 || sizeof(x) == 8, "bug"); \
59  	(typeof(x))(sizeof(x) == 2 ? bswap_16(x) : \
60  		    sizeof(x) == 4 ? bswap_32(x) : \
61  		    sizeof(x) == 8 ? bswap_64(x) : \
62  		    x); \
63  })
64  
65  #define TO_NATIVE(x)	\
66  	(target_is_big_endian == host_is_big_endian ? x : bswap(x))
67  
68  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
69  
70  struct buffer {
71  	char *p;
72  	int pos;
73  	int size;
74  };
75  
76  void __attribute__((format(printf, 2, 3)))
77  buf_printf(struct buffer *buf, const char *fmt, ...);
78  
79  void
80  buf_write(struct buffer *buf, const char *s, int len);
81  
82  struct module {
83  	struct list_head list;
84  	struct list_head exported_symbols;
85  	struct list_head unresolved_symbols;
86  	bool is_gpl_compatible;
87  	bool from_dump;		/* true if module was loaded from *.symvers */
88  	bool is_vmlinux;
89  	bool seen;
90  	bool has_init;
91  	bool has_cleanup;
92  	struct buffer dev_table_buf;
93  	char	     srcversion[25];
94  	// Missing namespace dependencies
95  	struct list_head missing_namespaces;
96  	// Actual imported namespaces
97  	struct list_head imported_namespaces;
98  	char name[];
99  };
100  
101  struct elf_info {
102  	size_t size;
103  	Elf_Ehdr     *hdr;
104  	Elf_Shdr     *sechdrs;
105  	Elf_Sym      *symtab_start;
106  	Elf_Sym      *symtab_stop;
107  	unsigned int export_symbol_secndx;	/* .export_symbol section */
108  	char         *strtab;
109  	char	     *modinfo;
110  	unsigned int modinfo_len;
111  
112  	/* support for 32bit section numbers */
113  
114  	unsigned int num_sections; /* max_secindex + 1 */
115  	unsigned int secindex_strings;
116  	/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
117  	 * take shndx from symtab_shndx_start[N] instead */
118  	Elf32_Word   *symtab_shndx_start;
119  	Elf32_Word   *symtab_shndx_stop;
120  
121  	struct symsearch *symsearch;
122  };
123  
124  /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
get_secindex(const struct elf_info * info,const Elf_Sym * sym)125  static inline unsigned int get_secindex(const struct elf_info *info,
126  					const Elf_Sym *sym)
127  {
128  	unsigned int index = sym->st_shndx;
129  
130  	/*
131  	 * Elf{32,64}_Sym::st_shndx is 2 byte. Big section numbers are available
132  	 * in the .symtab_shndx section.
133  	 */
134  	if (index == SHN_XINDEX)
135  		return info->symtab_shndx_start[sym - info->symtab_start];
136  
137  	/*
138  	 * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
139  	 * the way to UINT_MAX-255..UINT_MAX, to avoid conflicting with real
140  	 * section indices.
141  	 */
142  	if (index >= SHN_LORESERVE && index <= SHN_HIRESERVE)
143  		return index - SHN_HIRESERVE - 1;
144  
145  	return index;
146  }
147  
148  /*
149   * If there's no name there, ignore it; likewise, ignore it if it's
150   * one of the magic symbols emitted used by current tools.
151   *
152   * Internal symbols created by tools should be ignored by modpost.
153   */
is_valid_name(struct elf_info * elf,Elf_Sym * sym)154  static inline bool is_valid_name(struct elf_info *elf, Elf_Sym *sym)
155  {
156  	const char *name = elf->strtab + sym->st_name;
157  
158  	if (!name || !strlen(name))
159  		return false;
160  	return !is_mapping_symbol(name);
161  }
162  
163  /* symsearch.c */
164  void symsearch_init(struct elf_info *elf);
165  void symsearch_finish(struct elf_info *elf);
166  Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr,
167  				unsigned int secndx, bool allow_negative,
168  				Elf_Addr min_distance);
169  
170  /* file2alias.c */
171  void handle_moddevtable(struct module *mod, struct elf_info *info,
172  			Elf_Sym *sym, const char *symname);
173  void add_moddevtable(struct buffer *buf, struct module *mod);
174  
175  /* sumversion.c */
176  void get_src_version(const char *modname, char sum[], unsigned sumlen);
177  
178  /* from modpost.c */
179  extern bool target_is_big_endian;
180  extern bool host_is_big_endian;
181  char *read_text_file(const char *filename);
182  char *get_line(char **stringp);
183  void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
184  
185  void __attribute__((format(printf, 2, 3)))
186  modpost_log(bool is_error, const char *fmt, ...);
187  
188  /*
189   * warn - show the given message, then let modpost continue running, still
190   *        allowing modpost to exit successfully. This should be used when
191   *        we still allow to generate vmlinux and modules.
192   *
193   * error - show the given message, then let modpost continue running, but fail
194   *         in the end. This should be used when we should stop building vmlinux
195   *         or modules, but we can continue running modpost to catch as many
196   *         issues as possible.
197   *
198   * fatal - show the given message, and bail out immediately. This should be
199   *         used when there is no point to continue running modpost.
200   */
201  #define warn(fmt, args...)	modpost_log(false, fmt, ##args)
202  #define error(fmt, args...)	modpost_log(true, fmt, ##args)
203  #define fatal(fmt, args...)	do { error(fmt, ##args); exit(1); } while (1)
204