Commit 554bdfe5acf3715e87c8d5e25a4f9a896ac9f014

Authored by Jan Beulich
Committed by Rusty Russell
1 parent 4a4962263f

module: reduce string table for loaded modules (v2)

Also remove all parts of the string table (referenced by the symbol
table) that are not needed for kallsyms use (i.e. which were only
referenced by symbols discarded by the previous patch, or not
referenced at all for whatever reason).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 2 changed files with 57 additions and 13 deletions Side-by-side Diff

include/linux/module.h
... ... @@ -315,7 +315,7 @@
315 315 */
316 316 Elf_Sym *symtab, *core_symtab;
317 317 unsigned int num_symtab, core_num_syms;
318   - char *strtab;
  318 + char *strtab, *core_strtab;
319 319  
320 320 /* Section attributes */
321 321 struct module_sect_attrs *sect_attrs;
... ... @@ -1886,12 +1886,17 @@
1886 1886 static unsigned long layout_symtab(struct module *mod,
1887 1887 Elf_Shdr *sechdrs,
1888 1888 unsigned int symindex,
  1889 + unsigned int strindex,
1889 1890 const Elf_Ehdr *hdr,
1890   - const char *secstrings)
  1891 + const char *secstrings,
  1892 + unsigned long *pstroffs,
  1893 + unsigned long *strmap)
1891 1894 {
1892 1895 unsigned long symoffs;
1893 1896 Elf_Shdr *symsect = sechdrs + symindex;
  1897 + Elf_Shdr *strsect = sechdrs + strindex;
1894 1898 const Elf_Sym *src;
  1899 + const char *strtab;
1895 1900 unsigned int i, nsrc, ndst;
1896 1901  
1897 1902 /* Put symbol section at end of init part of module. */
1898 1903  
1899 1904  
1900 1905  
... ... @@ -1902,14 +1907,31 @@
1902 1907  
1903 1908 src = (void *)hdr + symsect->sh_offset;
1904 1909 nsrc = symsect->sh_size / sizeof(*src);
  1910 + strtab = (void *)hdr + strsect->sh_offset;
1905 1911 for (ndst = i = 1; i < nsrc; ++i, ++src)
1906   - if (is_core_symbol(src, sechdrs, hdr->e_shnum))
  1912 + if (is_core_symbol(src, sechdrs, hdr->e_shnum)) {
  1913 + unsigned int j = src->st_name;
  1914 +
  1915 + while(!__test_and_set_bit(j, strmap) && strtab[j])
  1916 + ++j;
1907 1917 ++ndst;
  1918 + }
1908 1919  
1909 1920 /* Append room for core symbols at end of core part. */
1910 1921 symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
1911 1922 mod->core_size = symoffs + ndst * sizeof(Elf_Sym);
1912 1923  
  1924 + /* Put string table section at end of init part of module. */
  1925 + strsect->sh_flags |= SHF_ALLOC;
  1926 + strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
  1927 + strindex) | INIT_OFFSET_MASK;
  1928 + DEBUGP("\t%s\n", secstrings + strsect->sh_name);
  1929 +
  1930 + /* Append room for core symbols' strings at end of core part. */
  1931 + *pstroffs = mod->core_size;
  1932 + __set_bit(0, strmap);
  1933 + mod->core_size += bitmap_weight(strmap, strsect->sh_size);
  1934 +
1913 1935 return symoffs;
1914 1936 }
1915 1937  
1916 1938  
... ... @@ -1919,11 +1941,14 @@
1919 1941 unsigned int symindex,
1920 1942 unsigned int strindex,
1921 1943 unsigned long symoffs,
1922   - const char *secstrings)
  1944 + unsigned long stroffs,
  1945 + const char *secstrings,
  1946 + unsigned long *strmap)
1923 1947 {
1924 1948 unsigned int i, ndst;
1925 1949 const Elf_Sym *src;
1926 1950 Elf_Sym *dst;
  1951 + char *s;
1927 1952  
1928 1953 mod->symtab = (void *)sechdrs[symindex].sh_addr;
1929 1954 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
1930 1955  
1931 1956  
1932 1957  
... ... @@ -1941,16 +1966,25 @@
1941 1966 if (!is_core_symbol(src, sechdrs, shnum))
1942 1967 continue;
1943 1968 dst[ndst] = *src;
  1969 + dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name);
1944 1970 ++ndst;
1945 1971 }
1946 1972 mod->core_num_syms = ndst;
  1973 +
  1974 + mod->core_strtab = s = mod->module_core + stroffs;
  1975 + for (*s = 0, i = 1; i < sechdrs[strindex].sh_size; ++i)
  1976 + if (test_bit(i, strmap))
  1977 + *++s = mod->strtab[i];
1947 1978 }
1948 1979 #else
1949 1980 static inline unsigned long layout_symtab(struct module *mod,
1950 1981 Elf_Shdr *sechdrs,
1951 1982 unsigned int symindex,
  1983 + unsigned int strindex,
1952 1984 const Elf_Hdr *hdr,
1953   - const char *secstrings)
  1985 + const char *secstrings,
  1986 + unsigned long *pstroffs,
  1987 + unsigned long *strmap)
1954 1988 {
1955 1989 }
1956 1990 static inline void add_kallsyms(struct module *mod,
... ... @@ -1959,7 +1993,9 @@
1959 1993 unsigned int symindex,
1960 1994 unsigned int strindex,
1961 1995 unsigned long symoffs,
1962   - const char *secstrings)
  1996 + unsigned long stroffs,
  1997 + const char *secstrings,
  1998 + const unsigned long *strmap)
1963 1999 {
1964 2000 }
1965 2001 #endif /* CONFIG_KALLSYMS */
... ... @@ -2035,7 +2071,7 @@
2035 2071 long err = 0;
2036 2072 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
2037 2073 #ifdef CONFIG_KALLSYMS
2038   - unsigned long symoffs;
  2074 + unsigned long symoffs, stroffs, *strmap;
2039 2075 #endif
2040 2076 mm_segment_t old_fs;
2041 2077  
... ... @@ -2118,10 +2154,6 @@
2118 2154 /* Don't keep modinfo and version sections. */
2119 2155 sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
2120 2156 sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
2121   -#ifdef CONFIG_KALLSYMS
2122   - /* Keep string table for decoding later. */
2123   - sechdrs[strindex].sh_flags |= SHF_ALLOC;
2124   -#endif
2125 2157  
2126 2158 /* Check module struct version now, before we try to use module. */
2127 2159 if (!check_modstruct_version(sechdrs, versindex, mod)) {
... ... @@ -2157,6 +2189,13 @@
2157 2189 goto free_hdr;
2158 2190 }
2159 2191  
  2192 + strmap = kzalloc(BITS_TO_LONGS(sechdrs[strindex].sh_size)
  2193 + * sizeof(long), GFP_KERNEL);
  2194 + if (!strmap) {
  2195 + err = -ENOMEM;
  2196 + goto free_mod;
  2197 + }
  2198 +
2160 2199 if (find_module(mod->name)) {
2161 2200 err = -EEXIST;
2162 2201 goto free_mod;
... ... @@ -2186,7 +2225,8 @@
2186 2225 this is done generically; there doesn't appear to be any
2187 2226 special cases for the architectures. */
2188 2227 layout_sections(mod, hdr, sechdrs, secstrings);
2189   - symoffs = layout_symtab(mod, sechdrs, symindex, hdr, secstrings);
  2228 + symoffs = layout_symtab(mod, sechdrs, symindex, strindex, hdr,
  2229 + secstrings, &stroffs, strmap);
2190 2230  
2191 2231 /* Do the allocs. */
2192 2232 ptr = module_alloc_update_bounds(mod->core_size);
... ... @@ -2392,7 +2432,9 @@
2392 2432 sechdrs[pcpuindex].sh_size);
2393 2433  
2394 2434 add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex,
2395   - symoffs, secstrings);
  2435 + symoffs, stroffs, secstrings, strmap);
  2436 + kfree(strmap);
  2437 + strmap = NULL;
2396 2438  
2397 2439 if (!mod->taints) {
2398 2440 struct _ddebug *debug;
... ... @@ -2481,6 +2523,7 @@
2481 2523 percpu_modfree(percpu);
2482 2524 free_mod:
2483 2525 kfree(args);
  2526 + kfree(strmap);
2484 2527 free_hdr:
2485 2528 vfree(hdr);
2486 2529 return ERR_PTR(err);
... ... @@ -2573,6 +2616,7 @@
2573 2616 #ifdef CONFIG_KALLSYMS
2574 2617 mod->num_symtab = mod->core_num_syms;
2575 2618 mod->symtab = mod->core_symtab;
  2619 + mod->strtab = mod->core_strtab;
2576 2620 #endif
2577 2621 module_free(mod, mod->module_init);
2578 2622 mod->module_init = NULL;