1 /* Load the given section: NULL on error. */
2 static void *PERBIT(load_section
)(ElfPERBIT(Ehdr
) *hdr
,
7 ElfPERBIT(Shdr
) *sechdrs
;
11 /* Grab section headers and strings so we can tell who is who */
12 sechdrs
= (void *)hdr
+ END(hdr
->e_shoff
, conv
);
13 secnames
= (void *)hdr
14 + END(sechdrs
[END(hdr
->e_shstrndx
, conv
)].sh_offset
, conv
);
16 /* Find the section they want */
17 for (i
= 1; i
< END(hdr
->e_shnum
, conv
); i
++) {
18 if (streq(secnames
+END(sechdrs
[i
].sh_name
, conv
), secname
)) {
19 *size
= END(sechdrs
[i
].sh_size
, conv
);
20 return (void *)hdr
+ END(sechdrs
[i
].sh_offset
, conv
);
27 static void PERBIT(load_symbols
)(struct module
*module
)
29 struct PERBIT(kernel_symbol
) *ksyms
;
31 unsigned long i
, size
;
33 /* New-style: strings are in this section. */
34 ksymstrings
= PERBIT(load_section
)(module
->data
, "__ksymtab_strings",
39 /* Skip any zero padding. */
40 while (!ksymstrings
[i
])
43 add_symbol(ksymstrings
+i
, module
);
44 i
+= strlen(ksymstrings
+i
);
47 ksymstrings
= PERBIT(load_section
)(module
->data
,
48 "__ksymtab_strings_gpl",
51 /* Skip any zero padding. */
52 while (!ksymstrings
[i
])
55 add_symbol(ksymstrings
+i
, module
);
56 i
+= strlen(ksymstrings
+i
);
62 ksyms
= PERBIT(load_section
)(module
->data
, "__ksymtab", &size
,
64 for (i
= 0; i
< size
/ sizeof(struct PERBIT(kernel_symbol
)); i
++)
65 add_symbol(ksyms
[i
].name
, module
);
66 ksyms
= PERBIT(load_section
)(module
->data
, "__gpl_ksymtab", &size
,
68 for (i
= 0; i
< size
/ sizeof(struct PERBIT(kernel_symbol
)); i
++)
69 add_symbol(ksyms
[i
].name
, module
);
72 static char *PERBIT(get_aliases
)(struct module
*module
, unsigned long *size
)
74 return PERBIT(load_section
)(module
->data
, ".modalias", size
,
78 static char *PERBIT(get_modinfo
)(struct module
*module
, unsigned long *size
)
80 return PERBIT(load_section
)(module
->data
, ".modinfo", size
,
85 #define STT_REGISTER 13 /* Global register reserved to app. */
88 /* Calculate the dependencies for this module */
89 static void PERBIT(calculate_deps
)(struct module
*module
, int verbose
)
96 int handle_register_symbols
;
98 strings
= PERBIT(load_section
)(module
->data
, ".strtab", &size
,
100 syms
= PERBIT(load_section
)(module
->data
, ".symtab", &size
,
103 module
->num_deps
= 0;
106 if (!strings
|| !syms
) {
107 warn("Couldn't find symtab and strtab in module %s\n",
113 handle_register_symbols
= 0;
114 if (END(hdr
->e_machine
, module
->conv
) == EM_SPARC
||
115 END(hdr
->e_machine
, module
->conv
) == EM_SPARCV9
)
116 handle_register_symbols
= 1;
118 for (i
= 1; i
< size
/ sizeof(syms
[0]); i
++) {
119 if (END(syms
[i
].st_shndx
, module
->conv
) == SHN_UNDEF
) {
120 /* Look for symbol */
122 struct module
*owner
;
125 name
= strings
+ END(syms
[i
].st_name
, module
->conv
);
127 /* Not really undefined: sparc gcc 3.3 creates
128 U references when you have global asm
129 variables, to avoid anyone else misusing
131 if (handle_register_symbols
132 && (ELFPERBIT(ST_TYPE
)(END(syms
[i
].st_info
,
137 weak
= (ELFPERBIT(ST_BIND
)(END(syms
[i
].st_info
,
140 owner
= find_symbol(name
, module
->pathname
, weak
);
143 printf("%s needs \"%s\": %s\n",
144 module
->pathname
, name
,
146 add_dep(module
, owner
);
152 static void *PERBIT(deref_sym
)(ElfPERBIT(Ehdr
) *hdr
,
153 ElfPERBIT(Shdr
) *sechdrs
,
155 unsigned int *secsize
,
158 /* In BSS? Happens for empty device tables on
159 * recent GCC versions. */
160 if (END(sechdrs
[END(sym
->st_shndx
, conv
)].sh_type
,conv
) == SHT_NOBITS
)
164 *secsize
= END(sym
->st_size
, conv
);
166 + END(sechdrs
[END(sym
->st_shndx
, conv
)].sh_offset
, conv
)
167 + END(sym
->st_value
, conv
);
170 /* FIXME: Check size, unless we end up using aliases anyway --RR */
171 static void PERBIT(fetch_tables
)(struct module
*module
)
176 ElfPERBIT(Ehdr
) *hdr
;
177 ElfPERBIT(Sym
) *syms
;
178 ElfPERBIT(Shdr
) *sechdrs
;
182 sechdrs
= (void *)hdr
+ END(hdr
->e_shoff
, module
->conv
);
183 strings
= PERBIT(load_section
)(hdr
, ".strtab", &size
, module
->conv
);
184 syms
= PERBIT(load_section
)(hdr
, ".symtab", &size
, module
->conv
);
186 /* Don't warn again: we already have above */
187 if (!strings
|| !syms
)
190 module
->pci_table
= NULL
;
191 module
->usb_table
= NULL
;
192 module
->ccw_table
= NULL
;
193 module
->ieee1394_table
= NULL
;
194 module
->pnp_table
= NULL
;
195 module
->pnp_card_table
= NULL
;
196 module
->input_table
= NULL
;
197 module
->serio_table
= NULL
;
198 module
->of_table
= NULL
;
200 for (i
= 0; i
< size
/ sizeof(syms
[0]); i
++) {
201 char *name
= strings
+ END(syms
[i
].st_name
, module
->conv
);
203 if (!module
->pci_table
&& streq(name
, "__mod_pci_device_table")) {
204 module
->pci_size
= PERBIT(PCI_DEVICE_SIZE
);
205 module
->pci_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
208 else if (!module
->usb_table
&& streq(name
, "__mod_usb_device_table")) {
209 module
->usb_size
= PERBIT(USB_DEVICE_SIZE
);
210 module
->usb_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
213 else if (!module
->ccw_table
&& streq(name
, "__mod_ccw_device_table")) {
214 module
->ccw_size
= PERBIT(CCW_DEVICE_SIZE
);
215 module
->ccw_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
218 else if (!module
->ieee1394_table
&& streq(name
, "__mod_ieee1394_device_table")) {
219 module
->ieee1394_size
= PERBIT(IEEE1394_DEVICE_SIZE
);
220 module
->ieee1394_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
223 else if (!module
->pnp_table
&& streq(name
, "__mod_pnp_device_table")) {
224 module
->pnp_size
= PERBIT(PNP_DEVICE_SIZE
);
225 module
->pnp_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
228 else if (!module
->pnp_card_table
&& streq(name
, "__mod_pnp_card_device_table")) {
229 module
->pnp_card_size
= PERBIT(PNP_CARD_DEVICE_SIZE
);
230 module
->pnp_card_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
232 module
->pnp_card_offset
= PERBIT(PNP_CARD_DEVICE_OFFSET
);
234 else if (!module
->input_table
&& streq(name
, "__mod_input_device_table")) {
235 module
->input_size
= PERBIT(INPUT_DEVICE_SIZE
);
236 module
->input_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
237 &module
->input_table_size
,
240 else if (!module
->serio_table
&& streq(name
, "__mod_serio_device_table")) {
241 module
->serio_size
= PERBIT(SERIO_DEVICE_SIZE
);
242 module
->serio_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
245 else if (!module
->of_table
&& streq(name
, "__mod_of_device_table")) {
246 module
->of_size
= PERBIT(OF_DEVICE_SIZE
);
247 module
->of_table
= PERBIT(deref_sym
)(hdr
, sechdrs
, &syms
[i
],
253 struct module_ops
PERBIT(mod_ops
) = {
254 .load_symbols
= PERBIT(load_symbols
),
255 .calculate_deps
= PERBIT(calculate_deps
),
256 .fetch_tables
= PERBIT(fetch_tables
),
257 .get_aliases
= PERBIT(get_aliases
),
258 .get_modinfo
= PERBIT(get_modinfo
),