3 #define PERBIT(x) x##32
4 #define ElfPERBIT(x) Elf32_##x
5 #define ELFPERBIT(x) ELF32_##x
6 /* 32-bit unsigned integer */
7 #define Elf32_Uint Elf32_Word
9 #elif defined(ELF64BIT)
11 #define PERBIT(x) x##64
12 #define ElfPERBIT(x) Elf64_##x
13 #define ELFPERBIT(x) ELF64_##x
14 /* 64-bit unsigned integer */
15 #define Elf64_Uint Elf64_Xword
18 # error "Undefined ELF word length"
21 static void *PERBIT(get_section
)(struct elf_file
*module
,
23 ElfPERBIT(Shdr
) **sechdr
,
24 unsigned long *secsize
)
26 void *data
= module
->data
;
27 unsigned long len
= module
->len
;
28 int conv
= module
->conv
;
31 ElfPERBIT(Shdr
) *sechdrs
;
32 ElfPERBIT(Off
) e_shoff
;
33 ElfPERBIT(Half
) e_shnum
, e_shstrndx
;
34 ElfPERBIT(Off
) secoffset
;
39 if (len
<= 0 || len
< sizeof(*hdr
))
43 e_shoff
= END(hdr
->e_shoff
, conv
);
44 e_shnum
= END(hdr
->e_shnum
, conv
);
45 e_shstrndx
= END(hdr
->e_shstrndx
, conv
);
47 if (len
< e_shoff
+ e_shnum
* sizeof(sechdrs
[0]))
50 sechdrs
= data
+ e_shoff
;
52 if (len
< END(sechdrs
[e_shstrndx
].sh_offset
, conv
))
55 /* Find section by name; return header, pointer and size. */
56 secnames
= data
+ END(sechdrs
[e_shstrndx
].sh_offset
, conv
);
57 for (i
= 1; i
< e_shnum
; i
++) {
58 if (streq(secnames
+ END(sechdrs
[i
].sh_name
, conv
), secname
)) {
59 *secsize
= END(sechdrs
[i
].sh_size
, conv
);
60 secoffset
= END(sechdrs
[i
].sh_offset
, conv
);
62 *sechdr
= sechdrs
+ i
;
63 if (len
< secoffset
+ *secsize
)
65 return data
+ secoffset
;
72 /* Load the given section: NULL on error. */
73 static void *PERBIT(load_section
)(struct elf_file
*module
,
75 unsigned long *secsize
)
77 return PERBIT(get_section
)(module
, secname
, NULL
, secsize
);
80 static struct string_table
*PERBIT(load_strings
)(struct elf_file
*module
,
82 struct string_table
*tbl
)
87 strings
= PERBIT(load_section
)(module
, secname
, &size
);
89 /* Skip any zero padding. */
95 for (; strings
; strings
= next_string(strings
, &size
))
96 tbl
= NOFAIL(strtbl_add(strings
, tbl
));
101 static struct string_table
*PERBIT(load_symbols
)(struct elf_file
*module
)
103 struct PERBIT(kernel_symbol
) *ksyms
;
104 struct string_table
*symtbl
;
105 unsigned long i
, size
;
109 /* New-style: strings are in this section. */
110 symtbl
= PERBIT(load_strings
)(module
, "__ksymtab_strings", symtbl
);
112 /* GPL symbols too */
113 return PERBIT(load_strings
)(module
, "__ksymtab_strings_gpl",
118 ksyms
= PERBIT(load_section
)(module
, "__ksymtab", &size
);
119 for (i
= 0; i
< size
/ sizeof(struct PERBIT(kernel_symbol
)); i
++)
120 symtbl
= NOFAIL(strtbl_add(ksyms
[i
].name
, symtbl
));
121 ksyms
= PERBIT(load_section
)(module
, "__gpl_ksymtab", &size
);
122 for (i
= 0; i
< size
/ sizeof(struct PERBIT(kernel_symbol
)); i
++)
123 symtbl
= NOFAIL(strtbl_add(ksyms
[i
].name
, symtbl
));
128 static char *PERBIT(get_aliases
)(struct elf_file
*module
, unsigned long *size
)
130 return PERBIT(load_section
)(module
, ".modalias", size
);
133 static char *PERBIT(get_modinfo
)(struct elf_file
*module
, unsigned long *size
)
135 return PERBIT(load_section
)(module
, ".modinfo", size
);
139 #define STT_REGISTER 13 /* Global register reserved to app. */
142 static struct string_table
*PERBIT(load_dep_syms
)(const char *pathname
,
143 struct elf_file
*module
,
144 struct string_table
**types
)
149 ElfPERBIT(Sym
) *syms
;
150 ElfPERBIT(Ehdr
) *hdr
;
151 int handle_register_symbols
;
152 struct string_table
*names
;
158 strings
= PERBIT(load_section
)(module
, ".strtab", &size
);
159 syms
= PERBIT(load_section
)(module
, ".symtab", &size
);
161 if (!strings
|| !syms
) {
162 warn("Couldn't find symtab and strtab in module %s\n",
170 handle_register_symbols
=
171 (END(hdr
->e_machine
, conv
) == EM_SPARC
||
172 END(hdr
->e_machine
, conv
) == EM_SPARCV9
);
174 for (i
= 1; i
< size
/ sizeof(syms
[0]); i
++) {
175 if (END(syms
[i
].st_shndx
, conv
) == SHN_UNDEF
) {
176 /* Look for symbol */
180 name
= strings
+ END(syms
[i
].st_name
, conv
);
182 /* Not really undefined: sparc gcc 3.3 creates
183 U references when you have global asm
184 variables, to avoid anyone else misusing
186 if (handle_register_symbols
187 && (ELFPERBIT(ST_TYPE
)(END(syms
[i
].st_info
, conv
))
191 weak
= (ELFPERBIT(ST_BIND
)(END(syms
[i
].st_info
, conv
))
193 names
= strtbl_add(name
, names
);
194 *types
= strtbl_add(weak
? weak_sym
: undef_sym
, *types
);
200 static void *PERBIT(deref_sym
)(ElfPERBIT(Ehdr
) *hdr
,
201 ElfPERBIT(Shdr
) *sechdrs
,
203 unsigned int *secsize
,
206 /* In BSS? Happens for empty device tables on
207 * recent GCC versions. */
208 if (END(sechdrs
[END(sym
->st_shndx
, conv
)].sh_type
,conv
) == SHT_NOBITS
)
212 *secsize
= END(sym
->st_size
, conv
);
214 + END(sechdrs
[END(sym
->st_shndx
, conv
)].sh_offset
, conv
)
215 + END(sym
->st_value
, conv
);
218 /* FIXME: Check size, unless we end up using aliases anyway --RR */
219 static void PERBIT(fetch_tables
)(struct elf_file
*module
,
220 struct module_tables
*tables
)
225 ElfPERBIT(Ehdr
) *hdr
;
226 ElfPERBIT(Sym
) *syms
;
227 ElfPERBIT(Shdr
) *sechdrs
;
233 sechdrs
= (void *)hdr
+ END(hdr
->e_shoff
, conv
);
234 strings
= PERBIT(load_section
)(module
, ".strtab", &size
);
235 syms
= PERBIT(load_section
)(module
, ".symtab", &size
);
237 /* Don't warn again: we already have above */
238 if (!strings
|| !syms
)
241 tables
->pci_table
= NULL
;
242 tables
->usb_table
= NULL
;
243 tables
->ccw_table
= NULL
;
244 tables
->ieee1394_table
= NULL
;
245 tables
->pnp_table
= NULL
;
246 tables
->pnp_card_table
= NULL
;
247 tables
->input_table
= NULL
;
248 tables
->serio_table
= NULL
;
249 tables
->of_table
= NULL
;
251 for (i
= 0; i
< size
/ sizeof(syms
[0]); i
++) {
252 char *name
= strings
+ END(syms
[i
].st_name
, conv
);
254 if (!tables
->pci_table
&& streq(name
, "__mod_pci_device_table")) {
255 tables
->pci_size
= PERBIT(PCI_DEVICE_SIZE
);
256 tables
->pci_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
259 else if (!tables
->usb_table
&& streq(name
, "__mod_usb_device_table")) {
260 tables
->usb_size
= PERBIT(USB_DEVICE_SIZE
);
261 tables
->usb_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
264 else if (!tables
->ccw_table
&& streq(name
, "__mod_ccw_device_table")) {
265 tables
->ccw_size
= PERBIT(CCW_DEVICE_SIZE
);
266 tables
->ccw_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
269 else if (!tables
->ieee1394_table
&& streq(name
, "__mod_ieee1394_device_table")) {
270 tables
->ieee1394_size
= PERBIT(IEEE1394_DEVICE_SIZE
);
271 tables
->ieee1394_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
274 else if (!tables
->pnp_table
&& streq(name
, "__mod_pnp_device_table")) {
275 tables
->pnp_size
= PERBIT(PNP_DEVICE_SIZE
);
276 tables
->pnp_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
279 else if (!tables
->pnp_card_table
&& streq(name
, "__mod_pnp_card_device_table")) {
280 tables
->pnp_card_size
= PERBIT(PNP_CARD_DEVICE_SIZE
);
281 tables
->pnp_card_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
283 tables
->pnp_card_offset
= PERBIT(PNP_CARD_DEVICE_OFFSET
);
285 else if (!tables
->input_table
&& streq(name
, "__mod_input_device_table")) {
286 tables
->input_size
= PERBIT(INPUT_DEVICE_SIZE
);
287 tables
->input_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
288 &tables
->input_table_size
,
291 else if (!tables
->serio_table
&& streq(name
, "__mod_serio_device_table")) {
292 tables
->serio_size
= PERBIT(SERIO_DEVICE_SIZE
);
293 tables
->serio_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
296 else if (!tables
->of_table
&& streq(name
, "__mod_of_device_table")) {
297 tables
->of_size
= PERBIT(OF_DEVICE_SIZE
);
298 tables
->of_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
305 * strip_section - tell the kernel to ignore the named section
307 static void PERBIT(strip_section
)(struct elf_file
*module
, const char *secname
)
310 ElfPERBIT(Shdr
) *sechdr
;
311 unsigned long secsize
;
313 p
= PERBIT(get_section
)(module
, secname
, &sechdr
, &secsize
);
315 ElfPERBIT(Uint
) mask
;
316 mask
= ~((ElfPERBIT(Uint
))SHF_ALLOC
);
317 sechdr
->sh_flags
&= END(mask
, module
->conv
);
321 static int PERBIT(dump_modversions
)(struct elf_file
*module
)
323 unsigned long secsize
;
324 struct PERBIT(modver_info
) *info
;
327 info
= module
->ops
->load_section(module
, "__versions", &secsize
);
329 return 0; /* not a kernel module */
330 if (secsize
% sizeof(*info
) != 0)
331 return -1; /* invalid section size */
333 for (n
= 0; n
< secsize
/ sizeof(*info
); n
++) {
334 #if defined(ELF32BIT)
335 printf("0x%08lx\t%s\n", (unsigned long)
336 #else /* defined(ELF64BIT) */
337 printf("0x%08llx\t%s\n", (unsigned long long)
339 END(info
[n
].crc
, module
->conv
),
340 skip_dot(info
[n
].name
));
345 struct module_ops
PERBIT(mod_ops
) = {
346 .load_section
= PERBIT(load_section
),
347 .load_symbols
= PERBIT(load_symbols
),
348 .load_dep_syms
= PERBIT(load_dep_syms
),
349 .fetch_tables
= PERBIT(fetch_tables
),
350 .get_aliases
= PERBIT(get_aliases
),
351 .get_modinfo
= PERBIT(get_modinfo
),
352 .strip_section
= PERBIT(strip_section
),
353 .dump_modvers
= PERBIT(dump_modversions
),