diff options
author | Gwenolé Beauchesne <gbeauchesne@mandriva.org> | 2002-10-09 13:15:31 +0000 |
---|---|---|
committer | Gwenolé Beauchesne <gbeauchesne@mandriva.org> | 2002-10-09 13:15:31 +0000 |
commit | db5cfd5022007d2a794730695b9db08f17634674 (patch) | |
tree | 2f1f2cfd8bcac71abf48e1700a40ff88c3c00224 /mdk-stage1 | |
parent | 5bd2378f17544a0a21d70e4535477d3d12db39a2 (diff) | |
download | drakx-backup-do-not-use-db5cfd5022007d2a794730695b9db08f17634674.tar drakx-backup-do-not-use-db5cfd5022007d2a794730695b9db08f17634674.tar.gz drakx-backup-do-not-use-db5cfd5022007d2a794730695b9db08f17634674.tar.bz2 drakx-backup-do-not-use-db5cfd5022007d2a794730695b9db08f17634674.tar.xz drakx-backup-do-not-use-db5cfd5022007d2a794730695b9db08f17634674.zip |
Update to modutils 2.4.19 with x86-64 support and other fixes
Diffstat (limited to 'mdk-stage1')
54 files changed, 1086 insertions, 465 deletions
diff --git a/mdk-stage1/insmod-modutils/Makefile b/mdk-stage1/insmod-modutils/Makefile index e8f78d2d0..794cfb22e 100644 --- a/mdk-stage1/insmod-modutils/Makefile +++ b/mdk-stage1/insmod-modutils/Makefile @@ -15,7 +15,11 @@ include $(top_dir)/Makefile.common INCS = -I./include -DEFS = -Wno-error -D_GNU_SOURCE -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) +TAINT_URL = http://www.tux.org/lkml/\#export-tainted + +DEFS = -Wno-error -D_GNU_SOURCE \ + -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) \ + -DTAINT_URL='"$(TAINT_URL)"' DIRS = util obj diff --git a/mdk-stage1/insmod-modutils/include/config.h b/mdk-stage1/insmod-modutils/include/config.h index 11da6a523..3a37b00d4 100644 --- a/mdk-stage1/insmod-modutils/include/config.h +++ b/mdk-stage1/insmod-modutils/include/config.h @@ -28,6 +28,7 @@ #include <stdio.h> #include <sys/utsname.h> +#define MODUTILS_MACROS "/lib/modutils/macros" #define ETC_MODULES_CONF "/etc/modules.conf" #define EXEC_PRE_INSTALL 0 @@ -92,6 +93,8 @@ enum gen_file_enum { GEN_ISAPNPMAPFILE, GEN_USBMAPFILE, GEN_PARPORTMAPFILE, + GEN_IEEE1394MAPFILE, + GEN_PNPBIOSMAPFILE, GEN_DEPFILE, }; diff --git a/mdk-stage1/insmod-modutils/include/elf_alpha.h b/mdk-stage1/insmod-modutils/include/elf_alpha.h index f1ec66f1c..4202bcc14 100644 --- a/mdk-stage1/insmod-modutils/include/elf_alpha.h +++ b/mdk-stage1/insmod-modutils/include/elf_alpha.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for the Alpha. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS64 #define ELFDATAM ELFDATA2LSB diff --git a/mdk-stage1/insmod-modutils/include/elf_arm.h b/mdk-stage1/insmod-modutils/include/elf_arm.h index f6b531e88..cf04cafe0 100644 --- a/mdk-stage1/insmod-modutils/include/elf_arm.h +++ b/mdk-stage1/insmod-modutils/include/elf_arm.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for ARM. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #define ELFDATAM ELFDATA2LSB diff --git a/mdk-stage1/insmod-modutils/include/elf_i386.h b/mdk-stage1/insmod-modutils/include/elf_i386.h index c6c2d326e..f5c57d384 100644 --- a/mdk-stage1/insmod-modutils/include/elf_i386.h +++ b/mdk-stage1/insmod-modutils/include/elf_i386.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for i386 et al. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #define ELFDATAM ELFDATA2LSB diff --git a/mdk-stage1/insmod-modutils/include/elf_m68k.h b/mdk-stage1/insmod-modutils/include/elf_m68k.h index 817fc8f2c..c488ba9d1 100644 --- a/mdk-stage1/insmod-modutils/include/elf_m68k.h +++ b/mdk-stage1/insmod-modutils/include/elf_m68k.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for m68k. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #define ELFDATAM ELFDATA2MSB diff --git a/mdk-stage1/insmod-modutils/include/elf_mips.h b/mdk-stage1/insmod-modutils/include/elf_mips.h index 8a0430216..4b91ddd01 100644 --- a/mdk-stage1/insmod-modutils/include/elf_mips.h +++ b/mdk-stage1/insmod-modutils/include/elf_mips.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for MIPS. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #ifdef __MIPSEB__ diff --git a/mdk-stage1/insmod-modutils/include/elf_ppc.h b/mdk-stage1/insmod-modutils/include/elf_ppc.h index 71596de8c..b0060ace1 100644 --- a/mdk-stage1/insmod-modutils/include/elf_ppc.h +++ b/mdk-stage1/insmod-modutils/include/elf_ppc.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for the PowerPC. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #define ELFDATAM ELFDATA2MSB diff --git a/mdk-stage1/insmod-modutils/include/elf_s390.h b/mdk-stage1/insmod-modutils/include/elf_s390.h index 547d66b83..7a35bde93 100644 --- a/mdk-stage1/insmod-modutils/include/elf_s390.h +++ b/mdk-stage1/insmod-modutils/include/elf_s390.h @@ -1,10 +1,11 @@ /* Machine-specific elf macros for i386 et al. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #define ELFDATAM ELFDATA2MSB -#define MATCH_MACHINE(x) (x == EM_S390) +#define EM_S390_OLD 0xa390 + +#define MATCH_MACHINE(x) (x == EM_S390 || x == EM_S390_OLD) #define SHT_RELM SHT_RELA #define Elf32_RelM Elf32_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_sparc.h b/mdk-stage1/insmod-modutils/include/elf_sparc.h index 9b5c348d9..8903b2654 100644 --- a/mdk-stage1/insmod-modutils/include/elf_sparc.h +++ b/mdk-stage1/insmod-modutils/include/elf_sparc.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for the Sparc. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS32 #define ELFDATAM ELFDATA2MSB diff --git a/mdk-stage1/insmod-modutils/include/elf_sparc64.h b/mdk-stage1/insmod-modutils/include/elf_sparc64.h index 158edd7e1..891e0c3d9 100644 --- a/mdk-stage1/insmod-modutils/include/elf_sparc64.h +++ b/mdk-stage1/insmod-modutils/include/elf_sparc64.h @@ -1,5 +1,4 @@ /* Machine-specific elf macros for the Sparc. */ -#ident "$Id$" #define ELFCLASSM ELFCLASS64 #define ELFDATAM ELFDATA2MSB diff --git a/mdk-stage1/insmod-modutils/include/elf_x86_64.h b/mdk-stage1/insmod-modutils/include/elf_x86_64.h new file mode 100644 index 000000000..6d7581b3f --- /dev/null +++ b/mdk-stage1/insmod-modutils/include/elf_x86_64.h @@ -0,0 +1,9 @@ +/* Machine-specific elf macros for x86_64. */ + +#define ELFCLASSM ELFCLASS64 +#define ELFDATAM ELFDATA2LSB + +#define MATCH_MACHINE(x) (x == EM_X86_64) + +#define SHT_RELM SHT_RELA +#define Elf64_RelM Elf64_Rela diff --git a/mdk-stage1/insmod-modutils/include/kallsyms.h b/mdk-stage1/insmod-modutils/include/kallsyms.h index 9748873cf..90bb75f22 100644 --- a/mdk-stage1/insmod-modutils/include/kallsyms.h +++ b/mdk-stage1/insmod-modutils/include/kallsyms.h @@ -1,3 +1,6 @@ +#ifndef MODUTILS_KALLSYMS_H +#define MODUTILS_KALLSYMS_H 1 + /* kallsyms headers Copyright 2000 Keith Owens <kaos@ocs.com.au> @@ -24,11 +27,6 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - -#ifndef MODUTILS_KALLSYMS_H -#define MODUTILS_KALLSYMS_H 1 - /* Have to (re)define these ElfW entries here because external kallsyms * code does not have access to modutils/include/obj.h. This code is * included from user spaces tools (modutils) and kernel, they need diff --git a/mdk-stage1/insmod-modutils/include/kerneld.h b/mdk-stage1/insmod-modutils/include/kerneld.h index 3bc2c9d42..f32e34b4a 100644 --- a/mdk-stage1/insmod-modutils/include/kerneld.h +++ b/mdk-stage1/insmod-modutils/include/kerneld.h @@ -4,8 +4,6 @@ #ifndef MODUTILS_KERNELD_H #define MODUTILS_KERNELD_H -#ident "$Id$" - #define KERNELD_SYSTEM 1 #define KERNELD_REQUEST_MODULE 2 /* "insmod" */ #define KERNELD_RELEASE_MODULE 3 /* "rmmod" */ diff --git a/mdk-stage1/insmod-modutils/include/module.h b/mdk-stage1/insmod-modutils/include/module.h index db49ab2b2..ae8224f8a 100644 --- a/mdk-stage1/insmod-modutils/include/module.h +++ b/mdk-stage1/insmod-modutils/include/module.h @@ -1,3 +1,6 @@ +#ifndef MODUTILS_MODULE_H +#define MODUTILS_MODULE_H 1 + /* Definitions for the Linux module syscall interface. Copyright 1996, 1997 Linux International. @@ -20,11 +23,6 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef MODUTILS_MODULE_H -#define MODUTILS_MODULE_H 1 - -#ident "$Id$" - /* This file contains the structures used by the 2.0 and 2.1 kernels. We do not use the kernel headers directly because we do not wish to be dependant on a particular kernel version to compile insmod. */ @@ -207,4 +205,13 @@ int delete_module(const char *); */ extern unsigned int safemode; +/*======================================================================*/ +/* Tainted kernel information. This must match include/linux/kernel.h */ +/* and kernel/panic.c. */ + +#define TAINT_FILENAME "/proc/sys/kernel/tainted" +#define TAINT_PROPRIETORY_MODULE (1<<0) +#define TAINT_FORCED_MODULE (1<<1) +#define TAINT_UNSAFE_SMP (1<<2) + #endif /* module.h */ diff --git a/mdk-stage1/insmod-modutils/include/obj.h b/mdk-stage1/insmod-modutils/include/obj.h index b140c65c3..de346b16a 100644 --- a/mdk-stage1/insmod-modutils/include/obj.h +++ b/mdk-stage1/insmod-modutils/include/obj.h @@ -1,3 +1,6 @@ +#ifndef MODUTILS_OBJ_H +#define MODUTILS_OBJ_H 1 + /* Elf object file loading and relocation routines. Copyright 1996, 1997 Linux International. @@ -21,16 +24,13 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef MODUTILS_OBJ_H -#define MODUTILS_OBJ_H 1 - -#ident "$Id$" - /* The relocatable object is manipulated using elfin types. */ #include <stdio.h> +#include <sys/types.h> #include <elf.h> #include ELF_MACHINE_H +#include "module.h" #ifndef ElfW # if ELFCLASSM == ELFCLASS32 @@ -77,7 +77,7 @@ struct obj_symbol { struct obj_symbol *next; /* hash table link */ const char *name; - unsigned long value; + tgt_long value; unsigned long size; int secidx; /* the defining section index/module */ int info; @@ -161,6 +161,8 @@ struct obj_symbol_patch_struct #define obj_create_image ObjW(create_image) #define obj_addr_to_native_ptr ObjW(addr_to_native_ptr) #define obj_native_ptr_to_addr ObjW(native_ptr_to_addr) +#define obj_kallsyms ObjW(kallsyms) +#define obj_gpl_license ObjW(gpl_license) #define arch_new_file ObjW(arch_new_file) #define arch_new_section ObjW(arch_new_section) #define arch_new_symbol ObjW(arch_new_symbol) @@ -198,7 +200,8 @@ void obj_insert_section_load_order (struct obj_file *f, struct obj_section *obj_create_alloced_section (struct obj_file *f, const char *name, unsigned long align, - unsigned long size); + unsigned long size, + unsigned long flags); struct obj_section *obj_create_alloced_section_first (struct obj_file *f, const char *name, @@ -264,7 +267,7 @@ union obj_ptr_4 { void *ptr; }; union obj_ptr_8 { - Elf64_Xword addr; + u_int64_t addr; /* Should be Elf64_Xword but not all users have this yet */ void *ptr; }; @@ -272,4 +275,24 @@ void *obj_addr_to_native_ptr(ElfW(Addr)); ElfW(Addr) obj_native_ptr_to_addr(void *); +/* Standard method of finding relocation symbols, sets isym */ +#define obj_find_relsym(isym, f, find, rel, symtab, strtab) \ + { \ + unsigned long symndx = ELFW(R_SYM)((rel)->r_info); \ + ElfW(Sym) *extsym = (symtab)+symndx; \ + if (ELFW(ST_BIND)(extsym->st_info) == STB_LOCAL) { \ + isym = (typeof(isym)) (f)->local_symtab[symndx]; \ + } \ + else { \ + const char *name; \ + if (extsym->st_name) \ + name = (strtab) + extsym->st_name; \ + else \ + name = (f)->sections[extsym->st_shndx]->name; \ + isym = (typeof(isym)) obj_find_symbol((find), name); \ + } \ + } + +int obj_gpl_license(struct obj_file *, const char **); + #endif /* obj.h */ diff --git a/mdk-stage1/insmod-modutils/include/util.h b/mdk-stage1/insmod-modutils/include/util.h index b2e4a67c3..0a1354bec 100644 --- a/mdk-stage1/insmod-modutils/include/util.h +++ b/mdk-stage1/insmod-modutils/include/util.h @@ -1,3 +1,6 @@ +#ifndef MODUTILS_UTIL_H +#define MODUTILS_UTIL_H 1 + /* Miscelaneous utility functions. Copyright 1996, 1997 Linux International. @@ -20,11 +23,6 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef MODUTILS_UTIL_H -#define MODUTILS_UTIL_H 1 - -#ident "$Id$" - #include <stdio.h> #include <sys/stat.h> diff --git a/mdk-stage1/insmod-modutils/include/version.h b/mdk-stage1/insmod-modutils/include/version.h index 51ca0eb29..9ca0c57a9 100644 --- a/mdk-stage1/insmod-modutils/include/version.h +++ b/mdk-stage1/insmod-modutils/include/version.h @@ -1 +1 @@ -#define MODUTILS_VERSION "2.4.2" +#define MODUTILS_VERSION "2.4.19" diff --git a/mdk-stage1/insmod-modutils/insmod.c b/mdk-stage1/insmod-modutils/insmod.c index 359b28837..b0b7c2a0d 100644 --- a/mdk-stage1/insmod-modutils/insmod.c +++ b/mdk-stage1/insmod-modutils/insmod.c @@ -54,16 +54,15 @@ Keith Owens <kaos@ocs.com.au> November 2000. Add persistent data support. Keith Owens <kaos@ocs.com.au> November 2000. + Add tainted module support. + Keith Owens <kaos@ocs.com.au> September 2001. */ -#ident "$Id$" - #include "../insmod.h" #include <sys/types.h> #include <stdlib.h> #include <unistd.h> #include <string.h> -//#include <alloca.h> provided by stdlib #include <limits.h> #include <ctype.h> #include <errno.h> @@ -71,6 +70,7 @@ #include <getopt.h> #include <sys/stat.h> #include <sys/file.h> +#include <sys/fcntl.h> #include "module.h" #include "obj.h" @@ -90,9 +90,12 @@ static int flag_silent_probe = 0; static int flag_export = 1; static int flag_load_map = 0; static int flag_ksymoops = 1; +static int flag_numeric_only = 0; static int n_ext_modules_used; static int m_has_modinfo; +static int gplonly_seen; +static int warnings; extern int insmod_main(int argc, char **argv); extern int insmod_main_32(int argc, char **argv); @@ -105,6 +108,15 @@ extern int kallsyms_main(int argc, char **argv); /*======================================================================*/ +/* Only use the numeric part of the version string? */ + +static void use_numeric_only(int major, int minor, char *str) +{ + if (((major << 8) + minor) >= 0x0205 /* kernel 2.5 */ + || flag_numeric_only) + *str = '\0'; +} + /* Get the kernel version in the canonical integer form. */ static int get_kernel_version(char str[STRVERSIONLEN]) @@ -112,8 +124,9 @@ static int get_kernel_version(char str[STRVERSIONLEN]) char *p, *q; int a, b, c; - strncpy(str, uts_info.release, STRVERSIONLEN); - p = uts_info.release; + strncpy(str, uts_info.release, STRVERSIONLEN-1); + str[STRVERSIONLEN-1] = '\0'; + p = str; a = strtoul(p, &p, 10); if (*p != '.') @@ -124,6 +137,7 @@ static int get_kernel_version(char str[STRVERSIONLEN]) c = strtoul(p + 1, &q, 10); if (p + 1 == q) return -1; + use_numeric_only(a, b, q); return a << 16 | b << 8 | c; } @@ -232,7 +246,7 @@ static unsigned long ncv_symbol_hash(const char *str) * to the new module. */ static int add_symbols_from(struct obj_file *f, int idx, - struct module_symbol *syms, size_t nsyms) + struct module_symbol *syms, size_t nsyms, int gpl) { struct module_symbol *s; size_t i; @@ -247,8 +261,57 @@ static int add_symbols_from(struct obj_file *f, int idx, */ struct obj_symbol *sym; + /* GPL licensed modules can use symbols exported with + * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the + * exported names. Non-GPL modules never see any GPLONLY_ + * symbols so they cannot fudge it by adding the prefix on + * their references. + */ + if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) { + gplonly_seen = 1; + if (gpl) + ((char *)s->name) += 8; + else + continue; + } + sym = obj_find_symbol(f, (char *) s->name); - if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) { +#ifdef ARCH_ppc64 + if (!sym) + { + static size_t buflen = 0; + static char *buf = 0; + int len; + + /* ppc64 is one of those architectures with + function descriptors. A function is exported + and accessed across object boundaries via its + function descriptor. The function code symbol + happens to be the function name, prefixed with + '.', and a function call is a branch to the + code symbol. The linker recognises when a call + crosses object boundaries, and inserts a stub + to call via the function descriptor. + obj_ppc64.c of course does the same thing, so + here we recognise that an undefined code symbol + can be satisfied by the corresponding function + descriptor symbol. */ + + len = strlen ((char *) s->name) + 2; + if (buflen < len) + { + buflen = len + (len >> 1); + if (buf) + free (buf); + buf = malloc (buflen); + } + buf[0] = '.'; + strcpy (buf + 1, (char *) s->name); + sym = obj_find_symbol(f, buf); + } +#endif /* ARCH_ppc64 */ + + if (sym && ELFW(ST_BIND) (sym->info) != STB_LOCAL) { sym = obj_add_symbol(f, (char *) s->name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), idx, s->value, 0); @@ -264,7 +327,7 @@ static int add_symbols_from(struct obj_file *f, int idx, return used; } -static void add_kernel_symbols(struct obj_file *f) +static void add_kernel_symbols(struct obj_file *f, int gpl) { struct module_stat *m; size_t i, nused = 0; @@ -272,13 +335,13 @@ static void add_kernel_symbols(struct obj_file *f) /* Add module symbols first. */ for (i = 0, m = module_stat; i < n_module_stat; ++i, ++m) if (m->nsyms && - add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms)) + add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms, gpl)) m->status = 1 /* used */, ++nused; n_ext_modules_used = nused; /* And finally the symbols from the kernel proper. */ if (nksyms) - add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms); + add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms, gpl); } static void hide_special_symbols(struct obj_file *f) @@ -326,7 +389,7 @@ static void print_load_map(struct obj_file *f) if (a == -1) a = 0; - lprintf("%-16s%08lx %0*lx 2**%d", + lprintf("%-15s %08lx %0*lx 2**%d", sec->name, (long)sec->header.sh_size, (int) (2 * sizeof(void *)), @@ -465,9 +528,10 @@ static int old_create_mod_use_count(struct obj_file *f) */ got = obj_find_symbol(f, "_GLOBAL_OFFSET_TABLE_"); if (got) -{ + { sec = obj_create_alloced_section(f, ".got", - sizeof(long), sizeof(long)); + sizeof(long), sizeof(long), + SHF_WRITE); got->secidx = sec->idx; /* mark the symbol as defined */ } return 1; @@ -491,7 +555,8 @@ static void add_ksymtab(struct obj_file *f, struct obj_symbol *sym) sec = NULL; } if (!sec) - sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0); + sec = obj_create_alloced_section(f, "__ksymtab", + tgt_sizeof_void_p, 0, 0); if (!sec) return; sec->header.sh_flags |= SHF_ALLOC; @@ -513,9 +578,9 @@ static int create_module_ksymtab(struct obj_file *f) struct module_ref *dep; struct obj_symbol *tm; - sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p, - (sizeof(struct module_ref) - * n_ext_modules_used)); + sec = obj_create_alloced_section(f, ".kmodtab", + tgt_sizeof_void_p, + sizeof(struct module_ref) * n_ext_modules_used, 0); if (!sec) return 0; @@ -524,6 +589,9 @@ static int create_module_ksymtab(struct obj_file *f) for (i = 0; i < n_module_stat; ++i) if (module_stat[i].status /* used */) { dep->dep = module_stat[i].addr; +#ifdef ARCH_ppc64 + dep->dep |= ppc64_module_base (f); +#endif obj_symbol_patch(f, sec->idx, (char *) &dep->ref - sec->contents, tm); dep->next_ref = 0; ++dep; @@ -573,7 +641,9 @@ static int get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) } else m_has_modinfo = 1; - strncpy(str, p, STRVERSIONLEN); + strncpy(str, p, STRVERSIONLEN-1); + str[STRVERSIONLEN-1] = '\0'; + p = str; a = strtoul(p, &p, 10); if (*p != '.') @@ -584,6 +654,7 @@ static int get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) c = strtoul(p + 1, &q, 10); if (p + 1 == q) return -1; + use_numeric_only(a, b, q); return a << 16 | b << 8 | c; } @@ -645,6 +716,7 @@ static void add_ksymoops_symbols(struct obj_file *f, const char *filename, int save_errno = errno; error("cannot get realpath for %s", filename); errno = save_errno; + perror(""); absolute_filename = xstrdup(filename); } @@ -679,7 +751,7 @@ static void add_ksymoops_symbols(struct obj_file *f, const char *filename, version = get_module_version(f, str); /* -1 if not found */ snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", symprefix, m_name, absolute_filename, - 2*sizeof(statbuf.st_mtime), statbuf.st_mtime, + (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, version); sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), @@ -756,14 +828,10 @@ static int process_module_arguments(struct obj_file *f, int argc, char **argv, i memcpy(key + 5, *argv, n); key[n + 5] = '\0'; if ((fmt = get_modinfo_value(f, key)) == NULL) { - if (required) { - error("invalid parameter %s", key); - return 0; - } - else { - if (flag_verbose) - lprintf("ignoring %s", *argv); - continue; /* silently ignore optional parameters */ + if (required || flag_verbose) { + lprintf("Warning: ignoring %s, no such parameter in this module", *argv); + ++warnings; + continue; } } key += 5; @@ -1014,7 +1082,7 @@ static int add_kallsyms(struct obj_file *f, } } if (!*module_kallsyms) - *module_kallsyms = obj_create_alloced_section(f, KALLSYMS_SEC_NAME, 0, 0); + *module_kallsyms = obj_create_alloced_section(f, KALLSYMS_SEC_NAME, 0, 0, 0); /* Size and populate kallsyms */ if (obj_kallsyms(f, &f_kallsyms)) @@ -1046,7 +1114,7 @@ static int add_archdata(struct obj_file *f, } } if (!*sec) - *sec = obj_create_alloced_section(f, ARCHDATA_SEC_NAME, 16, 0); + *sec = obj_create_alloced_section(f, ARCHDATA_SEC_NAME, 16, 0, 0); /* Size and populate archdata */ if (arch_archdata(f, *sec)) @@ -1147,7 +1215,8 @@ static int init_module(const char *m_name, struct obj_file *f, if (ret) { error("init_module: %m"); lprintf("Hint: insmod errors can be caused by incorrect module parameters, " - "including invalid IO or IRQ parameters"); + "including invalid IO or IRQ parameters.\n" + " You may find more information in syslog or the output from dmesg"); } } @@ -1276,6 +1345,7 @@ static int check_module_parameter(struct obj_file *f, char *key, char *value, in * most error conditions. Make these all errors in 2.5. */ lprintf("Warning: %s symbol for parameter %s not found", error_file, key); + ++warnings; return(1); } @@ -1290,6 +1360,7 @@ static int check_module_parameter(struct obj_file *f, char *key, char *value, in if (max < min) { lprintf("Warning: %s parameter %s has max < min!", error_file, key); + ++warnings; return(1); } @@ -1297,6 +1368,7 @@ static int check_module_parameter(struct obj_file *f, char *key, char *value, in case 'c': if (!isdigit(p[1])) { lprintf("%s parameter %s has no size after 'c'!", error_file, key); + ++warnings; return(1); } while (isdigit(p[1])) @@ -1310,9 +1382,11 @@ static int check_module_parameter(struct obj_file *f, char *key, char *value, in break; case '\0': lprintf("%s parameter %s has no format character!", error_file, key); + ++warnings; return(1); default: lprintf("%s parameter %s has unknown format character '%c'", error_file, key, *p); + ++warnings; return(1); } switch (*++p) { @@ -1327,6 +1401,7 @@ static int check_module_parameter(struct obj_file *f, char *key, char *value, in break; default: lprintf("%s parameter %s has unknown format modifier '%c'", error_file, key, *p); + ++warnings; return(1); } return(0); @@ -1374,6 +1449,74 @@ static void check_module_parameters(struct obj_file *f, int *persist_flag) return; } +static void set_tainted(struct obj_file *f, int fd, int kernel_has_tainted, + int noload, int taint, + const char *text1, const char *text2) +{ + char buf[80]; + int oldval; + static int first = 1; + if (fd < 0 && !kernel_has_tainted) + return; /* New modutils on old kernel */ + lprintf("Warning: loading %s will taint the kernel: %s%s", + f->filename, text1, text2); + ++warnings; + if (first) { + lprintf(" See %s for information about tainted modules", TAINT_URL); + first = 0; + } + if (fd >= 0 && !noload) { + read(fd, buf, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + oldval = strtoul(buf, NULL, 10); + sprintf(buf, "%d\n", oldval | taint); + write(fd, buf, strlen(buf)); + } +} + +/* Check if loading this module will taint the kernel. */ +static void check_tainted_module(struct obj_file *f, int noload) +{ + static const char tainted_file[] = TAINT_FILENAME; + int fd, kernel_has_tainted; + const char *ptr; + + if ((fd = open(tainted_file, O_RDWR)) < 0) { + if (errno == ENOENT) + kernel_has_tainted = 0; + else if (errno == EACCES) + kernel_has_tainted = 1; + else { + perror(tainted_file); + kernel_has_tainted = 0; + } + } + else + kernel_has_tainted = 1; + + switch (obj_gpl_license(f, &ptr)) { + case 0: + break; + case 1: + set_tainted(f, fd, kernel_has_tainted, noload, TAINT_PROPRIETORY_MODULE, "no license", ""); + break; + case 2: + /* The module has a non-GPL license so we pretend that the + * kernel always has a taint flag to get a warning even on + * kernels without the proc flag. + */ + set_tainted(f, fd, 1, noload, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); + break; + default: + set_tainted(f, fd, 1, noload, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); + break; + } + + if (flag_force_load) + set_tainted(f, fd, 1, noload, TAINT_FORCED_MODULE, "forced load", ""); + if (fd >= 0) + close(fd); +} /* For common 3264 code, only compile the usage message once, in the 64 bit version */ #if defined(COMMON_3264) && defined(ONLY_32) @@ -1382,7 +1525,7 @@ extern void insmod_usage(void); /* Use the copy in the 64 bit version */ void insmod_usage(void) { fputs("Usage:\n" - "insmod [-fhkLmnpqrsSvVxXyY] [-e persist_name] [-o module_name] [-O blob_name] [-P prefix] module [ symbol=value ... ]\n" + "insmod [-fhkLmnpqrsSvVxXyYN] [-e persist_name] [-o module_name] [-O blob_name] [-P prefix] module [ symbol=value ... ]\n" "\n" " module Name of a loadable kernel module ('.o' can be omitted)\n" " -f, --force Force loading under wrong kernel version\n" @@ -1402,6 +1545,7 @@ void insmod_usage(void) " -X, --export Do export externs (default)\n" " -y, --noksymoops Do not add ksymoops symbols\n" " -Y, --ksymoops Do add ksymoops symbols (default)\n" + " -N, --numeric-only Only check the numeric part of the kernel version\n" " -e persist_name\n" " --persist=persist_name Filename to hold any persistent data from the module\n" " -o NAME, --name=NAME Set internal module name to NAME\n" @@ -1445,8 +1589,8 @@ int INSMOD_MAIN(int argc, char **argv) {"export", 0, 0, 'X'}, {"noksymoops", 0, 0, 'y'}, {"ksymoops", 0, 0, 'Y'}, - {"persist", 1, 0, 'e'}, + {"numeric-only", 1, 0, 'N'}, {"name", 1, 0, 'o'}, {"blob", 1, 0, 'O'}, {"prefix", 1, 0, 'P'}, @@ -1472,6 +1616,7 @@ int INSMOD_MAIN(int argc, char **argv) int force_kallsyms = 0; int persist_parms = 0; /* does module have persistent parms? */ int i; + int gpl; error_file = "insmod"; @@ -1479,7 +1624,7 @@ int INSMOD_MAIN(int argc, char **argv) errors = optind = 0; /* Process the command line. */ - while ((o = getopt_long(argc, argv, "fhkLmnpqrsSvVxXyYe:o:O:P:R:", + while ((o = getopt_long(argc, argv, "fhkLmnpqrsSvVxXyYNe:o:O:P:R:", &long_opts[0], NULL)) != EOF) switch (o) { case 'f': /* force loading */ @@ -1533,6 +1678,9 @@ int INSMOD_MAIN(int argc, char **argv) case 'Y': /* do define ksymoops symbols */ flag_ksymoops = 1; break; + case 'N': /* only check numeric part of kernel version */ + flag_numeric_only = 1; + break; case 'e': /* persistent data filename */ free(persist_name); @@ -1566,8 +1714,10 @@ int INSMOD_MAIN(int argc, char **argv) (!persistdir || !*persistdir)) { free(persist_name); persist_name = NULL; - if (flag_verbose) + if (flag_verbose) { lprintf("insmod: -e \"\" ignored, no persistdir"); + ++warnings; + } } if (m_name == NULL) { @@ -1624,7 +1774,7 @@ int INSMOD_MAIN(int argc, char **argv) */ set_ncv_prefix(NULL); - for (i = 0; i < n_module_stat; ++i) { + for (i = 0; !noload && i < n_module_stat; ++i) { if (strcmp(module_stat[i].name, m_name) == 0) { error("a module named %s already exists", m_name); goto out; @@ -1652,6 +1802,7 @@ int INSMOD_MAIN(int argc, char **argv) "\t%s was compiled for kernel version %s\n" "\twhile this kernel is version %s", filename, m_strversion, k_strversion); + ++warnings; } else { if (!quiet) error("kernel-module version mismatch\n" @@ -1665,7 +1816,13 @@ int INSMOD_MAIN(int argc, char **argv) obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); /* Let the module know about the kernel symbols. */ - add_kernel_symbols(f); + gpl = obj_gpl_license(f, NULL) == 0; + add_kernel_symbols(f, gpl); + +#ifdef ARCH_ppc64 + if (!ppc64_process_syms (f)) + goto out; +#endif /* Allocate common symbols, symbol tables, and string tables. * @@ -1684,17 +1841,33 @@ int INSMOD_MAIN(int argc, char **argv) goto out; #endif - if (!obj_check_undefineds(f, quiet)) /* DEPMOD, obj_clear_undefineds */ + arch_create_got(f); /* DEPMOD */ + if (!obj_check_undefineds(f, quiet)) { /* DEPMOD, obj_clear_undefineds */ + if (!gpl && !quiet) { + if (gplonly_seen) + error("\n" + "Hint: You are trying to load a module without a GPL compatible license\n" + " and it has unresolved symbols. The module may be trying to access\n" + " GPLONLY symbols but the problem is more likely to be a coding or\n" + " user error. Contact the module supplier for assistance, only they\n" + " can help you.\n"); + else + error("\n" + "Hint: You are trying to load a module without a GPL compatible license\n" + " and it has unresolved symbols. Contact the module supplier for\n" + " assistance, only they can help you.\n"); + } goto out; + } obj_allocate_commons(f); /* DEPMOD */ check_module_parameters(f, &persist_parms); + check_tainted_module(f, noload); if (optind < argc) { if (!process_module_arguments(f, argc - optind, argv + optind, 1)) goto out; } - arch_create_got(f); /* DEPMOD */ hide_special_symbols(f); if (persist_parms && persist_name && *persist_name) { @@ -1842,6 +2015,9 @@ int INSMOD_MAIN(int argc, char **argv) } else { errno = 0; m_addr = create_module(m_name, m_size); +#ifdef ARCH_ppc64 + m_addr |= ppc64_module_base (f); +#endif switch (errno) { case 0: break; @@ -1917,6 +2093,8 @@ int INSMOD_MAIN(int argc, char **argv) delete_module(m_name); goto out; } + if (warnings && !noload) + lprintf("Module %s loaded, with warnings", m_name); exit_status = 0; out: @@ -1941,7 +2119,6 @@ int insmod_main(int argc, char **argv) #endif /* defined(COMMON_3264) && defined(ONLY_64) */ - int insmod_call(char * full_filename, char * params) { int argc = 2; diff --git a/mdk-stage1/insmod-modutils/obj/Makefile b/mdk-stage1/insmod-modutils/obj/Makefile index 34b5df2d9..4539a4cf7 100644 --- a/mdk-stage1/insmod-modutils/obj/Makefile +++ b/mdk-stage1/insmod-modutils/obj/Makefile @@ -23,7 +23,12 @@ INCS = -I./../include DEFS = -D_GNU_SOURCE -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) -DCONFIG_ROOT_CHECK_OFF=0 -OBJS = obj_kallsyms.o obj_common.o obj_load.o obj_reloc.o obj_$(ARCH).o +ifeq (x86_64, $(ARCH)) +DEFS += -Wno-error +endif + +OBJS = obj_kallsyms.o obj_common.o obj_load.o obj_reloc.o obj_$(ARCH).o \ + obj_gpl_license.o libobj.a: $(OBJS) ar cru $@ $^ diff --git a/mdk-stage1/insmod-modutils/obj/obj_alpha.c b/mdk-stage1/insmod-modutils/obj/obj_alpha.c index 4006b3442..175012716 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_alpha.c +++ b/mdk-stage1/insmod-modutils/obj/obj_alpha.c @@ -19,8 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> @@ -28,6 +26,12 @@ #include <obj.h> #include <util.h> + +/* This relocation got renamed, and the change hasn't propagated yet. */ +#ifndef R_ALPHA_GPREL16 +#define R_ALPHA_GPREL16 R_ALPHA_IMMED_GP_16 +#endif + /*======================================================================*/ struct alpha_got_entry @@ -100,6 +104,7 @@ arch_apply_relocation (struct obj_file *f, unsigned long *lloc = (unsigned long *)(targsec->contents + rel->r_offset); unsigned int *iloc = (unsigned int *)lloc; + unsigned short *sloc = (unsigned short *)lloc; Elf64_Addr dot = targsec->header.sh_addr + rel->r_offset; Elf64_Addr gp = af->got->header.sh_addr + 0x8000; @@ -115,6 +120,30 @@ arch_apply_relocation (struct obj_file *f, *lloc += v; break; + case R_ALPHA_GPREL16: + v -= gp; + if ((Elf64_Sxword)v > 0x7fff + || (Elf64_Sxword)v < -(Elf64_Sxword)0x8000) + ret = obj_reloc_overflow; + *sloc = v; + break; + + case R_ALPHA_GPRELLOW: + /* GPRELLOW does not overflow. Errors are seen in the + corresponding GPRELHIGH. */ + v -= gp; + *sloc = v; + break; + + case R_ALPHA_GPRELHIGH: + v -= gp; + v = ((Elf64_Sxword)v >> 16) + ((v >> 15) & 1); + if ((Elf64_Sxword)v > 0x7fff + || (Elf64_Sxword)v < -(Elf64_Sxword)0x8000) + ret = obj_reloc_overflow; + *sloc = v; + break; + case R_ALPHA_GPREL32: v -= gp; if ((Elf64_Sxword)v > 0x7fffffff @@ -138,7 +167,7 @@ arch_apply_relocation (struct obj_file *f, gotent->reloc_done = 1; } - *iloc = (*iloc & ~0xffff) | ((gotent->offset - 0x8000) & 0xffff); + *sloc = gotent->offset - 0x8000; } break; @@ -233,19 +262,12 @@ arch_create_got (struct obj_file *f) for (; rel < relend; ++rel) { struct alpha_got_entry *ent; - Elf64_Sym *extsym; struct alpha_symbol *intsym; - const char *name; if (ELF64_R_TYPE(rel->r_info) != R_ALPHA_LITERAL) continue; - extsym = &symtab[ELF64_R_SYM(rel->r_info)]; - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = (struct alpha_symbol *)obj_find_symbol(&af->root, name); + obj_find_relsym(intsym, f, &af->root, rel, symtab, strtab); for (ent = intsym->got_entries; ent ; ent = ent->next) if (ent->addend == rel->r_addend) @@ -270,9 +292,10 @@ arch_create_got (struct obj_file *f) } /* We always want a .got section so that we always have a GP for - use with GPDISP and GPREL32 relocs. Besides, if the section + use with GPDISP and GPREL relocs. Besides, if the section is empty we don't use up space anyway. */ - af->got = obj_create_alloced_section(&af->root, ".got", 8, offset); + af->got = obj_create_alloced_section(&af->root, ".got", 8, offset, + SHF_WRITE | SHF_ALPHA_GPREL); return 1; } diff --git a/mdk-stage1/insmod-modutils/obj/obj_arm.c b/mdk-stage1/insmod-modutils/obj/obj_arm.c index 7a843f947..78b53700c 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_arm.c +++ b/mdk-stage1/insmod-modutils/obj/obj_arm.c @@ -21,8 +21,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> @@ -201,7 +199,7 @@ arch_create_got (struct obj_file *f) struct obj_section *sec, *syms, *strs; ElfW(Rel) *rel, *relend; ElfW(Sym) *symtab, *extsym; - const char *strtab, *name; + const char *strtab; struct arm_symbol *intsym; struct arm_plt_entry *pe; struct arm_got_entry *ge; @@ -227,11 +225,7 @@ arch_create_got (struct obj_file *f) switch(ELF32_R_TYPE(rel->r_info)) { case R_ARM_PC24: case R_ARM_PLT32: - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = (struct arm_symbol *) obj_find_symbol(f, name); + obj_find_relsym(intsym, f, f, rel, symtab, strtab); pe = &intsym->pltent; @@ -252,11 +246,7 @@ arch_create_got (struct obj_file *f) break; case R_ARM_GOT32: - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = (struct arm_symbol *) obj_find_symbol(f, name); + obj_find_relsym(intsym, f, f, rel, symtab, strtab); ge = (struct arm_got_entry *) &intsym->gotent; if (! ge->allocated) @@ -282,14 +272,16 @@ arch_create_got (struct obj_file *f) obj_extend_section(sec, got_offset); else { - sec = obj_create_alloced_section(f, ".got", 8, got_offset); + sec = obj_create_alloced_section(f, ".got", 8, got_offset, + SHF_WRITE); assert(sec); } afile->got = sec; } if (plt_offset) - afile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset); + afile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset, + SHF_WRITE); return 1; } diff --git a/mdk-stage1/insmod-modutils/obj/obj_common.c b/mdk-stage1/insmod-modutils/obj/obj_common.c index 2a6606c94..a957ff1be 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_common.c +++ b/mdk-stage1/insmod-modutils/obj/obj_common.c @@ -19,11 +19,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <string.h> #include <assert.h> +#include <alloca.h> #include <obj.h> #include <util.h> @@ -229,6 +228,14 @@ obj_find_section (struct obj_file *f, const char *name) return NULL; } +#if defined (ARCH_alpha) +#define ARCH_SHF_SHORT SHF_ALPHA_GPREL +#elif defined (ARCH_ia64) +#define ARCH_SHF_SHORT SHF_IA_64_SHORT +#else +#define ARCH_SHF_SHORT 0 +#endif + static int obj_load_order_prio(struct obj_section *a) { @@ -237,15 +244,24 @@ obj_load_order_prio(struct obj_section *a) af = a->header.sh_flags; ac = 0; - if (a->name[0] != '.' || strlen(a->name) != 10 || - strcmp(a->name + 5, ".init")) ac |= 32; - if (af & SHF_ALLOC) ac |= 16; + if (a->name[0] != '.' + || strlen(a->name) != 10 + || strcmp(a->name + 5, ".init")) + ac |= 64; + if (af & SHF_ALLOC) ac |= 32; + if (af & SHF_EXECINSTR) ac |= 16; if (!(af & SHF_WRITE)) ac |= 8; - if (af & SHF_EXECINSTR) ac |= 4; - if (a->header.sh_type != SHT_NOBITS) ac |= 2; -#if defined(ARCH_ia64) - if (af & SHF_IA_64_SHORT) ac -= 1; -#endif + if (a->header.sh_type != SHT_NOBITS) ac |= 4; + /* Desired order is + P S AC & 7 + .data 1 0 4 + .got 1 1 3 + .sdata 1 1 1 + .sbss 0 1 1 + .bss 0 0 0 */ + if (strcmp (a->name, ".got") == 0) ac |= 2; + if (af & ARCH_SHF_SHORT) + ac = (ac & ~4) | 1; return ac; } @@ -264,7 +280,8 @@ obj_insert_section_load_order (struct obj_file *f, struct obj_section *sec) struct obj_section * obj_create_alloced_section (struct obj_file *f, const char *name, - unsigned long align, unsigned long size) + unsigned long align, unsigned long size, + unsigned long flags) { int newidx = f->header.e_shnum++; struct obj_section *sec; @@ -274,7 +291,7 @@ obj_create_alloced_section (struct obj_file *f, const char *name, memset(sec, 0, sizeof(*sec)); sec->header.sh_type = SHT_PROGBITS; - sec->header.sh_flags = SHF_WRITE|SHF_ALLOC; + sec->header.sh_flags = flags | SHF_ALLOC; sec->header.sh_size = size; sec->header.sh_addralign = align; sec->name = name; diff --git a/mdk-stage1/insmod-modutils/obj/obj_gpl_license.c b/mdk-stage1/insmod-modutils/obj/obj_gpl_license.c new file mode 100644 index 000000000..366b03e06 --- /dev/null +++ b/mdk-stage1/insmod-modutils/obj/obj_gpl_license.c @@ -0,0 +1,61 @@ +/* Return the type of license for a module. 0 for GPL, 1 for no license, 2 for + non-GPL. The license parameter is set to the license string or NULL. + + This file is part of the Linux modutils. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <string.h> +#include "obj.h" + +/* This list must match *exactly* the list of allowable licenses in + * linux/include/linux/module.h. Checking for leading "GPL" will not + * work, somebody will use "GPL sucks, this is proprietary". + */ +static const char *gpl_licenses[] = { + "GPL", + "GPL v2", + "GPL and additional rights", + "Dual BSD/GPL", + "Dual MPL/GPL", +}; + +int obj_gpl_license(struct obj_file *f, const char **license) +{ + struct obj_section *sec; + if ((sec = obj_find_section(f, ".modinfo"))) { + const char *value, *ptr, *endptr; + ptr = sec->contents; + endptr = ptr + sec->header.sh_size; + while (ptr < endptr) { + if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) { + int i; + if (license) + *license = value+1; + for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) { + if (strcmp(value+1, gpl_licenses[i]) == 0) + return(0); + } + return(2); + } + if (strchr(ptr, '\0')) + ptr = strchr(ptr, '\0') + 1; + else + ptr = endptr; + } + } + return(1); +} diff --git a/mdk-stage1/insmod-modutils/obj/obj_hppa.c b/mdk-stage1/insmod-modutils/obj/obj_hppa.c index 4207e692e..a6f703c5d 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_hppa.c +++ b/mdk-stage1/insmod-modutils/obj/obj_hppa.c @@ -64,36 +64,6 @@ enum hppa_fsel e_rrsel }; -/* This could be a call to obj_create_alloced_section() followed - * by an overwrite of sec->header.sh_flags. - */ - -struct obj_section * -obj_hppa_create_alloced_section (struct obj_file *f, const char *name, - unsigned long align, unsigned long size, - unsigned long sh_flags) -{ - int newidx = f->header.e_shnum++; - struct obj_section *sec; - - f->sections = xrealloc(f->sections, (newidx+1) * sizeof(sec)); - f->sections[newidx] = sec = arch_new_section(); - - memset(sec, 0, sizeof(*sec)); - sec->header.sh_type = SHT_PROGBITS; - sec->header.sh_flags = sh_flags; - sec->header.sh_size = size; - sec->header.sh_addralign = align; - sec->name = name; - sec->idx = newidx; - if (size) - sec->contents = xmalloc(size); - - obj_insert_section_load_order(f, sec); - - return sec; -} - struct obj_file * arch_new_file (void) { @@ -383,14 +353,14 @@ hppa_rebuild_insn (insn, value, r_format) This is significantly less complex than what we do for shared libraries because, obviously, modules are not shared. Also we have no issues related to symbol visibility, lazy linking, etc. - The kernels dp is fixed (at symbol data_start), and we can fix up any + The kernels dp is fixed (at symbol $global$), and we can fix up any DPREL refs in the module to use that same dp value. - All PCREL17F refs result in a stub with the following format: + All PCREL* refs result in a stub with the following format: ldil L'func_addr,%r1 be,n R'func_addr(%sr4,%r1) - Note, all PCREL17F get a stub, regardless of whether they are + Note, all PCREL* get a stub, regardless of whether they are local or external. With local ones, and external ones to other modules, there is a good chance we could manage without the stub. I'll leave that for a future optimisation. @@ -411,7 +381,8 @@ arch_create_got(struct obj_file *f) /* Create stub section. * XXX set flags, see obj_ia64.c */ - hfile->stub = obj_create_alloced_section(f, ".stub", STUB_SIZE, 0); + hfile->stub = obj_create_alloced_section(f, ".stub", STUB_SIZE, + 0, SHF_WRITE); /* Actually this is a lot like check_relocs() in a BFD backend. We walk all sections and all their relocations and look for ones @@ -446,30 +417,17 @@ arch_create_got(struct obj_file *f) continue; case R_PARISC_PCREL17F: + case R_PARISC_PCREL22F: need_stub = 1; break; } if (need_stub) { - Elf32_Sym *extsym; hppa_symbol_t *hsym; - char const *name; int local; - unsigned long symndx; - symndx = ELF32_R_SYM(rel->r_info); - extsym = symtab + symndx; - if (ELF32_ST_BIND(extsym->st_info) == STB_LOCAL) - hsym = (hppa_symbol_t *) f->local_symtab[symndx]; - else - { - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - hsym = (hppa_symbol_t *)obj_find_symbol(f, name); - } + obj_find_relsym(hsym, f, f, rel, symtab, strtab); local = hsym->root.secidx <= SHN_HIRESERVE; if (need_stub) @@ -529,12 +487,17 @@ arch_apply_relocation(struct obj_file *f, /* Easy. */ break; + case R_PARISC_SEGREL32: + v -= f->baseaddr; + break; + case R_PARISC_DPREL21L: case R_PARISC_DPREL14R: v -= dp; break; case R_PARISC_PCREL17F: + case R_PARISC_PCREL22F: /* Find an import stub. */ assert(hsym->stub != NULL); assert(hfile->stub != NULL); @@ -566,6 +529,8 @@ arch_apply_relocation(struct obj_file *f, case R_PARISC_DIR32: case R_PARISC_PLABEL32: case R_PARISC_PCREL17F: + case R_PARISC_SEGREL32: + case R_PARISC_PCREL22F: fsel = e_fsel; break; @@ -602,6 +567,7 @@ arch_apply_relocation(struct obj_file *f, { case R_PARISC_DIR32: case R_PARISC_PLABEL32: + case R_PARISC_SEGREL32: r_format = 32; break; @@ -619,6 +585,10 @@ arch_apply_relocation(struct obj_file *f, r_format = 14; break; + case R_PARISC_PCREL22F: + r_format = 22; + break; + default: abort(); } @@ -652,13 +622,13 @@ arch_archdata (struct obj_file *f, struct obj_section *sec) int i; hppa_file_t *hfile = (hppa_file_t *)f; - /* Initialise dp to the kernels dp (symbol data_start) + /* Initialise dp to the kernels dp (symbol $global$) */ for (i = 0, s = ksyms; i < nksyms; i++, s++) - if (!strcmp((char *)s->name, "data_start")) + if (!strcmp((char *)s->name, "$global$")) break; if (i >= nksyms) { - error("Cannot initialise dp, 'data_start' not found\n"); + error("Cannot initialise dp, '$global$' not found\n"); return 1; } hfile->dp = s->value; diff --git a/mdk-stage1/insmod-modutils/obj/obj_hppa64.c b/mdk-stage1/insmod-modutils/obj/obj_hppa64.c index fe32911ff..d9f1ada9d 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_hppa64.c +++ b/mdk-stage1/insmod-modutils/obj/obj_hppa64.c @@ -22,8 +22,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> #include <stdlib.h> @@ -94,15 +92,15 @@ typedef struct _hppa64_file_t * e8 20 d0 00 bve (r1) * 53 7b 00 30 ldd 18(dp),dp * - * We need a different stub for millicode calls, which doesn't screw - * dp: + * We need a different stub for millicode calls, which doesn't depend on + * or modify dp: * - * 53 61 00 00 ldd 0(dp),r1 - * R_PARISC_LTOFF14R <.got entry offset from dp> + * 20 20 00 00 ldil 0,r1 + * R_PARISC_DIR21L <addr of kernels opd entry> + * 34 21 00 00 ldo 0(r1),r1 + * R_PARISC_DIR14R <addr of kernels opd entry> * 50 21 00 20 ldd 10(r1),r1 - * e8 20 d0 00 bve (r1) - * 08 00 02 40 nop - * + * e8 20 d0 02 bve,n (r1) */ /* NOTE: to keep the code cleaner we make all stubs the same size. @@ -120,10 +118,10 @@ unsigned char hppa64_stub_extern[] = unsigned char hppa64_stub_millicode[] = { - 0x53, 0x61, 0x00, 0x00, + 0x20, 0x20, 0x00, 0x00, + 0x34, 0x21, 0x00, 0x00, 0x50, 0x21, 0x00, 0x20, - 0xe8, 0x20, 0xd0, 0x00, - 0x08, 0x00, 0x02, 0x40, + 0xe8, 0x20, 0xd0, 0x02, }; /*======================================================================*/ @@ -361,6 +359,7 @@ arch_create_got(struct obj_file *f) need_stub = TRUE; break; case R_PARISC_DIR64: + case R_PARISC_SEGREL32: break; case R_PARISC_FPTR64: /* This is a simple OPD entry (only created for local symbols, @@ -372,26 +371,10 @@ arch_create_got(struct obj_file *f) if (need_got || need_opd || need_stub) { - Elf64_Sym *extsym; hppa64_symbol_t *isym; - const char *name; int local; - unsigned long symndx; - symndx = ELF64_R_SYM(rel->r_info); - extsym = &symtab[symndx]; - if (ELF64_ST_BIND(extsym->st_info) == STB_LOCAL) - { - isym = (hppa64_symbol_t *) f->local_symtab[symndx]; - } - else - { - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - isym = (hppa64_symbol_t *)obj_find_symbol(f, name); - } + obj_find_relsym(isym, f, f, rel, symtab, strtab); local = isym->root.secidx <= SHN_HIRESERVE; if (need_stub) @@ -574,16 +557,24 @@ arch_apply_relocation(struct obj_file *f, */ unsigned char *stub; - if (!strncmp(isym->root.name, "$$", 2)) + if (!strncmp(isym->root.name, "$$", 2)) { stub = hppa64_stub_millicode; - else + memcpy((Elf64_Addr *)(hfile->stub->contents + se->offset), + stub, SIZEOF_STUB); + v = (Elf64_Addr)isym->root.value; + ret = patch_21l(v, (Elf64_Word *)(hfile->stub->contents + se->offset)); + if (ret == obj_reloc_ok) + ret = patch_14r(v, (Elf64_Word *)(hfile->stub->contents + se->offset + 4)); + } + else { stub = hppa64_stub_extern; - se->reloc_done = TRUE; memcpy((Elf64_Addr *)(hfile->stub->contents + se->offset), stub, SIZEOF_STUB); v = (Elf64_Addr)(hfile->got->header.sh_addr + ge->offset) - gp; ret = patch_14r2(v, (Elf64_Word *)(hfile->stub->contents + se->offset)); } + se->reloc_done = TRUE; + } v = hfile->stub->header.sh_addr + se->offset; } v = v - dot - 8; @@ -597,6 +588,11 @@ arch_apply_relocation(struct obj_file *f, loc[1] = v; } break; + case R_PARISC_SEGREL32: + { + loc[0] = v - f->baseaddr; + } + break; case R_PARISC_FPTR64: { assert(isym != NULL); diff --git a/mdk-stage1/insmod-modutils/obj/obj_i386.c b/mdk-stage1/insmod-modutils/obj/obj_i386.c index 28df3448c..fcbce8e04 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_i386.c +++ b/mdk-stage1/insmod-modutils/obj/obj_i386.c @@ -19,8 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> @@ -183,9 +181,7 @@ arch_create_got (struct obj_file *f) for (; rel < relend; ++rel) { - Elf32_Sym *extsym; struct i386_symbol *intsym; - const char *name; switch (ELF32_R_TYPE(rel->r_info)) { @@ -199,12 +195,7 @@ arch_create_got (struct obj_file *f) break; } - extsym = &symtab[ELF32_R_SYM(rel->r_info)]; - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = (struct i386_symbol *)obj_find_symbol(&ifile->root, name); + obj_find_relsym(intsym, f, &ifile->root, rel, symtab, strtab); if (!intsym->gotent.offset_done) { @@ -216,7 +207,8 @@ arch_create_got (struct obj_file *f) } if (offset > 0 || gotneeded) - ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset); + ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset, + SHF_WRITE); return 1; } diff --git a/mdk-stage1/insmod-modutils/obj/obj_ia64.c b/mdk-stage1/insmod-modutils/obj/obj_ia64.c index 4f92c5d27..d207a9042 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_ia64.c +++ b/mdk-stage1/insmod-modutils/obj/obj_ia64.c @@ -19,8 +19,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> #include <stdlib.h> @@ -255,14 +253,15 @@ obj_ia64_ins_imm64(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) { Elf64_Xword ins; - assert(slot == 1); + assert(slot == 2); + ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffee000101ff; - ins |= ((v & 0x8000000000000000) >> 28) | ((v & 0x0000000000200000)) | + ins &= 0xffffffe000101fff; + ins |= ((v & 0x8000000000000000) >> 27) | ((v & 0x0000000000200000)) | ((v & 0x00000000001f0000) << 6) | ((v & 0x000000000000ff80) << 20) | ((v & 0x000000000000007f) << 13); obj_ia64_ins_insert_in_bundle(bundle, slot, ins); - obj_ia64_ins_insert_in_bundle(bundle, ++slot, ((v & 0x7fffffffffc00000) >> 22)); + obj_ia64_ins_insert_in_bundle(bundle, --slot, ((v & 0x7fffffffffc00000) >> 22)); return obj_reloc_ok; } @@ -295,30 +294,6 @@ obj_ia64_generate_plt(Elf64_Addr v, (Elf64_Addr *)(ifile->pltt->contents + pltent->text_offset), 0); } -struct obj_section * -obj_ia64_create_alloced_section (struct obj_file *f, const char *name, - unsigned long align, unsigned long size, unsigned long sh_flags) -{ - int newidx = f->header.e_shnum++; - struct obj_section *sec; - - f->sections = xrealloc(f->sections, (newidx+1) * sizeof(sec)); - f->sections[newidx] = sec = arch_new_section(); - - memset(sec, 0, sizeof(*sec)); - sec->header.sh_type = SHT_PROGBITS; - sec->header.sh_flags = sh_flags; - sec->header.sh_size = size; - sec->header.sh_addralign = align; - sec->name = name; - sec->idx = newidx; - if (size) - sec->contents = xmalloc(size); - - obj_insert_section_load_order(f, sec); - - return sec; -} /*======================================================================*/ @@ -457,26 +432,10 @@ arch_create_got(struct obj_file *f) if (need_got || need_opd || need_plt) { - Elf64_Sym *extsym; ia64_symbol_t *isym; - const char *name; int local; - unsigned long symndx; - symndx = ELF64_R_SYM(rel->r_info); - extsym = &symtab[symndx]; - if (ELF64_ST_BIND(extsym->st_info) == STB_LOCAL) - { - isym = (ia64_symbol_t *) f->local_symtab[symndx]; - } - else - { - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - isym = (ia64_symbol_t *)obj_find_symbol(f, name); - } + obj_find_relsym(isym, f, f, rel, symtab, strtab); local = isym->root.secidx <= SHN_HIRESERVE; if (need_plt) @@ -545,20 +504,22 @@ arch_create_got(struct obj_file *f) } } - ifile->got = obj_ia64_create_alloced_section(f, ".got", 8, got_offset, - (SHF_ALLOC | SHF_WRITE | SHF_IA_64_SHORT)); + ifile->got = obj_create_alloced_section(f, ".got", 8, got_offset, + SHF_WRITE | SHF_IA_64_SHORT); assert(ifile->got != NULL); - ifile->opd = obj_ia64_create_alloced_section(f, ".opd", 16, opd_offset, - (SHF_ALLOC | SHF_WRITE | SHF_IA_64_SHORT)); + ifile->opd = obj_create_alloced_section(f, ".opd", 16, opd_offset, + SHF_WRITE | SHF_IA_64_SHORT); assert(ifile->opd != NULL); if (plt_text_offset > 0) { - ifile->pltt = obj_ia64_create_alloced_section(f, ".plt", 16, - plt_text_offset, (SHF_ALLOC | SHF_EXECINSTR | SHF_IA_64_SHORT)); - ifile->pltd = obj_ia64_create_alloced_section(f, ".IA_64.pltoff", - 16, plt_data_offset, (SHF_ALLOC | SHF_WRITE | SHF_IA_64_SHORT)); + ifile->pltt = obj_create_alloced_section(f, ".plt", 16, + plt_text_offset, + SHF_WRITE | SHF_IA_64_SHORT); + ifile->pltd = obj_create_alloced_section(f, ".IA_64.pltoff", 16, + plt_data_offset, + SHF_WRITE | SHF_IA_64_SHORT); assert(ifile->pltt != NULL); assert(ifile->pltd != NULL); } @@ -950,12 +911,8 @@ arch_apply_relocation(struct obj_file *f, case R_IA64_SEGREL32LSB : /* @segrel(sym + add), data4 LSB */ case R_IA64_SEGREL64LSB : /* @segrel(sym + add), data8 LSB */ - if (targsec->header.sh_type & SHT_NOBITS) - v = ifile->bss - v; - else if (targsec->header.sh_flags & SHF_EXECINSTR) - v = ifile->text - v; - else - v = ifile->data - v; + /* Only one segment for modules, see segment_base in arch_archdata */ + v -= f->sections[1]->header.sh_addr; if (r_info == R_IA64_SEGREL32LSB) COPY_32LSB(loc, v); else diff --git a/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c b/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c index 8385fb892..1836141e9 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c +++ b/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c @@ -17,8 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <string.h> #include <malloc.h> @@ -37,7 +35,7 @@ static void append_string (const char *s, char **strings, ElfW(Word) *strings_size, ElfW(Word) *strings_left) { - int l = strlen(s) + 1; + size_t l = strlen(s) + 1; while (l > *strings_left) { *strings = xrealloc(*strings, *strings_size += EXPAND_BY); *strings_left += EXPAND_BY; @@ -54,7 +52,7 @@ append_symbol (const struct kallsyms_symbol *s, struct kallsyms_symbol **symbols, ElfW(Word) *symbols_size, ElfW(Word) *symbols_left) { - int l = sizeof(*s); + size_t l = sizeof(*s); while (l > *symbols_left) { *symbols = xrealloc(*symbols, *symbols_size += EXPAND_BY); *symbols_left += EXPAND_BY; diff --git a/mdk-stage1/insmod-modutils/obj/obj_load.c b/mdk-stage1/insmod-modutils/obj/obj_load.c index 4db20a998..62977acb7 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_load.c +++ b/mdk-stage1/insmod-modutils/obj/obj_load.c @@ -21,8 +21,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <alloca.h> #include <string.h> #include <stdlib.h> @@ -52,7 +50,7 @@ obj_load (int fp, Elf32_Half e_type, const char *filename) gzf_lseek(fp, 0, SEEK_SET); if (gzf_read(fp, &f->header, sizeof(f->header)) != sizeof(f->header)) { - error("error reading ELF header %s: %m", filename); + error("cannot read ELF header from %s", filename); return NULL; } @@ -257,7 +255,7 @@ obj_load (int fp, Elf32_Half e_type, const char *filename) { case SHT_RELM: { - unsigned long nrel, j; + unsigned long nrel, j, nsyms; ElfW(RelM) *rel; struct obj_section *symtab; char *strtab; @@ -273,34 +271,25 @@ obj_load (int fp, Elf32_Half e_type, const char *filename) nrel = sec->header.sh_size / sizeof(ElfW(RelM)); rel = (ElfW(RelM) *) sec->contents; symtab = f->sections[sec->header.sh_link]; + nsyms = symtab->header.sh_size / symtab->header.sh_entsize; strtab = f->sections[symtab->header.sh_link]->contents; /* Save the relocate type in each symbol entry. */ for (j = 0; j < nrel; ++j, ++rel) { - ElfW(Sym) *extsym; struct obj_symbol *intsym; unsigned long symndx; symndx = ELFW(R_SYM)(rel->r_info); if (symndx) { - extsym = ((ElfW(Sym) *) symtab->contents) + symndx; - if (ELFW(ST_BIND)(extsym->st_info) == STB_LOCAL) - { - /* Local symbols we look up in the local table to be sure - we get the one that is really intended. */ - intsym = f->local_symtab[symndx]; - } - else + if (symndx >= nsyms) { - /* Others we look up in the hash table. */ - const char *name; - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = obj_find_symbol(f, name); + error("%s: Bad symbol index: %08lx >= %08lx", + filename, symndx, nsyms); + continue; } + + obj_find_relsym(intsym, f, f, rel, (ElfW(Sym) *)(symtab->contents), strtab); intsym->r_type = ELFW(R_TYPE)(rel->r_info); } } diff --git a/mdk-stage1/insmod-modutils/obj/obj_m68k.c b/mdk-stage1/insmod-modutils/obj/obj_m68k.c index cb485aed7..abc070bca 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_m68k.c +++ b/mdk-stage1/insmod-modutils/obj/obj_m68k.c @@ -19,8 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stddef.h> #include <module.h> #include <obj.h> diff --git a/mdk-stage1/insmod-modutils/obj/obj_mips.c b/mdk-stage1/insmod-modutils/obj/obj_mips.c index c2315b659..2db0791b6 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_mips.c +++ b/mdk-stage1/insmod-modutils/obj/obj_mips.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <stdlib.h> #include <assert.h> @@ -232,7 +230,25 @@ arch_finalize_section_address(struct obj_file *f, Elf32_Addr base) } int -arch_archdata (struct obj_file *fin, struct obj_section *sec) +arch_archdata (struct obj_file *f, struct obj_section *archdata_sec) { + struct archdata { + unsigned tgt_long __start___dbe_table; + unsigned tgt_long __stop___dbe_table; + } *ad; + struct obj_section *sec; + + if (archdata_sec->contents) + free(archdata_sec->contents); + archdata_sec->header.sh_size = 0; + sec = obj_find_section(f, "__dbe_table"); + if (sec) { + ad = (struct archdata *) (archdata_sec->contents) = xmalloc(sizeof(*ad)); + memset(ad, 0, sizeof(*ad)); + archdata_sec->header.sh_size = sizeof(*ad); + ad->__start___dbe_table = sec->header.sh_addr; + ad->__stop___dbe_table = sec->header.sh_addr + sec->header.sh_size; + } + return 0; } diff --git a/mdk-stage1/insmod-modutils/obj/obj_ppc.c b/mdk-stage1/insmod-modutils/obj/obj_ppc.c index 89bb8e46b..4889454f2 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_ppc.c +++ b/mdk-stage1/insmod-modutils/obj/obj_ppc.c @@ -20,8 +20,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stddef.h> #include <module.h> #include <obj.h> @@ -180,8 +178,8 @@ arch_create_got (struct obj_file *f) int i, offset; struct obj_section *sec, *syms, *strs; ElfW(Rela) *rel, *relend; - ElfW(Sym) *symtab, *extsym; - const char *strtab, *name; + ElfW(Sym) *symtab; + const char *strtab; struct ppc_symbol *intsym; struct ppc_plt_entry *pe; @@ -203,12 +201,7 @@ arch_create_got (struct obj_file *f) { if (ELF32_R_TYPE(rel->r_info) != R_PPC_REL24) continue; - extsym = &symtab[ELF32_R_SYM(rel->r_info)]; - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = (struct ppc_symbol *) obj_find_symbol(f, name); + obj_find_relsym(intsym, f, f, rel, symtab, strtab); for (pe = intsym->plt_entries; pe != NULL; pe = pe->next) if (pe->addend == rel->r_addend) @@ -226,7 +219,7 @@ arch_create_got (struct obj_file *f) } } - pf->plt = obj_create_alloced_section(f, ".plt", 16, offset); + pf->plt = obj_create_alloced_section(f, ".plt", 16, offset, SHF_WRITE); return 1; } @@ -249,7 +242,25 @@ arch_finalize_section_address(struct obj_file *f, Elf32_Addr base) } int -arch_archdata (struct obj_file *fin, struct obj_section *sec) +arch_archdata (struct obj_file *f, struct obj_section *archdata_sec) { + struct archdata { + unsigned tgt_long __start___ftr_fixup; + unsigned tgt_long __stop___ftr_fixup; + } *ad; + struct obj_section *sec; + + if (archdata_sec->contents) + free(archdata_sec->contents); + archdata_sec->header.sh_size = 0; + sec = obj_find_section(f, "__ftr_fixup"); + if (sec) { + ad = (struct archdata *) (archdata_sec->contents) = xmalloc(sizeof(*ad)); + memset(ad, 0, sizeof(*ad)); + archdata_sec->header.sh_size = sizeof(*ad); + ad->__start___ftr_fixup = sec->header.sh_addr; + ad->__stop___ftr_fixup = sec->header.sh_addr + sec->header.sh_size; + } + return 0; } diff --git a/mdk-stage1/insmod-modutils/obj/obj_reloc.c b/mdk-stage1/insmod-modutils/obj/obj_reloc.c index f5f2de90d..3f2c8aab0 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_reloc.c +++ b/mdk-stage1/insmod-modutils/obj/obj_reloc.c @@ -19,8 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> #include <alloca.h> @@ -48,7 +46,7 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, strsec = obj_find_section(f, ".kstrtab"); if (strsec == NULL) { - strsec = obj_create_alloced_section(f, ".kstrtab", 1, len); + strsec = obj_create_alloced_section(f, ".kstrtab", 1, len, 0); p->string_offset = 0; loc = strsec->contents; } @@ -284,6 +282,7 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base) ElfW(RelM) *rel, *relend; ElfW(Sym) *symtab; const char *strtab; + unsigned long nsyms; relsec = f->sections[i]; if (relsec->header.sh_type != SHT_RELM) @@ -293,9 +292,13 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base) targsec = f->sections[relsec->header.sh_info]; strsec = f->sections[symsec->header.sh_link]; + if (!(targsec->header.sh_flags & SHF_ALLOC)) + continue; + rel = (ElfW(RelM) *)relsec->contents; relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM))); symtab = (ElfW(Sym) *)symsec->contents; + nsyms = symsec->header.sh_size / symsec->header.sh_entsize; strtab = (const char *)strsec->contents; for (; rel < relend; ++rel) @@ -303,7 +306,6 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base) ElfW(Addr) value = 0; struct obj_symbol *intsym = NULL; unsigned long symndx; - ElfW(Sym) *extsym = 0; const char *errmsg; /* Attempt to find a value to use for this relocation. */ @@ -313,33 +315,18 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base) { /* Note we've already checked for undefined symbols. */ - extsym = &symtab[symndx]; - if (ELFW(ST_BIND)(extsym->st_info) == STB_LOCAL) - { - /* Local symbols we look up in the local table to be sure - we get the one that is really intended. */ - intsym = f->local_symtab[symndx]; - } - else + if (symndx >= nsyms) { - /* Others we look up in the hash table. */ - const char *name; - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = obj_find_symbol(f, name); + error("Bad symbol index: %08lx >= %08lx", + symndx, nsyms); + continue; } + obj_find_relsym(intsym, f, f, rel, symtab, strtab); value = obj_symbol_final_value(f, intsym); } #if SHT_RELM == SHT_RELA -#if defined(__alpha__) && defined(AXP_BROKEN_GAS) - /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ - if (!extsym || !extsym->st_name || - ELFW(ST_BIND)(extsym->st_info) != STB_LOCAL) -#endif value += rel->r_addend; #endif @@ -362,17 +349,8 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base) errmsg = "Modules compiled with -mconstant-gp cannot be loaded"; goto bad_reloc; bad_reloc: - if (extsym) - { error("%s of type %ld for %s", errmsg, - (long)ELFW(R_TYPE)(rel->r_info), - strtab + extsym->st_name); - } - else - { - error("%s of type %ld", errmsg, - (long)ELFW(R_TYPE)(rel->r_info)); - } + (long)ELFW(R_TYPE)(rel->r_info), intsym->name); ret = 0; break; } diff --git a/mdk-stage1/insmod-modutils/obj/obj_s390.c b/mdk-stage1/insmod-modutils/obj/obj_s390.c index 3da72e771..a76e28479 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_s390.c +++ b/mdk-stage1/insmod-modutils/obj/obj_s390.c @@ -1,6 +1,10 @@ -/* S/390 specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. +/* IBM S/390 31-bit specific support for Elf loading and relocation. + Copyright 2000, 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation. + Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com> + + Derived from obj/obj_i386.c: + Copyright 1996, 1997 Linux International. Contributed by Richard Henderson <rth@tamu.edu> This file is part of the Linux modutils. @@ -19,8 +23,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <string.h> #include <assert.h> @@ -31,22 +33,31 @@ /*======================================================================*/ +struct s390_plt_entry +{ + long offset; + int allocated:1; + int initialized:1; +}; + struct s390_got_entry { - int offset; - unsigned offset_done : 1; + long offset; + unsigned allocated:1; unsigned reloc_done : 1; }; struct s390_file { struct obj_file root; + struct obj_section *plt; struct obj_section *got; }; struct s390_symbol { struct obj_symbol root; + struct s390_plt_entry pltent; struct s390_got_entry gotent; }; @@ -59,6 +70,7 @@ arch_new_file (void) struct s390_file *f; f = xmalloc(sizeof(*f)); f->got = NULL; + f->plt = NULL; return &f->root; } @@ -74,6 +86,7 @@ arch_new_symbol (void) struct s390_symbol *sym; sym = xmalloc(sizeof(*sym)); memset(&sym->gotent, 0, sizeof(sym->gotent)); + memset(&sym->pltent, 0, sizeof(sym->pltent)); return &sym->root; } @@ -95,12 +108,14 @@ arch_apply_relocation (struct obj_file *f, Elf32_Rela *rel, Elf32_Addr v) { - struct s390_file *ifile = (struct s390_file *)f; - struct s390_symbol *isym = (struct s390_symbol *)sym; + struct s390_file *ifile = (struct s390_file *) f; + struct s390_symbol *isym = (struct s390_symbol *) sym; + struct s390_plt_entry *pe; Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset); Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0; + Elf32_Addr plt = ifile->plt ? ifile->plt->header.sh_addr : 0; enum obj_reloc ret = obj_reloc_ok; @@ -110,12 +125,48 @@ arch_apply_relocation (struct obj_file *f, break; case R_390_32: - *loc += v; + *(unsigned int *) loc += v; + break; + case R_390_16: + *(unsigned short *) loc += v; + break; + case R_390_8: + *(unsigned char *) loc += v; break; - case R_390_PLT32: case R_390_PC32: - *loc += v - dot; + *(unsigned int *) loc += v - dot; + break; + case R_390_PC16DBL: + *(unsigned short *) loc += (v - dot) >> 1; + break; + case R_390_PC16: + *(unsigned short *) loc += v - dot; + break; + + case R_390_PLT32: + case R_390_PLT16DBL: + /* find the plt entry and initialize it. */ + assert(isym != NULL); + pe = (struct s390_plt_entry *) &isym->pltent; + assert(pe->allocated); + if (pe->initialized == 0) { + unsigned int *ip = (unsigned int *)(ifile->plt->contents + pe->offset); + ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */ + ip[1] = 0x100607f1; + if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) + ip[2] = v - 2; + else + ip[2] = v; + pe->initialized = 1; + } + + /* Insert relative distance to target. */ + v = plt + pe->offset - dot; + if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32) + *(unsigned int *) loc = (unsigned int) v; + else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) + *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1); break; case R_390_GLOB_DAT: @@ -129,17 +180,25 @@ arch_apply_relocation (struct obj_file *f, case R_390_GOTPC: assert(got != 0); - *loc += got - dot; + *(unsigned long *) loc += got - dot; break; + case R_390_GOT12: + case R_390_GOT16: case R_390_GOT32: assert(isym != NULL); + assert(got != 0); if (!isym->gotent.reloc_done) { isym->gotent.reloc_done = 1; *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v; } - *loc += isym->gotent.offset; + if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12) + *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff; + else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16) + *(unsigned short *) loc += isym->gotent.offset; + else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32) + *(unsigned int *) loc += isym->gotent.offset; break; case R_390_GOTOFF: @@ -158,71 +217,98 @@ arch_apply_relocation (struct obj_file *f, int arch_create_got (struct obj_file *f) { - struct s390_file *ifile = (struct s390_file *)f; - int i, n, offset = 0, gotneeded = 0; + struct s390_file *ifile = (struct s390_file *) f; + int i, got_offset = 0, plt_offset = 0, gotneeded = 0; - n = ifile->root.header.e_shnum; - for (i = 0; i < n; ++i) + for (i = 0; i < f->header.e_shnum; ++i) { struct obj_section *relsec, *symsec, *strsec; - Elf32_Rel *rel, *relend; + Elf32_Rela *rel, *relend; Elf32_Sym *symtab; const char *strtab; - relsec = ifile->root.sections[i]; - if (relsec->header.sh_type != SHT_REL) + relsec = f->sections[i]; + if (relsec->header.sh_type != SHT_RELA) continue; - symsec = ifile->root.sections[relsec->header.sh_link]; - strsec = ifile->root.sections[symsec->header.sh_link]; + symsec = f->sections[relsec->header.sh_link]; + strsec = f->sections[symsec->header.sh_link]; - rel = (Elf32_Rel *)relsec->contents; - relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel)); + rel = (Elf32_Rela *)relsec->contents; + relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela)); symtab = (Elf32_Sym *)symsec->contents; strtab = (const char *)strsec->contents; for (; rel < relend; ++rel) { - Elf32_Sym *extsym; struct s390_symbol *intsym; - const char *name; - - switch (ELF32_R_TYPE(rel->r_info)) - { + struct s390_plt_entry *pe; + struct s390_got_entry *ge; + + switch (ELF32_R_TYPE(rel->r_info)) { + /* These four relocations refer to a plt entry. */ + case R_390_PLT16DBL: + case R_390_PLT32: + obj_find_relsym(intsym, f, f, rel, symtab, strtab); + assert(intsym); + pe = &intsym->pltent; + if (!pe->allocated) { + pe->allocated = 1; + pe->offset = plt_offset; + plt_offset += 12; + } + break; + /* The next three don't need got entries but the address + of the got itself. */ case R_390_GOTPC: case R_390_GOTOFF: gotneeded = 1; - default: - continue; + break; + case R_390_GOT12: + case R_390_GOT16: case R_390_GOT32: - break; + obj_find_relsym(intsym, f, f, rel, symtab, strtab); + assert(intsym); + ge = (struct s390_got_entry *) &intsym->gotent; + if (!ge->allocated) { + ge->allocated = 1; + ge->offset = got_offset; + got_offset += sizeof(void*); } + break; - extsym = &symtab[ELF32_R_SYM(rel->r_info)]; - if (extsym->st_name) - name = strtab + extsym->st_name; - else - name = f->sections[extsym->st_shndx]->name; - intsym = (struct s390_symbol *)obj_find_symbol(&ifile->root, name); - - if (!intsym->gotent.offset_done) - { - intsym->gotent.offset_done = 1; - intsym->gotent.offset = offset; - offset += 4; + default: + break; } } } - if (offset > 0 || gotneeded) - ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset); + if (got_offset > 0 || gotneeded) { + struct obj_section *gotsec; + struct obj_symbol *gotsym; + + gotsec = obj_find_section(f, ".got"); + if (gotsec == NULL) + gotsec = obj_create_alloced_section(f, ".got", 4, got_offset, SHF_WRITE); + else + obj_extend_section(gotsec, got_offset); + gotsym = obj_add_symbol(f, "_GLOBAL_OFFSET_TABLE_", -1, + ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), + gotsec->idx, 0, 0); + gotsym->secidx = gotsec->idx; /* mark the symbol as defined */ + ifile->got = gotsec; + } + + if (plt_offset > 0) + ifile->plt = obj_create_alloced_section(f, ".plt", 4, plt_offset, + SHF_WRITE); return 1; } int -arch_init_module (struct obj_file *f, struct module *m) +arch_init_module (struct obj_file *f, struct module *mod) { return 1; } @@ -243,3 +329,4 @@ arch_archdata (struct obj_file *fin, struct obj_section *sec) { return 0; } + diff --git a/mdk-stage1/insmod-modutils/obj/obj_sparc.c b/mdk-stage1/insmod-modutils/obj/obj_sparc.c index 1a03c9090..d1eb3da44 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_sparc.c +++ b/mdk-stage1/insmod-modutils/obj/obj_sparc.c @@ -19,8 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stddef.h> #include <module.h> #include <obj.h> diff --git a/mdk-stage1/insmod-modutils/obj/obj_sparc64.c b/mdk-stage1/insmod-modutils/obj/obj_sparc64.c index 84e8d18a0..f025667f8 100644 --- a/mdk-stage1/insmod-modutils/obj/obj_sparc64.c +++ b/mdk-stage1/insmod-modutils/obj/obj_sparc64.c @@ -19,8 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stddef.h> #include <module.h> #include <obj.h> diff --git a/mdk-stage1/insmod-modutils/obj/obj_x86_64.c b/mdk-stage1/insmod-modutils/obj/obj_x86_64.c new file mode 100644 index 000000000..56dfeeabd --- /dev/null +++ b/mdk-stage1/insmod-modutils/obj/obj_x86_64.c @@ -0,0 +1,253 @@ +/* x86-64 specific support for Elf loading and relocation. + Copyright 2002 SuSE Linux AG. + + Contributed by Andreas Jaeger <aj@suse.de>. + + This file is part of the Linux modutils. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ident "$Id$" + +#include <string.h> +#include <assert.h> + +#include <module.h> +#include <obj.h> +#include <util.h> + +/*======================================================================*/ + +struct x86_64_got_entry +{ + long int offset; + unsigned offset_done : 1; + unsigned reloc_done : 1; +}; + +struct x86_64_file +{ + struct obj_file root; + struct obj_section *got; +}; + +struct x86_64_symbol +{ + struct obj_symbol root; + struct x86_64_got_entry gotent; +}; + + +/*======================================================================*/ + +struct obj_file * +arch_new_file (void) +{ + struct x86_64_file *f; + f = xmalloc(sizeof(*f)); + f->got = NULL; + return &f->root; +} + +struct obj_section * +arch_new_section (void) +{ + return xmalloc(sizeof(struct obj_section)); +} + +struct obj_symbol * +arch_new_symbol (void) +{ + struct x86_64_symbol *sym; + sym = xmalloc(sizeof(*sym)); + memset(&sym->gotent, 0, sizeof(sym->gotent)); + return &sym->root; +} + +int +arch_load_proc_section(struct obj_section *sec, int fp) +{ + /* Assume it's just a debugging section that we can safely + ignore ... */ + sec->contents = NULL; + + return 0; +} + +enum obj_reloc +arch_apply_relocation (struct obj_file *f, + struct obj_section *targsec, + struct obj_section *symsec, + struct obj_symbol *sym, + Elf64_Rela *rel, + Elf64_Addr v) +{ + struct x86_64_file *ifile = (struct x86_64_file *)f; + struct x86_64_symbol *isym = (struct x86_64_symbol *)sym; + + Elf64_Addr *loc = (Elf64_Addr *)(targsec->contents + rel->r_offset); + Elf64_Addr dot = targsec->header.sh_addr + rel->r_offset; + Elf64_Addr got = ifile->got ? ifile->got->header.sh_addr : 0; + + enum obj_reloc ret = obj_reloc_ok; + + switch (ELF64_R_TYPE(rel->r_info)) + { + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *loc += v; + break; + + case R_X86_64_32: + *(unsigned int *) loc += v; + break; + + case R_X86_64_32S: + *(signed int *) loc += v; + break; + + case R_X86_64_16: + *(unsigned short *) loc += v; + break; + + case R_X86_64_8: + *(unsigned char *) loc += v; + break; + + case R_X86_64_PC32: + *(unsigned int *) loc += v - dot; + break; + + case R_X86_64_PC16: + *(unsigned short *) loc += v - dot; + break; + + case R_X86_64_PC8: + *(unsigned char *) loc += v - dot; + break; + + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + *loc = v; + break; + + case R_X86_64_RELATIVE: + *loc += f->baseaddr; + break; + + case R_X86_64_GOT32: + case R_X86_64_GOTPCREL: + assert(isym != NULL); + if (!isym->gotent.reloc_done) + { + isym->gotent.reloc_done = 1; + *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v; + } + /* XXX are these really correct? */ + if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL) + *(unsigned int *) loc += v + isym->gotent.offset; + else + *loc += isym->gotent.offset; + break; + + default: + ret = obj_reloc_unhandled; + break; + } + + return ret; +} + +int +arch_create_got (struct obj_file *f) +{ + struct x86_64_file *ifile = (struct x86_64_file *)f; + int i, n, offset = 0, gotneeded = 0; + + n = ifile->root.header.e_shnum; + for (i = 0; i < n; ++i) + { + struct obj_section *relsec, *symsec, *strsec; + Elf64_Rela *rel, *relend; + Elf64_Sym *symtab; + const char *strtab; + + relsec = ifile->root.sections[i]; + if (relsec->header.sh_type != SHT_REL) + continue; + + symsec = ifile->root.sections[relsec->header.sh_link]; + strsec = ifile->root.sections[symsec->header.sh_link]; + + rel = (Elf64_Rela *)relsec->contents; + relend = rel + (relsec->header.sh_size / sizeof(Elf64_Rela)); + symtab = (Elf64_Sym *)symsec->contents; + strtab = (const char *)strsec->contents; + + for (; rel < relend; ++rel) + { + struct x86_64_symbol *intsym; + + switch (ELF64_R_TYPE(rel->r_info)) + { + case R_X86_64_GOTPCREL: + case R_X86_64_GOT32: + gotneeded = 1; + default: + continue; + } + + obj_find_relsym(intsym, f, &ifile->root, rel, symtab, strtab); + + if (!intsym->gotent.offset_done) + { + intsym->gotent.offset_done = 1; + intsym->gotent.offset = offset; + offset += 4; + } + } + } + + if (offset > 0 || gotneeded) + ifile->got = obj_create_alloced_section(&ifile->root, ".got", 8, offset, + SHF_WRITE); + + return 1; +} + +int +arch_init_module (struct obj_file *f, struct module *mod) +{ + return 1; +} + +int +arch_finalize_section_address(struct obj_file *f, Elf64_Addr base) +{ + int i, n = f->header.e_shnum; + + f->baseaddr = base; + for (i = 0; i < n; ++i) + f->sections[i]->header.sh_addr += base; + return 1; +} + +int +arch_archdata (struct obj_file *fin, struct obj_section *sec) +{ + return 0; +} diff --git a/mdk-stage1/insmod-modutils/util/alias.h b/mdk-stage1/insmod-modutils/util/alias.h index c925a04f3..7d0c08938 100644 --- a/mdk-stage1/insmod-modutils/util/alias.h +++ b/mdk-stage1/insmod-modutils/util/alias.h @@ -42,6 +42,7 @@ char *tbtype[] = */ char *aliaslist[] = { + "binfmt-0000 off", "binfmt-204 binfmt_aout", "binfmt-263 binfmt_aout", "binfmt-264 binfmt_aout", @@ -75,15 +76,23 @@ char *aliaslist[] = "block-major-34 ide-probe-mod", "block-major-37 ide-tape", "block-major-44 ftl", /* from David Woodhouse <dwmw2@infradead.org> */ + "block-major-46 pcd", + "block-major-47 pf", "block-major-56 ide-probe-mod", "block-major-57 ide-probe-mod", + "block-major-58 lvm-mod", "block-major-88 ide-probe-mod", "block-major-89 ide-probe-mod", "block-major-90 ide-probe-mod", "block-major-91 ide-probe-mod", "block-major-93 nftl", /* from David Woodhouse <dwmw2@infradead.org> */ + "block-major-97 pg", +#if !defined(__s390__) && !defined(__s390x__) "char-major-4 serial", +#else + "char-major-4 off", +#endif "char-major-5 serial", "char-major-6 lp", "char-major-9 st", @@ -102,13 +111,15 @@ char *aliaslist[] = "char-major-10-131 wdt", /* /dev/temperature Machine internal temperature */ /* /dev/hwtrap Hardware fault trap */ /* /dev/exttrp External device trap */ - "char-major-10-135 off", /* rtc cannot be compiled as a module */ + "char-major-10-135 rtc", /* /dev/rtc Real time clock */ "char-major-10-139 openprom", /* /dev/openprom Linux/Sparc interface */ "char-major-10-144 nvram", /* from Tigran Aivazian <tigran@sco.COM> */ "char-major-10-157 applicom", /* from David Woodhouse <dwmw2@infradead.org> */ "char-major-10-175 agpgart", /* /dev/agpgart GART AGP mapping access */ "char-major-10-184 microcode", /* Tigran Aivazian <tigran@veritas.com> */ + "char-major-13 input", + "char-major-13-32 mousedev", "char-major-14 soundcore", "char-major-19 cyclades", "char-major-20 cyclades", @@ -126,9 +137,15 @@ char *aliaslist[] = "char-major-58 esp", "char-major-63 kdebug", "char-major-90 mtdchar", /* from David Woodhouse <dwmw2@infradead.org> */ + "char-major-96 pt", "char-major-99 ppdev", "char-major-107 3dfx", /* from Tigran Aivazian <tigran@sco.COM> */ + "char-major-108 ppp_generic", + "char-major-109 lvm-mod", "char-major-161 ircomm-tty", + "char-major-171 raw1394", + "char-major-195 NVdriver", + "char-major-200 vxspec", "dos msdos", "dummy0 dummy", @@ -139,6 +156,7 @@ char *aliaslist[] = "md-personality-2 raid0", "md-personality-3 raid1", "md-personality-4 raid5", + "md-personality-7 multipath", "net-pf-1 unix", /* PF_UNIX 1 Unix domain sockets */ "net-pf-2 ipv4", /* PF_INET 2 Internet IP Protocol */ @@ -149,29 +167,52 @@ char *aliaslist[] = /* PF_BRIDGE 7 Multiprotocol bridge */ /* PF_AAL5 8 Reserved for Werner's ATM */ /* PF_X25 9 Reserved for X.25 project */ - /* PF_INET6 10 IP version 6 */ + "net-pf-10 off", /* PF_INET6 10 IP version 6 */ /* next two from <dairiki@matthews.dairiki.org> Thanks! */ "net-pf-17 af_packet", "net-pf-19 off", /* acorn econet */ "netalias-2 ip_alias", + + /* To be able to attach some dongles */ + "irlan0 irlan", + "irda-dongle-0 tekram", + "irda-dongle-1 esi", + "irda-dongle-2 actisys", + "irda-dongle-3 actisys", + "irda-dongle-4 girbil", + "irda-dongle-5 litelink", + "irda-dongle-6 airport", + "irda-dongle-7 old_belkin", + "plip0 plip", "plip1 plip", + "tunl0 ipip", "cipcb0 cipcb", "cipcb1 cipcb", "cipcb2 cipcb", "cipcb3 cipcb", +#if defined(__s390__) || defined(__s390x__) + "ctc0 ctc", + "ctc1 ctc", + "ctc2 ctc", + "iucv0 netiucv", + "iucv1 netiucv", +#endif "ppp0 ppp", "ppp1 ppp", - "scsi_hostadapter off", /* if not in config file */ "slip0 slip", "slip1 slip", "tty-ldisc-1 slip", - "tty-ldisc-3 ppp", + "tty-ldisc-3 ppp_async", + "tty-ldisc-11 irtty", /* IrDA over a normal serial port, or a serial port compatible IrDA port */ + "tty-ldisc-14 ppp_synctty", + "ppp-compress-18 ppp_mppe", "ppp-compress-21 bsd_comp", "ppp-compress-24 ppp_deflate", "ppp-compress-26 ppp_deflate", + "ppp ppp_async", /* for 2.4 */ #ifndef __sparc__ "parport_lowlevel parport_pc", @@ -179,8 +220,6 @@ char *aliaslist[] = "parport_lowlevel parport_ax", #endif - "tty-ldisc-11 irtty", - "usbdevfs usbcore", NULL /* marks the end of the list! */ @@ -205,6 +244,9 @@ char *optlist[] = */ char *above[] = { + "hid keybdev mousedev", + "usbmouse hid", + "wacom evdev", NULL /* marks the end of the list! */ }; @@ -219,19 +261,43 @@ char *below[] = }; /* + * This is the list of pre-defined "post-install"s, + * used to execute commands after loading modules. + * /etc/modules.conf can add entries but not remove them. + */ +char *post_install[] = +{ + "binfmt_misc /bin/mount -t binfmt_misc none /proc/sys/fs/binfmt_misc > /dev/null 2>&1 || :", + NULL +}; + +/* + * This is the list of pre-defined "pre-remove"s, + * used to execute commands before unloading modules. + * /etc/modules.conf can add entries but not remove them. + */ +char *pre_remove[] = +{ + "binfmt_misc /bin/umount /proc/sys/fs/binfmt_misc > /dev/null 2>&1 || :", + NULL +}; + +/* * This is the list of pre-defined "prune"s, * used to exclude paths from scan of /lib/modules. * /etc/modules.conf can add entries but not remove them. */ char *prune[] = { - ".rhkmvtag", "modules.dep", + "modules.description", "modules.generic_string", "modules.pcimap", "modules.isapnpmap", "modules.usbmap", "modules.parportmap", + "modules.ieee1394map", + "modules.pnpbiosmap", "System.map", ".config", "build", /* symlink to source tree */ diff --git a/mdk-stage1/insmod-modutils/util/arch64.c b/mdk-stage1/insmod-modutils/util/arch64.c index 4d5ace223..90886d16b 100644 --- a/mdk-stage1/insmod-modutils/util/arch64.c +++ b/mdk-stage1/insmod-modutils/util/arch64.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <string.h> #include <sys/utsname.h> @@ -30,6 +28,16 @@ /* Indicate if the current machine uses 64 bit architecture */ int arch64(void) { - struct utsname u; - return(!uname(&u) && strstr(u.machine, "64")); + struct utsname uts; + char *uname_m; + if (uname(&uts)) + return(0); + if ((uname_m = getenv("UNAME_MACHINE"))) { + int l = strlen(uname_m); + if (l >= sizeof(uts.machine)) + l = sizeof(uts.machine)-1; + memcpy(uts.machine, uname_m, l); + uts.machine[l] = '\0'; + } + return(strstr(uts.machine, "64") != NULL); } diff --git a/mdk-stage1/insmod-modutils/util/config.c b/mdk-stage1/insmod-modutils/util/config.c index a860920f6..7568d955f 100644 --- a/mdk-stage1/insmod-modutils/util/config.c +++ b/mdk-stage1/insmod-modutils/util/config.c @@ -116,6 +116,8 @@ struct gen_files gen_file[] = { {"isapnpmap", NULL, 0}, {"usbmap", NULL, 0}, {"parportmap", NULL, 0}, + {"ieee1394map", NULL, 0}, + {"pnpbiosmap", NULL, 0}, {"dep", NULL, 0}, }; @@ -491,7 +493,7 @@ static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, in int state[MAX_LEVEL + 1]; /* nested "if" */ int level = 0; char buf[3000]; - char tmpline[100]; + char tmpline[PATH_MAX]; char **pathp; char *envpath; char *version; @@ -692,6 +694,20 @@ static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, in if (all && aliaslist[0]) n_aliases = build_list(aliaslist, &aliases, version, 0); + /* + * Build predef postinstalls + */ + if (all && post_install[0]) + for (i=0 ; post_install[i] ; i++ ) + decode_exec(xstrdup(post_install[i]), EXEC_POST_INSTALL); + + /* + * Build predef preremoves + */ + if (all && pre_remove[0]) + for (i=0 ; pre_remove[i] ; i++ ) + decode_exec(xstrdup(pre_remove[i]), EXEC_PRE_REMOVE); + /* Order and priority is now: (MODPATH + modules.conf) || (predefs + modules.conf) */ if ((envpath = getenv("MODPATH")) != NULL && !safemode) { size_t len; @@ -1073,7 +1089,7 @@ static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, in arg2 = next_word(arg); meta_expand(arg2, &g, NULL, version, ME_ALL); snprintf(env, sizeof(env), "%s=%s", arg, (g.pathc ? g.pathv[0] : "")); - putenv(env); + putenv(xstrdup(env)); one_err = 0; } @@ -1108,7 +1124,7 @@ static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, in /* * prune */ - else if (all && !assgn && strcmp(parm, "prune") == 0) { + else if (!assgn && strcmp(parm, "prune") == 0) { decode_list(&n_prunelist, &prunelist, arg, adding, version, 0); one_err = 0; } @@ -1349,9 +1365,11 @@ static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, in return ret; /* else */ + if (depth == 0) { /* Check we have names for generated files */ for (i = 0; !ret && i < gen_file_count; ++i) ret = gen_file_check(gen_file+i, &g, base_dir, version); + } return ret; } @@ -1367,7 +1385,12 @@ int config_read(int all, char *force_ver, char *base_dir, char *conf_file) return -1; } + if (access(MODUTILS_MACROS, R_OK) == 0){ + r = do_read(all, force_ver, base_dir, MODUTILS_MACROS, 0); + r = do_read(all, force_ver, "", conf_file, 1); + } else { r = do_read(all, force_ver, base_dir, conf_file, 0); + } if (quick && !r && !need_update (force_ver, base_dir)) exit (0); diff --git a/mdk-stage1/insmod-modutils/util/logger.c b/mdk-stage1/insmod-modutils/util/logger.c index 3b790df5a..4774a0beb 100644 --- a/mdk-stage1/insmod-modutils/util/logger.c +++ b/mdk-stage1/insmod-modutils/util/logger.c @@ -20,8 +20,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id$" - +#include <limits.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> @@ -32,9 +31,10 @@ /*======================================================================*/ +int log; + int errors; const char *error_file; -int log; #define STOREMSG #ifdef STOREMSG @@ -44,29 +44,12 @@ struct cbuf { char *msg; } *head, *tail; -static void savemsg(int type, char *msg) -{ - struct cbuf *me = (struct cbuf *)xmalloc(sizeof(struct cbuf)); - char *s = xstrdup(msg); - - me->next = NULL; - me->type = type; - me->msg = s; - - if (tail) - tail->next = me; - else - head = me; - tail = me; -} - -#endif /* STOREMSG */ - static void dumpmsg(void) { for (;head; head = head->next) syslog(head->type, "%s", head->msg); } +#endif /* STOREMSG */ void setsyslog(const char *program) { @@ -77,13 +60,27 @@ void setsyslog(const char *program) log = 1; } - - #ifdef _STANDALONE_ static int silent; const char *program_name; +static void savemsg(int type, char *msg) +{ + struct cbuf *me = (struct cbuf *)xmalloc(sizeof(struct cbuf)); + char *s = xstrdup(msg); + + me->next = NULL; + me->type = type; + me->msg = s; + + if (tail) + tail->next = me; + else + head = me; + tail = me; +} + void error(const char *fmt,...) { va_list args; @@ -91,7 +88,7 @@ void error(const char *fmt,...) if (silent) ; else if (log) { - char buf[1024]; + char buf[2*PATH_MAX]; int n; if (error_file) @@ -124,7 +121,7 @@ void lprintf(const char *fmt,...) if (silent); else if (log) { - char buf[1024]; + char buf[2*PATH_MAX]; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); @@ -140,7 +137,6 @@ void lprintf(const char *fmt,...) putchar('\n'); } } - #else /* _STANDALONE_ */ #include "../../log.h" void error(const char *s, ...) @@ -161,3 +157,4 @@ void lprintf(const char *s, ...) va_end(p); } #endif + diff --git a/mdk-stage1/insmod-modutils/util/snap_shot.c b/mdk-stage1/insmod-modutils/util/snap_shot.c index ae0cc7c79..adf54d28e 100644 --- a/mdk-stage1/insmod-modutils/util/snap_shot.c +++ b/mdk-stage1/insmod-modutils/util/snap_shot.c @@ -20,8 +20,6 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id$" - #include <errno.h> #include <stdio.h> #include <stdarg.h> @@ -108,6 +106,7 @@ void snap_shot(const char *module_names, int n_module_names) if (ferror(in)) error("unable to read from %s %m", infile[i]); fclose(in); + fflush(out); fclose(out); } } @@ -150,5 +149,6 @@ void snap_shot_log(const char *fmt,...) vfprintf(log, fmt, args); va_end(args); fprintf(log, "\n"); + fflush(log); fclose(log); } diff --git a/mdk-stage1/insmod-modutils/util/sys_cm.c b/mdk-stage1/insmod-modutils/util/sys_cm.c index 851fb709e..d19a5ba4b 100644 --- a/mdk-stage1/insmod-modutils/util/sys_cm.c +++ b/mdk-stage1/insmod-modutils/util/sys_cm.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <errno.h> diff --git a/mdk-stage1/insmod-modutils/util/sys_dm.c b/mdk-stage1/insmod-modutils/util/sys_dm.c index a166a30f4..611234efa 100644 --- a/mdk-stage1/insmod-modutils/util/sys_dm.c +++ b/mdk-stage1/insmod-modutils/util/sys_dm.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <errno.h> diff --git a/mdk-stage1/insmod-modutils/util/sys_gks.c b/mdk-stage1/insmod-modutils/util/sys_gks.c index f71772c71..b639fc990 100644 --- a/mdk-stage1/insmod-modutils/util/sys_gks.c +++ b/mdk-stage1/insmod-modutils/util/sys_gks.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <errno.h> diff --git a/mdk-stage1/insmod-modutils/util/sys_nim.c b/mdk-stage1/insmod-modutils/util/sys_nim.c index bbe42135c..c267ddf10 100644 --- a/mdk-stage1/insmod-modutils/util/sys_nim.c +++ b/mdk-stage1/insmod-modutils/util/sys_nim.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <errno.h> diff --git a/mdk-stage1/insmod-modutils/util/sys_oim.c b/mdk-stage1/insmod-modutils/util/sys_oim.c index 73ac6be52..b915e36a5 100644 --- a/mdk-stage1/insmod-modutils/util/sys_oim.c +++ b/mdk-stage1/insmod-modutils/util/sys_oim.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <errno.h> diff --git a/mdk-stage1/insmod-modutils/util/sys_qm.c b/mdk-stage1/insmod-modutils/util/sys_qm.c index 119a219a2..ba478832b 100644 --- a/mdk-stage1/insmod-modutils/util/sys_qm.c +++ b/mdk-stage1/insmod-modutils/util/sys_qm.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include <errno.h> diff --git a/mdk-stage1/insmod-modutils/util/xmalloc.c b/mdk-stage1/insmod-modutils/util/xmalloc.c index 9113d47fe..da0be2953 100644 --- a/mdk-stage1/insmod-modutils/util/xmalloc.c +++ b/mdk-stage1/insmod-modutils/util/xmalloc.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include "util.h" @@ -29,7 +27,7 @@ void * xmalloc(size_t size) { - void *ptr = malloc(size); + void *ptr = malloc(size ? size : 1); if (!ptr) { error("Out of memory"); diff --git a/mdk-stage1/insmod-modutils/util/xrealloc.c b/mdk-stage1/insmod-modutils/util/xrealloc.c index d287486f7..adc0558f1 100644 --- a/mdk-stage1/insmod-modutils/util/xrealloc.c +++ b/mdk-stage1/insmod-modutils/util/xrealloc.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - #include <stdlib.h> #include "util.h" diff --git a/mdk-stage1/insmod-modutils/util/xstrcat.c b/mdk-stage1/insmod-modutils/util/xstrcat.c index abb075c83..ed4a2bf20 100644 --- a/mdk-stage1/insmod-modutils/util/xstrcat.c +++ b/mdk-stage1/insmod-modutils/util/xstrcat.c @@ -17,8 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id" - #include <stdlib.h> #include <string.h> #include "util.h" diff --git a/mdk-stage1/insmod-modutils/util/xstrdup.c b/mdk-stage1/insmod-modutils/util/xstrdup.c index 11b289eb0..46889a094 100644 --- a/mdk-stage1/insmod-modutils/util/xstrdup.c +++ b/mdk-stage1/insmod-modutils/util/xstrdup.c @@ -18,10 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id$" - -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "util.h" diff --git a/mdk-stage1/insmod-modutils/util/xsystem.c b/mdk-stage1/insmod-modutils/util/xsystem.c index edb995268..8ffa490a9 100644 --- a/mdk-stage1/insmod-modutils/util/xsystem.c +++ b/mdk-stage1/insmod-modutils/util/xsystem.c @@ -17,8 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id" - #include <sys/types.h> #include <sys/wait.h> #include <errno.h> |