xref: /OK3568_Linux_fs/kernel/scripts/mod/modpost.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #include <stdio.h>
3*4882a593Smuzhiyun #include <stdlib.h>
4*4882a593Smuzhiyun #include <stdarg.h>
5*4882a593Smuzhiyun #include <stdbool.h>
6*4882a593Smuzhiyun #include <string.h>
7*4882a593Smuzhiyun #include <sys/types.h>
8*4882a593Smuzhiyun #include <sys/stat.h>
9*4882a593Smuzhiyun #include <sys/mman.h>
10*4882a593Smuzhiyun #include <fcntl.h>
11*4882a593Smuzhiyun #include <unistd.h>
12*4882a593Smuzhiyun #include <elf.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include "elfconfig.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /* On BSD-alike OSes elf.h defines these according to host's word size */
17*4882a593Smuzhiyun #undef ELF_ST_BIND
18*4882a593Smuzhiyun #undef ELF_ST_TYPE
19*4882a593Smuzhiyun #undef ELF_R_SYM
20*4882a593Smuzhiyun #undef ELF_R_TYPE
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #if KERNEL_ELFCLASS == ELFCLASS32
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define Elf_Ehdr    Elf32_Ehdr
25*4882a593Smuzhiyun #define Elf_Shdr    Elf32_Shdr
26*4882a593Smuzhiyun #define Elf_Sym     Elf32_Sym
27*4882a593Smuzhiyun #define Elf_Addr    Elf32_Addr
28*4882a593Smuzhiyun #define Elf_Sword   Elf64_Sword
29*4882a593Smuzhiyun #define Elf_Section Elf32_Half
30*4882a593Smuzhiyun #define ELF_ST_BIND ELF32_ST_BIND
31*4882a593Smuzhiyun #define ELF_ST_TYPE ELF32_ST_TYPE
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define Elf_Rel     Elf32_Rel
34*4882a593Smuzhiyun #define Elf_Rela    Elf32_Rela
35*4882a593Smuzhiyun #define ELF_R_SYM   ELF32_R_SYM
36*4882a593Smuzhiyun #define ELF_R_TYPE  ELF32_R_TYPE
37*4882a593Smuzhiyun #else
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define Elf_Ehdr    Elf64_Ehdr
40*4882a593Smuzhiyun #define Elf_Shdr    Elf64_Shdr
41*4882a593Smuzhiyun #define Elf_Sym     Elf64_Sym
42*4882a593Smuzhiyun #define Elf_Addr    Elf64_Addr
43*4882a593Smuzhiyun #define Elf_Sword   Elf64_Sxword
44*4882a593Smuzhiyun #define Elf_Section Elf64_Half
45*4882a593Smuzhiyun #define ELF_ST_BIND ELF64_ST_BIND
46*4882a593Smuzhiyun #define ELF_ST_TYPE ELF64_ST_TYPE
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define Elf_Rel     Elf64_Rel
49*4882a593Smuzhiyun #define Elf_Rela    Elf64_Rela
50*4882a593Smuzhiyun #define ELF_R_SYM   ELF64_R_SYM
51*4882a593Smuzhiyun #define ELF_R_TYPE  ELF64_R_TYPE
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
55*4882a593Smuzhiyun typedef struct
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	Elf32_Word    r_sym;	/* Symbol index */
58*4882a593Smuzhiyun 	unsigned char r_ssym;	/* Special symbol for 2nd relocation */
59*4882a593Smuzhiyun 	unsigned char r_type3;	/* 3rd relocation type */
60*4882a593Smuzhiyun 	unsigned char r_type2;	/* 2nd relocation type */
61*4882a593Smuzhiyun 	unsigned char r_type1;	/* 1st relocation type */
62*4882a593Smuzhiyun } _Elf64_Mips_R_Info;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun typedef union
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	Elf64_Xword		r_info_number;
67*4882a593Smuzhiyun 	_Elf64_Mips_R_Info	r_info_fields;
68*4882a593Smuzhiyun } _Elf64_Mips_R_Info_union;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #define ELF64_MIPS_R_SYM(i) \
71*4882a593Smuzhiyun   ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun #define ELF64_MIPS_R_TYPE(i) \
74*4882a593Smuzhiyun   ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #if KERNEL_ELFDATA != HOST_ELFDATA
77*4882a593Smuzhiyun 
__endian(const void * src,void * dest,unsigned int size)78*4882a593Smuzhiyun static inline void __endian(const void *src, void *dest, unsigned int size)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	unsigned int i;
81*4882a593Smuzhiyun 	for (i = 0; i < size; i++)
82*4882a593Smuzhiyun 		((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun #define TO_NATIVE(x)						\
86*4882a593Smuzhiyun ({								\
87*4882a593Smuzhiyun 	typeof(x) __x;						\
88*4882a593Smuzhiyun 	__endian(&(x), &(__x), sizeof(__x));			\
89*4882a593Smuzhiyun 	__x;							\
90*4882a593Smuzhiyun })
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun #else /* endianness matches */
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun #define TO_NATIVE(x) (x)
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun #endif
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun #define NOFAIL(ptr)   do_nofail((ptr), #ptr)
99*4882a593Smuzhiyun void *do_nofail(void *ptr, const char *expr);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun struct buffer {
102*4882a593Smuzhiyun 	char *p;
103*4882a593Smuzhiyun 	int pos;
104*4882a593Smuzhiyun 	int size;
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun void __attribute__((format(printf, 2, 3)))
108*4882a593Smuzhiyun buf_printf(struct buffer *buf, const char *fmt, ...);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun void
111*4882a593Smuzhiyun buf_write(struct buffer *buf, const char *s, int len);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun struct namespace_list {
114*4882a593Smuzhiyun 	struct namespace_list *next;
115*4882a593Smuzhiyun 	char namespace[];
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun struct module {
119*4882a593Smuzhiyun 	struct module *next;
120*4882a593Smuzhiyun 	int gpl_compatible;
121*4882a593Smuzhiyun 	struct symbol *unres;
122*4882a593Smuzhiyun 	int from_dump;  /* 1 if module was loaded from *.symvers */
123*4882a593Smuzhiyun 	int is_vmlinux;
124*4882a593Smuzhiyun 	int seen;
125*4882a593Smuzhiyun 	int has_init;
126*4882a593Smuzhiyun 	int has_cleanup;
127*4882a593Smuzhiyun 	struct buffer dev_table_buf;
128*4882a593Smuzhiyun 	char	     srcversion[25];
129*4882a593Smuzhiyun 	// Missing namespace dependencies
130*4882a593Smuzhiyun 	struct namespace_list *missing_namespaces;
131*4882a593Smuzhiyun 	// Actual imported namespaces
132*4882a593Smuzhiyun 	struct namespace_list *imported_namespaces;
133*4882a593Smuzhiyun 	char name[];
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun struct elf_info {
137*4882a593Smuzhiyun 	size_t size;
138*4882a593Smuzhiyun 	Elf_Ehdr     *hdr;
139*4882a593Smuzhiyun 	Elf_Shdr     *sechdrs;
140*4882a593Smuzhiyun 	Elf_Sym      *symtab_start;
141*4882a593Smuzhiyun 	Elf_Sym      *symtab_stop;
142*4882a593Smuzhiyun 	Elf_Section  export_sec;
143*4882a593Smuzhiyun 	Elf_Section  export_unused_sec;
144*4882a593Smuzhiyun 	Elf_Section  export_gpl_sec;
145*4882a593Smuzhiyun 	Elf_Section  export_unused_gpl_sec;
146*4882a593Smuzhiyun 	Elf_Section  export_gpl_future_sec;
147*4882a593Smuzhiyun 	char         *strtab;
148*4882a593Smuzhiyun 	char	     *modinfo;
149*4882a593Smuzhiyun 	unsigned int modinfo_len;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	/* support for 32bit section numbers */
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	unsigned int num_sections; /* max_secindex + 1 */
154*4882a593Smuzhiyun 	unsigned int secindex_strings;
155*4882a593Smuzhiyun 	/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
156*4882a593Smuzhiyun 	 * take shndx from symtab_shndx_start[N] instead */
157*4882a593Smuzhiyun 	Elf32_Word   *symtab_shndx_start;
158*4882a593Smuzhiyun 	Elf32_Word   *symtab_shndx_stop;
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
is_shndx_special(unsigned int i)161*4882a593Smuzhiyun static inline int is_shndx_special(unsigned int i)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /*
167*4882a593Smuzhiyun  * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
168*4882a593Smuzhiyun  * the way to -256..-1, to avoid conflicting with real section
169*4882a593Smuzhiyun  * indices.
170*4882a593Smuzhiyun  */
171*4882a593Smuzhiyun #define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
get_secindex(const struct elf_info * info,const Elf_Sym * sym)174*4882a593Smuzhiyun static inline unsigned int get_secindex(const struct elf_info *info,
175*4882a593Smuzhiyun 					const Elf_Sym *sym)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	if (is_shndx_special(sym->st_shndx))
178*4882a593Smuzhiyun 		return SPECIAL(sym->st_shndx);
179*4882a593Smuzhiyun 	if (sym->st_shndx != SHN_XINDEX)
180*4882a593Smuzhiyun 		return sym->st_shndx;
181*4882a593Smuzhiyun 	return info->symtab_shndx_start[sym - info->symtab_start];
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun 
strends(const char * str,const char * postfix)184*4882a593Smuzhiyun static inline bool strends(const char *str, const char *postfix)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	if (strlen(str) < strlen(postfix))
187*4882a593Smuzhiyun 		return false;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun /* file2alias.c */
193*4882a593Smuzhiyun extern unsigned int cross_build;
194*4882a593Smuzhiyun void handle_moddevtable(struct module *mod, struct elf_info *info,
195*4882a593Smuzhiyun 			Elf_Sym *sym, const char *symname);
196*4882a593Smuzhiyun void add_moddevtable(struct buffer *buf, struct module *mod);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun /* sumversion.c */
199*4882a593Smuzhiyun void get_src_version(const char *modname, char sum[], unsigned sumlen);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun /* from modpost.c */
202*4882a593Smuzhiyun char *read_text_file(const char *filename);
203*4882a593Smuzhiyun char *get_line(char **stringp);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun enum loglevel {
206*4882a593Smuzhiyun 	LOG_WARN,
207*4882a593Smuzhiyun 	LOG_ERROR,
208*4882a593Smuzhiyun 	LOG_FATAL
209*4882a593Smuzhiyun };
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun void modpost_log(enum loglevel loglevel, const char *fmt, ...);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun /*
214*4882a593Smuzhiyun  * warn - show the given message, then let modpost continue running, still
215*4882a593Smuzhiyun  *        allowing modpost to exit successfully. This should be used when
216*4882a593Smuzhiyun  *        we still allow to generate vmlinux and modules.
217*4882a593Smuzhiyun  *
218*4882a593Smuzhiyun  * error - show the given message, then let modpost continue running, but fail
219*4882a593Smuzhiyun  *         in the end. This should be used when we should stop building vmlinux
220*4882a593Smuzhiyun  *         or modules, but we can continue running modpost to catch as many
221*4882a593Smuzhiyun  *         issues as possible.
222*4882a593Smuzhiyun  *
223*4882a593Smuzhiyun  * fatal - show the given message, and bail out immediately. This should be
224*4882a593Smuzhiyun  *         used when there is no point to continue running modpost.
225*4882a593Smuzhiyun  */
226*4882a593Smuzhiyun #define warn(fmt, args...)	modpost_log(LOG_WARN, fmt, ##args)
227*4882a593Smuzhiyun #define error(fmt, args...)	modpost_log(LOG_ERROR, fmt, ##args)
228*4882a593Smuzhiyun #define fatal(fmt, args...)	modpost_log(LOG_FATAL, fmt, ##args)
229