xref: /linux/scripts/mod/modpost.h (revision 84a73014d86fd660822a20c032625e3afe99ca58)
11da177e4SLinus Torvalds #include <stdio.h>
21da177e4SLinus Torvalds #include <stdlib.h>
31da177e4SLinus Torvalds #include <stdarg.h>
41da177e4SLinus Torvalds #include <string.h>
51da177e4SLinus Torvalds #include <sys/types.h>
61da177e4SLinus Torvalds #include <sys/stat.h>
71da177e4SLinus Torvalds #include <sys/mman.h>
81da177e4SLinus Torvalds #include <fcntl.h>
91da177e4SLinus Torvalds #include <unistd.h>
101da177e4SLinus Torvalds #include <elf.h>
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include "elfconfig.h"
131da177e4SLinus Torvalds 
143c0561e0SPavel Fedin /* On BSD-alike OSes elf.h defines these according to host's word size */
153c0561e0SPavel Fedin #undef ELF_ST_BIND
163c0561e0SPavel Fedin #undef ELF_ST_TYPE
173c0561e0SPavel Fedin #undef ELF_R_SYM
183c0561e0SPavel Fedin #undef ELF_R_TYPE
193c0561e0SPavel Fedin 
201da177e4SLinus Torvalds #if KERNEL_ELFCLASS == ELFCLASS32
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds #define Elf_Ehdr    Elf32_Ehdr
231da177e4SLinus Torvalds #define Elf_Shdr    Elf32_Shdr
241da177e4SLinus Torvalds #define Elf_Sym     Elf32_Sym
25b39927cfSSam Ravnborg #define Elf_Addr    Elf32_Addr
269ad21c3fSSam Ravnborg #define Elf_Sword   Elf64_Sword
274f4c4ee1SSam Ravnborg #define Elf_Section Elf32_Half
281da177e4SLinus Torvalds #define ELF_ST_BIND ELF32_ST_BIND
291da177e4SLinus Torvalds #define ELF_ST_TYPE ELF32_ST_TYPE
301da177e4SLinus Torvalds 
312c1a51f3SAtsushi Nemoto #define Elf_Rel     Elf32_Rel
32b39927cfSSam Ravnborg #define Elf_Rela    Elf32_Rela
33b39927cfSSam Ravnborg #define ELF_R_SYM   ELF32_R_SYM
34b39927cfSSam Ravnborg #define ELF_R_TYPE  ELF32_R_TYPE
351da177e4SLinus Torvalds #else
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds #define Elf_Ehdr    Elf64_Ehdr
381da177e4SLinus Torvalds #define Elf_Shdr    Elf64_Shdr
391da177e4SLinus Torvalds #define Elf_Sym     Elf64_Sym
40b39927cfSSam Ravnborg #define Elf_Addr    Elf64_Addr
419ad21c3fSSam Ravnborg #define Elf_Sword   Elf64_Sxword
424f4c4ee1SSam Ravnborg #define Elf_Section Elf64_Half
431da177e4SLinus Torvalds #define ELF_ST_BIND ELF64_ST_BIND
441da177e4SLinus Torvalds #define ELF_ST_TYPE ELF64_ST_TYPE
451da177e4SLinus Torvalds 
462c1a51f3SAtsushi Nemoto #define Elf_Rel     Elf64_Rel
47b39927cfSSam Ravnborg #define Elf_Rela    Elf64_Rela
48b39927cfSSam Ravnborg #define ELF_R_SYM   ELF64_R_SYM
49b39927cfSSam Ravnborg #define ELF_R_TYPE  ELF64_R_TYPE
501da177e4SLinus Torvalds #endif
511da177e4SLinus Torvalds 
52eae07ac6SAtsushi Nemoto /* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
53eae07ac6SAtsushi Nemoto typedef struct
54eae07ac6SAtsushi Nemoto {
55eae07ac6SAtsushi Nemoto 	Elf32_Word    r_sym;	/* Symbol index */
56eae07ac6SAtsushi Nemoto 	unsigned char r_ssym;	/* Special symbol for 2nd relocation */
57eae07ac6SAtsushi Nemoto 	unsigned char r_type3;	/* 3rd relocation type */
58eae07ac6SAtsushi Nemoto 	unsigned char r_type2;	/* 2nd relocation type */
59eae07ac6SAtsushi Nemoto 	unsigned char r_type1;	/* 1st relocation type */
60eae07ac6SAtsushi Nemoto } _Elf64_Mips_R_Info;
61eae07ac6SAtsushi Nemoto 
62eae07ac6SAtsushi Nemoto typedef union
63eae07ac6SAtsushi Nemoto {
64eae07ac6SAtsushi Nemoto 	Elf64_Xword		r_info_number;
65eae07ac6SAtsushi Nemoto 	_Elf64_Mips_R_Info	r_info_fields;
66eae07ac6SAtsushi Nemoto } _Elf64_Mips_R_Info_union;
67eae07ac6SAtsushi Nemoto 
68eae07ac6SAtsushi Nemoto #define ELF64_MIPS_R_SYM(i) \
69eae07ac6SAtsushi Nemoto   ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
70eae07ac6SAtsushi Nemoto 
71ae4ac123SAtsushi Nemoto #define ELF64_MIPS_R_TYPE(i) \
72ae4ac123SAtsushi Nemoto   ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
73ae4ac123SAtsushi Nemoto 
741da177e4SLinus Torvalds #if KERNEL_ELFDATA != HOST_ELFDATA
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds static inline void __endian(const void *src, void *dest, unsigned int size)
771da177e4SLinus Torvalds {
781da177e4SLinus Torvalds 	unsigned int i;
791da177e4SLinus Torvalds 	for (i = 0; i < size; i++)
801da177e4SLinus Torvalds 		((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
811da177e4SLinus Torvalds }
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds #define TO_NATIVE(x)						\
841da177e4SLinus Torvalds ({								\
851da177e4SLinus Torvalds 	typeof(x) __x;						\
861da177e4SLinus Torvalds 	__endian(&(x), &(__x), sizeof(__x));			\
871da177e4SLinus Torvalds 	__x;							\
881da177e4SLinus Torvalds })
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds #else /* endianness matches */
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds #define TO_NATIVE(x) (x)
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds #endif
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds #define NOFAIL(ptr)   do_nofail((ptr), #ptr)
971da177e4SLinus Torvalds void *do_nofail(void *ptr, const char *expr);
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds struct buffer {
1001da177e4SLinus Torvalds 	char *p;
1011da177e4SLinus Torvalds 	int pos;
1021da177e4SLinus Torvalds 	int size;
1031da177e4SLinus Torvalds };
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds void __attribute__((format(printf, 2, 3)))
1061da177e4SLinus Torvalds buf_printf(struct buffer *buf, const char *fmt, ...);
1071da177e4SLinus Torvalds 
1081da177e4SLinus Torvalds void
1091da177e4SLinus Torvalds buf_write(struct buffer *buf, const char *s, int len);
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds struct module {
1121da177e4SLinus Torvalds 	struct module *next;
1131da177e4SLinus Torvalds 	const char *name;
114b817f6feSSam Ravnborg 	int gpl_compatible;
1151da177e4SLinus Torvalds 	struct symbol *unres;
1161da177e4SLinus Torvalds 	int seen;
1171da177e4SLinus Torvalds 	int skip;
1181da177e4SLinus Torvalds 	int has_init;
1191da177e4SLinus Torvalds 	int has_cleanup;
1201da177e4SLinus Torvalds 	struct buffer dev_table_buf;
1211da177e4SLinus Torvalds 	char	     srcversion[25];
122258f7426SFrank Rowand 	int is_dot_o;
1231da177e4SLinus Torvalds };
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds struct elf_info {
1261da177e4SLinus Torvalds 	unsigned long size;
1271da177e4SLinus Torvalds 	Elf_Ehdr     *hdr;
1281da177e4SLinus Torvalds 	Elf_Shdr     *sechdrs;
1291da177e4SLinus Torvalds 	Elf_Sym      *symtab_start;
1301da177e4SLinus Torvalds 	Elf_Sym      *symtab_stop;
131bd5cbcedSRam Pai 	Elf_Section  export_sec;
132c96fca21SSam Ravnborg 	Elf_Section  export_unused_sec;
133bd5cbcedSRam Pai 	Elf_Section  export_gpl_sec;
134c96fca21SSam Ravnborg 	Elf_Section  export_unused_gpl_sec;
135bd5cbcedSRam Pai 	Elf_Section  export_gpl_future_sec;
1367d02b490SAndi Kleen 	char         *strtab;
1371da177e4SLinus Torvalds 	char	     *modinfo;
1381da177e4SLinus Torvalds 	unsigned int modinfo_len;
1391ce53adfSDenys Vlasenko 
1401ce53adfSDenys Vlasenko 	/* support for 32bit section numbers */
1411ce53adfSDenys Vlasenko 
1421ce53adfSDenys Vlasenko 	unsigned int num_sections; /* max_secindex + 1 */
1431ce53adfSDenys Vlasenko 	unsigned int secindex_strings;
1441ce53adfSDenys Vlasenko 	/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
1451ce53adfSDenys Vlasenko 	 * take shndx from symtab_shndx_start[N] instead */
1461ce53adfSDenys Vlasenko 	Elf32_Word   *symtab_shndx_start;
1471ce53adfSDenys Vlasenko 	Elf32_Word   *symtab_shndx_stop;
1481da177e4SLinus Torvalds };
1491da177e4SLinus Torvalds 
1501ce53adfSDenys Vlasenko static inline int is_shndx_special(unsigned int i)
1511ce53adfSDenys Vlasenko {
1521ce53adfSDenys Vlasenko 	return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
1531ce53adfSDenys Vlasenko }
1541ce53adfSDenys Vlasenko 
1556845756bSAnders Kaseorg /*
1566845756bSAnders Kaseorg  * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
1576845756bSAnders Kaseorg  * the way to -256..-1, to avoid conflicting with real section
1586845756bSAnders Kaseorg  * indices.
1591ce53adfSDenys Vlasenko  */
1606845756bSAnders Kaseorg #define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
1611ce53adfSDenys Vlasenko 
1621ce53adfSDenys Vlasenko /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
1631ce53adfSDenys Vlasenko static inline unsigned int get_secindex(const struct elf_info *info,
1641ce53adfSDenys Vlasenko 					const Elf_Sym *sym)
1651ce53adfSDenys Vlasenko {
1666845756bSAnders Kaseorg 	if (is_shndx_special(sym->st_shndx))
1676845756bSAnders Kaseorg 		return SPECIAL(sym->st_shndx);
1681ce53adfSDenys Vlasenko 	if (sym->st_shndx != SHN_XINDEX)
1691ce53adfSDenys Vlasenko 		return sym->st_shndx;
1706845756bSAnders Kaseorg 	return info->symtab_shndx_start[sym - info->symtab_start];
1711ce53adfSDenys Vlasenko }
1721ce53adfSDenys Vlasenko 
173cb80514dSSam Ravnborg /* file2alias.c */
1744ce6efedSSam Ravnborg extern unsigned int cross_build;
1751da177e4SLinus Torvalds void handle_moddevtable(struct module *mod, struct elf_info *info,
1761da177e4SLinus Torvalds 			Elf_Sym *sym, const char *symname);
1771da177e4SLinus Torvalds void add_moddevtable(struct buffer *buf, struct module *mod);
1781da177e4SLinus Torvalds 
179cb80514dSSam Ravnborg /* sumversion.c */
1801da177e4SLinus Torvalds void maybe_frob_rcs_version(const char *modfilename,
1811da177e4SLinus Torvalds 			    char *version,
1821da177e4SLinus Torvalds 			    void *modinfo,
1831da177e4SLinus Torvalds 			    unsigned long modinfo_offset);
1841da177e4SLinus Torvalds void get_src_version(const char *modname, char sum[], unsigned sumlen);
1851da177e4SLinus Torvalds 
186cb80514dSSam Ravnborg /* from modpost.c */
1871da177e4SLinus Torvalds void *grab_file(const char *filename, unsigned long *size);
1881da177e4SLinus Torvalds char* get_next_line(unsigned long *pos, void *file, unsigned long size);
1891da177e4SLinus Torvalds void release_file(void *file, unsigned long size);
190cb80514dSSam Ravnborg 
191cb80514dSSam Ravnborg void fatal(const char *fmt, ...);
192cb80514dSSam Ravnborg void warn(const char *fmt, ...);
1932a116659SMatthew Wilcox void merror(const char *fmt, ...);
194