Commit 1833d6bc72893265f22addd79cf52e6987496e0f

Authored by Vivek Goyal
Committed by Andi Kleen
1 parent e073ae1b34

[PATCH] i386: modpost apic related warning fixes

o Modpost generates warnings for i386 if compiled with CONFIG_RELOCATABLE=y

WARNING: vmlinux - Section mismatch: reference to .init.text:find_unisys_acpi_oem_table from .text between 'acpi_madt_oem_check' (at offset 0xc0101eda) and 'enable_apic_mode'
WARNING: vmlinux - Section mismatch: reference to .init.text:acpi_get_table_header_early from .text between 'acpi_madt_oem_check' (at offset 0xc0101ef0) and 'enable_apic_mode'
WARNING: vmlinux - Section mismatch: reference to .init.text:parse_unisys_oem from .text between 'acpi_madt_oem_check' (at offset 0xc0101f2e) and 'enable_apic_mode'
WARNING: vmlinux - Section mismatch: reference to .init.text:setup_unisys from .text between 'acpi_madt_oem_check' (at offset 0xc0101f37) and 'enable_apic_mode'WARNING: vmlinux - Section mismatch: reference to .init.text:parse_unisys_oem from .text between 'mps_oem_check' (at offset 0xc0101ec7) and 'acpi_madt_oem_check'
WARNING: vmlinux - Section mismatch: reference to .init.text:es7000_sw_apic from .text between 'enable_apic_mode' (at offset 0xc0101f48) and 'check_apicid_present'

o Some functions which are inline (acpi_madt_oem_check) are not inlined by
  compiler as these functions are accessed using function pointer. These
  functions are put in .text section and they in-turn access __init type
  functions hence modpost generates warnings.

o Do not iniline acpi_madt_oem_check, instead make it __init.

Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Andi Kleen <ak@suse.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Showing 4 changed files with 42 additions and 39 deletions Inline Diff

arch/i386/mach-generic/es7000.c
1 /* 1 /*
2 * APIC driver for the Unisys ES7000 chipset. 2 * APIC driver for the Unisys ES7000 chipset.
3 */ 3 */
4 #define APIC_DEFINITION 1 4 #define APIC_DEFINITION 1
5 #include <linux/threads.h> 5 #include <linux/threads.h>
6 #include <linux/cpumask.h> 6 #include <linux/cpumask.h>
7 #include <asm/smp.h> 7 #include <asm/smp.h>
8 #include <asm/mpspec.h> 8 #include <asm/mpspec.h>
9 #include <asm/genapic.h> 9 #include <asm/genapic.h>
10 #include <asm/fixmap.h> 10 #include <asm/fixmap.h>
11 #include <asm/apicdef.h> 11 #include <asm/apicdef.h>
12 #include <linux/kernel.h> 12 #include <linux/kernel.h>
13 #include <linux/string.h> 13 #include <linux/string.h>
14 #include <linux/smp.h> 14 #include <linux/smp.h>
15 #include <linux/init.h> 15 #include <linux/init.h>
16 #include <asm/mach-es7000/mach_apicdef.h> 16 #include <asm/mach-es7000/mach_apicdef.h>
17 #include <asm/mach-es7000/mach_apic.h> 17 #include <asm/mach-es7000/mach_apic.h>
18 #include <asm/mach-es7000/mach_ipi.h> 18 #include <asm/mach-es7000/mach_ipi.h>
19 #include <asm/mach-es7000/mach_mpparse.h> 19 #include <asm/mach-es7000/mach_mpparse.h>
20 #include <asm/mach-es7000/mach_wakecpu.h> 20 #include <asm/mach-es7000/mach_wakecpu.h>
21 21
22 static int probe_es7000(void) 22 static int probe_es7000(void)
23 { 23 {
24 /* probed later in mptable/ACPI hooks */ 24 /* probed later in mptable/ACPI hooks */
25 return 0; 25 return 0;
26 } 26 }
27 27
28 extern void es7000_sw_apic(void);
29 static void __init enable_apic_mode(void)
30 {
31 es7000_sw_apic();
32 return;
33 }
34
35 static __init int mps_oem_check(struct mp_config_table *mpc, char *oem,
36 char *productid)
37 {
38 if (mpc->mpc_oemptr) {
39 struct mp_config_oemtable *oem_table =
40 (struct mp_config_oemtable *)mpc->mpc_oemptr;
41 if (!strncmp(oem, "UNISYS", 6))
42 return parse_unisys_oem((char *)oem_table);
43 }
44 return 0;
45 }
46
47 #ifdef CONFIG_ACPI
48 /* Hook from generic ACPI tables.c */
49 static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
50 {
51 unsigned long oem_addr;
52 if (!find_unisys_acpi_oem_table(&oem_addr)) {
53 if (es7000_check_dsdt())
54 return parse_unisys_oem((char *)oem_addr);
55 else {
56 setup_unisys();
57 return 1;
58 }
59 }
60 return 0;
61 }
62 #else
63 static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
64 {
65 return 0;
66 }
67 #endif
68
28 struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000); 69 struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000);
29 70
include/asm-i386/mach-es7000/mach_apic.h
1 #ifndef __ASM_MACH_APIC_H 1 #ifndef __ASM_MACH_APIC_H
2 #define __ASM_MACH_APIC_H 2 #define __ASM_MACH_APIC_H
3 3
4 extern u8 bios_cpu_apicid[]; 4 extern u8 bios_cpu_apicid[];
5 5
6 #define xapic_phys_to_log_apicid(cpu) (bios_cpu_apicid[cpu]) 6 #define xapic_phys_to_log_apicid(cpu) (bios_cpu_apicid[cpu])
7 #define esr_disable (1) 7 #define esr_disable (1)
8 8
9 static inline int apic_id_registered(void) 9 static inline int apic_id_registered(void)
10 { 10 {
11 return (1); 11 return (1);
12 } 12 }
13 13
14 static inline cpumask_t target_cpus(void) 14 static inline cpumask_t target_cpus(void)
15 { 15 {
16 #if defined CONFIG_ES7000_CLUSTERED_APIC 16 #if defined CONFIG_ES7000_CLUSTERED_APIC
17 return CPU_MASK_ALL; 17 return CPU_MASK_ALL;
18 #else 18 #else
19 return cpumask_of_cpu(smp_processor_id()); 19 return cpumask_of_cpu(smp_processor_id());
20 #endif 20 #endif
21 } 21 }
22 #define TARGET_CPUS (target_cpus()) 22 #define TARGET_CPUS (target_cpus())
23 23
24 #if defined CONFIG_ES7000_CLUSTERED_APIC 24 #if defined CONFIG_ES7000_CLUSTERED_APIC
25 #define APIC_DFR_VALUE (APIC_DFR_CLUSTER) 25 #define APIC_DFR_VALUE (APIC_DFR_CLUSTER)
26 #define INT_DELIVERY_MODE (dest_LowestPrio) 26 #define INT_DELIVERY_MODE (dest_LowestPrio)
27 #define INT_DEST_MODE (1) /* logical delivery broadcast to all procs */ 27 #define INT_DEST_MODE (1) /* logical delivery broadcast to all procs */
28 #define NO_BALANCE_IRQ (1) 28 #define NO_BALANCE_IRQ (1)
29 #undef WAKE_SECONDARY_VIA_INIT 29 #undef WAKE_SECONDARY_VIA_INIT
30 #define WAKE_SECONDARY_VIA_MIP 30 #define WAKE_SECONDARY_VIA_MIP
31 #else 31 #else
32 #define APIC_DFR_VALUE (APIC_DFR_FLAT) 32 #define APIC_DFR_VALUE (APIC_DFR_FLAT)
33 #define INT_DELIVERY_MODE (dest_Fixed) 33 #define INT_DELIVERY_MODE (dest_Fixed)
34 #define INT_DEST_MODE (0) /* phys delivery to target procs */ 34 #define INT_DEST_MODE (0) /* phys delivery to target procs */
35 #define NO_BALANCE_IRQ (0) 35 #define NO_BALANCE_IRQ (0)
36 #undef APIC_DEST_LOGICAL 36 #undef APIC_DEST_LOGICAL
37 #define APIC_DEST_LOGICAL 0x0 37 #define APIC_DEST_LOGICAL 0x0
38 #define WAKE_SECONDARY_VIA_INIT 38 #define WAKE_SECONDARY_VIA_INIT
39 #endif 39 #endif
40 40
41 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) 41 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
42 { 42 {
43 return 0; 43 return 0;
44 } 44 }
45 static inline unsigned long check_apicid_present(int bit) 45 static inline unsigned long check_apicid_present(int bit)
46 { 46 {
47 return physid_isset(bit, phys_cpu_present_map); 47 return physid_isset(bit, phys_cpu_present_map);
48 } 48 }
49 49
50 #define apicid_cluster(apicid) (apicid & 0xF0) 50 #define apicid_cluster(apicid) (apicid & 0xF0)
51 51
52 static inline unsigned long calculate_ldr(int cpu) 52 static inline unsigned long calculate_ldr(int cpu)
53 { 53 {
54 unsigned long id; 54 unsigned long id;
55 id = xapic_phys_to_log_apicid(cpu); 55 id = xapic_phys_to_log_apicid(cpu);
56 return (SET_APIC_LOGICAL_ID(id)); 56 return (SET_APIC_LOGICAL_ID(id));
57 } 57 }
58 58
59 /* 59 /*
60 * Set up the logical destination ID. 60 * Set up the logical destination ID.
61 * 61 *
62 * Intel recommends to set DFR, LdR and TPR before enabling 62 * Intel recommends to set DFR, LdR and TPR before enabling
63 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 63 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
64 * document number 292116). So here it goes... 64 * document number 292116). So here it goes...
65 */ 65 */
66 static inline void init_apic_ldr(void) 66 static inline void init_apic_ldr(void)
67 { 67 {
68 unsigned long val; 68 unsigned long val;
69 int cpu = smp_processor_id(); 69 int cpu = smp_processor_id();
70 70
71 apic_write_around(APIC_DFR, APIC_DFR_VALUE); 71 apic_write_around(APIC_DFR, APIC_DFR_VALUE);
72 val = calculate_ldr(cpu); 72 val = calculate_ldr(cpu);
73 apic_write_around(APIC_LDR, val); 73 apic_write_around(APIC_LDR, val);
74 } 74 }
75 75
76 extern void es7000_sw_apic(void);
77 static inline void enable_apic_mode(void)
78 {
79 es7000_sw_apic();
80 return;
81 }
82
83 extern int apic_version [MAX_APICS]; 76 extern int apic_version [MAX_APICS];
84 static inline void setup_apic_routing(void) 77 static inline void setup_apic_routing(void)
85 { 78 {
86 int apic = bios_cpu_apicid[smp_processor_id()]; 79 int apic = bios_cpu_apicid[smp_processor_id()];
87 printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", 80 printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
88 (apic_version[apic] == 0x14) ? 81 (apic_version[apic] == 0x14) ?
89 "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]); 82 "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]);
90 } 83 }
91 84
92 static inline int multi_timer_check(int apic, int irq) 85 static inline int multi_timer_check(int apic, int irq)
93 { 86 {
94 return 0; 87 return 0;
95 } 88 }
96 89
97 static inline int apicid_to_node(int logical_apicid) 90 static inline int apicid_to_node(int logical_apicid)
98 { 91 {
99 return 0; 92 return 0;
100 } 93 }
101 94
102 95
103 static inline int cpu_present_to_apicid(int mps_cpu) 96 static inline int cpu_present_to_apicid(int mps_cpu)
104 { 97 {
105 if (!mps_cpu) 98 if (!mps_cpu)
106 return boot_cpu_physical_apicid; 99 return boot_cpu_physical_apicid;
107 else if (mps_cpu < NR_CPUS) 100 else if (mps_cpu < NR_CPUS)
108 return (int) bios_cpu_apicid[mps_cpu]; 101 return (int) bios_cpu_apicid[mps_cpu];
109 else 102 else
110 return BAD_APICID; 103 return BAD_APICID;
111 } 104 }
112 105
113 static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) 106 static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
114 { 107 {
115 static int id = 0; 108 static int id = 0;
116 physid_mask_t mask; 109 physid_mask_t mask;
117 mask = physid_mask_of_physid(id); 110 mask = physid_mask_of_physid(id);
118 ++id; 111 ++id;
119 return mask; 112 return mask;
120 } 113 }
121 114
122 extern u8 cpu_2_logical_apicid[]; 115 extern u8 cpu_2_logical_apicid[];
123 /* Mapping from cpu number to logical apicid */ 116 /* Mapping from cpu number to logical apicid */
124 static inline int cpu_to_logical_apicid(int cpu) 117 static inline int cpu_to_logical_apicid(int cpu)
125 { 118 {
126 #ifdef CONFIG_SMP 119 #ifdef CONFIG_SMP
127 if (cpu >= NR_CPUS) 120 if (cpu >= NR_CPUS)
128 return BAD_APICID; 121 return BAD_APICID;
129 return (int)cpu_2_logical_apicid[cpu]; 122 return (int)cpu_2_logical_apicid[cpu];
130 #else 123 #else
131 return logical_smp_processor_id(); 124 return logical_smp_processor_id();
132 #endif 125 #endif
133 } 126 }
134 127
135 static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused) 128 static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused)
136 { 129 {
137 printk("Processor #%d %ld:%ld APIC version %d\n", 130 printk("Processor #%d %ld:%ld APIC version %d\n",
138 m->mpc_apicid, 131 m->mpc_apicid,
139 (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, 132 (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
140 (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, 133 (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
141 m->mpc_apicver); 134 m->mpc_apicver);
142 return (m->mpc_apicid); 135 return (m->mpc_apicid);
143 } 136 }
144 137
145 static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) 138 static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
146 { 139 {
147 /* For clustered we don't have a good way to do this yet - hack */ 140 /* For clustered we don't have a good way to do this yet - hack */
148 return physids_promote(0xff); 141 return physids_promote(0xff);
149 } 142 }
150 143
151 144
152 static inline void setup_portio_remap(void) 145 static inline void setup_portio_remap(void)
153 { 146 {
154 } 147 }
155 148
156 extern unsigned int boot_cpu_physical_apicid; 149 extern unsigned int boot_cpu_physical_apicid;
157 static inline int check_phys_apicid_present(int cpu_physical_apicid) 150 static inline int check_phys_apicid_present(int cpu_physical_apicid)
158 { 151 {
159 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 152 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
160 return (1); 153 return (1);
161 } 154 }
162 155
163 static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) 156 static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
164 { 157 {
165 int num_bits_set; 158 int num_bits_set;
166 int cpus_found = 0; 159 int cpus_found = 0;
167 int cpu; 160 int cpu;
168 int apicid; 161 int apicid;
169 162
170 num_bits_set = cpus_weight(cpumask); 163 num_bits_set = cpus_weight(cpumask);
171 /* Return id to all */ 164 /* Return id to all */
172 if (num_bits_set == NR_CPUS) 165 if (num_bits_set == NR_CPUS)
173 #if defined CONFIG_ES7000_CLUSTERED_APIC 166 #if defined CONFIG_ES7000_CLUSTERED_APIC
174 return 0xFF; 167 return 0xFF;
175 #else 168 #else
176 return cpu_to_logical_apicid(0); 169 return cpu_to_logical_apicid(0);
177 #endif 170 #endif
178 /* 171 /*
179 * The cpus in the mask must all be on the apic cluster. If are not 172 * The cpus in the mask must all be on the apic cluster. If are not
180 * on the same apicid cluster return default value of TARGET_CPUS. 173 * on the same apicid cluster return default value of TARGET_CPUS.
181 */ 174 */
182 cpu = first_cpu(cpumask); 175 cpu = first_cpu(cpumask);
183 apicid = cpu_to_logical_apicid(cpu); 176 apicid = cpu_to_logical_apicid(cpu);
184 while (cpus_found < num_bits_set) { 177 while (cpus_found < num_bits_set) {
185 if (cpu_isset(cpu, cpumask)) { 178 if (cpu_isset(cpu, cpumask)) {
186 int new_apicid = cpu_to_logical_apicid(cpu); 179 int new_apicid = cpu_to_logical_apicid(cpu);
187 if (apicid_cluster(apicid) != 180 if (apicid_cluster(apicid) !=
188 apicid_cluster(new_apicid)){ 181 apicid_cluster(new_apicid)){
189 printk ("%s: Not a valid mask!\n",__FUNCTION__); 182 printk ("%s: Not a valid mask!\n",__FUNCTION__);
190 #if defined CONFIG_ES7000_CLUSTERED_APIC 183 #if defined CONFIG_ES7000_CLUSTERED_APIC
191 return 0xFF; 184 return 0xFF;
192 #else 185 #else
193 return cpu_to_logical_apicid(0); 186 return cpu_to_logical_apicid(0);
194 #endif 187 #endif
195 } 188 }
196 apicid = new_apicid; 189 apicid = new_apicid;
197 cpus_found++; 190 cpus_found++;
198 } 191 }
199 cpu++; 192 cpu++;
200 } 193 }
201 return apicid; 194 return apicid;
202 } 195 }
203 196
204 static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) 197 static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
205 { 198 {
206 return cpuid_apic >> index_msb; 199 return cpuid_apic >> index_msb;
207 } 200 }
208 201
209 #endif /* __ASM_MACH_APIC_H */ 202 #endif /* __ASM_MACH_APIC_H */
210 203
include/asm-i386/mach-es7000/mach_mpparse.h
1 #ifndef __ASM_MACH_MPPARSE_H 1 #ifndef __ASM_MACH_MPPARSE_H
2 #define __ASM_MACH_MPPARSE_H 2 #define __ASM_MACH_MPPARSE_H
3 3
4 #include <linux/acpi.h> 4 #include <linux/acpi.h>
5 5
6 static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, 6 static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
7 struct mpc_config_translation *translation) 7 struct mpc_config_translation *translation)
8 { 8 {
9 Dprintk("Bus #%d is %s\n", m->mpc_busid, name); 9 Dprintk("Bus #%d is %s\n", m->mpc_busid, name);
10 } 10 }
11 11
12 static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, 12 static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
13 struct mpc_config_translation *translation) 13 struct mpc_config_translation *translation)
14 { 14 {
15 } 15 }
16 16
17 extern int parse_unisys_oem (char *oemptr); 17 extern int parse_unisys_oem (char *oemptr);
18 extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); 18 extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
19 extern void setup_unisys(void); 19 extern void setup_unisys(void);
20 20
21 static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
22 char *productid)
23 {
24 if (mpc->mpc_oemptr) {
25 struct mp_config_oemtable *oem_table =
26 (struct mp_config_oemtable *)mpc->mpc_oemptr;
27 if (!strncmp(oem, "UNISYS", 6))
28 return parse_unisys_oem((char *)oem_table);
29 }
30 return 0;
31 }
32
33 #ifdef CONFIG_ACPI 21 #ifdef CONFIG_ACPI
34 22
35 static inline int es7000_check_dsdt(void) 23 static inline int es7000_check_dsdt(void)
36 { 24 {
37 struct acpi_table_header header; 25 struct acpi_table_header header;
38 memcpy(&header, 0, sizeof(struct acpi_table_header)); 26 memcpy(&header, 0, sizeof(struct acpi_table_header));
39 acpi_get_table_header(ACPI_SIG_DSDT, 0, &header); 27 acpi_get_table_header(ACPI_SIG_DSDT, 0, &header);
40 if (!strncmp(header.oem_id, "UNISYS", 6)) 28 if (!strncmp(header.oem_id, "UNISYS", 6))
41 return 1; 29 return 1;
42 return 0;
43 }
44
45 /* Hook from generic ACPI tables.c */
46 static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
47 {
48 unsigned long oem_addr;
49 if (!find_unisys_acpi_oem_table(&oem_addr)) {
50 if (es7000_check_dsdt())
51 return parse_unisys_oem((char *)oem_addr);
52 else {
53 setup_unisys();
54 return 1;
55 }
56 }
57 return 0;
58 }
59 #else
60 static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
61 {
62 return 0; 30 return 0;
63 } 31 }
64 #endif 32 #endif
65 33
66 #endif /* __ASM_MACH_MPPARSE_H */ 34 #endif /* __ASM_MACH_MPPARSE_H */
67 35
scripts/mod/modpost.c
1 /* Postprocess module symbol versions 1 /* Postprocess module symbol versions
2 * 2 *
3 * Copyright 2003 Kai Germaschewski 3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation 4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
5 * Copyright 2006 Sam Ravnborg 5 * Copyright 2006 Sam Ravnborg
6 * Based in part on module-init-tools/depmod.c,file2alias 6 * Based in part on module-init-tools/depmod.c,file2alias
7 * 7 *
8 * This software may be used and distributed according to the terms 8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference. 9 * of the GNU General Public License, incorporated herein by reference.
10 * 10 *
11 * Usage: modpost vmlinux module1.o module2.o ... 11 * Usage: modpost vmlinux module1.o module2.o ...
12 */ 12 */
13 13
14 #include <ctype.h> 14 #include <ctype.h>
15 #include "modpost.h" 15 #include "modpost.h"
16 #include "../../include/linux/license.h" 16 #include "../../include/linux/license.h"
17 17
18 /* Are we using CONFIG_MODVERSIONS? */ 18 /* Are we using CONFIG_MODVERSIONS? */
19 int modversions = 0; 19 int modversions = 0;
20 /* Warn about undefined symbols? (do so if we have vmlinux) */ 20 /* Warn about undefined symbols? (do so if we have vmlinux) */
21 int have_vmlinux = 0; 21 int have_vmlinux = 0;
22 /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ 22 /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
23 static int all_versions = 0; 23 static int all_versions = 0;
24 /* If we are modposting external module set to 1 */ 24 /* If we are modposting external module set to 1 */
25 static int external_module = 0; 25 static int external_module = 0;
26 /* Only warn about unresolved symbols */ 26 /* Only warn about unresolved symbols */
27 static int warn_unresolved = 0; 27 static int warn_unresolved = 0;
28 /* How a symbol is exported */ 28 /* How a symbol is exported */
29 enum export { 29 enum export {
30 export_plain, export_unused, export_gpl, 30 export_plain, export_unused, export_gpl,
31 export_unused_gpl, export_gpl_future, export_unknown 31 export_unused_gpl, export_gpl_future, export_unknown
32 }; 32 };
33 33
34 void fatal(const char *fmt, ...) 34 void fatal(const char *fmt, ...)
35 { 35 {
36 va_list arglist; 36 va_list arglist;
37 37
38 fprintf(stderr, "FATAL: "); 38 fprintf(stderr, "FATAL: ");
39 39
40 va_start(arglist, fmt); 40 va_start(arglist, fmt);
41 vfprintf(stderr, fmt, arglist); 41 vfprintf(stderr, fmt, arglist);
42 va_end(arglist); 42 va_end(arglist);
43 43
44 exit(1); 44 exit(1);
45 } 45 }
46 46
47 void warn(const char *fmt, ...) 47 void warn(const char *fmt, ...)
48 { 48 {
49 va_list arglist; 49 va_list arglist;
50 50
51 fprintf(stderr, "WARNING: "); 51 fprintf(stderr, "WARNING: ");
52 52
53 va_start(arglist, fmt); 53 va_start(arglist, fmt);
54 vfprintf(stderr, fmt, arglist); 54 vfprintf(stderr, fmt, arglist);
55 va_end(arglist); 55 va_end(arglist);
56 } 56 }
57 57
58 static int is_vmlinux(const char *modname) 58 static int is_vmlinux(const char *modname)
59 { 59 {
60 const char *myname; 60 const char *myname;
61 61
62 if ((myname = strrchr(modname, '/'))) 62 if ((myname = strrchr(modname, '/')))
63 myname++; 63 myname++;
64 else 64 else
65 myname = modname; 65 myname = modname;
66 66
67 return strcmp(myname, "vmlinux") == 0; 67 return strcmp(myname, "vmlinux") == 0;
68 } 68 }
69 69
70 void *do_nofail(void *ptr, const char *expr) 70 void *do_nofail(void *ptr, const char *expr)
71 { 71 {
72 if (!ptr) { 72 if (!ptr) {
73 fatal("modpost: Memory allocation failure: %s.\n", expr); 73 fatal("modpost: Memory allocation failure: %s.\n", expr);
74 } 74 }
75 return ptr; 75 return ptr;
76 } 76 }
77 77
78 /* A list of all modules we processed */ 78 /* A list of all modules we processed */
79 79
80 static struct module *modules; 80 static struct module *modules;
81 81
82 static struct module *find_module(char *modname) 82 static struct module *find_module(char *modname)
83 { 83 {
84 struct module *mod; 84 struct module *mod;
85 85
86 for (mod = modules; mod; mod = mod->next) 86 for (mod = modules; mod; mod = mod->next)
87 if (strcmp(mod->name, modname) == 0) 87 if (strcmp(mod->name, modname) == 0)
88 break; 88 break;
89 return mod; 89 return mod;
90 } 90 }
91 91
92 static struct module *new_module(char *modname) 92 static struct module *new_module(char *modname)
93 { 93 {
94 struct module *mod; 94 struct module *mod;
95 char *p, *s; 95 char *p, *s;
96 96
97 mod = NOFAIL(malloc(sizeof(*mod))); 97 mod = NOFAIL(malloc(sizeof(*mod)));
98 memset(mod, 0, sizeof(*mod)); 98 memset(mod, 0, sizeof(*mod));
99 p = NOFAIL(strdup(modname)); 99 p = NOFAIL(strdup(modname));
100 100
101 /* strip trailing .o */ 101 /* strip trailing .o */
102 if ((s = strrchr(p, '.')) != NULL) 102 if ((s = strrchr(p, '.')) != NULL)
103 if (strcmp(s, ".o") == 0) 103 if (strcmp(s, ".o") == 0)
104 *s = '\0'; 104 *s = '\0';
105 105
106 /* add to list */ 106 /* add to list */
107 mod->name = p; 107 mod->name = p;
108 mod->gpl_compatible = -1; 108 mod->gpl_compatible = -1;
109 mod->next = modules; 109 mod->next = modules;
110 modules = mod; 110 modules = mod;
111 111
112 return mod; 112 return mod;
113 } 113 }
114 114
115 /* A hash of all exported symbols, 115 /* A hash of all exported symbols,
116 * struct symbol is also used for lists of unresolved symbols */ 116 * struct symbol is also used for lists of unresolved symbols */
117 117
118 #define SYMBOL_HASH_SIZE 1024 118 #define SYMBOL_HASH_SIZE 1024
119 119
120 struct symbol { 120 struct symbol {
121 struct symbol *next; 121 struct symbol *next;
122 struct module *module; 122 struct module *module;
123 unsigned int crc; 123 unsigned int crc;
124 int crc_valid; 124 int crc_valid;
125 unsigned int weak:1; 125 unsigned int weak:1;
126 unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ 126 unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
127 unsigned int kernel:1; /* 1 if symbol is from kernel 127 unsigned int kernel:1; /* 1 if symbol is from kernel
128 * (only for external modules) **/ 128 * (only for external modules) **/
129 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ 129 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
130 enum export export; /* Type of export */ 130 enum export export; /* Type of export */
131 char name[0]; 131 char name[0];
132 }; 132 };
133 133
134 static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; 134 static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
135 135
136 /* This is based on the hash agorithm from gdbm, via tdb */ 136 /* This is based on the hash agorithm from gdbm, via tdb */
137 static inline unsigned int tdb_hash(const char *name) 137 static inline unsigned int tdb_hash(const char *name)
138 { 138 {
139 unsigned value; /* Used to compute the hash value. */ 139 unsigned value; /* Used to compute the hash value. */
140 unsigned i; /* Used to cycle through random values. */ 140 unsigned i; /* Used to cycle through random values. */
141 141
142 /* Set the initial value from the key size. */ 142 /* Set the initial value from the key size. */
143 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) 143 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
144 value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); 144 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
145 145
146 return (1103515243 * value + 12345); 146 return (1103515243 * value + 12345);
147 } 147 }
148 148
149 /** 149 /**
150 * Allocate a new symbols for use in the hash of exported symbols or 150 * Allocate a new symbols for use in the hash of exported symbols or
151 * the list of unresolved symbols per module 151 * the list of unresolved symbols per module
152 **/ 152 **/
153 static struct symbol *alloc_symbol(const char *name, unsigned int weak, 153 static struct symbol *alloc_symbol(const char *name, unsigned int weak,
154 struct symbol *next) 154 struct symbol *next)
155 { 155 {
156 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); 156 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
157 157
158 memset(s, 0, sizeof(*s)); 158 memset(s, 0, sizeof(*s));
159 strcpy(s->name, name); 159 strcpy(s->name, name);
160 s->weak = weak; 160 s->weak = weak;
161 s->next = next; 161 s->next = next;
162 return s; 162 return s;
163 } 163 }
164 164
165 /* For the hash of exported symbols */ 165 /* For the hash of exported symbols */
166 static struct symbol *new_symbol(const char *name, struct module *module, 166 static struct symbol *new_symbol(const char *name, struct module *module,
167 enum export export) 167 enum export export)
168 { 168 {
169 unsigned int hash; 169 unsigned int hash;
170 struct symbol *new; 170 struct symbol *new;
171 171
172 hash = tdb_hash(name) % SYMBOL_HASH_SIZE; 172 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
173 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); 173 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
174 new->module = module; 174 new->module = module;
175 new->export = export; 175 new->export = export;
176 return new; 176 return new;
177 } 177 }
178 178
179 static struct symbol *find_symbol(const char *name) 179 static struct symbol *find_symbol(const char *name)
180 { 180 {
181 struct symbol *s; 181 struct symbol *s;
182 182
183 /* For our purposes, .foo matches foo. PPC64 needs this. */ 183 /* For our purposes, .foo matches foo. PPC64 needs this. */
184 if (name[0] == '.') 184 if (name[0] == '.')
185 name++; 185 name++;
186 186
187 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) { 187 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
188 if (strcmp(s->name, name) == 0) 188 if (strcmp(s->name, name) == 0)
189 return s; 189 return s;
190 } 190 }
191 return NULL; 191 return NULL;
192 } 192 }
193 193
194 static struct { 194 static struct {
195 const char *str; 195 const char *str;
196 enum export export; 196 enum export export;
197 } export_list[] = { 197 } export_list[] = {
198 { .str = "EXPORT_SYMBOL", .export = export_plain }, 198 { .str = "EXPORT_SYMBOL", .export = export_plain },
199 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused }, 199 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
200 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, 200 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
201 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl }, 201 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
202 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future }, 202 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
203 { .str = "(unknown)", .export = export_unknown }, 203 { .str = "(unknown)", .export = export_unknown },
204 }; 204 };
205 205
206 206
207 static const char *export_str(enum export ex) 207 static const char *export_str(enum export ex)
208 { 208 {
209 return export_list[ex].str; 209 return export_list[ex].str;
210 } 210 }
211 211
212 static enum export export_no(const char * s) 212 static enum export export_no(const char * s)
213 { 213 {
214 int i; 214 int i;
215 if (!s) 215 if (!s)
216 return export_unknown; 216 return export_unknown;
217 for (i = 0; export_list[i].export != export_unknown; i++) { 217 for (i = 0; export_list[i].export != export_unknown; i++) {
218 if (strcmp(export_list[i].str, s) == 0) 218 if (strcmp(export_list[i].str, s) == 0)
219 return export_list[i].export; 219 return export_list[i].export;
220 } 220 }
221 return export_unknown; 221 return export_unknown;
222 } 222 }
223 223
224 static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) 224 static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
225 { 225 {
226 if (sec == elf->export_sec) 226 if (sec == elf->export_sec)
227 return export_plain; 227 return export_plain;
228 else if (sec == elf->export_unused_sec) 228 else if (sec == elf->export_unused_sec)
229 return export_unused; 229 return export_unused;
230 else if (sec == elf->export_gpl_sec) 230 else if (sec == elf->export_gpl_sec)
231 return export_gpl; 231 return export_gpl;
232 else if (sec == elf->export_unused_gpl_sec) 232 else if (sec == elf->export_unused_gpl_sec)
233 return export_unused_gpl; 233 return export_unused_gpl;
234 else if (sec == elf->export_gpl_future_sec) 234 else if (sec == elf->export_gpl_future_sec)
235 return export_gpl_future; 235 return export_gpl_future;
236 else 236 else
237 return export_unknown; 237 return export_unknown;
238 } 238 }
239 239
240 /** 240 /**
241 * Add an exported symbol - it may have already been added without a 241 * Add an exported symbol - it may have already been added without a
242 * CRC, in this case just update the CRC 242 * CRC, in this case just update the CRC
243 **/ 243 **/
244 static struct symbol *sym_add_exported(const char *name, struct module *mod, 244 static struct symbol *sym_add_exported(const char *name, struct module *mod,
245 enum export export) 245 enum export export)
246 { 246 {
247 struct symbol *s = find_symbol(name); 247 struct symbol *s = find_symbol(name);
248 248
249 if (!s) { 249 if (!s) {
250 s = new_symbol(name, mod, export); 250 s = new_symbol(name, mod, export);
251 } else { 251 } else {
252 if (!s->preloaded) { 252 if (!s->preloaded) {
253 warn("%s: '%s' exported twice. Previous export " 253 warn("%s: '%s' exported twice. Previous export "
254 "was in %s%s\n", mod->name, name, 254 "was in %s%s\n", mod->name, name,
255 s->module->name, 255 s->module->name,
256 is_vmlinux(s->module->name) ?"":".ko"); 256 is_vmlinux(s->module->name) ?"":".ko");
257 } 257 }
258 } 258 }
259 s->preloaded = 0; 259 s->preloaded = 0;
260 s->vmlinux = is_vmlinux(mod->name); 260 s->vmlinux = is_vmlinux(mod->name);
261 s->kernel = 0; 261 s->kernel = 0;
262 s->export = export; 262 s->export = export;
263 return s; 263 return s;
264 } 264 }
265 265
266 static void sym_update_crc(const char *name, struct module *mod, 266 static void sym_update_crc(const char *name, struct module *mod,
267 unsigned int crc, enum export export) 267 unsigned int crc, enum export export)
268 { 268 {
269 struct symbol *s = find_symbol(name); 269 struct symbol *s = find_symbol(name);
270 270
271 if (!s) 271 if (!s)
272 s = new_symbol(name, mod, export); 272 s = new_symbol(name, mod, export);
273 s->crc = crc; 273 s->crc = crc;
274 s->crc_valid = 1; 274 s->crc_valid = 1;
275 } 275 }
276 276
277 void *grab_file(const char *filename, unsigned long *size) 277 void *grab_file(const char *filename, unsigned long *size)
278 { 278 {
279 struct stat st; 279 struct stat st;
280 void *map; 280 void *map;
281 int fd; 281 int fd;
282 282
283 fd = open(filename, O_RDONLY); 283 fd = open(filename, O_RDONLY);
284 if (fd < 0 || fstat(fd, &st) != 0) 284 if (fd < 0 || fstat(fd, &st) != 0)
285 return NULL; 285 return NULL;
286 286
287 *size = st.st_size; 287 *size = st.st_size;
288 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); 288 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
289 close(fd); 289 close(fd);
290 290
291 if (map == MAP_FAILED) 291 if (map == MAP_FAILED)
292 return NULL; 292 return NULL;
293 return map; 293 return map;
294 } 294 }
295 295
296 /** 296 /**
297 * Return a copy of the next line in a mmap'ed file. 297 * Return a copy of the next line in a mmap'ed file.
298 * spaces in the beginning of the line is trimmed away. 298 * spaces in the beginning of the line is trimmed away.
299 * Return a pointer to a static buffer. 299 * Return a pointer to a static buffer.
300 **/ 300 **/
301 char* get_next_line(unsigned long *pos, void *file, unsigned long size) 301 char* get_next_line(unsigned long *pos, void *file, unsigned long size)
302 { 302 {
303 static char line[4096]; 303 static char line[4096];
304 int skip = 1; 304 int skip = 1;
305 size_t len = 0; 305 size_t len = 0;
306 signed char *p = (signed char *)file + *pos; 306 signed char *p = (signed char *)file + *pos;
307 char *s = line; 307 char *s = line;
308 308
309 for (; *pos < size ; (*pos)++) 309 for (; *pos < size ; (*pos)++)
310 { 310 {
311 if (skip && isspace(*p)) { 311 if (skip && isspace(*p)) {
312 p++; 312 p++;
313 continue; 313 continue;
314 } 314 }
315 skip = 0; 315 skip = 0;
316 if (*p != '\n' && (*pos < size)) { 316 if (*p != '\n' && (*pos < size)) {
317 len++; 317 len++;
318 *s++ = *p++; 318 *s++ = *p++;
319 if (len > 4095) 319 if (len > 4095)
320 break; /* Too long, stop */ 320 break; /* Too long, stop */
321 } else { 321 } else {
322 /* End of string */ 322 /* End of string */
323 *s = '\0'; 323 *s = '\0';
324 return line; 324 return line;
325 } 325 }
326 } 326 }
327 /* End of buffer */ 327 /* End of buffer */
328 return NULL; 328 return NULL;
329 } 329 }
330 330
331 void release_file(void *file, unsigned long size) 331 void release_file(void *file, unsigned long size)
332 { 332 {
333 munmap(file, size); 333 munmap(file, size);
334 } 334 }
335 335
336 static void parse_elf(struct elf_info *info, const char *filename) 336 static void parse_elf(struct elf_info *info, const char *filename)
337 { 337 {
338 unsigned int i; 338 unsigned int i;
339 Elf_Ehdr *hdr = info->hdr; 339 Elf_Ehdr *hdr = info->hdr;
340 Elf_Shdr *sechdrs; 340 Elf_Shdr *sechdrs;
341 Elf_Sym *sym; 341 Elf_Sym *sym;
342 342
343 hdr = grab_file(filename, &info->size); 343 hdr = grab_file(filename, &info->size);
344 if (!hdr) { 344 if (!hdr) {
345 perror(filename); 345 perror(filename);
346 exit(1); 346 exit(1);
347 } 347 }
348 info->hdr = hdr; 348 info->hdr = hdr;
349 if (info->size < sizeof(*hdr)) 349 if (info->size < sizeof(*hdr))
350 goto truncated; 350 goto truncated;
351 351
352 /* Fix endianness in ELF header */ 352 /* Fix endianness in ELF header */
353 hdr->e_shoff = TO_NATIVE(hdr->e_shoff); 353 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
354 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); 354 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
355 hdr->e_shnum = TO_NATIVE(hdr->e_shnum); 355 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
356 hdr->e_machine = TO_NATIVE(hdr->e_machine); 356 hdr->e_machine = TO_NATIVE(hdr->e_machine);
357 sechdrs = (void *)hdr + hdr->e_shoff; 357 sechdrs = (void *)hdr + hdr->e_shoff;
358 info->sechdrs = sechdrs; 358 info->sechdrs = sechdrs;
359 359
360 /* Fix endianness in section headers */ 360 /* Fix endianness in section headers */
361 for (i = 0; i < hdr->e_shnum; i++) { 361 for (i = 0; i < hdr->e_shnum; i++) {
362 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); 362 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
363 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); 363 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
364 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); 364 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
365 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); 365 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
366 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); 366 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
367 } 367 }
368 /* Find symbol table. */ 368 /* Find symbol table. */
369 for (i = 1; i < hdr->e_shnum; i++) { 369 for (i = 1; i < hdr->e_shnum; i++) {
370 const char *secstrings 370 const char *secstrings
371 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 371 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
372 const char *secname; 372 const char *secname;
373 373
374 if (sechdrs[i].sh_offset > info->size) 374 if (sechdrs[i].sh_offset > info->size)
375 goto truncated; 375 goto truncated;
376 secname = secstrings + sechdrs[i].sh_name; 376 secname = secstrings + sechdrs[i].sh_name;
377 if (strcmp(secname, ".modinfo") == 0) { 377 if (strcmp(secname, ".modinfo") == 0) {
378 info->modinfo = (void *)hdr + sechdrs[i].sh_offset; 378 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
379 info->modinfo_len = sechdrs[i].sh_size; 379 info->modinfo_len = sechdrs[i].sh_size;
380 } else if (strcmp(secname, "__ksymtab") == 0) 380 } else if (strcmp(secname, "__ksymtab") == 0)
381 info->export_sec = i; 381 info->export_sec = i;
382 else if (strcmp(secname, "__ksymtab_unused") == 0) 382 else if (strcmp(secname, "__ksymtab_unused") == 0)
383 info->export_unused_sec = i; 383 info->export_unused_sec = i;
384 else if (strcmp(secname, "__ksymtab_gpl") == 0) 384 else if (strcmp(secname, "__ksymtab_gpl") == 0)
385 info->export_gpl_sec = i; 385 info->export_gpl_sec = i;
386 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0) 386 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
387 info->export_unused_gpl_sec = i; 387 info->export_unused_gpl_sec = i;
388 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 388 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
389 info->export_gpl_future_sec = i; 389 info->export_gpl_future_sec = i;
390 390
391 if (sechdrs[i].sh_type != SHT_SYMTAB) 391 if (sechdrs[i].sh_type != SHT_SYMTAB)
392 continue; 392 continue;
393 393
394 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; 394 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
395 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset 395 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
396 + sechdrs[i].sh_size; 396 + sechdrs[i].sh_size;
397 info->strtab = (void *)hdr + 397 info->strtab = (void *)hdr +
398 sechdrs[sechdrs[i].sh_link].sh_offset; 398 sechdrs[sechdrs[i].sh_link].sh_offset;
399 } 399 }
400 if (!info->symtab_start) { 400 if (!info->symtab_start) {
401 fatal("%s has no symtab?\n", filename); 401 fatal("%s has no symtab?\n", filename);
402 } 402 }
403 /* Fix endianness in symbols */ 403 /* Fix endianness in symbols */
404 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { 404 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
405 sym->st_shndx = TO_NATIVE(sym->st_shndx); 405 sym->st_shndx = TO_NATIVE(sym->st_shndx);
406 sym->st_name = TO_NATIVE(sym->st_name); 406 sym->st_name = TO_NATIVE(sym->st_name);
407 sym->st_value = TO_NATIVE(sym->st_value); 407 sym->st_value = TO_NATIVE(sym->st_value);
408 sym->st_size = TO_NATIVE(sym->st_size); 408 sym->st_size = TO_NATIVE(sym->st_size);
409 } 409 }
410 return; 410 return;
411 411
412 truncated: 412 truncated:
413 fatal("%s is truncated.\n", filename); 413 fatal("%s is truncated.\n", filename);
414 } 414 }
415 415
416 static void parse_elf_finish(struct elf_info *info) 416 static void parse_elf_finish(struct elf_info *info)
417 { 417 {
418 release_file(info->hdr, info->size); 418 release_file(info->hdr, info->size);
419 } 419 }
420 420
421 #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" 421 #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
422 #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" 422 #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
423 423
424 static void handle_modversions(struct module *mod, struct elf_info *info, 424 static void handle_modversions(struct module *mod, struct elf_info *info,
425 Elf_Sym *sym, const char *symname) 425 Elf_Sym *sym, const char *symname)
426 { 426 {
427 unsigned int crc; 427 unsigned int crc;
428 enum export export = export_from_sec(info, sym->st_shndx); 428 enum export export = export_from_sec(info, sym->st_shndx);
429 429
430 switch (sym->st_shndx) { 430 switch (sym->st_shndx) {
431 case SHN_COMMON: 431 case SHN_COMMON:
432 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); 432 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
433 break; 433 break;
434 case SHN_ABS: 434 case SHN_ABS:
435 /* CRC'd symbol */ 435 /* CRC'd symbol */
436 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 436 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
437 crc = (unsigned int) sym->st_value; 437 crc = (unsigned int) sym->st_value;
438 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 438 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
439 export); 439 export);
440 } 440 }
441 break; 441 break;
442 case SHN_UNDEF: 442 case SHN_UNDEF:
443 /* undefined symbol */ 443 /* undefined symbol */
444 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && 444 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
445 ELF_ST_BIND(sym->st_info) != STB_WEAK) 445 ELF_ST_BIND(sym->st_info) != STB_WEAK)
446 break; 446 break;
447 /* ignore global offset table */ 447 /* ignore global offset table */
448 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) 448 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
449 break; 449 break;
450 /* ignore __this_module, it will be resolved shortly */ 450 /* ignore __this_module, it will be resolved shortly */
451 if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) 451 if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
452 break; 452 break;
453 /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */ 453 /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */
454 #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER) 454 #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
455 /* add compatibility with older glibc */ 455 /* add compatibility with older glibc */
456 #ifndef STT_SPARC_REGISTER 456 #ifndef STT_SPARC_REGISTER
457 #define STT_SPARC_REGISTER STT_REGISTER 457 #define STT_SPARC_REGISTER STT_REGISTER
458 #endif 458 #endif
459 if (info->hdr->e_machine == EM_SPARC || 459 if (info->hdr->e_machine == EM_SPARC ||
460 info->hdr->e_machine == EM_SPARCV9) { 460 info->hdr->e_machine == EM_SPARCV9) {
461 /* Ignore register directives. */ 461 /* Ignore register directives. */
462 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) 462 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
463 break; 463 break;
464 if (symname[0] == '.') { 464 if (symname[0] == '.') {
465 char *munged = strdup(symname); 465 char *munged = strdup(symname);
466 munged[0] = '_'; 466 munged[0] = '_';
467 munged[1] = toupper(munged[1]); 467 munged[1] = toupper(munged[1]);
468 symname = munged; 468 symname = munged;
469 } 469 }
470 } 470 }
471 #endif 471 #endif
472 472
473 if (memcmp(symname, MODULE_SYMBOL_PREFIX, 473 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
474 strlen(MODULE_SYMBOL_PREFIX)) == 0) 474 strlen(MODULE_SYMBOL_PREFIX)) == 0)
475 mod->unres = alloc_symbol(symname + 475 mod->unres = alloc_symbol(symname +
476 strlen(MODULE_SYMBOL_PREFIX), 476 strlen(MODULE_SYMBOL_PREFIX),
477 ELF_ST_BIND(sym->st_info) == STB_WEAK, 477 ELF_ST_BIND(sym->st_info) == STB_WEAK,
478 mod->unres); 478 mod->unres);
479 break; 479 break;
480 default: 480 default:
481 /* All exported symbols */ 481 /* All exported symbols */
482 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 482 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
483 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, 483 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
484 export); 484 export);
485 } 485 }
486 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) 486 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
487 mod->has_init = 1; 487 mod->has_init = 1;
488 if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0) 488 if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
489 mod->has_cleanup = 1; 489 mod->has_cleanup = 1;
490 break; 490 break;
491 } 491 }
492 } 492 }
493 493
494 /** 494 /**
495 * Parse tag=value strings from .modinfo section 495 * Parse tag=value strings from .modinfo section
496 **/ 496 **/
497 static char *next_string(char *string, unsigned long *secsize) 497 static char *next_string(char *string, unsigned long *secsize)
498 { 498 {
499 /* Skip non-zero chars */ 499 /* Skip non-zero chars */
500 while (string[0]) { 500 while (string[0]) {
501 string++; 501 string++;
502 if ((*secsize)-- <= 1) 502 if ((*secsize)-- <= 1)
503 return NULL; 503 return NULL;
504 } 504 }
505 505
506 /* Skip any zero padding. */ 506 /* Skip any zero padding. */
507 while (!string[0]) { 507 while (!string[0]) {
508 string++; 508 string++;
509 if ((*secsize)-- <= 1) 509 if ((*secsize)-- <= 1)
510 return NULL; 510 return NULL;
511 } 511 }
512 return string; 512 return string;
513 } 513 }
514 514
515 static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len, 515 static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
516 const char *tag, char *info) 516 const char *tag, char *info)
517 { 517 {
518 char *p; 518 char *p;
519 unsigned int taglen = strlen(tag); 519 unsigned int taglen = strlen(tag);
520 unsigned long size = modinfo_len; 520 unsigned long size = modinfo_len;
521 521
522 if (info) { 522 if (info) {
523 size -= info - (char *)modinfo; 523 size -= info - (char *)modinfo;
524 modinfo = next_string(info, &size); 524 modinfo = next_string(info, &size);
525 } 525 }
526 526
527 for (p = modinfo; p; p = next_string(p, &size)) { 527 for (p = modinfo; p; p = next_string(p, &size)) {
528 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') 528 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
529 return p + taglen + 1; 529 return p + taglen + 1;
530 } 530 }
531 return NULL; 531 return NULL;
532 } 532 }
533 533
534 static char *get_modinfo(void *modinfo, unsigned long modinfo_len, 534 static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
535 const char *tag) 535 const char *tag)
536 536
537 { 537 {
538 return get_next_modinfo(modinfo, modinfo_len, tag, NULL); 538 return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
539 } 539 }
540 540
541 /** 541 /**
542 * Test if string s ends in string sub 542 * Test if string s ends in string sub
543 * return 0 if match 543 * return 0 if match
544 **/ 544 **/
545 static int strrcmp(const char *s, const char *sub) 545 static int strrcmp(const char *s, const char *sub)
546 { 546 {
547 int slen, sublen; 547 int slen, sublen;
548 548
549 if (!s || !sub) 549 if (!s || !sub)
550 return 1; 550 return 1;
551 551
552 slen = strlen(s); 552 slen = strlen(s);
553 sublen = strlen(sub); 553 sublen = strlen(sub);
554 554
555 if ((slen == 0) || (sublen == 0)) 555 if ((slen == 0) || (sublen == 0))
556 return 1; 556 return 1;
557 557
558 if (sublen > slen) 558 if (sublen > slen)
559 return 1; 559 return 1;
560 560
561 return memcmp(s + slen - sublen, sub, sublen); 561 return memcmp(s + slen - sublen, sub, sublen);
562 } 562 }
563 563
564 /** 564 /**
565 * Whitelist to allow certain references to pass with no warning. 565 * Whitelist to allow certain references to pass with no warning.
566 * Pattern 1: 566 * Pattern 1:
567 * If a module parameter is declared __initdata and permissions=0 567 * If a module parameter is declared __initdata and permissions=0
568 * then this is legal despite the warning generated. 568 * then this is legal despite the warning generated.
569 * We cannot see value of permissions here, so just ignore 569 * We cannot see value of permissions here, so just ignore
570 * this pattern. 570 * this pattern.
571 * The pattern is identified by: 571 * The pattern is identified by:
572 * tosec = .init.data 572 * tosec = .init.data
573 * fromsec = .data* 573 * fromsec = .data*
574 * atsym =__param* 574 * atsym =__param*
575 * 575 *
576 * Pattern 2: 576 * Pattern 2:
577 * Many drivers utilise a *driver container with references to 577 * Many drivers utilise a *driver container with references to
578 * add, remove, probe functions etc. 578 * add, remove, probe functions etc.
579 * These functions may often be marked __init and we do not want to 579 * These functions may often be marked __init and we do not want to
580 * warn here. 580 * warn here.
581 * the pattern is identified by: 581 * the pattern is identified by:
582 * tosec = .init.text | .exit.text | .init.data 582 * tosec = .init.text | .exit.text | .init.data
583 * fromsec = .data 583 * fromsec = .data
584 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one 584 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
585 * 585 *
586 * Pattern 3: 586 * Pattern 3:
587 * Some symbols belong to init section but still it is ok to reference 587 * Some symbols belong to init section but still it is ok to reference
588 * these from non-init sections as these symbols don't have any memory 588 * these from non-init sections as these symbols don't have any memory
589 * allocated for them and symbol address and value are same. So even 589 * allocated for them and symbol address and value are same. So even
590 * if init section is freed, its ok to reference those symbols. 590 * if init section is freed, its ok to reference those symbols.
591 * For ex. symbols marking the init section boundaries. 591 * For ex. symbols marking the init section boundaries.
592 * This pattern is identified by 592 * This pattern is identified by
593 * refsymname = __init_begin, _sinittext, _einittext 593 * refsymname = __init_begin, _sinittext, _einittext
594 **/ 594 **/
595 static int secref_whitelist(const char *modname, const char *tosec, 595 static int secref_whitelist(const char *modname, const char *tosec,
596 const char *fromsec, const char *atsym, 596 const char *fromsec, const char *atsym,
597 const char *refsymname) 597 const char *refsymname)
598 { 598 {
599 int f1 = 1, f2 = 1; 599 int f1 = 1, f2 = 1;
600 const char **s; 600 const char **s;
601 const char *pat2sym[] = { 601 const char *pat2sym[] = {
602 "driver", 602 "driver",
603 "_template", /* scsi uses *_template a lot */ 603 "_template", /* scsi uses *_template a lot */
604 "_sht", /* scsi also used *_sht to some extent */ 604 "_sht", /* scsi also used *_sht to some extent */
605 "_ops", 605 "_ops",
606 "_probe", 606 "_probe",
607 "_probe_one", 607 "_probe_one",
608 "_console", 608 "_console",
609 "apic_es7000",
609 NULL 610 NULL
610 }; 611 };
611 612
612 const char *pat3refsym[] = { 613 const char *pat3refsym[] = {
613 "__init_begin", 614 "__init_begin",
614 "_sinittext", 615 "_sinittext",
615 "_einittext", 616 "_einittext",
616 NULL 617 NULL
617 }; 618 };
618 619
619 /* Check for pattern 1 */ 620 /* Check for pattern 1 */
620 if (strcmp(tosec, ".init.data") != 0) 621 if (strcmp(tosec, ".init.data") != 0)
621 f1 = 0; 622 f1 = 0;
622 if (strncmp(fromsec, ".data", strlen(".data")) != 0) 623 if (strncmp(fromsec, ".data", strlen(".data")) != 0)
623 f1 = 0; 624 f1 = 0;
624 if (strncmp(atsym, "__param", strlen("__param")) != 0) 625 if (strncmp(atsym, "__param", strlen("__param")) != 0)
625 f1 = 0; 626 f1 = 0;
626 627
627 if (f1) 628 if (f1)
628 return f1; 629 return f1;
629 630
630 /* Check for pattern 2 */ 631 /* Check for pattern 2 */
631 if ((strcmp(tosec, ".init.text") != 0) && 632 if ((strcmp(tosec, ".init.text") != 0) &&
632 (strcmp(tosec, ".exit.text") != 0) && 633 (strcmp(tosec, ".exit.text") != 0) &&
633 (strcmp(tosec, ".init.data") != 0)) 634 (strcmp(tosec, ".init.data") != 0))
634 f2 = 0; 635 f2 = 0;
635 if (strcmp(fromsec, ".data") != 0) 636 if (strcmp(fromsec, ".data") != 0)
636 f2 = 0; 637 f2 = 0;
637 638
638 for (s = pat2sym; *s; s++) 639 for (s = pat2sym; *s; s++)
639 if (strrcmp(atsym, *s) == 0) 640 if (strrcmp(atsym, *s) == 0)
640 f1 = 1; 641 f1 = 1;
641 if (f1 && f2) 642 if (f1 && f2)
642 return 1; 643 return 1;
643 644
644 /* Whitelist all references from .pci_fixup section if vmlinux 645 /* Whitelist all references from .pci_fixup section if vmlinux
645 * Whitelist all refereces from .text.head to .init.data if vmlinux 646 * Whitelist all refereces from .text.head to .init.data if vmlinux
646 * Whitelist all refereces from .text.head to .init.text if vmlinux 647 * Whitelist all refereces from .text.head to .init.text if vmlinux
647 */ 648 */
648 if (is_vmlinux(modname)) { 649 if (is_vmlinux(modname)) {
649 if ((strcmp(fromsec, ".pci_fixup") == 0) && 650 if ((strcmp(fromsec, ".pci_fixup") == 0) &&
650 (strcmp(tosec, ".init.text") == 0)) 651 (strcmp(tosec, ".init.text") == 0))
651 return 1; 652 return 1;
652 653
653 if ((strcmp(fromsec, ".text.head") == 0) && 654 if ((strcmp(fromsec, ".text.head") == 0) &&
654 ((strcmp(tosec, ".init.data") == 0) || 655 ((strcmp(tosec, ".init.data") == 0) ||
655 (strcmp(tosec, ".init.text") == 0))) 656 (strcmp(tosec, ".init.text") == 0)))
656 return 1; 657 return 1;
657 658
658 /* Check for pattern 3 */ 659 /* Check for pattern 3 */
659 for (s = pat3refsym; *s; s++) 660 for (s = pat3refsym; *s; s++)
660 if (strcmp(refsymname, *s) == 0) 661 if (strcmp(refsymname, *s) == 0)
661 return 1; 662 return 1;
662 } 663 }
663 return 0; 664 return 0;
664 } 665 }
665 666
666 /** 667 /**
667 * Find symbol based on relocation record info. 668 * Find symbol based on relocation record info.
668 * In some cases the symbol supplied is a valid symbol so 669 * In some cases the symbol supplied is a valid symbol so
669 * return refsym. If st_name != 0 we assume this is a valid symbol. 670 * return refsym. If st_name != 0 we assume this is a valid symbol.
670 * In other cases the symbol needs to be looked up in the symbol table 671 * In other cases the symbol needs to be looked up in the symbol table
671 * based on section and address. 672 * based on section and address.
672 * **/ 673 * **/
673 static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, 674 static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
674 Elf_Sym *relsym) 675 Elf_Sym *relsym)
675 { 676 {
676 Elf_Sym *sym; 677 Elf_Sym *sym;
677 678
678 if (relsym->st_name != 0) 679 if (relsym->st_name != 0)
679 return relsym; 680 return relsym;
680 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 681 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
681 if (sym->st_shndx != relsym->st_shndx) 682 if (sym->st_shndx != relsym->st_shndx)
682 continue; 683 continue;
683 if (sym->st_value == addr) 684 if (sym->st_value == addr)
684 return sym; 685 return sym;
685 } 686 }
686 return NULL; 687 return NULL;
687 } 688 }
688 689
689 static inline int is_arm_mapping_symbol(const char *str) 690 static inline int is_arm_mapping_symbol(const char *str)
690 { 691 {
691 return str[0] == '$' && strchr("atd", str[1]) 692 return str[0] == '$' && strchr("atd", str[1])
692 && (str[2] == '\0' || str[2] == '.'); 693 && (str[2] == '\0' || str[2] == '.');
693 } 694 }
694 695
695 /* 696 /*
696 * If there's no name there, ignore it; likewise, ignore it if it's 697 * If there's no name there, ignore it; likewise, ignore it if it's
697 * one of the magic symbols emitted used by current ARM tools. 698 * one of the magic symbols emitted used by current ARM tools.
698 * 699 *
699 * Otherwise if find_symbols_between() returns those symbols, they'll 700 * Otherwise if find_symbols_between() returns those symbols, they'll
700 * fail the whitelist tests and cause lots of false alarms ... fixable 701 * fail the whitelist tests and cause lots of false alarms ... fixable
701 * only by merging __exit and __init sections into __text, bloating 702 * only by merging __exit and __init sections into __text, bloating
702 * the kernel (which is especially evil on embedded platforms). 703 * the kernel (which is especially evil on embedded platforms).
703 */ 704 */
704 static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) 705 static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
705 { 706 {
706 const char *name = elf->strtab + sym->st_name; 707 const char *name = elf->strtab + sym->st_name;
707 708
708 if (!name || !strlen(name)) 709 if (!name || !strlen(name))
709 return 0; 710 return 0;
710 return !is_arm_mapping_symbol(name); 711 return !is_arm_mapping_symbol(name);
711 } 712 }
712 713
713 /* 714 /*
714 * Find symbols before or equal addr and after addr - in the section sec. 715 * Find symbols before or equal addr and after addr - in the section sec.
715 * If we find two symbols with equal offset prefer one with a valid name. 716 * If we find two symbols with equal offset prefer one with a valid name.
716 * The ELF format may have a better way to detect what type of symbol 717 * The ELF format may have a better way to detect what type of symbol
717 * it is, but this works for now. 718 * it is, but this works for now.
718 **/ 719 **/
719 static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, 720 static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
720 const char *sec, 721 const char *sec,
721 Elf_Sym **before, Elf_Sym **after) 722 Elf_Sym **before, Elf_Sym **after)
722 { 723 {
723 Elf_Sym *sym; 724 Elf_Sym *sym;
724 Elf_Ehdr *hdr = elf->hdr; 725 Elf_Ehdr *hdr = elf->hdr;
725 Elf_Addr beforediff = ~0; 726 Elf_Addr beforediff = ~0;
726 Elf_Addr afterdiff = ~0; 727 Elf_Addr afterdiff = ~0;
727 const char *secstrings = (void *)hdr + 728 const char *secstrings = (void *)hdr +
728 elf->sechdrs[hdr->e_shstrndx].sh_offset; 729 elf->sechdrs[hdr->e_shstrndx].sh_offset;
729 730
730 *before = NULL; 731 *before = NULL;
731 *after = NULL; 732 *after = NULL;
732 733
733 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 734 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
734 const char *symsec; 735 const char *symsec;
735 736
736 if (sym->st_shndx >= SHN_LORESERVE) 737 if (sym->st_shndx >= SHN_LORESERVE)
737 continue; 738 continue;
738 symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name; 739 symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
739 if (strcmp(symsec, sec) != 0) 740 if (strcmp(symsec, sec) != 0)
740 continue; 741 continue;
741 if (!is_valid_name(elf, sym)) 742 if (!is_valid_name(elf, sym))
742 continue; 743 continue;
743 if (sym->st_value <= addr) { 744 if (sym->st_value <= addr) {
744 if ((addr - sym->st_value) < beforediff) { 745 if ((addr - sym->st_value) < beforediff) {
745 beforediff = addr - sym->st_value; 746 beforediff = addr - sym->st_value;
746 *before = sym; 747 *before = sym;
747 } 748 }
748 else if ((addr - sym->st_value) == beforediff) { 749 else if ((addr - sym->st_value) == beforediff) {
749 *before = sym; 750 *before = sym;
750 } 751 }
751 } 752 }
752 else 753 else
753 { 754 {
754 if ((sym->st_value - addr) < afterdiff) { 755 if ((sym->st_value - addr) < afterdiff) {
755 afterdiff = sym->st_value - addr; 756 afterdiff = sym->st_value - addr;
756 *after = sym; 757 *after = sym;
757 } 758 }
758 else if ((sym->st_value - addr) == afterdiff) { 759 else if ((sym->st_value - addr) == afterdiff) {
759 *after = sym; 760 *after = sym;
760 } 761 }
761 } 762 }
762 } 763 }
763 } 764 }
764 765
765 /** 766 /**
766 * Print a warning about a section mismatch. 767 * Print a warning about a section mismatch.
767 * Try to find symbols near it so user can find it. 768 * Try to find symbols near it so user can find it.
768 * Check whitelist before warning - it may be a false positive. 769 * Check whitelist before warning - it may be a false positive.
769 **/ 770 **/
770 static void warn_sec_mismatch(const char *modname, const char *fromsec, 771 static void warn_sec_mismatch(const char *modname, const char *fromsec,
771 struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) 772 struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
772 { 773 {
773 const char *refsymname = ""; 774 const char *refsymname = "";
774 Elf_Sym *before, *after; 775 Elf_Sym *before, *after;
775 Elf_Sym *refsym; 776 Elf_Sym *refsym;
776 Elf_Ehdr *hdr = elf->hdr; 777 Elf_Ehdr *hdr = elf->hdr;
777 Elf_Shdr *sechdrs = elf->sechdrs; 778 Elf_Shdr *sechdrs = elf->sechdrs;
778 const char *secstrings = (void *)hdr + 779 const char *secstrings = (void *)hdr +
779 sechdrs[hdr->e_shstrndx].sh_offset; 780 sechdrs[hdr->e_shstrndx].sh_offset;
780 const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; 781 const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
781 782
782 find_symbols_between(elf, r.r_offset, fromsec, &before, &after); 783 find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
783 784
784 refsym = find_elf_symbol(elf, r.r_addend, sym); 785 refsym = find_elf_symbol(elf, r.r_addend, sym);
785 if (refsym && strlen(elf->strtab + refsym->st_name)) 786 if (refsym && strlen(elf->strtab + refsym->st_name))
786 refsymname = elf->strtab + refsym->st_name; 787 refsymname = elf->strtab + refsym->st_name;
787 788
788 /* check whitelist - we may ignore it */ 789 /* check whitelist - we may ignore it */
789 if (before && 790 if (before &&
790 secref_whitelist(modname, secname, fromsec, 791 secref_whitelist(modname, secname, fromsec,
791 elf->strtab + before->st_name, refsymname)) 792 elf->strtab + before->st_name, refsymname))
792 return; 793 return;
793 794
794 if (before && after) { 795 if (before && after) {
795 warn("%s - Section mismatch: reference to %s:%s from %s " 796 warn("%s - Section mismatch: reference to %s:%s from %s "
796 "between '%s' (at offset 0x%llx) and '%s'\n", 797 "between '%s' (at offset 0x%llx) and '%s'\n",
797 modname, secname, refsymname, fromsec, 798 modname, secname, refsymname, fromsec,
798 elf->strtab + before->st_name, 799 elf->strtab + before->st_name,
799 (long long)r.r_offset, 800 (long long)r.r_offset,
800 elf->strtab + after->st_name); 801 elf->strtab + after->st_name);
801 } else if (before) { 802 } else if (before) {
802 warn("%s - Section mismatch: reference to %s:%s from %s " 803 warn("%s - Section mismatch: reference to %s:%s from %s "
803 "after '%s' (at offset 0x%llx)\n", 804 "after '%s' (at offset 0x%llx)\n",
804 modname, secname, refsymname, fromsec, 805 modname, secname, refsymname, fromsec,
805 elf->strtab + before->st_name, 806 elf->strtab + before->st_name,
806 (long long)r.r_offset); 807 (long long)r.r_offset);
807 } else if (after) { 808 } else if (after) {
808 warn("%s - Section mismatch: reference to %s:%s from %s " 809 warn("%s - Section mismatch: reference to %s:%s from %s "
809 "before '%s' (at offset -0x%llx)\n", 810 "before '%s' (at offset -0x%llx)\n",
810 modname, secname, refsymname, fromsec, 811 modname, secname, refsymname, fromsec,
811 elf->strtab + after->st_name, 812 elf->strtab + after->st_name,
812 (long long)r.r_offset); 813 (long long)r.r_offset);
813 } else { 814 } else {
814 warn("%s - Section mismatch: reference to %s:%s from %s " 815 warn("%s - Section mismatch: reference to %s:%s from %s "
815 "(offset 0x%llx)\n", 816 "(offset 0x%llx)\n",
816 modname, secname, fromsec, refsymname, 817 modname, secname, fromsec, refsymname,
817 (long long)r.r_offset); 818 (long long)r.r_offset);
818 } 819 }
819 } 820 }
820 821
821 /** 822 /**
822 * A module includes a number of sections that are discarded 823 * A module includes a number of sections that are discarded
823 * either when loaded or when used as built-in. 824 * either when loaded or when used as built-in.
824 * For loaded modules all functions marked __init and all data 825 * For loaded modules all functions marked __init and all data
825 * marked __initdata will be discarded when the module has been intialized. 826 * marked __initdata will be discarded when the module has been intialized.
826 * Likewise for modules used built-in the sections marked __exit 827 * Likewise for modules used built-in the sections marked __exit
827 * are discarded because __exit marked function are supposed to be called 828 * are discarded because __exit marked function are supposed to be called
828 * only when a moduel is unloaded which never happes for built-in modules. 829 * only when a moduel is unloaded which never happes for built-in modules.
829 * The check_sec_ref() function traverses all relocation records 830 * The check_sec_ref() function traverses all relocation records
830 * to find all references to a section that reference a section that will 831 * to find all references to a section that reference a section that will
831 * be discarded and warns about it. 832 * be discarded and warns about it.
832 **/ 833 **/
833 static void check_sec_ref(struct module *mod, const char *modname, 834 static void check_sec_ref(struct module *mod, const char *modname,
834 struct elf_info *elf, 835 struct elf_info *elf,
835 int section(const char*), 836 int section(const char*),
836 int section_ref_ok(const char *)) 837 int section_ref_ok(const char *))
837 { 838 {
838 int i; 839 int i;
839 Elf_Sym *sym; 840 Elf_Sym *sym;
840 Elf_Ehdr *hdr = elf->hdr; 841 Elf_Ehdr *hdr = elf->hdr;
841 Elf_Shdr *sechdrs = elf->sechdrs; 842 Elf_Shdr *sechdrs = elf->sechdrs;
842 const char *secstrings = (void *)hdr + 843 const char *secstrings = (void *)hdr +
843 sechdrs[hdr->e_shstrndx].sh_offset; 844 sechdrs[hdr->e_shstrndx].sh_offset;
844 845
845 /* Walk through all sections */ 846 /* Walk through all sections */
846 for (i = 0; i < hdr->e_shnum; i++) { 847 for (i = 0; i < hdr->e_shnum; i++) {
847 const char *name = secstrings + sechdrs[i].sh_name; 848 const char *name = secstrings + sechdrs[i].sh_name;
848 const char *secname; 849 const char *secname;
849 Elf_Rela r; 850 Elf_Rela r;
850 unsigned int r_sym; 851 unsigned int r_sym;
851 /* We want to process only relocation sections and not .init */ 852 /* We want to process only relocation sections and not .init */
852 if (sechdrs[i].sh_type == SHT_RELA) { 853 if (sechdrs[i].sh_type == SHT_RELA) {
853 Elf_Rela *rela; 854 Elf_Rela *rela;
854 Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; 855 Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
855 Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; 856 Elf_Rela *stop = (void*)start + sechdrs[i].sh_size;
856 name += strlen(".rela"); 857 name += strlen(".rela");
857 if (section_ref_ok(name)) 858 if (section_ref_ok(name))
858 continue; 859 continue;
859 860
860 for (rela = start; rela < stop; rela++) { 861 for (rela = start; rela < stop; rela++) {
861 r.r_offset = TO_NATIVE(rela->r_offset); 862 r.r_offset = TO_NATIVE(rela->r_offset);
862 #if KERNEL_ELFCLASS == ELFCLASS64 863 #if KERNEL_ELFCLASS == ELFCLASS64
863 if (hdr->e_machine == EM_MIPS) { 864 if (hdr->e_machine == EM_MIPS) {
864 r_sym = ELF64_MIPS_R_SYM(rela->r_info); 865 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
865 r_sym = TO_NATIVE(r_sym); 866 r_sym = TO_NATIVE(r_sym);
866 } else { 867 } else {
867 r.r_info = TO_NATIVE(rela->r_info); 868 r.r_info = TO_NATIVE(rela->r_info);
868 r_sym = ELF_R_SYM(r.r_info); 869 r_sym = ELF_R_SYM(r.r_info);
869 } 870 }
870 #else 871 #else
871 r.r_info = TO_NATIVE(rela->r_info); 872 r.r_info = TO_NATIVE(rela->r_info);
872 r_sym = ELF_R_SYM(r.r_info); 873 r_sym = ELF_R_SYM(r.r_info);
873 #endif 874 #endif
874 r.r_addend = TO_NATIVE(rela->r_addend); 875 r.r_addend = TO_NATIVE(rela->r_addend);
875 sym = elf->symtab_start + r_sym; 876 sym = elf->symtab_start + r_sym;
876 /* Skip special sections */ 877 /* Skip special sections */
877 if (sym->st_shndx >= SHN_LORESERVE) 878 if (sym->st_shndx >= SHN_LORESERVE)
878 continue; 879 continue;
879 880
880 secname = secstrings + 881 secname = secstrings +
881 sechdrs[sym->st_shndx].sh_name; 882 sechdrs[sym->st_shndx].sh_name;
882 if (section(secname)) 883 if (section(secname))
883 warn_sec_mismatch(modname, name, 884 warn_sec_mismatch(modname, name,
884 elf, sym, r); 885 elf, sym, r);
885 } 886 }
886 } else if (sechdrs[i].sh_type == SHT_REL) { 887 } else if (sechdrs[i].sh_type == SHT_REL) {
887 Elf_Rel *rel; 888 Elf_Rel *rel;
888 Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset; 889 Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset;
889 Elf_Rel *stop = (void*)start + sechdrs[i].sh_size; 890 Elf_Rel *stop = (void*)start + sechdrs[i].sh_size;
890 name += strlen(".rel"); 891 name += strlen(".rel");
891 if (section_ref_ok(name)) 892 if (section_ref_ok(name))
892 continue; 893 continue;
893 894
894 for (rel = start; rel < stop; rel++) { 895 for (rel = start; rel < stop; rel++) {
895 r.r_offset = TO_NATIVE(rel->r_offset); 896 r.r_offset = TO_NATIVE(rel->r_offset);
896 #if KERNEL_ELFCLASS == ELFCLASS64 897 #if KERNEL_ELFCLASS == ELFCLASS64
897 if (hdr->e_machine == EM_MIPS) { 898 if (hdr->e_machine == EM_MIPS) {
898 r_sym = ELF64_MIPS_R_SYM(rel->r_info); 899 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
899 r_sym = TO_NATIVE(r_sym); 900 r_sym = TO_NATIVE(r_sym);
900 } else { 901 } else {
901 r.r_info = TO_NATIVE(rel->r_info); 902 r.r_info = TO_NATIVE(rel->r_info);
902 r_sym = ELF_R_SYM(r.r_info); 903 r_sym = ELF_R_SYM(r.r_info);
903 } 904 }
904 #else 905 #else
905 r.r_info = TO_NATIVE(rel->r_info); 906 r.r_info = TO_NATIVE(rel->r_info);
906 r_sym = ELF_R_SYM(r.r_info); 907 r_sym = ELF_R_SYM(r.r_info);
907 #endif 908 #endif
908 r.r_addend = 0; 909 r.r_addend = 0;
909 sym = elf->symtab_start + r_sym; 910 sym = elf->symtab_start + r_sym;
910 /* Skip special sections */ 911 /* Skip special sections */
911 if (sym->st_shndx >= SHN_LORESERVE) 912 if (sym->st_shndx >= SHN_LORESERVE)
912 continue; 913 continue;
913 914
914 secname = secstrings + 915 secname = secstrings +
915 sechdrs[sym->st_shndx].sh_name; 916 sechdrs[sym->st_shndx].sh_name;
916 if (section(secname)) 917 if (section(secname))
917 warn_sec_mismatch(modname, name, 918 warn_sec_mismatch(modname, name,
918 elf, sym, r); 919 elf, sym, r);
919 } 920 }
920 } 921 }
921 } 922 }
922 } 923 }
923 924
924 /** 925 /**
925 * Functions used only during module init is marked __init and is stored in 926 * Functions used only during module init is marked __init and is stored in
926 * a .init.text section. Likewise data is marked __initdata and stored in 927 * a .init.text section. Likewise data is marked __initdata and stored in
927 * a .init.data section. 928 * a .init.data section.
928 * If this section is one of these sections return 1 929 * If this section is one of these sections return 1
929 * See include/linux/init.h for the details 930 * See include/linux/init.h for the details
930 **/ 931 **/
931 static int init_section(const char *name) 932 static int init_section(const char *name)
932 { 933 {
933 if (strcmp(name, ".init") == 0) 934 if (strcmp(name, ".init") == 0)
934 return 1; 935 return 1;
935 if (strncmp(name, ".init.", strlen(".init.")) == 0) 936 if (strncmp(name, ".init.", strlen(".init.")) == 0)
936 return 1; 937 return 1;
937 return 0; 938 return 0;
938 } 939 }
939 940
940 /** 941 /**
941 * Identify sections from which references to a .init section is OK. 942 * Identify sections from which references to a .init section is OK.
942 * 943 *
943 * Unfortunately references to read only data that referenced .init 944 * Unfortunately references to read only data that referenced .init
944 * sections had to be excluded. Almost all of these are false 945 * sections had to be excluded. Almost all of these are false
945 * positives, they are created by gcc. The downside of excluding rodata 946 * positives, they are created by gcc. The downside of excluding rodata
946 * is that there really are some user references from rodata to 947 * is that there really are some user references from rodata to
947 * init code, e.g. drivers/video/vgacon.c: 948 * init code, e.g. drivers/video/vgacon.c:
948 * 949 *
949 * const struct consw vga_con = { 950 * const struct consw vga_con = {
950 * con_startup: vgacon_startup, 951 * con_startup: vgacon_startup,
951 * 952 *
952 * where vgacon_startup is __init. If you want to wade through the false 953 * where vgacon_startup is __init. If you want to wade through the false
953 * positives, take out the check for rodata. 954 * positives, take out the check for rodata.
954 **/ 955 **/
955 static int init_section_ref_ok(const char *name) 956 static int init_section_ref_ok(const char *name)
956 { 957 {
957 const char **s; 958 const char **s;
958 /* Absolute section names */ 959 /* Absolute section names */
959 const char *namelist1[] = { 960 const char *namelist1[] = {
960 ".init", 961 ".init",
961 ".opd", /* see comment [OPD] at exit_section_ref_ok() */ 962 ".opd", /* see comment [OPD] at exit_section_ref_ok() */
962 ".toc1", /* used by ppc64 */ 963 ".toc1", /* used by ppc64 */
963 ".stab", 964 ".stab",
964 ".data.rel.ro", /* used by parisc64 */ 965 ".data.rel.ro", /* used by parisc64 */
965 ".parainstructions", 966 ".parainstructions",
966 ".text.lock", 967 ".text.lock",
967 "__bug_table", /* used by powerpc for BUG() */ 968 "__bug_table", /* used by powerpc for BUG() */
968 ".pci_fixup_header", 969 ".pci_fixup_header",
969 ".pci_fixup_final", 970 ".pci_fixup_final",
970 ".pdr", 971 ".pdr",
971 "__param", 972 "__param",
972 "__ex_table", 973 "__ex_table",
973 ".fixup", 974 ".fixup",
974 ".smp_locks", 975 ".smp_locks",
975 ".plt", /* seen on ARCH=um build on x86_64. Harmless */ 976 ".plt", /* seen on ARCH=um build on x86_64. Harmless */
976 "__ftr_fixup", /* powerpc cpu feature fixup */ 977 "__ftr_fixup", /* powerpc cpu feature fixup */
977 "__fw_ftr_fixup", /* powerpc firmware feature fixup */ 978 "__fw_ftr_fixup", /* powerpc firmware feature fixup */
978 NULL 979 NULL
979 }; 980 };
980 /* Start of section names */ 981 /* Start of section names */
981 const char *namelist2[] = { 982 const char *namelist2[] = {
982 ".init.", 983 ".init.",
983 ".altinstructions", 984 ".altinstructions",
984 ".eh_frame", 985 ".eh_frame",
985 ".debug", 986 ".debug",
986 ".parainstructions", 987 ".parainstructions",
987 ".rodata", 988 ".rodata",
988 NULL 989 NULL
989 }; 990 };
990 /* part of section name */ 991 /* part of section name */
991 const char *namelist3 [] = { 992 const char *namelist3 [] = {
992 ".unwind", /* sample: IA_64.unwind.init.text */ 993 ".unwind", /* sample: IA_64.unwind.init.text */
993 NULL 994 NULL
994 }; 995 };
995 996
996 for (s = namelist1; *s; s++) 997 for (s = namelist1; *s; s++)
997 if (strcmp(*s, name) == 0) 998 if (strcmp(*s, name) == 0)
998 return 1; 999 return 1;
999 for (s = namelist2; *s; s++) 1000 for (s = namelist2; *s; s++)
1000 if (strncmp(*s, name, strlen(*s)) == 0) 1001 if (strncmp(*s, name, strlen(*s)) == 0)
1001 return 1; 1002 return 1;
1002 for (s = namelist3; *s; s++) 1003 for (s = namelist3; *s; s++)
1003 if (strstr(name, *s) != NULL) 1004 if (strstr(name, *s) != NULL)
1004 return 1; 1005 return 1;
1005 if (strrcmp(name, ".init") == 0) 1006 if (strrcmp(name, ".init") == 0)
1006 return 1; 1007 return 1;
1007 return 0; 1008 return 0;
1008 } 1009 }
1009 1010
1010 /* 1011 /*
1011 * Functions used only during module exit is marked __exit and is stored in 1012 * Functions used only during module exit is marked __exit and is stored in
1012 * a .exit.text section. Likewise data is marked __exitdata and stored in 1013 * a .exit.text section. Likewise data is marked __exitdata and stored in
1013 * a .exit.data section. 1014 * a .exit.data section.
1014 * If this section is one of these sections return 1 1015 * If this section is one of these sections return 1
1015 * See include/linux/init.h for the details 1016 * See include/linux/init.h for the details
1016 **/ 1017 **/
1017 static int exit_section(const char *name) 1018 static int exit_section(const char *name)
1018 { 1019 {
1019 if (strcmp(name, ".exit.text") == 0) 1020 if (strcmp(name, ".exit.text") == 0)
1020 return 1; 1021 return 1;
1021 if (strcmp(name, ".exit.data") == 0) 1022 if (strcmp(name, ".exit.data") == 0)
1022 return 1; 1023 return 1;
1023 return 0; 1024 return 0;
1024 1025
1025 } 1026 }
1026 1027
1027 /* 1028 /*
1028 * Identify sections from which references to a .exit section is OK. 1029 * Identify sections from which references to a .exit section is OK.
1029 * 1030 *
1030 * [OPD] Keith Ownes <kaos@sgi.com> commented: 1031 * [OPD] Keith Ownes <kaos@sgi.com> commented:
1031 * For our future {in}sanity, add a comment that this is the ppc .opd 1032 * For our future {in}sanity, add a comment that this is the ppc .opd
1032 * section, not the ia64 .opd section. 1033 * section, not the ia64 .opd section.
1033 * ia64 .opd should not point to discarded sections. 1034 * ia64 .opd should not point to discarded sections.
1034 * [.rodata] like for .init.text we ignore .rodata references -same reason 1035 * [.rodata] like for .init.text we ignore .rodata references -same reason
1035 **/ 1036 **/
1036 static int exit_section_ref_ok(const char *name) 1037 static int exit_section_ref_ok(const char *name)
1037 { 1038 {
1038 const char **s; 1039 const char **s;
1039 /* Absolute section names */ 1040 /* Absolute section names */
1040 const char *namelist1[] = { 1041 const char *namelist1[] = {
1041 ".exit.text", 1042 ".exit.text",
1042 ".exit.data", 1043 ".exit.data",
1043 ".init.text", 1044 ".init.text",
1044 ".rodata", 1045 ".rodata",
1045 ".opd", /* See comment [OPD] */ 1046 ".opd", /* See comment [OPD] */
1046 ".toc1", /* used by ppc64 */ 1047 ".toc1", /* used by ppc64 */
1047 ".altinstructions", 1048 ".altinstructions",
1048 ".pdr", 1049 ".pdr",
1049 "__bug_table", /* used by powerpc for BUG() */ 1050 "__bug_table", /* used by powerpc for BUG() */
1050 ".exitcall.exit", 1051 ".exitcall.exit",
1051 ".eh_frame", 1052 ".eh_frame",
1052 ".parainstructions", 1053 ".parainstructions",
1053 ".stab", 1054 ".stab",
1054 "__ex_table", 1055 "__ex_table",
1055 ".fixup", 1056 ".fixup",
1056 ".smp_locks", 1057 ".smp_locks",
1057 ".plt", /* seen on ARCH=um build on x86_64. Harmless */ 1058 ".plt", /* seen on ARCH=um build on x86_64. Harmless */
1058 NULL 1059 NULL
1059 }; 1060 };
1060 /* Start of section names */ 1061 /* Start of section names */
1061 const char *namelist2[] = { 1062 const char *namelist2[] = {
1062 ".debug", 1063 ".debug",
1063 NULL 1064 NULL
1064 }; 1065 };
1065 /* part of section name */ 1066 /* part of section name */
1066 const char *namelist3 [] = { 1067 const char *namelist3 [] = {
1067 ".unwind", /* Sample: IA_64.unwind.exit.text */ 1068 ".unwind", /* Sample: IA_64.unwind.exit.text */
1068 NULL 1069 NULL
1069 }; 1070 };
1070 1071
1071 for (s = namelist1; *s; s++) 1072 for (s = namelist1; *s; s++)
1072 if (strcmp(*s, name) == 0) 1073 if (strcmp(*s, name) == 0)
1073 return 1; 1074 return 1;
1074 for (s = namelist2; *s; s++) 1075 for (s = namelist2; *s; s++)
1075 if (strncmp(*s, name, strlen(*s)) == 0) 1076 if (strncmp(*s, name, strlen(*s)) == 0)
1076 return 1; 1077 return 1;
1077 for (s = namelist3; *s; s++) 1078 for (s = namelist3; *s; s++)
1078 if (strstr(name, *s) != NULL) 1079 if (strstr(name, *s) != NULL)
1079 return 1; 1080 return 1;
1080 return 0; 1081 return 0;
1081 } 1082 }
1082 1083
1083 static void read_symbols(char *modname) 1084 static void read_symbols(char *modname)
1084 { 1085 {
1085 const char *symname; 1086 const char *symname;
1086 char *version; 1087 char *version;
1087 char *license; 1088 char *license;
1088 struct module *mod; 1089 struct module *mod;
1089 struct elf_info info = { }; 1090 struct elf_info info = { };
1090 Elf_Sym *sym; 1091 Elf_Sym *sym;
1091 1092
1092 parse_elf(&info, modname); 1093 parse_elf(&info, modname);
1093 1094
1094 mod = new_module(modname); 1095 mod = new_module(modname);
1095 1096
1096 /* When there's no vmlinux, don't print warnings about 1097 /* When there's no vmlinux, don't print warnings about
1097 * unresolved symbols (since there'll be too many ;) */ 1098 * unresolved symbols (since there'll be too many ;) */
1098 if (is_vmlinux(modname)) { 1099 if (is_vmlinux(modname)) {
1099 have_vmlinux = 1; 1100 have_vmlinux = 1;
1100 mod->skip = 1; 1101 mod->skip = 1;
1101 } 1102 }
1102 1103
1103 license = get_modinfo(info.modinfo, info.modinfo_len, "license"); 1104 license = get_modinfo(info.modinfo, info.modinfo_len, "license");
1104 while (license) { 1105 while (license) {
1105 if (license_is_gpl_compatible(license)) 1106 if (license_is_gpl_compatible(license))
1106 mod->gpl_compatible = 1; 1107 mod->gpl_compatible = 1;
1107 else { 1108 else {
1108 mod->gpl_compatible = 0; 1109 mod->gpl_compatible = 0;
1109 break; 1110 break;
1110 } 1111 }
1111 license = get_next_modinfo(info.modinfo, info.modinfo_len, 1112 license = get_next_modinfo(info.modinfo, info.modinfo_len,
1112 "license", license); 1113 "license", license);
1113 } 1114 }
1114 1115
1115 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { 1116 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
1116 symname = info.strtab + sym->st_name; 1117 symname = info.strtab + sym->st_name;
1117 1118
1118 handle_modversions(mod, &info, sym, symname); 1119 handle_modversions(mod, &info, sym, symname);
1119 handle_moddevtable(mod, &info, sym, symname); 1120 handle_moddevtable(mod, &info, sym, symname);
1120 } 1121 }
1121 check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); 1122 check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok);
1122 check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); 1123 check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok);
1123 1124
1124 version = get_modinfo(info.modinfo, info.modinfo_len, "version"); 1125 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
1125 if (version) 1126 if (version)
1126 maybe_frob_rcs_version(modname, version, info.modinfo, 1127 maybe_frob_rcs_version(modname, version, info.modinfo,
1127 version - (char *)info.hdr); 1128 version - (char *)info.hdr);
1128 if (version || (all_versions && !is_vmlinux(modname))) 1129 if (version || (all_versions && !is_vmlinux(modname)))
1129 get_src_version(modname, mod->srcversion, 1130 get_src_version(modname, mod->srcversion,
1130 sizeof(mod->srcversion)-1); 1131 sizeof(mod->srcversion)-1);
1131 1132
1132 parse_elf_finish(&info); 1133 parse_elf_finish(&info);
1133 1134
1134 /* Our trick to get versioning for struct_module - it's 1135 /* Our trick to get versioning for struct_module - it's
1135 * never passed as an argument to an exported function, so 1136 * never passed as an argument to an exported function, so
1136 * the automatic versioning doesn't pick it up, but it's really 1137 * the automatic versioning doesn't pick it up, but it's really
1137 * important anyhow */ 1138 * important anyhow */
1138 if (modversions) 1139 if (modversions)
1139 mod->unres = alloc_symbol("struct_module", 0, mod->unres); 1140 mod->unres = alloc_symbol("struct_module", 0, mod->unres);
1140 } 1141 }
1141 1142
1142 #define SZ 500 1143 #define SZ 500
1143 1144
1144 /* We first write the generated file into memory using the 1145 /* We first write the generated file into memory using the
1145 * following helper, then compare to the file on disk and 1146 * following helper, then compare to the file on disk and
1146 * only update the later if anything changed */ 1147 * only update the later if anything changed */
1147 1148
1148 void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, 1149 void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
1149 const char *fmt, ...) 1150 const char *fmt, ...)
1150 { 1151 {
1151 char tmp[SZ]; 1152 char tmp[SZ];
1152 int len; 1153 int len;
1153 va_list ap; 1154 va_list ap;
1154 1155
1155 va_start(ap, fmt); 1156 va_start(ap, fmt);
1156 len = vsnprintf(tmp, SZ, fmt, ap); 1157 len = vsnprintf(tmp, SZ, fmt, ap);
1157 buf_write(buf, tmp, len); 1158 buf_write(buf, tmp, len);
1158 va_end(ap); 1159 va_end(ap);
1159 } 1160 }
1160 1161
1161 void buf_write(struct buffer *buf, const char *s, int len) 1162 void buf_write(struct buffer *buf, const char *s, int len)
1162 { 1163 {
1163 if (buf->size - buf->pos < len) { 1164 if (buf->size - buf->pos < len) {
1164 buf->size += len + SZ; 1165 buf->size += len + SZ;
1165 buf->p = realloc(buf->p, buf->size); 1166 buf->p = realloc(buf->p, buf->size);
1166 } 1167 }
1167 strncpy(buf->p + buf->pos, s, len); 1168 strncpy(buf->p + buf->pos, s, len);
1168 buf->pos += len; 1169 buf->pos += len;
1169 } 1170 }
1170 1171
1171 static void check_for_gpl_usage(enum export exp, const char *m, const char *s) 1172 static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
1172 { 1173 {
1173 const char *e = is_vmlinux(m) ?"":".ko"; 1174 const char *e = is_vmlinux(m) ?"":".ko";
1174 1175
1175 switch (exp) { 1176 switch (exp) {
1176 case export_gpl: 1177 case export_gpl:
1177 fatal("modpost: GPL-incompatible module %s%s " 1178 fatal("modpost: GPL-incompatible module %s%s "
1178 "uses GPL-only symbol '%s'\n", m, e, s); 1179 "uses GPL-only symbol '%s'\n", m, e, s);
1179 break; 1180 break;
1180 case export_unused_gpl: 1181 case export_unused_gpl:
1181 fatal("modpost: GPL-incompatible module %s%s " 1182 fatal("modpost: GPL-incompatible module %s%s "
1182 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s); 1183 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
1183 break; 1184 break;
1184 case export_gpl_future: 1185 case export_gpl_future:
1185 warn("modpost: GPL-incompatible module %s%s " 1186 warn("modpost: GPL-incompatible module %s%s "
1186 "uses future GPL-only symbol '%s'\n", m, e, s); 1187 "uses future GPL-only symbol '%s'\n", m, e, s);
1187 break; 1188 break;
1188 case export_plain: 1189 case export_plain:
1189 case export_unused: 1190 case export_unused:
1190 case export_unknown: 1191 case export_unknown:
1191 /* ignore */ 1192 /* ignore */
1192 break; 1193 break;
1193 } 1194 }
1194 } 1195 }
1195 1196
1196 static void check_for_unused(enum export exp, const char* m, const char* s) 1197 static void check_for_unused(enum export exp, const char* m, const char* s)
1197 { 1198 {
1198 const char *e = is_vmlinux(m) ?"":".ko"; 1199 const char *e = is_vmlinux(m) ?"":".ko";
1199 1200
1200 switch (exp) { 1201 switch (exp) {
1201 case export_unused: 1202 case export_unused:
1202 case export_unused_gpl: 1203 case export_unused_gpl:
1203 warn("modpost: module %s%s " 1204 warn("modpost: module %s%s "
1204 "uses symbol '%s' marked UNUSED\n", m, e, s); 1205 "uses symbol '%s' marked UNUSED\n", m, e, s);
1205 break; 1206 break;
1206 default: 1207 default:
1207 /* ignore */ 1208 /* ignore */
1208 break; 1209 break;
1209 } 1210 }
1210 } 1211 }
1211 1212
1212 static void check_exports(struct module *mod) 1213 static void check_exports(struct module *mod)
1213 { 1214 {
1214 struct symbol *s, *exp; 1215 struct symbol *s, *exp;
1215 1216
1216 for (s = mod->unres; s; s = s->next) { 1217 for (s = mod->unres; s; s = s->next) {
1217 const char *basename; 1218 const char *basename;
1218 exp = find_symbol(s->name); 1219 exp = find_symbol(s->name);
1219 if (!exp || exp->module == mod) 1220 if (!exp || exp->module == mod)
1220 continue; 1221 continue;
1221 basename = strrchr(mod->name, '/'); 1222 basename = strrchr(mod->name, '/');
1222 if (basename) 1223 if (basename)
1223 basename++; 1224 basename++;
1224 else 1225 else
1225 basename = mod->name; 1226 basename = mod->name;
1226 if (!mod->gpl_compatible) 1227 if (!mod->gpl_compatible)
1227 check_for_gpl_usage(exp->export, basename, exp->name); 1228 check_for_gpl_usage(exp->export, basename, exp->name);
1228 check_for_unused(exp->export, basename, exp->name); 1229 check_for_unused(exp->export, basename, exp->name);
1229 } 1230 }
1230 } 1231 }
1231 1232
1232 /** 1233 /**
1233 * Header for the generated file 1234 * Header for the generated file
1234 **/ 1235 **/
1235 static void add_header(struct buffer *b, struct module *mod) 1236 static void add_header(struct buffer *b, struct module *mod)
1236 { 1237 {
1237 buf_printf(b, "#include <linux/module.h>\n"); 1238 buf_printf(b, "#include <linux/module.h>\n");
1238 buf_printf(b, "#include <linux/vermagic.h>\n"); 1239 buf_printf(b, "#include <linux/vermagic.h>\n");
1239 buf_printf(b, "#include <linux/compiler.h>\n"); 1240 buf_printf(b, "#include <linux/compiler.h>\n");
1240 buf_printf(b, "\n"); 1241 buf_printf(b, "\n");
1241 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); 1242 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
1242 buf_printf(b, "\n"); 1243 buf_printf(b, "\n");
1243 buf_printf(b, "struct module __this_module\n"); 1244 buf_printf(b, "struct module __this_module\n");
1244 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); 1245 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
1245 buf_printf(b, " .name = KBUILD_MODNAME,\n"); 1246 buf_printf(b, " .name = KBUILD_MODNAME,\n");
1246 if (mod->has_init) 1247 if (mod->has_init)
1247 buf_printf(b, " .init = init_module,\n"); 1248 buf_printf(b, " .init = init_module,\n");
1248 if (mod->has_cleanup) 1249 if (mod->has_cleanup)
1249 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n" 1250 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
1250 " .exit = cleanup_module,\n" 1251 " .exit = cleanup_module,\n"
1251 "#endif\n"); 1252 "#endif\n");
1252 buf_printf(b, "};\n"); 1253 buf_printf(b, "};\n");
1253 } 1254 }
1254 1255
1255 /** 1256 /**
1256 * Record CRCs for unresolved symbols 1257 * Record CRCs for unresolved symbols
1257 **/ 1258 **/
1258 static int add_versions(struct buffer *b, struct module *mod) 1259 static int add_versions(struct buffer *b, struct module *mod)
1259 { 1260 {
1260 struct symbol *s, *exp; 1261 struct symbol *s, *exp;
1261 int err = 0; 1262 int err = 0;
1262 1263
1263 for (s = mod->unres; s; s = s->next) { 1264 for (s = mod->unres; s; s = s->next) {
1264 exp = find_symbol(s->name); 1265 exp = find_symbol(s->name);
1265 if (!exp || exp->module == mod) { 1266 if (!exp || exp->module == mod) {
1266 if (have_vmlinux && !s->weak) { 1267 if (have_vmlinux && !s->weak) {
1267 warn("\"%s\" [%s.ko] undefined!\n", 1268 warn("\"%s\" [%s.ko] undefined!\n",
1268 s->name, mod->name); 1269 s->name, mod->name);
1269 err = warn_unresolved ? 0 : 1; 1270 err = warn_unresolved ? 0 : 1;
1270 } 1271 }
1271 continue; 1272 continue;
1272 } 1273 }
1273 s->module = exp->module; 1274 s->module = exp->module;
1274 s->crc_valid = exp->crc_valid; 1275 s->crc_valid = exp->crc_valid;
1275 s->crc = exp->crc; 1276 s->crc = exp->crc;
1276 } 1277 }
1277 1278
1278 if (!modversions) 1279 if (!modversions)
1279 return err; 1280 return err;
1280 1281
1281 buf_printf(b, "\n"); 1282 buf_printf(b, "\n");
1282 buf_printf(b, "static const struct modversion_info ____versions[]\n"); 1283 buf_printf(b, "static const struct modversion_info ____versions[]\n");
1283 buf_printf(b, "__attribute_used__\n"); 1284 buf_printf(b, "__attribute_used__\n");
1284 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); 1285 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
1285 1286
1286 for (s = mod->unres; s; s = s->next) { 1287 for (s = mod->unres; s; s = s->next) {
1287 if (!s->module) { 1288 if (!s->module) {
1288 continue; 1289 continue;
1289 } 1290 }
1290 if (!s->crc_valid) { 1291 if (!s->crc_valid) {
1291 warn("\"%s\" [%s.ko] has no CRC!\n", 1292 warn("\"%s\" [%s.ko] has no CRC!\n",
1292 s->name, mod->name); 1293 s->name, mod->name);
1293 continue; 1294 continue;
1294 } 1295 }
1295 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); 1296 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
1296 } 1297 }
1297 1298
1298 buf_printf(b, "};\n"); 1299 buf_printf(b, "};\n");
1299 1300
1300 return err; 1301 return err;
1301 } 1302 }
1302 1303
1303 static void add_depends(struct buffer *b, struct module *mod, 1304 static void add_depends(struct buffer *b, struct module *mod,
1304 struct module *modules) 1305 struct module *modules)
1305 { 1306 {
1306 struct symbol *s; 1307 struct symbol *s;
1307 struct module *m; 1308 struct module *m;
1308 int first = 1; 1309 int first = 1;
1309 1310
1310 for (m = modules; m; m = m->next) { 1311 for (m = modules; m; m = m->next) {
1311 m->seen = is_vmlinux(m->name); 1312 m->seen = is_vmlinux(m->name);
1312 } 1313 }
1313 1314
1314 buf_printf(b, "\n"); 1315 buf_printf(b, "\n");
1315 buf_printf(b, "static const char __module_depends[]\n"); 1316 buf_printf(b, "static const char __module_depends[]\n");
1316 buf_printf(b, "__attribute_used__\n"); 1317 buf_printf(b, "__attribute_used__\n");
1317 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); 1318 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
1318 buf_printf(b, "\"depends="); 1319 buf_printf(b, "\"depends=");
1319 for (s = mod->unres; s; s = s->next) { 1320 for (s = mod->unres; s; s = s->next) {
1320 if (!s->module) 1321 if (!s->module)
1321 continue; 1322 continue;
1322 1323
1323 if (s->module->seen) 1324 if (s->module->seen)
1324 continue; 1325 continue;
1325 1326
1326 s->module->seen = 1; 1327 s->module->seen = 1;
1327 buf_printf(b, "%s%s", first ? "" : ",", 1328 buf_printf(b, "%s%s", first ? "" : ",",
1328 strrchr(s->module->name, '/') + 1); 1329 strrchr(s->module->name, '/') + 1);
1329 first = 0; 1330 first = 0;
1330 } 1331 }
1331 buf_printf(b, "\";\n"); 1332 buf_printf(b, "\";\n");
1332 } 1333 }
1333 1334
1334 static void add_srcversion(struct buffer *b, struct module *mod) 1335 static void add_srcversion(struct buffer *b, struct module *mod)
1335 { 1336 {
1336 if (mod->srcversion[0]) { 1337 if (mod->srcversion[0]) {
1337 buf_printf(b, "\n"); 1338 buf_printf(b, "\n");
1338 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", 1339 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
1339 mod->srcversion); 1340 mod->srcversion);
1340 } 1341 }
1341 } 1342 }
1342 1343
1343 static void write_if_changed(struct buffer *b, const char *fname) 1344 static void write_if_changed(struct buffer *b, const char *fname)
1344 { 1345 {
1345 char *tmp; 1346 char *tmp;
1346 FILE *file; 1347 FILE *file;
1347 struct stat st; 1348 struct stat st;
1348 1349
1349 file = fopen(fname, "r"); 1350 file = fopen(fname, "r");
1350 if (!file) 1351 if (!file)
1351 goto write; 1352 goto write;
1352 1353
1353 if (fstat(fileno(file), &st) < 0) 1354 if (fstat(fileno(file), &st) < 0)
1354 goto close_write; 1355 goto close_write;
1355 1356
1356 if (st.st_size != b->pos) 1357 if (st.st_size != b->pos)
1357 goto close_write; 1358 goto close_write;
1358 1359
1359 tmp = NOFAIL(malloc(b->pos)); 1360 tmp = NOFAIL(malloc(b->pos));
1360 if (fread(tmp, 1, b->pos, file) != b->pos) 1361 if (fread(tmp, 1, b->pos, file) != b->pos)
1361 goto free_write; 1362 goto free_write;
1362 1363
1363 if (memcmp(tmp, b->p, b->pos) != 0) 1364 if (memcmp(tmp, b->p, b->pos) != 0)
1364 goto free_write; 1365 goto free_write;
1365 1366
1366 free(tmp); 1367 free(tmp);
1367 fclose(file); 1368 fclose(file);
1368 return; 1369 return;
1369 1370
1370 free_write: 1371 free_write:
1371 free(tmp); 1372 free(tmp);
1372 close_write: 1373 close_write:
1373 fclose(file); 1374 fclose(file);
1374 write: 1375 write:
1375 file = fopen(fname, "w"); 1376 file = fopen(fname, "w");
1376 if (!file) { 1377 if (!file) {
1377 perror(fname); 1378 perror(fname);
1378 exit(1); 1379 exit(1);
1379 } 1380 }
1380 if (fwrite(b->p, 1, b->pos, file) != b->pos) { 1381 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
1381 perror(fname); 1382 perror(fname);
1382 exit(1); 1383 exit(1);
1383 } 1384 }
1384 fclose(file); 1385 fclose(file);
1385 } 1386 }
1386 1387
1387 /* parse Module.symvers file. line format: 1388 /* parse Module.symvers file. line format:
1388 * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something] 1389 * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
1389 **/ 1390 **/
1390 static void read_dump(const char *fname, unsigned int kernel) 1391 static void read_dump(const char *fname, unsigned int kernel)
1391 { 1392 {
1392 unsigned long size, pos = 0; 1393 unsigned long size, pos = 0;
1393 void *file = grab_file(fname, &size); 1394 void *file = grab_file(fname, &size);
1394 char *line; 1395 char *line;
1395 1396
1396 if (!file) 1397 if (!file)
1397 /* No symbol versions, silently ignore */ 1398 /* No symbol versions, silently ignore */
1398 return; 1399 return;
1399 1400
1400 while ((line = get_next_line(&pos, file, size))) { 1401 while ((line = get_next_line(&pos, file, size))) {
1401 char *symname, *modname, *d, *export, *end; 1402 char *symname, *modname, *d, *export, *end;
1402 unsigned int crc; 1403 unsigned int crc;
1403 struct module *mod; 1404 struct module *mod;
1404 struct symbol *s; 1405 struct symbol *s;
1405 1406
1406 if (!(symname = strchr(line, '\t'))) 1407 if (!(symname = strchr(line, '\t')))
1407 goto fail; 1408 goto fail;
1408 *symname++ = '\0'; 1409 *symname++ = '\0';
1409 if (!(modname = strchr(symname, '\t'))) 1410 if (!(modname = strchr(symname, '\t')))
1410 goto fail; 1411 goto fail;
1411 *modname++ = '\0'; 1412 *modname++ = '\0';
1412 if ((export = strchr(modname, '\t')) != NULL) 1413 if ((export = strchr(modname, '\t')) != NULL)
1413 *export++ = '\0'; 1414 *export++ = '\0';
1414 if (export && ((end = strchr(export, '\t')) != NULL)) 1415 if (export && ((end = strchr(export, '\t')) != NULL))
1415 *end = '\0'; 1416 *end = '\0';
1416 crc = strtoul(line, &d, 16); 1417 crc = strtoul(line, &d, 16);
1417 if (*symname == '\0' || *modname == '\0' || *d != '\0') 1418 if (*symname == '\0' || *modname == '\0' || *d != '\0')
1418 goto fail; 1419 goto fail;
1419 1420
1420 if (!(mod = find_module(modname))) { 1421 if (!(mod = find_module(modname))) {
1421 if (is_vmlinux(modname)) { 1422 if (is_vmlinux(modname)) {
1422 have_vmlinux = 1; 1423 have_vmlinux = 1;
1423 } 1424 }
1424 mod = new_module(NOFAIL(strdup(modname))); 1425 mod = new_module(NOFAIL(strdup(modname)));
1425 mod->skip = 1; 1426 mod->skip = 1;
1426 } 1427 }
1427 s = sym_add_exported(symname, mod, export_no(export)); 1428 s = sym_add_exported(symname, mod, export_no(export));
1428 s->kernel = kernel; 1429 s->kernel = kernel;
1429 s->preloaded = 1; 1430 s->preloaded = 1;
1430 sym_update_crc(symname, mod, crc, export_no(export)); 1431 sym_update_crc(symname, mod, crc, export_no(export));
1431 } 1432 }
1432 return; 1433 return;
1433 fail: 1434 fail:
1434 fatal("parse error in symbol dump file\n"); 1435 fatal("parse error in symbol dump file\n");
1435 } 1436 }
1436 1437
1437 /* For normal builds always dump all symbols. 1438 /* For normal builds always dump all symbols.
1438 * For external modules only dump symbols 1439 * For external modules only dump symbols
1439 * that are not read from kernel Module.symvers. 1440 * that are not read from kernel Module.symvers.
1440 **/ 1441 **/
1441 static int dump_sym(struct symbol *sym) 1442 static int dump_sym(struct symbol *sym)
1442 { 1443 {
1443 if (!external_module) 1444 if (!external_module)
1444 return 1; 1445 return 1;
1445 if (sym->vmlinux || sym->kernel) 1446 if (sym->vmlinux || sym->kernel)
1446 return 0; 1447 return 0;
1447 return 1; 1448 return 1;
1448 } 1449 }
1449 1450
1450 static void write_dump(const char *fname) 1451 static void write_dump(const char *fname)
1451 { 1452 {
1452 struct buffer buf = { }; 1453 struct buffer buf = { };
1453 struct symbol *symbol; 1454 struct symbol *symbol;
1454 int n; 1455 int n;
1455 1456
1456 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { 1457 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
1457 symbol = symbolhash[n]; 1458 symbol = symbolhash[n];
1458 while (symbol) { 1459 while (symbol) {
1459 if (dump_sym(symbol)) 1460 if (dump_sym(symbol))
1460 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n", 1461 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
1461 symbol->crc, symbol->name, 1462 symbol->crc, symbol->name,
1462 symbol->module->name, 1463 symbol->module->name,
1463 export_str(symbol->export)); 1464 export_str(symbol->export));
1464 symbol = symbol->next; 1465 symbol = symbol->next;
1465 } 1466 }
1466 } 1467 }
1467 write_if_changed(&buf, fname); 1468 write_if_changed(&buf, fname);
1468 } 1469 }
1469 1470
1470 int main(int argc, char **argv) 1471 int main(int argc, char **argv)
1471 { 1472 {
1472 struct module *mod; 1473 struct module *mod;
1473 struct buffer buf = { }; 1474 struct buffer buf = { };
1474 char fname[SZ]; 1475 char fname[SZ];
1475 char *kernel_read = NULL, *module_read = NULL; 1476 char *kernel_read = NULL, *module_read = NULL;
1476 char *dump_write = NULL; 1477 char *dump_write = NULL;
1477 int opt; 1478 int opt;
1478 int err; 1479 int err;
1479 1480
1480 while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) { 1481 while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) {
1481 switch(opt) { 1482 switch(opt) {
1482 case 'i': 1483 case 'i':
1483 kernel_read = optarg; 1484 kernel_read = optarg;
1484 break; 1485 break;
1485 case 'I': 1486 case 'I':
1486 module_read = optarg; 1487 module_read = optarg;
1487 external_module = 1; 1488 external_module = 1;
1488 break; 1489 break;
1489 case 'm': 1490 case 'm':
1490 modversions = 1; 1491 modversions = 1;
1491 break; 1492 break;
1492 case 'o': 1493 case 'o':
1493 dump_write = optarg; 1494 dump_write = optarg;
1494 break; 1495 break;
1495 case 'a': 1496 case 'a':
1496 all_versions = 1; 1497 all_versions = 1;
1497 break; 1498 break;
1498 case 'w': 1499 case 'w':
1499 warn_unresolved = 1; 1500 warn_unresolved = 1;
1500 break; 1501 break;
1501 default: 1502 default:
1502 exit(1); 1503 exit(1);
1503 } 1504 }
1504 } 1505 }
1505 1506
1506 if (kernel_read) 1507 if (kernel_read)
1507 read_dump(kernel_read, 1); 1508 read_dump(kernel_read, 1);
1508 if (module_read) 1509 if (module_read)
1509 read_dump(module_read, 0); 1510 read_dump(module_read, 0);
1510 1511
1511 while (optind < argc) { 1512 while (optind < argc) {
1512 read_symbols(argv[optind++]); 1513 read_symbols(argv[optind++]);
1513 } 1514 }
1514 1515
1515 for (mod = modules; mod; mod = mod->next) { 1516 for (mod = modules; mod; mod = mod->next) {
1516 if (mod->skip) 1517 if (mod->skip)
1517 continue; 1518 continue;
1518 check_exports(mod); 1519 check_exports(mod);
1519 } 1520 }
1520 1521
1521 err = 0; 1522 err = 0;
1522 1523
1523 for (mod = modules; mod; mod = mod->next) { 1524 for (mod = modules; mod; mod = mod->next) {
1524 if (mod->skip) 1525 if (mod->skip)
1525 continue; 1526 continue;
1526 1527
1527 buf.pos = 0; 1528 buf.pos = 0;
1528 1529
1529 add_header(&buf, mod); 1530 add_header(&buf, mod);
1530 err |= add_versions(&buf, mod); 1531 err |= add_versions(&buf, mod);
1531 add_depends(&buf, mod, modules); 1532 add_depends(&buf, mod, modules);
1532 add_moddevtable(&buf, mod); 1533 add_moddevtable(&buf, mod);
1533 add_srcversion(&buf, mod); 1534 add_srcversion(&buf, mod);
1534 1535
1535 sprintf(fname, "%s.mod.c", mod->name); 1536 sprintf(fname, "%s.mod.c", mod->name);
1536 write_if_changed(&buf, fname); 1537 write_if_changed(&buf, fname);
1537 } 1538 }
1538 1539
1539 if (dump_write) 1540 if (dump_write)
1540 write_dump(dump_write); 1541 write_dump(dump_write);
1541 1542
1542 return err; 1543 return err;
1543 } 1544 }
1544 1545