Annotation of /trunk/grub/patches/grub-2.02-binutils-2.27-support-modules-without-symbol-table.patch
Parent Directory | Revision Log
Revision 2900 -
(hide annotations)
(download)
Tue Apr 4 09:31:09 2017 UTC (7 years, 5 months ago) by niro
File size: 4440 byte(s)
Tue Apr 4 09:31:09 2017 UTC (7 years, 5 months ago) by niro
File size: 4440 byte(s)
-renamed
1 | niro | 2898 | [PATCH v2] support modules without symbol table |
2 | |||
3 | From: Andrei Borzenkov | ||
4 | Subject: [PATCH v2] support modules without symbol table | ||
5 | Date: Wed, 3 Feb 2016 20:01:24 +0300 | ||
6 | all_video module does not have any code or data and exists solely for | ||
7 | .moddeps section to pull in dependencies. This makes all symbols unneeded. | ||
8 | |||
9 | While in current binutils (last released version as of this commit is 2.26) | ||
10 | ``strip --strip-unneeded'' unintentionally adds section symbols for each | ||
11 | existing section, this behavior was considered a bug and changed in commit | ||
12 | 14f2c699ddca1e2f706342dffc59a6c7e23e844c to completely strip symbol table | ||
13 | in this case. | ||
14 | |||
15 | Older binutils (verified with 2.17) and some other toolchains (at least | ||
16 | elftoolchain r3223M), both used in FreeBSD, remove symbol table in all_video | ||
17 | as well. | ||
18 | |||
19 | Relax run-time check and do not return error for modules without symbol table. | ||
20 | Add additional checks to module verifier to make sure such modules | ||
21 | |||
22 | a) have non-empty .moddeps section. Without either externally visible symbols | ||
23 | or .moddeps modules are completely useless and should not be built. | ||
24 | |||
25 | b) do not have any relocations. | ||
26 | |||
27 | Closes: 46986 | ||
28 | |||
29 | v2: add run-time check for empty symbol table if relocations are present as | ||
30 | suggested by Vladimir. | ||
31 | |||
32 | --- | ||
33 | grub-core/kern/dl.c | 8 +++++++- | ||
34 | util/grub-module-verifierXX.c | 19 ++++++++++++++++++- | ||
35 | 2 files changed, 25 insertions(+), 2 deletions(-) | ||
36 | |||
37 | diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c | ||
38 | index 59a6ef4..e394cd9 100644 | ||
39 | --- a/grub-core/kern/dl.c | ||
40 | +++ b/grub-core/kern/dl.c | ||
41 | @@ -333,8 +333,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) | ||
42 | if (s->sh_type == SHT_SYMTAB) | ||
43 | break; | ||
44 | |||
45 | + /* Module without symbol table may still be used to pull in dependencies. | ||
46 | + We verify at build time that such modules do not contain any relocations | ||
47 | + that may reference symbol table. */ | ||
48 | if (i == e->e_shnum) | ||
49 | - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); | ||
50 | + return GRUB_ERR_NONE; | ||
51 | |||
52 | #ifdef GRUB_MODULES_MACHINE_READONLY | ||
53 | mod->symtab = grub_malloc (s->sh_size); | ||
54 | @@ -576,6 +579,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) | ||
55 | |||
56 | if (seg) | ||
57 | { | ||
58 | + if (!mod->symtab) | ||
59 | + return grub_error (GRUB_ERR_BAD_MODULE, "relocation without | ||
60 | symbol table"); | ||
61 | + | ||
62 | err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg); | ||
63 | if (err) | ||
64 | return err; | ||
65 | diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c | ||
66 | index f612d51..f8c15b0 100644 | ||
67 | --- a/util/grub-module-verifierXX.c | ||
68 | +++ b/util/grub-module-verifierXX.c | ||
69 | @@ -176,7 +176,7 @@ get_symtab (const struct grub_module_verifier_arch *arch, | ||
70 | Elf_Ehdr *e, Elf_Word | ||
71 | break; | ||
72 | |||
73 | if (i == grub_target_to_host16 (e->e_shnum)) | ||
74 | - grub_util_error ("no symbol table"); | ||
75 | + return NULL; | ||
76 | |||
77 | sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset)); | ||
78 | *size = grub_target_to_host (s->sh_size); | ||
79 | @@ -191,7 +191,21 @@ check_symbols (const struct grub_module_verifier_arch | ||
80 | *arch, Elf_Ehdr *e) | ||
81 | Elf_Word size, entsize; | ||
82 | unsigned i; | ||
83 | |||
84 | + /* Module without symbol table and without .moddeps section is useless | ||
85 | + at boot time, so catch it early to prevent build errors */ | ||
86 | sym = get_symtab (arch, e, &size, &entsize); | ||
87 | + if (!sym) | ||
88 | + { | ||
89 | + Elf_Shdr *s = find_section (arch, e, ".moddeps"); | ||
90 | + | ||
91 | + if (!s) | ||
92 | + grub_util_error ("no symbol table and no .moddeps section"); | ||
93 | + | ||
94 | + if (!s->sh_size) | ||
95 | + grub_util_error ("no symbol table and empty .moddeps section"); | ||
96 | + | ||
97 | + return; | ||
98 | + } | ||
99 | |||
100 | for (i = 0; | ||
101 | i < size / entsize; | ||
102 | @@ -243,6 +257,8 @@ section_check_relocations (const struct | ||
103 | grub_module_verifier_arch *arch, void *e | ||
104 | Elf_Word symtabsize, symtabentsize; | ||
105 | |||
106 | symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize); | ||
107 | + if (!symtab) | ||
108 | + grub_util_error ("relocation without symbol table"); | ||
109 | |||
110 | for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)), | ||
111 | max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size)); | ||
112 | @@ -272,6 +288,7 @@ section_check_relocations (const struct | ||
113 | grub_module_verifier_arch *arch, void *e | ||
114 | break; | ||
115 | if (arch->short_relocations[i] == -1) | ||
116 | grub_util_error ("unsupported relocation 0x%x", type); | ||
117 | + | ||
118 | sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM | ||
119 | (grub_target_to_host (rel->r_info))); | ||
120 | |||
121 | if (is_symbol_local (sym)) | ||
122 | -- | ||
123 | tg: (7290bb5..) bug/46986 (depends on: master) | ||
124 |