diff options
Diffstat (limited to 'mdk-stage1/insmod-modutils')
61 files changed, 0 insertions, 13390 deletions
diff --git a/mdk-stage1/insmod-modutils/Makefile b/mdk-stage1/insmod-modutils/Makefile deleted file mode 100644 index e8f78d2d0..000000000 --- a/mdk-stage1/insmod-modutils/Makefile +++ /dev/null @@ -1,63 +0,0 @@ - #****************************************************************************** - # - # insmod from modutils (generic) - # - # $Id$ - # - # Copyright 1996, 1997 Linux International. - # - #***************************************************************************** - -top_dir = .. - -include $(top_dir)/Makefile.common - - -INCS = -I./include - -DEFS = -Wno-error -D_GNU_SOURCE -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) - - -DIRS = util obj - -all: dirs insmod libinsmod.a #libinsmod-DIET.a - -dirs: - @for n in . $(DIRS); do \ - [ "$$n" = "." ] || make -C $$n ;\ - done - -clean: - @for n in $(DIRS); do \ - (cd $$n; make clean) \ - done - rm -rf t *.o insmod libinsmod.a libinsmod-DIET.a - - -insmod: insmod-frontend.o insmod.o ./util/libutil-STANDALONE.a ./obj/libobj.a - gcc -o $@ $^ - $(STRIPCMD) $@ - -t/.create_stuff: util/libutil.a obj/libobj.a - rm -rf t - mkdir t - cd t && for e in $^; do ar -x ../$$e; done - touch t/.create_stuff - -libinsmod.a: insmod.o t/.create_stuff - ar cru $@ insmod.o t/* - ranlib $@ - -libinsmod-DIET.a: insmod-DIET.o ./util/libutil-DIET.a ./obj/libobj-DIET.a - ar cru $@ $^ - ranlib $@ - -insmod-frontend.o: insmod-frontend.c insmod.c - gcc $(CFLAGS) $(DEFS) $(INCS) $(GLIBC_INCLUDES) -c insmod-frontend.c - -insmod.o: insmod.c - gcc $(CFLAGS) $(DEFS) $(INCS) $(GLIBC_INCLUDES) -c insmod.c - -insmod-DIET.o: insmod.c - gcc $(CFLAGS) $(DEFS) $(INCS) $(DIETLIBC_INCLUDES) -o $@ -c insmod.c - diff --git a/mdk-stage1/insmod-modutils/include/config.h b/mdk-stage1/insmod-modutils/include/config.h deleted file mode 100644 index 11da6a523..000000000 --- a/mdk-stage1/insmod-modutils/include/config.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Configuration file management - * - * Copyright 1994, 1995, 1996, 1997: - * Jacques Gelinas <jack@solucorp.qc.ca> - * Björn Ekwall <bj0rn@blox.se> February, March 1999 - * - * 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. - */ - -#ifndef _CONFIG_H -#define _CONFIG_H - -#include <stdio.h> -#include <sys/utsname.h> - -#define ETC_MODULES_CONF "/etc/modules.conf" - -#define EXEC_PRE_INSTALL 0 -#define EXEC_POST_INSTALL 1 -#define EXEC_PRE_REMOVE 2 -#define EXEC_POST_REMOVE 3 -#define EXEC_INSTALL 4 -#define EXEC_REMOVE 5 - -struct PATH_TYPE { - char *type; - char *path; -}; - -struct EXEC_TYPE { - int when; - char *module; - char *cmd; -}; - -typedef struct { - char *name; - GLOB_LIST *opts; - int autoclean; -} OPT_LIST; - -/* config.c */ -extern int flag_autoclean; -extern struct utsname uts_info; -extern char *aliaslist[]; -extern struct PATH_TYPE *modpath; -extern int nmodpath; -extern struct EXEC_TYPE *execs; -extern int nexecs; -extern char *insmod_opt; -extern char *config_file; -extern char *optlist[]; -extern char *prune[]; -extern OPT_LIST *opt_list; -extern OPT_LIST *abovelist; -extern OPT_LIST *belowlist; -extern OPT_LIST *prunelist; -extern OPT_LIST *probe_list; -extern OPT_LIST *probeall_list; -extern OPT_LIST *aliases; -extern time_t config_mtime; -extern int root_check_off; /* Check modules are owned by root? */ - -/* Information about generated files */ -struct gen_files { - char *base; /* xxx in /lib/modules/`uname -r`/modules.xxx */ - char *name; /* name actually used */ - time_t mtime; -}; - -extern struct gen_files gen_file[]; -extern const int gen_file_count; -/* The enum order must match the gen_file initialization order in config.c */ -enum gen_file_enum { - GEN_GENERIC_STRINGFILE, - GEN_PCIMAPFILE, - GEN_ISAPNPMAPFILE, - GEN_USBMAPFILE, - GEN_PARPORTMAPFILE, - GEN_DEPFILE, -}; - -extern char *persistdir; - -char *fgets_strip(char *buf, int sizebuf, FILE * fin, int *lineno); -int config_read(int all, char *force_ver, char *base_dir, char *conf_file); -GLOB_LIST *config_lstmod(const char *match, const char *type, int first_only); -char *search_module_path(const char *base); - -#endif /* _CONFIG_H */ diff --git a/mdk-stage1/insmod-modutils/include/elf_alpha.h b/mdk-stage1/insmod-modutils/include/elf_alpha.h deleted file mode 100644 index f1ec66f1c..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_alpha.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for the Alpha. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS64 -#define ELFDATAM ELFDATA2LSB - -#define MATCH_MACHINE(x) (x == EM_ALPHA) - -#define SHT_RELM SHT_RELA -#define Elf64_RelM Elf64_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_arm.h b/mdk-stage1/insmod-modutils/include/elf_arm.h deleted file mode 100644 index f6b531e88..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_arm.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for ARM. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2LSB - -#define MATCH_MACHINE(x) (x == EM_ARM) - -#define SHT_RELM SHT_REL -#define Elf32_RelM Elf32_Rel diff --git a/mdk-stage1/insmod-modutils/include/elf_hppa.h b/mdk-stage1/insmod-modutils/include/elf_hppa.h deleted file mode 100644 index 9a1bd34ce..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_hppa.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Machine-specific elf macros for HP-PA. */ - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2MSB - -#define MATCH_MACHINE(x) (x == EM_PARISC) - -#define SHT_RELM SHT_RELA -#define Elf32_RelM Elf32_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_hppa64.h b/mdk-stage1/insmod-modutils/include/elf_hppa64.h deleted file mode 100644 index 05b201aef..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_hppa64.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Machine-specific elf macros for HP-PA64. */ - -#define ELFCLASSM ELFCLASS64 -#define ELFDATAM ELFDATA2MSB - -#define MATCH_MACHINE(x) (x == EM_PARISC) - -#define SHT_RELM SHT_RELA -#define Elf64_RelM Elf64_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_i386.h b/mdk-stage1/insmod-modutils/include/elf_i386.h deleted file mode 100644 index c6c2d326e..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_i386.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for i386 et al. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2LSB - -#define MATCH_MACHINE(x) (x == EM_386) - -#define SHT_RELM SHT_REL -#define Elf32_RelM Elf32_Rel diff --git a/mdk-stage1/insmod-modutils/include/elf_ia64.h b/mdk-stage1/insmod-modutils/include/elf_ia64.h deleted file mode 100644 index b4d902956..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_ia64.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Machine-specific elf macros for ia64. */ - -#define ELFCLASSM ELFCLASS64 -#define ELFDATAM ELFDATA2LSB - -#define MATCH_MACHINE(x) (x == EM_IA_64) - -#define SHT_RELM SHT_RELA -#define Elf64_RelM Elf64_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_m68k.h b/mdk-stage1/insmod-modutils/include/elf_m68k.h deleted file mode 100644 index 817fc8f2c..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_m68k.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for m68k. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2MSB - -#define MATCH_MACHINE(x) (x == EM_68K) - -#define SHT_RELM SHT_RELA -#define Elf32_RelM Elf32_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_mips.h b/mdk-stage1/insmod-modutils/include/elf_mips.h deleted file mode 100644 index 8a0430216..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_mips.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Machine-specific elf macros for MIPS. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#ifdef __MIPSEB__ -#define ELFDATAM ELFDATA2MSB -#endif -#ifdef __MIPSEL__ -#define ELFDATAM ELFDATA2LSB -#endif - -/* Account for ELF spec changes. */ -#ifndef EM_MIPS_RS3_LE -#ifdef EM_MIPS_RS4_BE -#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE -#else -#define EM_MIPS_RS3_LE 10 -#endif -#endif /* !EM_MIPS_RS3_LE */ - -#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE) - -#define SHT_RELM SHT_REL -#define Elf32_RelM Elf32_Rel diff --git a/mdk-stage1/insmod-modutils/include/elf_ppc.h b/mdk-stage1/insmod-modutils/include/elf_ppc.h deleted file mode 100644 index 71596de8c..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_ppc.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for the PowerPC. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2MSB - -#define MATCH_MACHINE(x) (x == EM_PPC) - -#define SHT_RELM SHT_RELA -#define Elf32_RelM Elf32_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_s390.h b/mdk-stage1/insmod-modutils/include/elf_s390.h deleted file mode 100644 index 547d66b83..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_s390.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for i386 et al. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2MSB - -#define MATCH_MACHINE(x) (x == EM_S390) - -#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 deleted file mode 100644 index 9b5c348d9..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_sparc.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Machine-specific elf macros for the Sparc. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS32 -#define ELFDATAM ELFDATA2MSB - -#define MATCH_MACHINE(x) (x == EM_SPARC) - -#define SHT_RELM SHT_RELA -#define Elf32_RelM Elf32_Rela diff --git a/mdk-stage1/insmod-modutils/include/elf_sparc64.h b/mdk-stage1/insmod-modutils/include/elf_sparc64.h deleted file mode 100644 index 158edd7e1..000000000 --- a/mdk-stage1/insmod-modutils/include/elf_sparc64.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Machine-specific elf macros for the Sparc. */ -#ident "$Id$" - -#define ELFCLASSM ELFCLASS64 -#define ELFDATAM ELFDATA2MSB - -#ifndef EM_SPARCV9 -#define EM_SPARCV9 43 -#endif -#ifndef EM_SPARC64 -#define EM_SPARC64 11 -#endif -#define MATCH_MACHINE(x) ((x) == EM_SPARCV9 || (x) == EM_SPARC64) - -#define SHT_RELM SHT_RELA -#define Elf64_RelM Elf64_Rela - -#ifndef ELF64_R_SYM -#define ELF64_R_SYM(x) ((x) >> 32) -#define ELF64_R_TYPE(x) ((unsigned)(x)) -#endif - -#ifndef ELF64_ST_BIND -#define ELF64_ST_BIND(x) ((x) >> 4) -#define ELF64_ST_TYPE(x) ((x) & 0xf) -#endif - diff --git a/mdk-stage1/insmod-modutils/include/kallsyms.h b/mdk-stage1/insmod-modutils/include/kallsyms.h deleted file mode 100644 index 9748873cf..000000000 --- a/mdk-stage1/insmod-modutils/include/kallsyms.h +++ /dev/null @@ -1,131 +0,0 @@ -/* kallsyms headers - Copyright 2000 Keith Owens <kaos@ocs.com.au> - - This file is part of the Linux modutils. It is exported to kernel - space so debuggers can access the kallsyms data. - - The kallsyms data contains all the non-stack symbols from a kernel - or a module. The kernel symbols are held between __start___kallsyms - and __stop___kallsyms. The symbols for a module are accessed via - the struct module chain which is based at module_list. - - 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$" - -#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 - * different includes. - */ - -#ifndef ELFCLASS32 -#ifdef __KERNEL__ -#include <linux/elf.h> -#else /* __KERNEL__ */ -#include <elf.h> -#endif /* __KERNEL__ */ -#endif /* ELFCLASS32 */ - -#ifndef ELFCLASSM -#define ELFCLASSM ELF_CLASS -#endif - -#ifndef ElfW -# if ELFCLASSM == ELFCLASS32 -# define ElfW(x) Elf32_ ## x -# define ELFW(x) ELF32_ ## x -# else -# define ElfW(x) Elf64_ ## x -# define ELFW(x) ELF64_ ## x -# endif -#endif - -/* Format of data in the kallsyms section. - * Most of the fields are small numbers but the total size and all - * offsets can be large so use the 32/64 bit types for these fields. - * - * Do not use sizeof() on these structures, modutils may be using extra - * fields. Instead use the size fields in the header to access the - * other bits of data. - */ - -struct kallsyms_header { - int size; /* Size of this header */ - ElfW(Word) total_size; /* Total size of kallsyms data */ - int sections; /* Number of section entries */ - ElfW(Off) section_off; /* Offset to first section entry */ - int section_size; /* Size of one section entry */ - int symbols; /* Number of symbol entries */ - ElfW(Off) symbol_off; /* Offset to first symbol entry */ - int symbol_size; /* Size of one symbol entry */ - ElfW(Off) string_off; /* Offset to first string */ - ElfW(Addr) start; /* Start address of first section */ - ElfW(Addr) end; /* End address of last section */ -}; - -struct kallsyms_section { - ElfW(Addr) start; /* Start address of section */ - ElfW(Word) size; /* Size of this section */ - ElfW(Off) name_off; /* Offset to section name */ - ElfW(Word) flags; /* Flags from section */ -}; - -struct kallsyms_symbol { - ElfW(Off) section_off; /* Offset to section that owns this symbol */ - ElfW(Addr) symbol_addr; /* Address of symbol */ - ElfW(Off) name_off; /* Offset to symbol name */ -}; - -#define KALLSYMS_SEC_NAME "__kallsyms" -#define KALLSYMS_IDX 2 /* obj_kallsyms creates kallsyms as section 2 */ - -#define kallsyms_next_sec(h,s) \ - ((s) = (struct kallsyms_section *)((char *)(s) + (h)->section_size)) -#define kallsyms_next_sym(h,s) \ - ((s) = (struct kallsyms_symbol *)((char *)(s) + (h)->symbol_size)) - -int kallsyms_symbol_to_address( - const char *name, /* Name to lookup */ - unsigned long *token, /* Which module to start with */ - const char **mod_name, /* Set to module name or "kernel" */ - unsigned long *mod_start, /* Set to start address of module */ - unsigned long *mod_end, /* Set to end address of module */ - const char **sec_name, /* Set to section name */ - unsigned long *sec_start, /* Set to start address of section */ - unsigned long *sec_end, /* Set to end address of section */ - const char **sym_name, /* Set to full symbol name */ - unsigned long *sym_start, /* Set to start address of symbol */ - unsigned long *sym_end /* Set to end address of symbol */ - ); - -int kallsyms_address_to_symbol( - unsigned long address, /* Address to lookup */ - const char **mod_name, /* Set to module name */ - unsigned long *mod_start, /* Set to start address of module */ - unsigned long *mod_end, /* Set to end address of module */ - const char **sec_name, /* Set to section name */ - unsigned long *sec_start, /* Set to start address of section */ - unsigned long *sec_end, /* Set to end address of section */ - const char **sym_name, /* Set to full symbol name */ - unsigned long *sym_start, /* Set to start address of symbol */ - unsigned long *sym_end /* Set to end address of symbol */ - ); - -#endif /* kallsyms.h */ diff --git a/mdk-stage1/insmod-modutils/include/kerneld.h b/mdk-stage1/insmod-modutils/include/kerneld.h deleted file mode 100644 index 3bc2c9d42..000000000 --- a/mdk-stage1/insmod-modutils/include/kerneld.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Definitions for the Linux kerneld SYSV IPC interface. - This file was part of the Linux kernel, and so is covered by the GPL. */ - -#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" */ -#define KERNELD_DELAYED_RELEASE_MODULE 4 /* "rmmod" */ -#define KERNELD_CANCEL_RELEASE_MODULE 5 /* "rmmod" */ -#define KERNELD_REQUEST_ROUTE 6 /* net/ipv4/route.c */ -#define KERNELD_BLANKER 7 /* drivers/char/console.c */ -#define KERNELD_PNP 8 /* drivers/pnp/kerneld.c */ -#define KERNELD_ARP 256 /* net/ipv4/arp.c */ - -#ifdef NEW_KERNELD_PROTOCOL -# define OLDIPC_KERNELD 00040000 /* old kerneld message channel */ -# define IPC_KERNELD 00140000 /* new kerneld message channel */ -# define KDHDR (sizeof(long) + sizeof(short) + sizeof(short)) -# define NULL_KDHDR 0, 2, 0 -#else /* NEW_KERNELD_PROTOCOL */ -# define IPC_KERNELD 00040000 -# define KDHDR (sizeof(long)) -# define NULL_KDHDR 0 -#endif /* NEW_KERNELD_PROTOCOL */ - -#define KERNELD_MAXCMD 0x7ffeffff -#define KERNELD_MINSEQ 0x7fff0000 /* "commands" legal up to 0x7ffeffff */ -#define KERNELD_WAIT 0x80000000 -#define KERNELD_NOWAIT 0 - -struct kerneld_msg - { - long mtype; - long id; -#ifdef NEW_KERNELD_PROTOCOL - short version; - short pid; -#endif /* NEW_KERNELD_PROTOCOL */ - char text[1]; - }; - -#endif /* kerneld.h */ diff --git a/mdk-stage1/insmod-modutils/include/modstat.h b/mdk-stage1/insmod-modutils/include/modstat.h deleted file mode 100644 index b8a58eeae..000000000 --- a/mdk-stage1/insmod-modutils/include/modstat.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * For kernel module status and information - * - * Add module_name_list and l_module_name_list. - * Keith Owens <kaos@ocs.com.au> November 1999. - * Björn Ekwall <bj0rn@blox.se> February 1999. - * - * 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. - */ -#ifndef _KERNEL_H -#define _KERNEL_H - -#define K_SYMBOLS 1 /* Want info about symbols */ -#define K_INFO 2 /* Want extended module info */ -#define K_REFS 4 /* Want info about references */ - -struct module_stat { - char *name; - unsigned long addr; - unsigned long modstruct; /* COMPAT_2_0! *//* depends on architecture? */ - unsigned long size; - unsigned long flags; - long usecount; - size_t nsyms; - struct module_symbol *syms; - size_t nrefs; - struct module_stat **refs; - unsigned long status; -}; - -extern struct module_stat *module_stat; -extern size_t n_module_stat; -extern char *module_name_list; -extern size_t l_module_name_list; -extern struct module_symbol *ksyms; -extern size_t nksyms; -extern int k_new_syscalls; - -int get_kernel_info(int type); - -#endif /* _KERNEL_H */ diff --git a/mdk-stage1/insmod-modutils/include/module.h b/mdk-stage1/insmod-modutils/include/module.h deleted file mode 100644 index db49ab2b2..000000000 --- a/mdk-stage1/insmod-modutils/include/module.h +++ /dev/null @@ -1,210 +0,0 @@ -/* Definitions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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. */ - - -#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. */ - - -/*======================================================================*/ -/* The structures used by Linux 2.0. */ - -/* The symbol format used by get_kernel_syms(2). */ -struct old_kernel_sym -{ - unsigned long value; - char name[60]; -}; - -struct old_module_ref -{ - unsigned long module; /* kernel addresses */ - unsigned long next; -}; - -struct old_module_symbol -{ - unsigned long addr; - unsigned long name; -}; - -struct old_symbol_table -{ - int size; /* total, including string table!!! */ - int n_symbols; - int n_refs; - struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */ - struct old_module_ref ref[0]; /* actual size defined by n_refs */ -}; - -struct old_mod_routines -{ - unsigned long init; - unsigned long cleanup; -}; - -struct old_module -{ - unsigned long next; - unsigned long ref; /* the list of modules that refer to me */ - unsigned long symtab; - unsigned long name; - int size; /* size of module in pages */ - unsigned long addr; /* address of module */ - int state; - unsigned long cleanup; /* cleanup routine */ -}; - -/* Sent to init_module(2) or'ed into the code size parameter. */ -#define OLD_MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */ - -int get_kernel_syms(struct old_kernel_sym *); -int old_sys_init_module(const char *name, char *code, unsigned codesize, - struct old_mod_routines *, struct old_symbol_table *); - -/*======================================================================*/ -/* For sizeof() which are related to the module platform and not to the - environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */ - -#define tgt_sizeof_char sizeof(char) -#define tgt_sizeof_short sizeof(short) -#define tgt_sizeof_int sizeof(int) -#define tgt_sizeof_long sizeof(long) -#define tgt_sizeof_char_p sizeof(char *) -#define tgt_sizeof_void_p sizeof(void *) -#define tgt_long long -#define tgt_long_fmt "l" - -/* This assumes that long long on a 32 bit system is equivalent to long on the - * equivalent 64 bit system. Also that void and char pointers are 8 bytes on - * all 64 bit systems. Add per system tweaks if it ever becomes necessary. - */ -#if defined(COMMON_3264) && defined(ONLY_64) -#undef tgt_long -#undef tgt_long_fmt -#undef tgt_sizeof_long -#undef tgt_sizeof_char_p -#undef tgt_sizeof_void_p -#define tgt_long long long -#define tgt_long_fmt "ll" -#define tgt_sizeof_long 8 -#define tgt_sizeof_char_p 8 -#define tgt_sizeof_void_p 8 -#endif - -/*======================================================================*/ -/* The structures used in Linux 2.1 onwards. */ - -/* Note: module_symbol does not use tgt_long intentionally */ -struct module_symbol -{ - unsigned long value; - unsigned long name; -}; - -struct module_ref -{ - unsigned tgt_long dep; /* kernel addresses */ - unsigned tgt_long ref; - unsigned tgt_long next_ref; -}; - -struct module -{ - unsigned tgt_long size_of_struct; /* == sizeof(module) */ - unsigned tgt_long next; - unsigned tgt_long name; - unsigned tgt_long size; - - tgt_long usecount; - unsigned tgt_long flags; /* AUTOCLEAN et al */ - - unsigned nsyms; - unsigned ndeps; - - unsigned tgt_long syms; - unsigned tgt_long deps; - unsigned tgt_long refs; - unsigned tgt_long init; - unsigned tgt_long cleanup; - unsigned tgt_long ex_table_start; - unsigned tgt_long ex_table_end; -#ifdef __alpha__ - unsigned tgt_long gp; -#endif - /* Everything after here is extension. */ - unsigned tgt_long read_start; /* Read data from existing module */ - unsigned tgt_long read_end; - unsigned tgt_long can_unload; - unsigned tgt_long runsize; - unsigned tgt_long kallsyms_start; - unsigned tgt_long kallsyms_end; - unsigned tgt_long archdata_start; - unsigned tgt_long archdata_end; - unsigned tgt_long kernel_data; -}; - -struct module_info -{ - unsigned long addr; - unsigned long size; - unsigned long flags; - long usecount; -}; - -/* Bits of module.flags. */ -#define NEW_MOD_RUNNING 1 -#define NEW_MOD_DELETED 2 -#define NEW_MOD_AUTOCLEAN 4 -#define NEW_MOD_VISITED 8 -#define NEW_MOD_USED_ONCE 16 -#define NEW_MOD_INITIALIZING 64 - -int sys_init_module(const char *name, const struct module *); -int query_module(const char *name, int which, void *buf, size_t bufsize, - size_t *ret); - -/* Values for query_module's which. */ - -#define QM_MODULES 1 -#define QM_DEPS 2 -#define QM_REFS 3 -#define QM_SYMBOLS 4 -#define QM_INFO 5 - -/*======================================================================*/ -/* The system calls unchanged between 2.0 and 2.1. */ - -unsigned long create_module(const char *, size_t); -int delete_module(const char *); - -/* In safe mode the last parameter is forced to be a module name and meta - * expansion is not allowed on that name. - */ -extern unsigned int safemode; - -#endif /* module.h */ diff --git a/mdk-stage1/insmod-modutils/include/obj.h b/mdk-stage1/insmod-modutils/include/obj.h deleted file mode 100644 index b140c65c3..000000000 --- a/mdk-stage1/insmod-modutils/include/obj.h +++ /dev/null @@ -1,275 +0,0 @@ -/* Elf object file loading and relocation routines. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - obj_free() added by Björn Ekwall <bj0rn@blox.se> March 1999 - - 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. */ - - -#ifndef MODUTILS_OBJ_H -#define MODUTILS_OBJ_H 1 - -#ident "$Id$" - -/* The relocatable object is manipulated using elfin types. */ - -#include <stdio.h> -#include <elf.h> -#include ELF_MACHINE_H - -#ifndef ElfW -# if ELFCLASSM == ELFCLASS32 -# define ElfW(x) Elf32_ ## x -# define ELFW(x) ELF32_ ## x -# else -# define ElfW(x) Elf64_ ## x -# define ELFW(x) ELF64_ ## x -# endif -#endif - -#if defined(COMMON_3264) && defined(ONLY_32) -# define ObjW(x) obj32_ ## x -#else -# if defined(COMMON_3264) && defined(ONLY_64) -# define ObjW(x) obj64_ ## x -# else -# define ObjW(x) obj_ ## x -# endif -#endif - -/* For some reason this is missing from lib5. */ -#ifndef ELF32_ST_INFO -# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -#endif - -#ifndef ELF64_ST_INFO -# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -#endif - -struct obj_string_patch_struct; -struct obj_symbol_patch_struct; - -struct obj_section -{ - ElfW(Shdr) header; - const char *name; - char *contents; - struct obj_section *load_next; - int idx; -}; - -struct obj_symbol -{ - struct obj_symbol *next; /* hash table link */ - const char *name; - unsigned long value; - unsigned long size; - int secidx; /* the defining section index/module */ - int info; - int ksymidx; /* for export to the kernel symtab */ - int r_type; /* relocation type */ -}; - -/* Hardcode the hash table size. We shouldn't be needing so many - symbols that we begin to degrade performance, and we get a big win - by giving the compiler a constant divisor. */ - -#define HASH_BUCKETS 521 - -struct obj_file -{ - ElfW(Ehdr) header; - ElfW(Addr) baseaddr; - struct obj_section **sections; - struct obj_section *load_order; - struct obj_section **load_order_search_start; - struct obj_string_patch_struct *string_patches; - struct obj_symbol_patch_struct *symbol_patches; - int (*symbol_cmp)(const char *, const char *); - unsigned long (*symbol_hash)(const char *); - unsigned long local_symtab_size; - struct obj_symbol **local_symtab; - struct obj_symbol *symtab[HASH_BUCKETS]; - const char *filename; - char *persist; -}; - -enum obj_reloc -{ - obj_reloc_ok, - obj_reloc_overflow, - obj_reloc_dangerous, - obj_reloc_unhandled, - obj_reloc_constant_gp -}; - -struct obj_string_patch_struct -{ - struct obj_string_patch_struct *next; - int reloc_secidx; - ElfW(Addr) reloc_offset; - ElfW(Addr) string_offset; -}; - -struct obj_symbol_patch_struct -{ - struct obj_symbol_patch_struct *next; - int reloc_secidx; - ElfW(Addr) reloc_offset; - struct obj_symbol *sym; -}; - - -/* Generic object manipulation routines. */ - -#define obj_elf_hash ObjW(elf_hash) -#define obj_elf_hash_n ObjW(elf_hash_n) -#define obj_add_symbol ObjW(add_symbol) -#define obj_find_symbol ObjW(find_symbol) -#define obj_symbol_final_value ObjW(symbol_final_value) -#define obj_set_symbol_compare ObjW(set_symbol_compare) -#define obj_find_section ObjW(find_section) -#define obj_insert_section_load_order ObjW(insert_section_load_order) -#define obj_create_alloced_section ObjW(create_alloced_section) -#define obj_create_alloced_section_first \ - ObjW(create_alloced_section_first) -#define obj_extend_section ObjW(extend_section) -#define obj_string_patch ObjW(string_patch) -#define obj_symbol_patch ObjW(symbol_patch) -#define obj_check_undefineds ObjW(check_undefineds) -#define obj_clear_undefineds ObjW(clear_undefineds) -#define obj_allocate_commons ObjW(allocate_commons) -#define obj_load_size ObjW(load_size) -#define obj_relocate ObjW(relocate) -#define obj_load ObjW(load) -#define obj_free ObjW(free) -#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 arch_new_file ObjW(arch_new_file) -#define arch_new_section ObjW(arch_new_section) -#define arch_new_symbol ObjW(arch_new_symbol) -#define arch_apply_relocation ObjW(arch_apply_relocation) -#define arch_create_got ObjW(arch_create_got) -#define arch_init_module ObjW(arch_init_module) -#define arch_load_proc_section ObjW(arch_load_proc_section) -#define arch_finalize_section_address ObjW(arch_finalize_section_address) -#define arch_archdata ObjW(arch_archdata) - -unsigned long obj_elf_hash (const char *); - -unsigned long obj_elf_hash_n (const char *, unsigned long len); - -struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name, - unsigned long symidx, int info, int secidx, - ElfW(Addr) value, unsigned long size); - -struct obj_symbol *obj_find_symbol (struct obj_file *f, - const char *name); - -ElfW(Addr) obj_symbol_final_value (struct obj_file *f, - struct obj_symbol *sym); - -void obj_set_symbol_compare (struct obj_file *f, - int (*cmp)(const char *, const char *), - unsigned long (*hash)(const char *)); - -struct obj_section *obj_find_section (struct obj_file *f, - const char *name); - -void 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); - -struct obj_section *obj_create_alloced_section_first (struct obj_file *f, - const char *name, - unsigned long align, - unsigned long size); - -void *obj_extend_section (struct obj_section *sec, unsigned long more); - -int obj_string_patch (struct obj_file *f, int secidx, ElfW(Addr) offset, - const char *string); - -int obj_symbol_patch (struct obj_file *f, int secidx, ElfW(Addr) offset, - struct obj_symbol *sym); - -int obj_check_undefineds (struct obj_file *f, int quiet); - -void obj_clear_undefineds (struct obj_file *f); - -void obj_allocate_commons (struct obj_file *f); - -unsigned long obj_load_size (struct obj_file *f); - -int obj_relocate (struct obj_file *f, ElfW(Addr) base); - -struct obj_file *obj_load (int f, Elf32_Half e_type, const char *filename); - -void obj_free (struct obj_file *f); - -int obj_create_image (struct obj_file *f, char *image); - -int obj_kallsyms (struct obj_file *fin, struct obj_file **fout); - -/* Architecture specific manipulation routines. */ - -struct obj_file *arch_new_file (void); - -struct obj_section *arch_new_section (void); - -struct obj_symbol *arch_new_symbol (void); - -enum obj_reloc arch_apply_relocation (struct obj_file *f, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - ElfW(RelM) *rel, ElfW(Addr) value); - -int arch_create_got (struct obj_file *f); - -struct module; -int arch_init_module (struct obj_file *f, struct module *); - -int arch_load_proc_section (struct obj_section *sec, int fp); - -int arch_finalize_section_address (struct obj_file *f, ElfW(Addr) base); - -int arch_archdata (struct obj_file *fin, struct obj_section *sec); - -#define ARCHDATA_SEC_NAME "__archdata" - -/* Pointers in objects can be 32 or 64 bit */ -union obj_ptr_4 { - Elf32_Word addr; - void *ptr; -}; -union obj_ptr_8 { - Elf64_Xword addr; - void *ptr; -}; - -void *obj_addr_to_native_ptr(ElfW(Addr)); - -ElfW(Addr) obj_native_ptr_to_addr(void *); - -#endif /* obj.h */ diff --git a/mdk-stage1/insmod-modutils/include/util.h b/mdk-stage1/insmod-modutils/include/util.h deleted file mode 100644 index b2e4a67c3..000000000 --- a/mdk-stage1/insmod-modutils/include/util.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Miscelaneous utility functions. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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. */ - - -#ifndef MODUTILS_UTIL_H -#define MODUTILS_UTIL_H 1 - -#ident "$Id$" - -#include <stdio.h> -#include <sys/stat.h> - -#define SHELL_META "&();|<>$`\"'\\!{}[]~=+:?*" /* Sum of bj0rn and Debian */ - -void *xmalloc(size_t); -void *xrealloc(void *, size_t); -char *xstrdup(const char *); -char *xstrcat(char *, const char *, size_t); -int xsystem(const char *, char *const[]); -int arch64(void); - -typedef int (*xftw_func_t)(const char *, const struct stat *); -extern int xftw(const char *directory, xftw_func_t); - -/* Error logging */ -extern int log; -extern int errors; -extern const char *error_file; - -extern int flag_verbose; -extern void verbose(const char *ctl,...); - -void error(const char *fmt, ...) -#ifdef __GNUC__ - __attribute__((format(printf, 1, 2))) -#endif - ; - -void lprintf(const char *fmt, ...) -#ifdef __GNUC__ - __attribute__((format(printf, 1, 2))) -#endif - ; - -void setsyslog(const char *program); - -/* - * Generic globlist <bj0rn@blox.se> - */ -typedef struct { - int pathc; /* Count of paths matched so far */ - char **pathv; /* List of matched pathnames. */ -} GLOB_LIST; -int meta_expand(char *pt, GLOB_LIST *g, char *base_dir, char *version, int type); -#define ME_BUILTIN_COMMAND 1 -#define ME_SHELL_COMMAND 2 -#define ME_GLOB 4 -#define ME_ALL (ME_GLOB|ME_SHELL_COMMAND|ME_BUILTIN_COMMAND) - -extern void snap_shot(const char *module_name, int number); -extern void snap_shot_log(const char *fmt,...); - -#ifdef CONFIG_USE_ZLIB -int gzf_open(const char *name, int mode); -int gzf_read(int fd, void *buf, size_t count); -off_t gzf_lseek(int fd, off_t offset, int whence); -void gzf_close(int fd); - -#else /* ! CONFIG_USE_ZLIB */ - -#include <unistd.h> - -#define gzf_open open -#define gzf_read read -#define gzf_lseek lseek -#define gzf_close close - -#endif /* CONFIG_USE_ZLIB */ - -#define SYMPREFIX "__insmod_"; -extern const char symprefix[10]; /* Must be sizeof(SYMPREFIX), including nul */ - -#endif /* util.h */ diff --git a/mdk-stage1/insmod-modutils/include/version.h b/mdk-stage1/insmod-modutils/include/version.h deleted file mode 100644 index 51ca0eb29..000000000 --- a/mdk-stage1/insmod-modutils/include/version.h +++ /dev/null @@ -1 +0,0 @@ -#define MODUTILS_VERSION "2.4.2" diff --git a/mdk-stage1/insmod-modutils/insmod-frontend.c b/mdk-stage1/insmod-modutils/insmod-frontend.c deleted file mode 100644 index 2b3aa1acb..000000000 --- a/mdk-stage1/insmod-modutils/insmod-frontend.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Guillaume Cottenceau (gc@mandrakesoft.com) - * - * Copyright 2000 MandrakeSoft - * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <stdio.h> - - -int insmod_main( int argc, char **argv); - -int main( int argc, char **argv) -{ - printf("Using insmod provided by modutils.\n"); - return insmod_main(argc, argv); -} diff --git a/mdk-stage1/insmod-modutils/insmod.c b/mdk-stage1/insmod-modutils/insmod.c deleted file mode 100644 index 359b28837..000000000 --- a/mdk-stage1/insmod-modutils/insmod.c +++ /dev/null @@ -1,1964 +0,0 @@ -/* Insert a module into a running kernel. - Copyright 1996, 1997 Linux International. - - New implementation contributed by Richard Henderson <rth@tamu.edu> - Based on original work by Bjorn Ekwall <bj0rn@blox.se> - Restructured (and partly rewritten) by: - Björn Ekwall <bj0rn@blox.se> February 1999 - - 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. - */ - - /* - Fixes: - - Adjust module size for mod_use_count in old_init_module: - B. James Phillippe <bryan@terran.org> - - Merged modprobe + many fixes: Björn Ekwall <bj0rn@blox.se> February 1999 - SMP "friendliness" (and -P): Bill Zumach <zumach+@transarc.com> - - Ksymoops support: Keith Owens <kaos@ocs.com.au> August 1999. - - Add -r flag: Keith Owens <kaos@ocs.com.au> October 1999. - - More flexible recognition of the way the utility was called. - Suggested by Stepan Kasal, implemented in a different way by Keith - Owens <kaos@ocs.com.au> December 1999. - - Rationalize common code for 32/64 bit architectures. - Keith Owens <kaos@ocs.com.au> December 1999. - Add arch64(). - Keith Owens <kaos@ocs.com.au> December 1999. - kallsyms support - Keith Owens <kaos@ocs.com.au> April 2000. - archdata support - Keith Owens <kaos@ocs.com.au> August 2000. - Add insmod -O, move print map before sys_init_module. - Keith Owens <kaos@ocs.com.au> October 2000. - Add insmod -S. - Keith Owens <kaos@ocs.com.au> November 2000. - Add persistent data support. - Keith Owens <kaos@ocs.com.au> November 2000. - */ - -#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> -#include <stddef.h> -#include <getopt.h> -#include <sys/stat.h> -#include <sys/file.h> - -#include "module.h" -#include "obj.h" -#include "kallsyms.h" -#include "util.h" -#include "version.h" - -#include "modstat.h" -#include "config.h" - -#define STRVERSIONLEN 32 - -/*======================================================================*/ - -static int flag_force_load = 0; -static int flag_silent_probe = 0; -static int flag_export = 1; -static int flag_load_map = 0; -static int flag_ksymoops = 1; - -static int n_ext_modules_used; -static int m_has_modinfo; - -extern int insmod_main(int argc, char **argv); -extern int insmod_main_32(int argc, char **argv); -extern int insmod_main_64(int argc, char **argv); -extern int modprobe_main(int argc, char **argv); -extern int rmmod_main(int argc, char **argv); -extern int ksyms_main(int argc, char **argv); -extern int lsmod_main(int argc, char **argv); -extern int kallsyms_main(int argc, char **argv); - -/*======================================================================*/ - -/* Get the kernel version in the canonical integer form. */ - -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; - - a = strtoul(p, &p, 10); - if (*p != '.') - return -1; - b = strtoul(p + 1, &p, 10); - if (*p != '.') - return -1; - c = strtoul(p + 1, &q, 10); - if (p + 1 == q) - return -1; - - return a << 16 | b << 8 | c; -} - -/* String comparison for non-co-versioned kernel and module. - * prefix should be the same as used by genksyms for this kernel. - */ -static char *ncv_prefix = NULL; /* Overridden by --prefix option */ -static int ncv_plen = 0; - -/* Only set prefix once. If set by the user, use it. If not set by the - * user, look for a well known kernel symbol and derive the prefix from - * there. Otherwise set the prefix depending on whether uts_info - * includes SMP or not for backwards compatibility. - */ -static void set_ncv_prefix(char *prefix) -{ - static char derived_prefix[256]; - static const char *well_known_symbol[] = { "get_module_symbol_R", - "inter_module_get_R", - }; - struct module_symbol *s; - int i, j, l, m, pl; - const char *name; - char *p; - - if (ncv_prefix) - return; - - if (prefix) - ncv_prefix = prefix; - else { - /* Extract the prefix (if any) from well known symbols */ - for (i = 0, s = ksyms; i < nksyms; ++i, ++s) { - name = (char *) s->name; - l = strlen(name); - for (j = 0; j < sizeof(well_known_symbol)/sizeof(well_known_symbol[0]); ++j) { - m = strlen(well_known_symbol[j]); - if (m + 8 > l || - strncmp(name, well_known_symbol[j], m)) - continue; - pl = l - m - 8; - if (pl > sizeof(derived_prefix)-1) - continue; /* Prefix is wrong length */ - /* Must end with 8 hex digits */ - (void) strtoul(name+l-8, &p, 16); - if (*p == 0) { - strncpy(derived_prefix, name+m, pl); - *(derived_prefix+pl) = '\0'; - ncv_prefix = derived_prefix; - break; - } - } - } - } - if (!ncv_prefix) { - p = strchr(uts_info.version, ' '); - if (p && *(++p) && !strncmp(p, "SMP ", 4)) - ncv_prefix = "smp_"; - else - ncv_prefix = ""; - } - ncv_plen = strlen(ncv_prefix); - if (flag_verbose) - lprintf("Symbol version prefix '%s'", ncv_prefix); -} - -static int ncv_strcmp(const char *a, const char *b) -{ - size_t alen = strlen(a), blen = strlen(b); - - if (blen == alen + 10 + ncv_plen && - b[alen] == '_' && - b[alen + 1] == 'R' && - !(ncv_plen && strncmp(b + alen + 2, ncv_prefix, ncv_plen))) { - return strncmp(a, b, alen); - } else if (alen == blen + 10 + ncv_plen && - a[blen] == '_' && a[blen + 1] == 'R' && - !(ncv_plen && strncmp(a + blen + 2, ncv_prefix, ncv_plen))) { - return strncmp(a, b, blen); - } else - return strcmp(a, b); -} - -/* - * String hashing for non-co-versioned kernel and module. - * Here we are simply forced to drop the crc from the hash. - */ -static unsigned long ncv_symbol_hash(const char *str) -{ - size_t len = strlen(str); - - if (len > 10 + ncv_plen && - str[len - 10 - ncv_plen] == '_' && - str[len - 9 - ncv_plen] == 'R' && - !( - ncv_plen && - strncmp(str + len - (8 + ncv_plen), ncv_prefix, ncv_plen) - )) - len -= 10 + ncv_plen; - return obj_elf_hash_n(str, len); -} - -/* - * Conditionally add the symbols from the given symbol set - * 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 *s; - size_t i; - int used = 0; - - for (i = 0, s = syms; i < nsyms; ++i, ++s) { - /* - * Only add symbols that are already marked external. - * If we override locals we may cause problems for - * argument initialization. - * We will also create a false dependency on the module. - */ - struct obj_symbol *sym; - - sym = obj_find_symbol(f, (char *) s->name); - 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); - /* - * Did our symbol just get installed? - * If so, mark the module as "used". - */ - if (sym->secidx == idx) - used = 1; - } - } - - return used; -} - -static void add_kernel_symbols(struct obj_file *f) -{ - struct module_stat *m; - size_t i, nused = 0; - - /* 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)) - 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); -} - -static void hide_special_symbols(struct obj_file *f) -{ - struct obj_symbol *sym; - const char *const *p; - static const char *const specials[] = - { - "cleanup_module", - "init_module", - "kernel_version", - NULL - }; - - for (p = specials; *p; ++p) - if ((sym = obj_find_symbol(f, *p)) != NULL) - sym->info = ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info)); -} - -static void print_load_map(struct obj_file *f) -{ - struct obj_symbol *sym; - struct obj_symbol **all, **p; - struct obj_section *sec; - int load_map_cmp(const void *a, const void *b) { - struct obj_symbol **as = (struct obj_symbol **) a; - struct obj_symbol **bs = (struct obj_symbol **) b; - unsigned long aa = obj_symbol_final_value(f, *as); - unsigned long ba = obj_symbol_final_value(f, *bs); - return aa < ba ? -1 : aa > ba ? 1 : 0; - } - int i, nsyms, *loaded; - - /* Report on the section layout. */ - - lprintf("Sections: Size %-*s Align", - (int) (2 * sizeof(void *)), "Address"); - - for (sec = f->load_order; sec; sec = sec->load_next) { - int a; - unsigned long tmp; - - for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a) - tmp >>= 1; - if (a == -1) - a = 0; - - lprintf("%-16s%08lx %0*lx 2**%d", - sec->name, - (long)sec->header.sh_size, - (int) (2 * sizeof(void *)), - (long)sec->header.sh_addr, - a); - } - - /* Quick reference which section indicies are loaded. */ - - loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); - while (--i >= 0) - loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; - - /* Collect the symbols we'll be listing. */ - - for (nsyms = i = 0; i < HASH_BUCKETS; ++i) - for (sym = f->symtab[i]; sym; sym = sym->next) - if (sym->secidx <= SHN_HIRESERVE - && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) - ++nsyms; - - all = alloca(nsyms * sizeof(struct obj_symbol *)); - - for (i = 0, p = all; i < HASH_BUCKETS; ++i) - for (sym = f->symtab[i]; sym; sym = sym->next) - if (sym->secidx <= SHN_HIRESERVE - && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) - *p++ = sym; - - /* Sort them by final value. */ - qsort(all, nsyms, sizeof(struct obj_file *), load_map_cmp); - - /* And list them. */ - lprintf("\nSymbols:"); - for (p = all; p < all + nsyms; ++p) { - char type = '?'; - unsigned long value; - - sym = *p; - if (sym->secidx == SHN_ABS) { - type = 'A'; - value = sym->value; - } else if (sym->secidx == SHN_UNDEF) { - type = 'U'; - value = 0; - } else { - struct obj_section *sec = f->sections[sym->secidx]; - - if (sec->header.sh_type == SHT_NOBITS) - type = 'B'; - else if (sec->header.sh_flags & SHF_ALLOC) { - if (sec->header.sh_flags & SHF_EXECINSTR) - type = 'T'; - else if (sec->header.sh_flags & SHF_WRITE) - type = 'D'; - else - type = 'R'; - } - value = sym->value + sec->header.sh_addr; - } - - if (ELFW(ST_BIND) (sym->info) == STB_LOCAL) - type = tolower(type); - - lprintf("%0*lx %c %s", (int) (2 * sizeof(void *)), value, - type, sym->name); - } -} - -/************************************************************************/ -/* begin compat */ - -static char * get_modinfo_value(struct obj_file *f, const char *key) -{ - struct obj_section *sec; - char *p, *v, *n, *ep; - size_t klen = strlen(key); - - sec = obj_find_section(f, ".modinfo"); - if (sec == NULL) - return NULL; - - p = sec->contents; - ep = p + sec->header.sh_size; - while (p < ep) { - v = strchr(p, '='); - n = strchr(p, '\0'); - if (v) { - if (v - p == klen && strncmp(p, key, klen) == 0) - return v + 1; - } else { - if (n - p == klen && strcmp(p, key) == 0) - return n; - } - p = n + 1; - } - - return NULL; -} - -static int create_this_module(struct obj_file *f, const char *m_name) -{ - struct obj_section *sec; - - sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, - sizeof(struct module)); - memset(sec->contents, 0, sizeof(struct module)); - - obj_add_symbol(f, "__this_module", -1, ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), - sec->idx, 0, sizeof(struct module)); - - obj_string_patch(f, sec->idx, offsetof(struct module, name), m_name); - - return 1; -} - -#ifdef COMPAT_2_0 -static int old_create_mod_use_count(struct obj_file *f) -{ - struct obj_section *sec; - struct obj_symbol *got; - - sec = obj_create_alloced_section_first(f, ".moduse", - sizeof(long), sizeof(long)); - - obj_add_symbol(f, "mod_use_count_", - -1, ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT), - sec->idx, 0, sizeof(long)); - - /* - * patb: if there is a _GLOBAL_OFFSET_TABLE_, - * add .got section for PIC type modules; - * we have to do this here, because obj_* calls are not made until - * after obj_check_undefined - * is there a better place for this exception? - */ - got = obj_find_symbol(f, "_GLOBAL_OFFSET_TABLE_"); - if (got) -{ - sec = obj_create_alloced_section(f, ".got", - sizeof(long), sizeof(long)); - got->secidx = sec->idx; /* mark the symbol as defined */ - } - return 1; -} -#endif - -/* add an entry to the __ksymtab section, creating it if necessary */ -static void add_ksymtab(struct obj_file *f, struct obj_symbol *sym) -{ - struct obj_section *sec; - ElfW(Addr) ofs; - - /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section. - * If __ksymtab is defined but not marked alloc, x out the first character - * (no obj_delete routine) and create a new __ksymtab with the correct - * characteristics. - */ - sec = obj_find_section(f, "__ksymtab"); - if (sec && !(sec->header.sh_flags & SHF_ALLOC)) { - *((char *)(sec->name)) = 'x'; /* override const */ - sec = NULL; - } - if (!sec) - sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0); - if (!sec) - return; - sec->header.sh_flags |= SHF_ALLOC; - - ofs = sec->header.sh_size; - obj_symbol_patch(f, sec->idx, ofs, sym); - obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name); - obj_extend_section(sec, 2 * tgt_sizeof_char_p); -} - -static int create_module_ksymtab(struct obj_file *f) -{ - struct obj_section *sec; - int i; - - /* We must always add the module references. */ - - if (n_ext_modules_used) { - 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)); - if (!sec) - return 0; - - tm = obj_find_symbol(f, "__this_module"); - dep = (struct module_ref *) sec->contents; - for (i = 0; i < n_module_stat; ++i) - if (module_stat[i].status /* used */) { - dep->dep = module_stat[i].addr; - obj_symbol_patch(f, sec->idx, (char *) &dep->ref - sec->contents, tm); - dep->next_ref = 0; - ++dep; - } - } - if (flag_export && !obj_find_section(f, "__ksymtab")) { - int *loaded; - - /* We don't want to export symbols residing in sections that - aren't loaded. There are a number of these created so that - we make sure certain module options don't appear twice. */ - - loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); - while (--i >= 0) - loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; - - for (i = 0; i < HASH_BUCKETS; ++i) { - struct obj_symbol *sym; - for (sym = f->symtab[i]; sym; sym = sym->next) { - if (ELFW(ST_BIND) (sym->info) != STB_LOCAL - && sym->secidx <= SHN_HIRESERVE - && (sym->secidx >= SHN_LORESERVE - || loaded[sym->secidx])) { - add_ksymtab(f, sym); - } - } - } - } - return 1; -} - -/* Get the module's kernel version in the canonical integer form. */ -static int get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) -{ - int a, b, c; - char *p, *q; - - if ((p = get_modinfo_value(f, "kernel_version")) == NULL) { - struct obj_symbol *sym; - - m_has_modinfo = 0; - if ((sym = obj_find_symbol(f, "kernel_version")) == NULL) - sym = obj_find_symbol(f, "__module_kernel_version"); - if (sym == NULL) - return -1; - p = f->sections[sym->secidx]->contents + sym->value; - } else - m_has_modinfo = 1; - - strncpy(str, p, STRVERSIONLEN); - - a = strtoul(p, &p, 10); - if (*p != '.') - return -1; - b = strtoul(p + 1, &p, 10); - if (*p != '.') - return -1; - c = strtoul(p + 1, &q, 10); - if (p + 1 == q) - return -1; - - return a << 16 | b << 8 | c; -} - -/* Return the kernel symbol checksum version, or zero if not used. */ -static int is_kernel_checksummed(void) -{ - struct module_symbol *s; - size_t i; - - /* - * Using_Versions might not be the first symbol, - * but it should be in there. - */ - for (i = 0, s = ksyms; i < nksyms; ++i, ++s) - if (strcmp((char *) s->name, "Using_Versions") == 0) - return s->value; - - return 0; -} - -static int is_module_checksummed(struct obj_file *f) -{ - if (m_has_modinfo) { - const char *p = get_modinfo_value(f, "using_checksums"); - if (p) - return atoi(p); - else - return 0; - } else - return obj_find_symbol(f, "Using_Versions") != NULL; -} - -/* add module source, timestamp, kernel version and a symbol for the - * start of some sections. this info is used by ksymoops to do better - * debugging. - */ -static void add_ksymoops_symbols(struct obj_file *f, const char *filename, - const char *m_name) -{ - struct obj_section *sec; - struct obj_symbol *sym; - char *name, *absolute_filename; - char str[STRVERSIONLEN], real[PATH_MAX]; - int i, l, lm_name, lfilename, use_ksymtab, version; - struct stat statbuf; - - static const char *section_names[] = { - ".text", - ".rodata", - ".data", - ".bss" - }; - - if (realpath(filename, real)) { - absolute_filename = xstrdup(real); - } - else { - int save_errno = errno; - error("cannot get realpath for %s", filename); - errno = save_errno; - absolute_filename = xstrdup(filename); - } - - lm_name = strlen(m_name); - lfilename = strlen(absolute_filename); - - /* add to ksymtab if it already exists or there is no ksymtab and other symbols - * are not to be exported. otherwise leave ksymtab alone for now, the - * "export all symbols" compatibility code will export these symbols later. - */ - - use_ksymtab = obj_find_section(f, "__ksymtab") || !flag_export; - - if ((sec = obj_find_section(f, ".this"))) { - /* tag the module header with the object name, last modified - * timestamp and module version. worst case for module version - * is 0xffffff, decimal 16777215. putting all three fields in - * one symbol is less readable but saves kernel space. - */ - l = sizeof(symprefix)+ /* "__insmod_" */ - lm_name+ /* module name */ - 2+ /* "_O" */ - lfilename+ /* object filename */ - 2+ /* "_M" */ - 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ - 2+ /* "_V" */ - 8+ /* version in dec */ - 1; /* nul */ - name = xmalloc(l); - if (stat(absolute_filename, &statbuf) != 0) - statbuf.st_mtime = 0; - 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, - version); - sym = obj_add_symbol(f, name, -1, - ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), - sec->idx, sec->header.sh_addr, 0); - if (use_ksymtab) - add_ksymtab(f, sym); - } - free(absolute_filename); - - /* record where the persistent data is going, same address as previous symbol */ - - if (f->persist) { - l = sizeof(symprefix)+ /* "__insmod_" */ - lm_name+ /* module name */ - 2+ /* "_P" */ - strlen(f->persist)+ /* data store */ - 1; /* nul */ - name = xmalloc(l); - snprintf(name, l, "%s%s_P%s", - symprefix, m_name, f->persist); - sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), - sec->idx, sec->header.sh_addr, 0); - if (use_ksymtab) - add_ksymtab(f, sym); - } - - /* tag the desired sections if size is non-zero */ - - for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) { - if ((sec = obj_find_section(f, section_names[i])) && - sec->header.sh_size) { - l = sizeof(symprefix)+ /* "__insmod_" */ - lm_name+ /* module name */ - 2+ /* "_S" */ - strlen(sec->name)+ /* section name */ - 2+ /* "_L" */ - 8+ /* length in dec */ - 1; /* nul */ - name = xmalloc(l); - snprintf(name, l, "%s%s_S%s_L%ld", - symprefix, m_name, sec->name, - (long)sec->header.sh_size); - sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), - sec->idx, sec->header.sh_addr, 0); - if (use_ksymtab) - add_ksymtab(f, sym); - } - } -} - -static int process_module_arguments(struct obj_file *f, int argc, char **argv, int required) -{ - for (; argc > 0; ++argv, --argc) { - struct obj_symbol *sym; - int c; - int min, max; - int n; - char *contents; - char *input; - char *fmt; - char *key; - char *loc; - - if ((input = strchr(*argv, '=')) == NULL) - continue; - - n = input - *argv; - input += 1; /* skip '=' */ - - key = alloca(n + 6); - - if (m_has_modinfo) { - memcpy(key, "parm_", 5); - 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 */ - } - } - key += 5; - - if (isdigit(*fmt)) { - min = strtoul(fmt, &fmt, 10); - if (*fmt == '-') - max = strtoul(fmt + 1, &fmt, 10); - else - max = min; - } else - min = max = 1; - } else { /* not m_has_modinfo */ - memcpy(key, *argv, n); - key[n] = '\0'; - - if (isdigit(*input)) - fmt = "i"; - else - fmt = "s"; - min = max = 0; - } - - sym = obj_find_symbol(f, key); - - /* - * Also check that the parameter was not - * resolved from the kernel. - */ - if (sym == NULL || sym->secidx > SHN_HIRESERVE) { - error("symbol for parameter %s not found", key); - return 0; - } - - contents = f->sections[sym->secidx]->contents; - loc = contents + sym->value; - n = 1; - - while (*input) { - char *str; - - switch (*fmt) { - case 's': - case 'c': - /* - * Do C quoting if we begin with a ", - * else slurp the lot. - */ - if (*input == '"') { - char *r; - - str = alloca(strlen(input)); - for (r = str, input++; *input != '"'; ++input, ++r) { - if (*input == '\0') { - error("improperly terminated string argument for %s", key); - return 0; - } - /* else */ - if (*input != '\\') { - *r = *input; - continue; - } - /* else handle \ */ - switch (*++input) { - case 'a': *r = '\a'; break; - case 'b': *r = '\b'; break; - case 'e': *r = '\033'; break; - case 'f': *r = '\f'; break; - case 'n': *r = '\n'; break; - case 'r': *r = '\r'; break; - case 't': *r = '\t'; break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - c = *input - '0'; - if ('0' <= input[1] && input[1] <= '7') { - c = (c * 8) + *++input - '0'; - if ('0' <= input[1] && input[1] <= '7') - c = (c * 8) + *++input - '0'; - } - *r = c; - break; - - default: *r = *input; break; - } - } - *r = '\0'; - ++input; - } else { - /* - * The string is not quoted. - * We will break it using the comma - * (like for ints). - * If the user wants to include commas - * in a string, he just has to quote it - */ - char *r; - - /* Search the next comma */ - if ((r = strchr(input, ',')) != NULL) { - /* - * Found a comma - * Recopy the current field - */ - str = alloca(r - input + 1); - memcpy(str, input, r - input); - str[r - input] = '\0'; - /* Keep next fields */ - input = r; - } else { - /* last string */ - str = input; - input = ""; - } - } - - if (*fmt == 's') { - /* Normal string */ - obj_string_patch(f, sym->secidx, loc - contents, str); - loc += tgt_sizeof_char_p; - } else { - /* Array of chars (in fact, matrix !) */ - long charssize; /* size of each member */ - - /* Get the size of each member */ - /* Probably we should do that outside the loop ? */ - if (!isdigit(*(fmt + 1))) { - error("parameter type 'c' for %s must be followed by" - " the maximum size", key); - return 0; - } - charssize = strtoul(fmt + 1, (char **) NULL, 10); - - /* Check length */ - if (strlen(str) >= charssize-1) { - error("string too long for %s (max %ld)", - key, charssize - 1); - return 0; - } - /* Copy to location */ - strcpy((char *) loc, str); /* safe, see check above */ - loc += charssize; - } - /* - * End of 's' and 'c' - */ - break; - - case 'b': - *loc++ = strtoul(input, &input, 0); - break; - - case 'h': - *(short *) loc = strtoul(input, &input, 0); - loc += tgt_sizeof_short; - break; - - case 'i': - *(int *) loc = strtoul(input, &input, 0); - loc += tgt_sizeof_int; - break; - - case 'l': - *(long *) loc = strtoul(input, &input, 0); - loc += tgt_sizeof_long; - break; - - default: - error("unknown parameter type '%c' for %s", - *fmt, key); - return 0; - } - /* - * end of switch (*fmt) - */ - - while (*input && isspace(*input)) - ++input; - if (*input == '\0') - break; /* while (*input) */ - /* else */ - - if (*input == ',') { - if (max && (++n > max)) { - error("too many values for %s (max %d)", key, max); - return 0; - } - ++input; - /* continue with while (*input) */ - } else { - error("invalid argument syntax for %s: '%c'", - key, *input); - return 0; - } - } /* end of while (*input) */ - - if (min && (n < min)) { - error("too few values for %s (min %d)", key, min); - return 0; - } - } /* end of for (;argc > 0;) */ - - return 1; -} - - -/* Add a kallsyms section if the kernel supports all symbols. */ -static int add_kallsyms(struct obj_file *f, - struct obj_section **module_kallsyms, int force_kallsyms) -{ - struct module_symbol *s; - struct obj_file *f_kallsyms; - struct obj_section *sec_kallsyms; - size_t i; - int l; - const char *p, *pt_R; - unsigned long start = 0, stop = 0; - - for (i = 0, s = ksyms; i < nksyms; ++i, ++s) { - p = (char *)s->name; - pt_R = strstr(p, "_R"); - if (pt_R) - l = pt_R - p; - else - l = strlen(p); - if (strncmp(p, "__start_" KALLSYMS_SEC_NAME, l) == 0) - start = s->value; - else if (strncmp(p, "__stop_" KALLSYMS_SEC_NAME, l) == 0) - stop = s->value; - } - - if (start >= stop && !force_kallsyms) - return(0); - - /* The kernel contains all symbols, do the same for this module. */ - - /* Add an empty kallsyms section to the module if necessary */ - for (i = 0; i < f->header.e_shnum; ++i) { - if (strcmp(f->sections[i]->name, KALLSYMS_SEC_NAME) == 0) { - *module_kallsyms = f->sections[i]; - break; - } - } - if (!*module_kallsyms) - *module_kallsyms = obj_create_alloced_section(f, KALLSYMS_SEC_NAME, 0, 0); - - /* Size and populate kallsyms */ - if (obj_kallsyms(f, &f_kallsyms)) - return(1); - sec_kallsyms = f_kallsyms->sections[KALLSYMS_IDX]; - (*module_kallsyms)->header.sh_addralign = sec_kallsyms->header.sh_addralign; - (*module_kallsyms)->header.sh_size = sec_kallsyms->header.sh_size; - free((*module_kallsyms)->contents); - (*module_kallsyms)->contents = sec_kallsyms->contents; - sec_kallsyms->contents = NULL; - obj_free(f_kallsyms); - - return 0; -} - - -/* Add an arch data section if the arch wants it. */ -static int add_archdata(struct obj_file *f, - struct obj_section **sec) -{ - size_t i; - - *sec = NULL; - /* Add an empty archdata section to the module if necessary */ - for (i = 0; i < f->header.e_shnum; ++i) { - if (strcmp(f->sections[i]->name, ARCHDATA_SEC_NAME) == 0) { - *sec = f->sections[i]; - break; - } - } - if (!*sec) - *sec = obj_create_alloced_section(f, ARCHDATA_SEC_NAME, 16, 0); - - /* Size and populate archdata */ - if (arch_archdata(f, *sec)) - return(1); - return 0; -} - - -static int init_module(const char *m_name, struct obj_file *f, - unsigned long m_size, const char *blob_name, - unsigned int noload, unsigned int flag_load_map) -{ - struct module *module; - struct obj_section *sec; - void *image; - int ret = 0; - tgt_long m_addr; - - sec = obj_find_section(f, ".this"); - module = (struct module *) sec->contents; - m_addr = sec->header.sh_addr; - - module->size_of_struct = sizeof(*module); - module->size = m_size; - module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0; - - sec = obj_find_section(f, "__ksymtab"); - if (sec && sec->header.sh_size) { - module->syms = sec->header.sh_addr; - module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p); - } - if (n_ext_modules_used) { - sec = obj_find_section(f, ".kmodtab"); - module->deps = sec->header.sh_addr; - module->ndeps = n_ext_modules_used; - } - module->init = obj_symbol_final_value(f, obj_find_symbol(f, "init_module")); - module->cleanup = obj_symbol_final_value(f, - obj_find_symbol(f, "cleanup_module")); - - sec = obj_find_section(f, "__ex_table"); - if (sec) { - module->ex_table_start = sec->header.sh_addr; - module->ex_table_end = sec->header.sh_addr + sec->header.sh_size; - } - sec = obj_find_section(f, ".text.init"); - if (sec) { - module->runsize = sec->header.sh_addr - m_addr; - } - sec = obj_find_section(f, ".data.init"); - if (sec) { - if (!module->runsize || - module->runsize > sec->header.sh_addr - m_addr) - module->runsize = sec->header.sh_addr - m_addr; - } - sec = obj_find_section(f, ARCHDATA_SEC_NAME); - if (sec && sec->header.sh_size) { - module->archdata_start = sec->header.sh_addr; - module->archdata_end = module->archdata_start + sec->header.sh_size; - } - sec = obj_find_section(f, KALLSYMS_SEC_NAME); - if (sec && sec->header.sh_size) { - module->kallsyms_start = sec->header.sh_addr; - module->kallsyms_end = module->kallsyms_start + sec->header.sh_size; - } - if (!arch_init_module(f, module)) - return 0; - - /* - * Whew! All of the initialization is complete. - * Collect the final module image and give it to the kernel. - */ - image = xmalloc(m_size); - obj_create_image(f, image); - - if (flag_load_map) - print_load_map(f); - - if (blob_name) { - int fd, l; - fd = open(blob_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (fd < 0) { - error("open %s failed %m", blob_name); - ret = -1; - } - else { - if ((l = write(fd, image, m_size)) != m_size) { - error("write %s failed %m", blob_name); - ret = -1; - } - close(fd); - } - } - - if (ret == 0 && !noload) { - fflush(stdout); /* Flush any debugging output */ - ret = sys_init_module(m_name, (struct module *) image); - if (ret) { - error("init_module: %m"); - lprintf("Hint: insmod errors can be caused by incorrect module parameters, " - "including invalid IO or IRQ parameters"); - } - } - - free(image); - - return ret == 0; -} - -#ifdef COMPAT_2_0 -static int old_init_module(const char *m_name, struct obj_file *f, - unsigned long m_size) -{ - char *image; - struct old_mod_routines routines; - struct old_symbol_table *symtab; - int ret; - int nsyms = 0, strsize = 0, total; - - /* Create the symbol table */ - /* Size things first... */ - if (flag_export) { - int i; - for (i = 0; i < HASH_BUCKETS; ++i) { - struct obj_symbol *sym; - - for (sym = f->symtab[i]; sym; sym = sym->next) - if (ELFW(ST_BIND) (sym->info) != STB_LOCAL && - sym->secidx <= SHN_HIRESERVE) { - sym->ksymidx = nsyms++; - strsize += strlen(sym->name) + 1; - } - } - } - total = (sizeof(struct old_symbol_table) + - nsyms * sizeof(struct old_module_symbol) + - n_ext_modules_used * sizeof(struct old_module_ref) + - strsize); - symtab = xmalloc(total); - symtab->size = total; - symtab->n_symbols = nsyms; - symtab->n_refs = n_ext_modules_used; - - if (flag_export && nsyms) { - struct old_module_symbol *ksym; - char *str; - int i; - - ksym = symtab->symbol; - str = ((char *) ksym + - nsyms * sizeof(struct old_module_symbol) + - n_ext_modules_used * sizeof(struct old_module_ref)); - - for (i = 0; i < HASH_BUCKETS; ++i) { - struct obj_symbol *sym; - for (sym = f->symtab[i]; sym; sym = sym->next) - if (sym->ksymidx >= 0) { - ksym->addr = obj_symbol_final_value(f, sym); - ksym->name = (unsigned long) str - (unsigned long) symtab; - - str = stpcpy(str, sym->name) + 1; - ksym++; - } - } - } - - if (n_ext_modules_used) { - struct old_module_ref *ref; - int i; - - ref = (struct old_module_ref *) - ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol)); - - for (i = 0; i < n_module_stat; ++i) { - if (module_stat[i].status /* used */) { - ref++->module = module_stat[i].modstruct; - } - } - } - - /* Fill in routines. */ - - routines.init = obj_symbol_final_value(f, obj_find_symbol(f, "init_module")); - routines.cleanup = obj_symbol_final_value(f, - obj_find_symbol(f, "cleanup_module")); - - /* - * Whew! All of the initialization is complete. - * Collect the final module image and give it to the kernel. - */ - image = xmalloc(m_size); - obj_create_image(f, image); - - /* - * image holds the complete relocated module, - * accounting correctly for mod_use_count. - * However the old module kernel support assume that it - * is receiving something which does not contain mod_use_count. - */ - ret = old_sys_init_module(m_name, image + sizeof(long), - (m_size - sizeof(long)) | - (flag_autoclean ? OLD_MOD_AUTOCLEAN : 0), - &routines, - symtab); - if (ret) - error("init_module: %m"); - - free(image); - free(symtab); - - return ret == 0; -} -#endif -/* end compat */ -/************************************************************************/ - -/* Check that a module parameter has a reasonable definition */ -static int check_module_parameter(struct obj_file *f, char *key, char *value, int *persist_flag) -{ - struct obj_symbol *sym; - int min, max; - char *p = value; - - sym = obj_find_symbol(f, key); - if (sym == NULL) { - /* FIXME: For 2.2 kernel compatibility, only issue warnings for - * most error conditions. Make these all errors in 2.5. - */ - lprintf("Warning: %s symbol for parameter %s not found", error_file, key); - return(1); - } - - if (isdigit(*p)) { - min = strtoul(p, &p, 10); - if (*p == '-') - max = strtoul(p + 1, &p, 10); - else - max = min; - } else - min = max = 1; - - if (max < min) { - lprintf("Warning: %s parameter %s has max < min!", error_file, key); - return(1); - } - - switch (*p) { - case 'c': - if (!isdigit(p[1])) { - lprintf("%s parameter %s has no size after 'c'!", error_file, key); - return(1); - } - while (isdigit(p[1])) - ++p; /* swallow c array size */ - break; - case 'b': /* drop through */ - case 'h': /* drop through */ - case 'i': /* drop through */ - case 'l': /* drop through */ - case 's': - break; - case '\0': - lprintf("%s parameter %s has no format character!", error_file, key); - return(1); - default: - lprintf("%s parameter %s has unknown format character '%c'", error_file, key, *p); - return(1); - } - switch (*++p) { - case 'p': - if (*(p-1) == 's') { - error("parameter %s is invalid persistent string", key); - return(1); - } - *persist_flag = 1; - break; - case '\0': - break; - default: - lprintf("%s parameter %s has unknown format modifier '%c'", error_file, key, *p); - return(1); - } - return(0); -} - -/* Check that all module parameters have reasonable definitions */ -static void check_module_parameters(struct obj_file *f, int *persist_flag) -{ - struct obj_section *sec; - char *ptr, *value, *n, *endptr; - int namelen, err = 0; - - sec = obj_find_section(f, ".modinfo"); - if (sec == NULL) { - /* module does not support typed parameters */ - return; - } - - ptr = sec->contents; - endptr = ptr + sec->header.sh_size; - while (ptr < endptr && !err) { - value = strchr(ptr, '='); - n = strchr(ptr, '\0'); - if (value) { - namelen = value - ptr; - if (namelen >= 5 && strncmp(ptr, "parm_", 5) == 0 - && !(namelen > 10 && strncmp(ptr, "parm_desc_", 10) == 0)) { - char *pname = xmalloc(namelen + 1); - strncpy(pname, ptr + 5, namelen - 5); - pname[namelen - 5] = '\0'; - err = check_module_parameter(f, pname, value+1, persist_flag); - free(pname); - } - } else { - if (n - ptr >= 5 && strncmp(ptr, "parm_", 5) == 0) { - error("parameter %s found with no value", ptr); - err = 1; - } - } - ptr = n + 1; - } - - if (err) - *persist_flag = 0; - return; -} - - -/* For common 3264 code, only compile the usage message once, in the 64 bit version */ -#if defined(COMMON_3264) && defined(ONLY_32) -extern void insmod_usage(void); /* Use the copy in the 64 bit version */ -#else /* Common 64 bit version or any non common code - compile usage routine */ -void insmod_usage(void) -{ - fputs("Usage:\n" - "insmod [-fhkLmnpqrsSvVxXyY] [-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" - " -h, --help Print this message\n" - " -k, --autoclean Make module autoclean-able\n" - " -L, --lock Prevent simultaneous loads of the same module\n" - " -m, --map Generate load map (so crashes can be traced)\n" - " -n, --noload Don't load, just show\n" - " -p, --probe Probe mode; check if the module matches the kernel\n" - " -q, --quiet Don't print unresolved symbols\n" - " -r, --root Allow root to load modules not owned by root\n" - " -s, --syslog Report errors via syslog\n" - " -S, --kallsyms Force kallsyms on module\n" - " -v, --verbose Verbose output\n" - " -V, --version Show version\n" - " -x, --noexport Do not export externs\n" - " -X, --export Do export externs (default)\n" - " -y, --noksymoops Do not add ksymoops symbols\n" - " -Y, --ksymoops Do add ksymoops symbols (default)\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" - " -O NAME, --blob=NAME Save the object as a binary blob in NAME\n" - " -P PREFIX\n" - " --prefix=PREFIX Prefix for kernel or module symbols\n" - ,stderr); - exit(1); -} -#endif /* defined(COMMON_3264) && defined(ONLY_32) */ - -#if defined(COMMON_3264) && defined(ONLY_32) -#define INSMOD_MAIN insmod_main_32 /* 32 bit version */ -#elif defined(COMMON_3264) && defined(ONLY_64) -#define INSMOD_MAIN insmod_main_64 /* 64 bit version */ -#else -#define INSMOD_MAIN insmod_main /* Not common code */ -#endif - -int INSMOD_MAIN(int argc, char **argv) -{ - int k_version; - int k_crcs; - char k_strversion[STRVERSIONLEN]; - struct option long_opts[] = { - {"force", 0, 0, 'f'}, - {"help", 0, 0, 'h'}, - {"autoclean", 0, 0, 'k'}, - {"lock", 0, 0, 'L'}, - {"map", 0, 0, 'm'}, - {"noload", 0, 0, 'n'}, - {"probe", 0, 0, 'p'}, - {"poll", 0, 0, 'p'}, /* poll is deprecated, remove in 2.5 */ - {"quiet", 0, 0, 'q'}, - {"root", 0, 0, 'r'}, - {"syslog", 0, 0, 's'}, - {"kallsyms", 0, 0, 'S'}, - {"verbose", 0, 0, 'v'}, - {"version", 0, 0, 'V'}, - {"noexport", 0, 0, 'x'}, - {"export", 0, 0, 'X'}, - {"noksymoops", 0, 0, 'y'}, - {"ksymoops", 0, 0, 'Y'}, - - {"persist", 1, 0, 'e'}, - {"name", 1, 0, 'o'}, - {"blob", 1, 0, 'O'}, - {"prefix", 1, 0, 'P'}, - {0, 0, 0, 0} - }; - char *m_name = NULL; - char *blob_name = NULL; /* Save object as binary blob */ - int m_version; - ElfW(Addr) m_addr; - unsigned long m_size; - int m_crcs; - char m_strversion[STRVERSIONLEN]; - char *filename; - char *persist_name = NULL; /* filename to hold any persistent data */ - int fp; - struct obj_file *f; - struct obj_section *kallsyms = NULL, *archdata = NULL; - int o; - int noload = 0; - int dolock = 1; /*Note: was: 0; */ - int quiet = 0; - int exit_status = 1; - int force_kallsyms = 0; - int persist_parms = 0; /* does module have persistent parms? */ - int i; - - error_file = "insmod"; - - /* To handle repeated calls from combined modprobe */ - errors = optind = 0; - - /* Process the command line. */ - while ((o = getopt_long(argc, argv, "fhkLmnpqrsSvVxXyYe:o:O:P:R:", - &long_opts[0], NULL)) != EOF) - switch (o) { - case 'f': /* force loading */ - flag_force_load = 1; - break; - case 'h': /* Print the usage message. */ - insmod_usage(); - break; - case 'k': /* module loaded by kerneld, auto-cleanable */ - flag_autoclean = 1; - break; - case 'L': /* protect against recursion. */ - dolock = 1; - break; - case 'm': /* generate load map */ - flag_load_map = 1; - break; - case 'n': /* don't load, just check */ - noload = 1; - break; - case 'p': /* silent probe mode */ - flag_silent_probe = 1; - break; - case 'q': /* Don't print unresolved symbols */ - quiet = 1; - break; - case 'r': /* allow root to load non-root modules */ - root_check_off = !root_check_off; - break; - case 's': /* start syslog */ - setsyslog("insmod"); - break; - case 'S': /* Force kallsyms */ - force_kallsyms = 1; - break; - case 'v': /* verbose output */ - flag_verbose = 1; - break; - case 'V': - fputs("insmod version " MODUTILS_VERSION "\n", stderr); - break; - case 'x': /* do not export externs */ - flag_export = 0; - break; - case 'X': /* do export externs */ - flag_export = 1; - break; - case 'y': /* do not define ksymoops symbols */ - flag_ksymoops = 0; - break; - case 'Y': /* do define ksymoops symbols */ - flag_ksymoops = 1; - break; - - case 'e': /* persistent data filename */ - free(persist_name); - persist_name = xstrdup(optarg); - break; - case 'o': /* name the output module */ - m_name = optarg; - break; - case 'O': /* save the output module object */ - blob_name = optarg; - break; - case 'P': /* use prefix on crc */ - set_ncv_prefix(optarg); - break; - - default: - insmod_usage(); - break; - } - - if (optind >= argc) { - insmod_usage(); - } - filename = argv[optind++]; - - if (config_read(0, NULL, "", NULL) < 0) { - error("Failed handle configuration"); - } - - if (persist_name && !*persist_name && - (!persistdir || !*persistdir)) { - free(persist_name); - persist_name = NULL; - if (flag_verbose) - lprintf("insmod: -e \"\" ignored, no persistdir"); - } - - if (m_name == NULL) { - size_t len; - char *p; - - if ((p = strrchr(filename, '/')) != NULL) - p++; - else - p = filename; - len = strlen(p); - if (len > 2 && p[len - 2] == '.' && p[len - 1] == 'o') - len -= 2; - else if (len > 4 && p[len - 4] == '.' && p[len - 3] == 'm' - && p[len - 2] == 'o' && p[len - 1] == 'd') - len -= 4; -#ifdef CONFIG_USE_ZLIB - else if (len > 5 && !strcmp(p + len - 5, ".o.gz")) - len -= 5; -#endif - - m_name = xmalloc(len + 1); - memcpy(m_name, p, len); - m_name[len] = '\0'; - } - - /* Locate the file to be loaded. */ - if (!strchr(filename, '/') && !strchr(filename, '.')) { - char *tmp = search_module_path(filename); - if (tmp == NULL) { - error("%s: no module by that name found", filename); - return 1; - } - filename = tmp; - lprintf("Using %s", filename); - } else if (flag_verbose) - lprintf("Using %s", filename); - - /* And open it. */ - if ((fp = gzf_open(filename, O_RDONLY)) == -1) { - error("%s: %m", filename); - return 1; - } - /* Try to prevent multiple simultaneous loads. */ - if (dolock) - flock(fp, LOCK_EX); - - if (!get_kernel_info(K_SYMBOLS)) - goto out; - - /* - * Set the genksyms prefix if this is a versioned kernel - * and it's not already set. - */ - set_ncv_prefix(NULL); - - for (i = 0; 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; - } - } - - error_file = filename; - if ((f = obj_load(fp, ET_REL, filename)) == NULL) - goto out; - - /* Version correspondence? */ - k_version = get_kernel_version(k_strversion); - m_version = get_module_version(f, m_strversion); - if (m_version == -1) { - error("couldn't find the kernel version the module was compiled for"); - goto out; - } - - k_crcs = is_kernel_checksummed(); - m_crcs = is_module_checksummed(f); - if ((m_crcs == 0 || k_crcs == 0) && - strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) { - if (flag_force_load) { - lprintf("Warning: kernel-module version mismatch\n" - "\t%s was compiled for kernel version %s\n" - "\twhile this kernel is version %s", - filename, m_strversion, k_strversion); - } else { - if (!quiet) - error("kernel-module version mismatch\n" - "\t%s was compiled for kernel version %s\n" - "\twhile this kernel is version %s.", - filename, m_strversion, k_strversion); - goto out; - } - } - if (m_crcs != k_crcs) - obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); - - /* Let the module know about the kernel symbols. */ - add_kernel_symbols(f); - - /* Allocate common symbols, symbol tables, and string tables. - * - * The calls marked DEPMOD indicate the bits of code that depmod - * uses to do a pseudo relocation, ignoring undefined symbols. - * Any changes made to the relocation sequence here should be - * checked against depmod. - */ -#ifdef COMPAT_2_0 - if (k_new_syscalls - ? !create_this_module(f, m_name) - : !old_create_mod_use_count(f)) - goto out; -#else - if (!create_this_module(f, m_name)) - goto out; -#endif - - if (!obj_check_undefineds(f, quiet)) /* DEPMOD, obj_clear_undefineds */ - goto out; - obj_allocate_commons(f); /* DEPMOD */ - - check_module_parameters(f, &persist_parms); - - 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) { - f->persist = persist_name; - persist_name = NULL; - } - - if (persist_parms && - persist_name && !*persist_name) { - /* -e "". This is ugly. Take the filename, compare it against - * each of the module paths until we find a match on the start - * of the filename, assume the rest is the relative path. Have - * to do it this way because modprobe uses absolute filenames - * for module names in modules.dep and the format of modules.dep - * does not allow for any backwards compatible changes, so there - * is nowhere to store the relative filename. The only way this - * should fail to calculate a relative path is "insmod ./xxx", for - * that case the user has to specify -e filename. - */ - int j, l = strlen(filename); - char *relative = NULL; - char *p; - for (i = 0; i < nmodpath; ++i) { - p = modpath[i].path; - j = strlen(p); - while (j && p[j] == '/') - --j; - if (j < l && strncmp(filename, p, j) == 0 && filename[j] == '/') { - while (filename[j] == '/') - ++j; - relative = xstrdup(filename+j); - break; - } - } - if (relative) { - i = strlen(relative); - if (i > 3 && strcmp(relative+i-3, ".gz") == 0) - relative[i -= 3] = '\0'; - if (i > 2 && strcmp(relative+i-2, ".o") == 0) - relative[i -= 2] = '\0'; - else if (i > 4 && strcmp(relative+i-4, ".mod") == 0) - relative[i -= 4] = '\0'; - f->persist = xmalloc(strlen(persistdir) + 1 + i + 1); - strcpy(f->persist, persistdir); /* safe, xmalloc */ - strcat(f->persist, "/"); /* safe, xmalloc */ - strcat(f->persist, relative); /* safe, xmalloc */ - free(relative); - } - else - error("Cannot calculate persistent filename"); - } - - if (f->persist && *(f->persist) != '/') { - error("Persistent filenames must be absolute, ignoring '%s'", - f->persist); - free(f->persist); - f->persist = NULL; - } - - if (f->persist && !flag_ksymoops) { - error("has persistent data but ksymoops symbols are not available"); - free(f->persist); - f->persist = NULL; - } - - if (f->persist && !k_new_syscalls) { - error("has persistent data but the kernel is too old to support it"); - free(f->persist); - f->persist = NULL; - } - - if (persist_parms && flag_verbose) { - if (f->persist) - lprintf("Persist filename '%s'", f->persist); - else - lprintf("No persistent filename available"); - } - - if (f->persist) { - FILE *fp = fopen(f->persist, "r"); - if (!fp) { - if (flag_verbose) - lprintf("Cannot open persist file '%s' %m", f->persist); - } - else { - int pargc = 0; - char *pargv[1000]; /* hard coded but big enough */ - char line[3000]; /* hard coded but big enough */ - char *p; - while (fgets(line, sizeof(line), fp)) { - p = strchr(line, '\n'); - if (!p) { - error("Persistent data line is too long\n%s", line); - break; - } - *p = '\0'; - p = line; - while (isspace(*p)) - ++p; - if (!*p || *p == '#') - continue; - if (pargc == sizeof(pargv)/sizeof(pargv[0])) { - error("More than %d persistent parameters", pargc); - break; - } - pargv[pargc++] = xstrdup(p); - } - fclose(fp); - if (!process_module_arguments(f, pargc, pargv, 0)) - goto out; - while (pargc--) - free(pargv[pargc]); - } - } - - if (flag_ksymoops) - add_ksymoops_symbols(f, filename, m_name); - - if (k_new_syscalls) - create_module_ksymtab(f); - - /* archdata based on relocatable addresses */ - if (add_archdata(f, &archdata)) - goto out; - - /* kallsyms based on relocatable addresses */ - if (add_kallsyms(f, &kallsyms, force_kallsyms)) - goto out; - /**** No symbols or sections to be changed after kallsyms above ***/ - - if (errors) - goto out; - - /* If we were just checking, we made it. */ - if (flag_silent_probe) { - exit_status = 0; - goto out; - } - /* Module has now finished growing; find its size and install it. */ - m_size = obj_load_size(f); /* DEPMOD */ - - if (noload) { - /* Don't bother actually touching the kernel. */ - m_addr = 0x12340000; - } else { - errno = 0; - m_addr = create_module(m_name, m_size); - switch (errno) { - case 0: - break; - case EEXIST: - if (dolock) { - /* - * Assume that we were just invoked - * simultaneous with another insmod - * and return success. - */ - exit_status = 0; - goto out; - } - error("a module named %s already exists", m_name); - goto out; - case ENOMEM: - error("can't allocate kernel memory for module; needed %lu bytes", - m_size); - goto out; - default: - error("create_module: %m"); - goto out; - } - } - - /* module is already built, complete with ksymoops symbols for the - * persistent filename. If the kernel does not support persistent data - * then give an error but continue. It is too difficult to clean up at - * this stage and this error will only occur on backported modules. - * rmmod will also get an error so warn the user now. - */ - if (f->persist && !noload) { - struct { - struct module m; - int data; - } test_read; - memset(&test_read, 0, sizeof(test_read)); - test_read.m.size_of_struct = -sizeof(test_read.m); /* -ve size => read, not write */ - test_read.m.read_start = m_addr + sizeof(struct module); - test_read.m.read_end = test_read.m.read_start + sizeof(test_read.data); - if (sys_init_module(m_name, (struct module *) &test_read)) { - int old_errors = errors; - error("has persistent data but the kernel is too old to support it." - " Expect errors during rmmod as well"); - errors = old_errors; - } - } - - if (!obj_relocate(f, m_addr)) { /* DEPMOD */ - if (!noload) - delete_module(m_name); - goto out; - } - - /* Do archdata again, this time we have the final addresses */ - if (add_archdata(f, &archdata)) - goto out; - - /* Do kallsyms again, this time we have the final addresses */ - if (add_kallsyms(f, &kallsyms, force_kallsyms)) - goto out; - -#ifdef COMPAT_2_0 - if (k_new_syscalls) - init_module(m_name, f, m_size, blob_name, noload, flag_load_map); - else if (!noload) - old_init_module(m_name, f, m_size); -#else - init_module(m_name, f, m_size, blob_name, noload, flag_load_map); -#endif - if (errors) { - if (!noload) - delete_module(m_name); - goto out; - } - exit_status = 0; - - out: - if (dolock) - flock(fp, LOCK_UN); - close(fp); - if (!noload) - snap_shot(NULL, 0); - - return exit_status; -} - -/* For common 3264 code, add an overall insmod_main, in the 64 bit version. */ -#if defined(COMMON_3264) && defined(ONLY_64) -int insmod_main(int argc, char **argv) -{ - if (arch64()) - return insmod_main_64(argc, argv); - else - return insmod_main_32(argc, argv); -} -#endif /* defined(COMMON_3264) && defined(ONLY_64) */ - - - -int insmod_call(char * full_filename, char * params) -{ - int argc = 2; - char *argv[50]; - char * ptr = params; - argv[0] = "stage1"; - argv[1] = full_filename; - - while (ptr != NULL) { - argv[argc] = ptr; - argc++; - ptr = strchr(ptr, ' '); - if (ptr) { - ptr[0] = '\0'; - ptr++; - } - } - - return insmod_main(argc, argv); -} diff --git a/mdk-stage1/insmod-modutils/obj/Makefile b/mdk-stage1/insmod-modutils/obj/Makefile deleted file mode 100644 index 34b5df2d9..000000000 --- a/mdk-stage1/insmod-modutils/obj/Makefile +++ /dev/null @@ -1,33 +0,0 @@ - #****************************************************************************** - # - # insmod from modutils (generic) - # - # $Id$ - # - # Copyright 1996, 1997 Linux International. - # - #***************************************************************************** - -top_dir = ../.. - -include $(top_dir)/Makefile.common - - -all: libobj.a - -clean: - rm -f *.o *.a - - -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 - -libobj.a: $(OBJS) - ar cru $@ $^ - ranlib $@ - -.c.o: - gcc $(CFLAGS) $(DEFS) $(INCS) $(GLIBC_INCLUDES) -c $< diff --git a/mdk-stage1/insmod-modutils/obj/obj_alpha.c b/mdk-stage1/insmod-modutils/obj/obj_alpha.c deleted file mode 100644 index 4006b3442..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_alpha.c +++ /dev/null @@ -1,305 +0,0 @@ -/* Alpha specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 alpha_got_entry -{ - struct alpha_got_entry *next; - ElfW(Addr) addend; - int offset; - int reloc_done; -}; - -struct alpha_file -{ - struct obj_file root; - struct obj_section *got; -}; - -struct alpha_symbol -{ - struct obj_symbol root; - struct alpha_got_entry *got_entries; -}; - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - struct alpha_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 alpha_symbol *sym; - sym = xmalloc(sizeof(*sym)); - sym->got_entries = NULL; - 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 alpha_file *af = (struct alpha_file *)f; - struct alpha_symbol *asym = (struct alpha_symbol *)sym; - - unsigned long *lloc = (unsigned long *)(targsec->contents + rel->r_offset); - unsigned int *iloc = (unsigned int *)lloc; - Elf64_Addr dot = targsec->header.sh_addr + rel->r_offset; - Elf64_Addr gp = af->got->header.sh_addr + 0x8000; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF64_R_TYPE(rel->r_info)) - { - case R_ALPHA_NONE: - case R_ALPHA_LITUSE: - break; - - case R_ALPHA_REFQUAD: - *lloc += v; - break; - - case R_ALPHA_GPREL32: - v -= gp; - if ((Elf64_Sxword)v > 0x7fffffff - || (Elf64_Sxword)v < -(Elf64_Sxword)0x80000000) - ret = obj_reloc_overflow; - *iloc = v; - break; - - case R_ALPHA_LITERAL: - { - struct alpha_got_entry *gotent; - - assert(asym != NULL); - gotent = asym->got_entries; - while (gotent->addend != rel->r_addend) - gotent = gotent->next; - - if (!gotent->reloc_done) - { - *(unsigned long *)(af->got->contents + gotent->offset) = v; - gotent->reloc_done = 1; - } - - *iloc = (*iloc & ~0xffff) | ((gotent->offset - 0x8000) & 0xffff); - } - break; - - case R_ALPHA_GPDISP: - { - unsigned int *p_ldah, *p_lda; - unsigned int i_ldah, i_lda, hi, lo; - - p_ldah = iloc; - p_lda = (unsigned int *)((char *)iloc + rel->r_addend); - i_ldah = *p_ldah; - i_lda = *p_lda; - - /* Make sure the instructions are righteous. */ - if ((i_ldah >> 26) != 9 || (i_lda >> 26) != 8) - ret = obj_reloc_dangerous; - - /* Extract the existing addend. */ - v = (i_ldah & 0xffff) << 16 | (i_lda & 0xffff); - v = (v ^ 0x80008000) - 0x80008000; - - v += gp - dot; - - if ((Elf64_Sxword)v >= 0x7fff8000 - || (Elf64_Sxword)v < -(Elf64_Sxword)0x80000000) - ret = obj_reloc_overflow; - - /* Modify the instructions and finish up. */ - lo = v & 0xffff; - hi = ((v >> 16) + ((v >> 15) & 1)) & 0xffff; - - *p_ldah = (i_ldah & 0xffff0000) | hi; - *p_lda = (i_lda & 0xffff0000) | lo; - } - break; - - case R_ALPHA_BRADDR: - v -= dot + 4; - if (v % 4) - ret = obj_reloc_dangerous; - else if ((Elf64_Sxword)v > 0x3fffff - || (Elf64_Sxword)v < -(Elf64_Sxword)0x400000) - ret = obj_reloc_overflow; - v /= 4; - - *iloc = (*iloc & ~0x1fffff) | (v & 0x1fffff); - break; - - case R_ALPHA_HINT: - v -= dot + 4; - if (v % 4) - ret = obj_reloc_dangerous; - v /= 4; - - *iloc = (*iloc & ~0x3fff) | (v & 0x3fff); - break; - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *f) -{ - struct alpha_file *af = (struct alpha_file *)f; - int i, n, offset = 0; - - n = af->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 = af->root.sections[i]; - if (relsec->header.sh_type != SHT_RELA) - continue; - - symsec = af->root.sections[relsec->header.sh_link]; - strsec = af->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 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); - - for (ent = intsym->got_entries; ent ; ent = ent->next) - if (ent->addend == rel->r_addend) - goto found; - - ent = xmalloc(sizeof(*ent)); - ent->addend = rel->r_addend; - ent->offset = offset; - ent->reloc_done = 0; - ent->next = intsym->got_entries; - intsym->got_entries = ent; - offset += 8; - - found:; - } - } - - if (offset > 0x10000) - { - error(".got section overflow: %#x > 0x10000", offset); - return 0; - } - - /* We always want a .got section so that we always have a GP for - use with GPDISP and GPREL32 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); - - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - struct alpha_file *af = (struct alpha_file *)f; - - mod->gp = af->got->header.sh_addr + 0x8000; - - 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/obj/obj_arm.c b/mdk-stage1/insmod-modutils/obj/obj_arm.c deleted file mode 100644 index 7a843f947..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_arm.c +++ /dev/null @@ -1,318 +0,0 @@ -/* ARM specific support for Elf loading and relocation. - Copyright 1996, 1997, 1998 Linux International. - - Contributed by Phil Blundell <philb@gnu.org> - and wms <woody@corelcomputer.com> - based on the i386 code by Richard Henderson <rth@tamu.edu> - - 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 arm_plt_entry -{ - int offset; - int allocated:1; - int inited:1; // has been set up -}; - -struct arm_got_entry -{ - int offset; - int allocated : 1; - unsigned reloc_done : 1; -}; - -struct arm_file -{ - struct obj_file root; - struct obj_section *plt; - struct obj_section *got; -}; - -struct arm_symbol -{ - struct obj_symbol root; - struct arm_plt_entry pltent; - struct arm_got_entry gotent; -}; - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - struct arm_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 arm_symbol *sym; - sym = xmalloc(sizeof(*sym)); - memset(&sym->gotent, 0, sizeof(sym->gotent)); - memset(&sym->pltent, 0, sizeof(sym->pltent)); - 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, - Elf32_Rel *rel, - Elf32_Addr v) -{ - struct arm_file *afile = (struct arm_file *)f; - struct arm_symbol *asym = (struct arm_symbol *)sym; - - Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset); - Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; - Elf32_Addr got = afile->got ? afile->got->header.sh_addr : 0; - Elf32_Addr plt = afile->plt ? afile->plt->header.sh_addr : 0; - - struct arm_plt_entry *pe; - unsigned long *ip; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_ARM_NONE: - break; - - case R_ARM_ABS32: - *loc += v; - break; - - case R_ARM_GOT32: - /* needs an entry in the .got: set it, once */ - if (! asym->gotent.reloc_done) - { - asym->gotent.reloc_done = 1; - *(Elf32_Addr *)(afile->got->contents + asym->gotent.offset) = v; - } - /* make the reloc with_respect_to_.got */ - *loc += asym->gotent.offset; - break; - - /* relative reloc, always to _GLOBAL_OFFSET_TABLE_ (which is .got) - similar to branch, but is full 32 bits relative */ - case R_ARM_GOTPC: - assert(got); - *loc += got - dot; - break; - - case R_ARM_PC24: - case R_ARM_PLT32: - /* find the plt entry and initialize it if necessary */ - assert(asym != NULL); - pe = (struct arm_plt_entry*) &asym->pltent; - if (! pe->inited) - { - ip = (unsigned long *) (afile->plt->contents + pe->offset); - ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ - ip[1] = v; /* sym@ */ - pe->inited = 1; - } - - /* relative distance to target */ - v -= dot; - /* if the target is too far away.... */ - if ((int)v < -0x02000000 || (int)v >= 0x02000000) - { - /* go via the plt */ - v = plt + pe->offset - dot; - } - if (v & 3) - ret = obj_reloc_dangerous; - - /* Convert to words. */ - v >>= 2; - - /* merge the offset into the instruction. */ - *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); - break; - - /* address relative to the got */ - case R_ARM_GOTOFF: - assert(got); - *loc += v - got; - break; - - default: - printf("Warning: unhandled reloc %d\n",ELF32_R_TYPE(rel->r_info)); - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *f) -{ - struct arm_file *afile = (struct arm_file *) f; - int i; - struct obj_section *sec, *syms, *strs; - ElfW(Rel) *rel, *relend; - ElfW(Sym) *symtab, *extsym; - const char *strtab, *name; - struct arm_symbol *intsym; - struct arm_plt_entry *pe; - struct arm_got_entry *ge; - int got_offset = 0, plt_offset = 0; - - for (i = 0; i < f->header.e_shnum; ++i) - { - sec = f->sections[i]; - if (sec->header.sh_type != SHT_RELM) - continue; - syms = f->sections[sec->header.sh_link]; - strs = f->sections[syms->header.sh_link]; - - rel = (ElfW(RelM) *) sec->contents; - relend = rel + (sec->header.sh_size / sizeof(ElfW(RelM))); - symtab = (ElfW(Sym) *) syms->contents; - strtab = (const char *) strs->contents; - - for (; rel < relend; ++rel) - { - extsym = &symtab[ELF32_R_SYM(rel->r_info)]; - - 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); - - pe = &intsym->pltent; - - if (! pe->allocated) - { - pe->allocated = 1; - pe->offset = plt_offset; - plt_offset += 8; - pe->inited = 0; - } - break; - - /* these two don_t need got entries, but they need - the .got to exist */ - case R_ARM_GOTOFF: - case R_ARM_GOTPC: - if (got_offset==0) got_offset = 4; - 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); - - ge = (struct arm_got_entry *) &intsym->gotent; - if (! ge->allocated) - { - ge->allocated = 1; - ge->offset = got_offset; - got_offset += sizeof(void*); - } - break; - - default: - continue; - } - } - } - - /* if there was a _GLOBAL_OFFSET_TABLE_, then the .got section - exists already; find it and use it */ - if (got_offset) - { - struct obj_section* sec = obj_find_section(f, ".got"); - if (sec) - obj_extend_section(sec, got_offset); - else - { - sec = obj_create_alloced_section(f, ".got", 8, got_offset); - assert(sec); - } - afile->got = sec; - } - - if (plt_offset) - afile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset); - - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_common.c b/mdk-stage1/insmod-modutils/obj/obj_common.c deleted file mode 100644 index 2a6606c94..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_common.c +++ /dev/null @@ -1,399 +0,0 @@ -/* Elf file, section, and symbol manipulation routines. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <obj.h> -#include <util.h> -#include <module.h> - -/*======================================================================*/ - -/* Standard ELF hash function. */ -inline unsigned long -obj_elf_hash_n(const char *name, unsigned long n) -{ - unsigned long h = 0; - unsigned long g; - unsigned char ch; - - while (n > 0) - { - ch = *name++; - h = (h << 4) + ch; - if ((g = (h & 0xf0000000)) != 0) - { - h ^= g >> 24; - h &= ~g; - } - n--; - } - return h; -} - -unsigned long -obj_elf_hash (const char *name) -{ - return obj_elf_hash_n(name, strlen(name)); -} - -void -obj_set_symbol_compare (struct obj_file *f, - int (*cmp)(const char *, const char *), - unsigned long (*hash)(const char *)) -{ - if (cmp) - f->symbol_cmp = cmp; - if (hash) - { - struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next; - int i; - - f->symbol_hash = hash; - - memcpy(tmptab, f->symtab, sizeof(tmptab)); - memset(f->symtab, 0, sizeof(f->symtab)); - - for (i = 0; i < HASH_BUCKETS; ++i) - for (sym = tmptab[i]; sym ; sym = next) - { - unsigned long h = hash(sym->name) % HASH_BUCKETS; - next = sym->next; - sym->next = f->symtab[h]; - f->symtab[h] = sym; - } - } -} - -struct obj_symbol * -obj_add_symbol (struct obj_file *f, const char *name, unsigned long symidx, - int info, int secidx, ElfW(Addr) value, unsigned long size) -{ - struct obj_symbol *sym; - unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS; - int n_type = ELFW(ST_TYPE)(info); - int n_binding = ELFW(ST_BIND)(info); - - for (sym = f->symtab[hash]; sym; sym = sym->next) - if (f->symbol_cmp(sym->name, name) == 0) - { - int o_secidx = sym->secidx; - int o_info = sym->info; - int o_type = ELFW(ST_TYPE)(o_info); - int o_binding = ELFW(ST_BIND)(o_info); - - /* A redefinition! Is it legal? */ - - if (secidx == SHN_UNDEF) - return sym; - else if (o_secidx == SHN_UNDEF) - goto found; - else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) - { - /* Cope with local and global symbols of the same name - in the same object file, as might have been created - by ld -r. The only reason locals are now seen at this - level at all is so that we can do semi-sensible things - with parameters. */ - - struct obj_symbol *nsym, **p; - - nsym = arch_new_symbol(); - nsym->next = sym->next; - nsym->ksymidx = -1; - - /* Excise the old (local) symbol from the hash chain. */ - for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next) - continue; - *p = sym = nsym; - goto found; - } - else if (n_binding == STB_LOCAL) - { - /* Another symbol of the same name has already been defined. - Just add this to the local table. */ - sym = arch_new_symbol(); - sym->next = NULL; - sym->ksymidx = -1; - f->local_symtab[symidx] = sym; - goto found; - } - else if (n_binding == STB_WEAK) - return sym; - else if (o_binding == STB_WEAK) - goto found; - /* Don't unify COMMON symbols with object types the programmer - doesn't expect. */ - else if (secidx == SHN_COMMON - && (o_type == STT_NOTYPE || o_type == STT_OBJECT)) - return sym; - else if (o_secidx == SHN_COMMON - && (n_type == STT_NOTYPE || n_type == STT_OBJECT)) - goto found; - else - { - /* Don't report an error if the symbol is coming from - the kernel or some external module. */ - if (secidx <= SHN_HIRESERVE) - error("%s multiply defined", name); - return sym; - } - } - - /* Completely new symbol. */ - sym = arch_new_symbol(); - sym->next = f->symtab[hash]; - f->symtab[hash] = sym; - sym->ksymidx = -1; - - if (ELFW(ST_BIND)(info) == STB_LOCAL && symidx != -1) { - if (symidx >= f->local_symtab_size) - error("local symbol %s with index %ld exceeds local_symtab_size %ld", - name, (long) symidx, (long) f->local_symtab_size); - else - f->local_symtab[symidx] = sym; - } - -found: - sym->name = name; - sym->value = value; - sym->size = size; - sym->secidx = secidx; - sym->info = info; - sym->r_type = 0; /* should be R_arch_NONE for all arch */ - - return sym; -} - -struct obj_symbol * -obj_find_symbol (struct obj_file *f, const char *name) -{ - struct obj_symbol *sym; - unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS; - - for (sym = f->symtab[hash]; sym; sym = sym->next) - if (f->symbol_cmp(sym->name, name) == 0) - return sym; - - return NULL; -} - -ElfW(Addr) -obj_symbol_final_value (struct obj_file *f, struct obj_symbol *sym) -{ - if (sym) - { - if (sym->secidx >= SHN_LORESERVE) - return sym->value; - - return sym->value + f->sections[sym->secidx]->header.sh_addr; - } - else - { - /* As a special case, a NULL sym has value zero. */ - return 0; - } -} - -struct obj_section * -obj_find_section (struct obj_file *f, const char *name) -{ - int i, n = f->header.e_shnum; - - for (i = 0; i < n; ++i) - if (strcmp(f->sections[i]->name, name) == 0) - return f->sections[i]; - - return NULL; -} - -static int -obj_load_order_prio(struct obj_section *a) -{ - unsigned long af, ac; - - 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 (!(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 - - return ac; -} - -void -obj_insert_section_load_order (struct obj_file *f, struct obj_section *sec) -{ - struct obj_section **p; - int prio = obj_load_order_prio(sec); - for (p = f->load_order_search_start; *p ; p = &(*p)->load_next) - if (obj_load_order_prio(*p) < prio) - break; - sec->load_next = *p; - *p = sec; -} - -struct obj_section * -obj_create_alloced_section (struct obj_file *f, const char *name, - unsigned long align, unsigned long size) -{ - 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 = SHF_WRITE|SHF_ALLOC; - 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_section * -obj_create_alloced_section_first (struct obj_file *f, const char *name, - unsigned long align, unsigned long size) -{ - 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 = SHF_WRITE|SHF_ALLOC; - sec->header.sh_size = size; - sec->header.sh_addralign = align; - sec->name = name; - sec->idx = newidx; - if (size) - sec->contents = xmalloc(size); - - sec->load_next = f->load_order; - f->load_order = sec; - if (f->load_order_search_start == &f->load_order) - f->load_order_search_start = &sec->load_next; - - return sec; -} - -void * -obj_extend_section (struct obj_section *sec, unsigned long more) -{ - unsigned long oldsize = sec->header.sh_size; - sec->contents = xrealloc(sec->contents, sec->header.sh_size += more); - return sec->contents + oldsize; -} - -/* Convert an object pointer (address) to a native pointer and vice versa. - * It gets interesting when the object has 64 bit pointers but modutils - * is running 32 bit. This is nasty code but it stops the compiler giving - * spurious warning messages. "I know what I am doing" ... - */ - -void * -obj_addr_to_native_ptr (ElfW(Addr) addr) -{ - unsigned int convert = (sizeof(void *) << 8) + sizeof(addr); /* to, from */ - union obj_ptr_4 p4; - union obj_ptr_8 p8; - switch (convert) { - case 0x0404: - p4.addr = addr; - return(p4.ptr); - break; - case 0x0408: - p4.addr = addr; - if (p4.addr != addr) { - error("obj_addr_to_native_ptr truncation %" tgt_long_fmt "x", - (tgt_long) addr); - exit(1); - } - return(p4.ptr); - break; - case 0x0804: - p8.addr = addr; - return(p8.ptr); - break; - case 0x0808: - p8.addr = addr; - return(p8.ptr); - break; - default: - error("obj_addr_to_native_ptr unknown conversion 0x%04x", convert); - exit(1); - } -} - -ElfW(Addr) -obj_native_ptr_to_addr (void *ptr) -{ - unsigned int convert = (sizeof(ElfW(Addr)) << 8) + sizeof(ptr); /* to, from */ - union obj_ptr_4 p4; - union obj_ptr_8 p8; - switch (convert) { - case 0x0404: - p4.ptr = ptr; - return(p4.addr); - break; - case 0x0408: - p8.ptr = ptr; - p4.addr = p8.addr; - if (p4.addr != p8.addr) { - error("obj_native_ptr_to_addr truncation %" tgt_long_fmt "x", - (tgt_long) p8.addr); - exit(1); - } - return(p4.addr); - break; - case 0x0804: - p4.ptr = ptr; - return(p4.addr); /* compiler expands to 8 */ - break; - case 0x0808: - p8.ptr = ptr; - return(p8.addr); - break; - default: - error("obj_native_ptr_to_addr unknown conversion 0x%04x", convert); - exit(1); - } -} diff --git a/mdk-stage1/insmod-modutils/obj/obj_hppa.c b/mdk-stage1/insmod-modutils/obj/obj_hppa.c deleted file mode 100644 index 4207e692e..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_hppa.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * PA-RISC specific support for Elf loading and relocation. - * Copyright 2000 David Huggins-Daines <dhd@linuxcare.com>, Linuxcare Inc. - * Copyright 2000 Richard Hirst <rhirst@linuxcare.com>, Linuxcare Inc. - * - * Based on the IA-64 support, which is: - * Copyright 2000 Mike Stephens <mike.stephens@intel.com> - * - * 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 <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <module.h> -#include <obj.h> -#include <util.h> -#include <modstat.h> /* For ksyms */ - - -typedef struct _hppa_stub_t -{ - struct _hppa_stub_t *next; - int offset; - int reloc_done; -} hppa_stub_t; - -typedef struct _hppa_symbol_t -{ - struct obj_symbol root; - hppa_stub_t *stub; -} hppa_symbol_t; - -typedef struct _hppa_file_t -{ - struct obj_file root; - struct obj_section *stub; - Elf32_Addr dp; -} hppa_file_t; - -/* The ABI defines various more esoteric types, but these are the only - ones we actually need. */ -enum hppa_fsel -{ - e_fsel, - e_lsel, - e_rsel, - e_lrsel, - 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) -{ - hppa_file_t *f; - f = xmalloc(sizeof(*f)); - f->stub = NULL; - return &f->root; -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - hppa_symbol_t *sym; - sym = xmalloc(sizeof(*sym)); - sym->stub = NULL; - return &sym->root; -} - -/* This is called for architecture specific sections we might need to - do special things to. */ -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; -} - -/* ================================================================= - - These functions are from libhppa.h in the GNU BFD library. - (c) 1990, 91, 92, 93, 94, 95, 96, 98, 99, 2000 - Free Software Foundation, Inc. - - ================================================================= */ - -/* The *sign_extend functions are used to assemble various bitfields - taken from an instruction and return the resulting immediate - value. */ - -static inline int -sign_extend (x, len) - int x, len; -{ - int signbit = (1 << (len - 1)); - int mask = (signbit << 1) - 1; - return ((x & mask) ^ signbit) - signbit; -} - -static inline int -low_sign_extend (x, len) - int x, len; -{ - return (x >> 1) - ((x & 1) << (len - 1)); -} - - -/* The re_assemble_* functions prepare an immediate value for - insertion into an opcode. pa-risc uses all sorts of weird bitfields - in the instruction to hold the value. */ - -static inline int -sign_unext (x, len) - int x, len; -{ - int len_ones; - - len_ones = (1 << len) - 1; - - return x & len_ones; -} - -static inline int -low_sign_unext (x, len) - int x, len; -{ - int temp; - int sign; - - sign = (x >> (len-1)) & 1; - - temp = sign_unext (x, len-1); - - return (temp << 1) | sign; -} - -static inline int -re_assemble_3 (as3) - int as3; -{ - return (( (as3 & 4) << (13-2)) - | ((as3 & 3) << (13+1))); -} - -static inline int -re_assemble_12 (as12) - int as12; -{ - return (( (as12 & 0x800) >> 11) - | ((as12 & 0x400) >> (10 - 2)) - | ((as12 & 0x3ff) << (1 + 2))); -} - -static inline int -re_assemble_14 (as14) - int as14; -{ - return (( (as14 & 0x1fff) << 1) - | ((as14 & 0x2000) >> 13)); -} - -static inline int -re_assemble_16 (as16) - int as16; -{ - int s, t; - - /* Unusual 16-bit encoding, for wide mode only. */ - t = (as16 << 1) & 0xffff; - s = (as16 & 0x8000); - return (t ^ s ^ (s >> 1)) | (s >> 15); -} - -static inline int -re_assemble_17 (as17) - int as17; -{ - return (( (as17 & 0x10000) >> 16) - | ((as17 & 0x0f800) << (16 - 11)) - | ((as17 & 0x00400) >> (10 - 2)) - | ((as17 & 0x003ff) << (1 + 2))); -} - -static inline int -re_assemble_21 (as21) - int as21; -{ - return (( (as21 & 0x100000) >> 20) - | ((as21 & 0x0ffe00) >> 8) - | ((as21 & 0x000180) << 7) - | ((as21 & 0x00007c) << 14) - | ((as21 & 0x000003) << 12)); -} - -static inline int -re_assemble_22 (as22) - int as22; -{ - return (( (as22 & 0x200000) >> 21) - | ((as22 & 0x1f0000) << (21 - 16)) - | ((as22 & 0x00f800) << (16 - 11)) - | ((as22 & 0x000400) >> (10 - 2)) - | ((as22 & 0x0003ff) << (1 + 2))); -} - - -/* Handle field selectors for PA instructions. - The L and R (and LS, RS etc.) selectors are used in pairs to form a - full 32 bit address. eg. - - LDIL L'start,%r1 ; put left part into r1 - LDW R'start(%r1),%r2 ; add r1 and right part to form address - - This function returns sign extended values in all cases. -*/ - -static inline unsigned int -hppa_field_adjust (value, addend, r_field) - unsigned int value; - int addend; - enum hppa_fsel r_field; -{ - unsigned int sym_val; - - sym_val = value - addend; - switch (r_field) - { - case e_fsel: - /* F: No change. */ - break; - - case e_lsel: - /* L: Select top 21 bits. */ - value = value >> 11; - break; - - case e_rsel: - /* R: Select bottom 11 bits. */ - value = value & 0x7ff; - break; - - case e_lrsel: - /* LR: L with rounding of the addend to nearest 8k. */ - value = sym_val + ((addend + 0x1000) & -0x2000); - value = value >> 11; - break; - - case e_rrsel: - /* RR: R with rounding of the addend to nearest 8k. - We need to return a value such that 2048 * LR'x + RR'x == x - ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800)) - . = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000)) - . = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000) */ - value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000); - break; - - default: - abort(); - } - return value; -} - -/* Insert VALUE into INSN using R_FORMAT to determine exactly what - bits to change. */ - -static inline int -hppa_rebuild_insn (insn, value, r_format) - int insn; - int value; - int r_format; -{ - switch (r_format) - { - case 11: - return (insn & ~ 0x7ff) | low_sign_unext (value, 11); - - case 12: - return (insn & ~ 0x1ffd) | re_assemble_12 (value); - - - case 10: - return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8); - - case -11: - return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4); - - case 14: - return (insn & ~ 0x3fff) | re_assemble_14 (value); - - - case -10: - return (insn & ~ 0xfff1) | re_assemble_16 (value & -8); - - case -16: - return (insn & ~ 0xfff9) | re_assemble_16 (value & -4); - - case 16: - return (insn & ~ 0xffff) | re_assemble_16 (value); - - - case 17: - return (insn & ~ 0x1f1ffd) | re_assemble_17 (value); - - case 21: - return (insn & ~ 0x1fffff) | re_assemble_21 (value); - - case 22: - return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value); - - case 32: - return value; - - default: - abort (); - } - return insn; -} - -/* ==================================================================== - - End of functions from GNU BFD. - - ==================================================================== */ - -/* This is where we get the opportunity to create any extra dynamic - sections we might need. In our case we do not need a GOT because - our code is not PIC, but we do need to create a stub section. - - 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 - DPREL refs in the module to use that same dp value. - All PCREL17F 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 - 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. - */ - -#define LDIL_R1 0x20200000 /* ldil L'XXX,%r1 */ -#define BE_N_SR4_R1 0xe0202002 /* be,n R'XXX(%sr4,%r1) */ - -#define STUB_SIZE 8 - -int -arch_create_got(struct obj_file *f) -{ - hppa_file_t *hfile = (hppa_file_t *)f; - int i, n; - int stub_offset = 0; - - /* Create stub section. - * XXX set flags, see obj_ia64.c - */ - hfile->stub = obj_create_alloced_section(f, ".stub", STUB_SIZE, 0); - - /* Actually this is a lot like check_relocs() in a BFD backend. We - walk all sections and all their relocations and look for ones - that need special treatment. */ - n = hfile->root.header.e_shnum; - for (i = 0; i < n; ++i) - { - struct obj_section *relsec, *symsec, *strsec; - Elf32_Rela *rel, *relend; - Elf32_Sym *symtab; - char const *strtab; - - relsec = hfile->root.sections[i]; - if (relsec->header.sh_type != SHT_RELA) - continue; - - symsec = hfile->root.sections[relsec->header.sh_link]; - strsec = hfile->root.sections[symsec->header.sh_link]; - - rel = (Elf32_Rela *)relsec->contents; - relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela)); - symtab = (Elf32_Sym *)symsec->contents; - strtab = (char const *)strsec->contents; - - for (; rel < relend; rel++) - { - int need_stub = 0; - - switch (ELF32_R_TYPE(rel->r_info)) - { - default: - continue; - - case R_PARISC_PCREL17F: - 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); - } - local = hsym->root.secidx <= SHN_HIRESERVE; - - if (need_stub) - { - hppa_stub_t *stub; - - if (hsym->stub == NULL) - { - stub = (hppa_stub_t *) xmalloc(sizeof(hppa_stub_t)); - stub->offset = stub_offset; - stub->reloc_done = 0; - hsym->stub = stub; - stub_offset += STUB_SIZE; - need_stub = 0; - } - } - } - } - } - if (stub_offset) - { - hfile->stub->contents = xmalloc(stub_offset); - hfile->stub->header.sh_size = stub_offset; - } - return 1; -} - - -enum obj_reloc -arch_apply_relocation(struct obj_file *f, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - Elf32_Rela *rel, - Elf32_Addr v) -{ - hppa_file_t *hfile = (hppa_file_t *) f; - hppa_symbol_t *hsym = (hppa_symbol_t *) sym; - - Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset); - Elf32_Addr dot = (targsec->header.sh_addr + rel->r_offset) & ~0x03; - Elf32_Addr dp = hfile->dp; - Elf32_Word r_info = ELF32_R_TYPE(rel->r_info); - - enum obj_reloc ret = obj_reloc_ok; - enum hppa_fsel fsel = e_fsel; /* Avoid compiler warning */ - unsigned int r_format; - - /* Fix up the value, and determine whether we can handle this - relocation. */ - switch (r_info) - { - case R_PARISC_PLABEL32: - case R_PARISC_DIR32: - case R_PARISC_DIR21L: - case R_PARISC_DIR14R: - /* Easy. */ - break; - - case R_PARISC_DPREL21L: - case R_PARISC_DPREL14R: - v -= dp; - break; - - case R_PARISC_PCREL17F: - /* Find an import stub. */ - assert(hsym->stub != NULL); - assert(hfile->stub != NULL); - /* XXX Optimise. We may not need a stub for short branches */ - if (!hsym->stub->reloc_done) { - /* Need to create the .stub entry */ - Elf32_Addr *pstub, stubv; - - pstub = (Elf32_Addr *)(hfile->stub->contents + hsym->stub->offset); - pstub[0] = LDIL_R1; - pstub[1] = BE_N_SR4_R1; - stubv = hppa_field_adjust(v, rel->r_addend, e_lrsel); - pstub[0] = hppa_rebuild_insn(pstub[0], stubv, 21); - stubv = hppa_field_adjust(v, rel->r_addend, e_rrsel); - stubv >>= 2; /* Branch; divide by 4 */ - pstub[1] = hppa_rebuild_insn(pstub[1], stubv, 17); - hsym->stub->reloc_done = 1; - } - v = hsym->stub->offset + hfile->stub->header.sh_addr; - break; - - default: - return obj_reloc_unhandled; - } - - /* Find the field selector. */ - switch (r_info) - { - case R_PARISC_DIR32: - case R_PARISC_PLABEL32: - case R_PARISC_PCREL17F: - fsel = e_fsel; - break; - - case R_PARISC_DPREL21L: - case R_PARISC_DIR21L: - fsel = e_lrsel; - break; - - case R_PARISC_DPREL14R: - case R_PARISC_DIR14R: - fsel = e_rrsel; - break; - } - - v = hppa_field_adjust(v, rel->r_addend, fsel); - - switch (r_info) - { - case R_PARISC_PCREL17F: - case R_PARISC_PCREL17R: - case R_PARISC_PCREL22F: - v = v - dot - 8; - case R_PARISC_DIR17F: - case R_PARISC_DIR17R: - /* This is a branch. Divide the offset by four. */ - v >>= 2; - break; - default: - break; - } - - /* Find the format. */ - switch (r_info) - { - case R_PARISC_DIR32: - case R_PARISC_PLABEL32: - r_format = 32; - break; - - case R_PARISC_DPREL21L: - case R_PARISC_DIR21L: - r_format = 21; - break; - - case R_PARISC_PCREL17F: - r_format = 17; - break; - - case R_PARISC_DPREL14R: - case R_PARISC_DIR14R: - r_format = 14; - break; - - default: - abort(); - } - - *loc = hppa_rebuild_insn(*loc, v, r_format); - - return ret; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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 *f, struct obj_section *sec) -{ - struct module_symbol *s; - int i; - hppa_file_t *hfile = (hppa_file_t *)f; - - /* Initialise dp to the kernels dp (symbol data_start) - */ - for (i = 0, s = ksyms; i < nksyms; i++, s++) - if (!strcmp((char *)s->name, "data_start")) - break; - if (i >= nksyms) { - error("Cannot initialise dp, 'data_start' not found\n"); - return 1; - } - hfile->dp = s->value; - - return 0; -} - diff --git a/mdk-stage1/insmod-modutils/obj/obj_hppa64.c b/mdk-stage1/insmod-modutils/obj/obj_hppa64.c deleted file mode 100644 index fe32911ff..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_hppa64.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * hppa parisc64 specific support for Elf loading and relocation. - * Copyright 2000 Richard Hirst <rhirst@linuxcare.com>, Linuxcare Inc. - * - * Based on ia64 specific support which was - * Copyright 2000 Mike Stephens <mike.stephens@intel.com> - * - * 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 <stdlib.h> - -#include <module.h> -#include <obj.h> -#include <util.h> - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE ~FALSE -#endif - -/*======================================================================*/ - -typedef struct _hppa64_opd_t -{ - int offset; - int reloc_done; -} hppa64_opd_t; - -typedef struct _hppa64_stub_t -{ - struct _hppa64_stub_t *next; - Elf64_Addr addend; - int offset; - int reloc_done; -} hppa64_stub_t; - -typedef struct _hppa64_got_t -{ - struct _hppa64_got_t *next; - Elf64_Addr addend; - int offset; - int reloc_done; -} hppa64_got_t; - -typedef struct _hppa64_symbol_t -{ - struct obj_symbol root; - hppa64_got_t *gotent; - hppa64_opd_t *opdent; - hppa64_stub_t *stubent; -} hppa64_symbol_t; - -typedef struct _hppa64_file_t -{ - struct obj_file root; - struct obj_section *got; - struct obj_section *opd; - struct obj_section *stub; - Elf64_Addr gp; - Elf64_Addr text; - Elf64_Addr data; - Elf64_Addr bss; -} hppa64_file_t; - -/* - * XXX This stub assumes it can reach the .got entry with a +/- 8K offset - * from dp. Perhaps we should use a .plt for these entries to give a - * greater chance of that being true. - * - * 53 7b 00 00 ldd 0(dp),dp - * R_PARISC_LTOFF14R <.got entry offset from dp> - * 53 61 00 20 ldd 10(dp),r1 - * 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: - * - * 53 61 00 00 ldd 0(dp),r1 - * R_PARISC_LTOFF14R <.got entry offset from dp> - * 50 21 00 20 ldd 10(r1),r1 - * e8 20 d0 00 bve (r1) - * 08 00 02 40 nop - * - */ - -/* NOTE: to keep the code cleaner we make all stubs the same size. - */ - -#define SIZEOF_STUB 16 - -unsigned char hppa64_stub_extern[] = -{ - 0x53, 0x7b, 0x00, 0x00, - 0x53, 0x61, 0x00, 0x20, - 0xe8, 0x20, 0xd0, 0x00, - 0x53, 0x7b, 0x00, 0x30, -}; - -unsigned char hppa64_stub_millicode[] = -{ - 0x53, 0x61, 0x00, 0x00, - 0x50, 0x21, 0x00, 0x20, - 0xe8, 0x20, 0xd0, 0x00, - 0x08, 0x00, 0x02, 0x40, -}; - -/*======================================================================*/ - -enum obj_reloc -patch_14r(Elf64_Xword v64, Elf64_Word *p) -{ - Elf64_Word i = *p; - Elf64_Word v = (Elf64_Word)v64; - - if (v & 0x80000000) - v |= ~0x7ff; - else - v &= 0x7ff; - i &= ~ 0x3fff; - i |= (v & 0x1fff) << 1 | - (v & 0x2000) >> 13; - *p = i; - - return obj_reloc_ok; -} - -enum obj_reloc -patch_21l(Elf64_Xword v64, Elf64_Word *p) -{ - Elf64_Word i = *p; - Elf64_Word v = (Elf64_Word)v64; - - v &= 0xfffff800; - if (v & 0x80000000) - v += 0x800; - i &= ~ 0x1fffff; - i |= (v & 0x80000000) >> 31 | - (v & 0x7ff00000) >> 19 | - (v & 0x000c0000) >> 4 | - (v & 0x0003e000) << 3 | - (v & 0x00001800) << 1; - *p = i; - - return obj_reloc_ok; -} - - -/* All 14 bits this time... This is used to patch the .got offset in - * a stub for PCREL22F. - */ - -enum obj_reloc -patch_14r2(Elf64_Xword v64, Elf64_Word *p) -{ - Elf64_Word i = *p; - Elf64_Word v = (Elf64_Word)v64; - - if ((Elf64_Sxword)v64 > 0x1fffL || - (Elf64_Sxword)v64 < -0x2000L) - return obj_reloc_overflow; - i &= ~ 0x3fff; - i |= (v & 0x2000) >> 13 | - (v & 0x1fff) << 1; - *p = i; - - return obj_reloc_ok; -} - - -enum obj_reloc -patch_22f(Elf64_Xword v64, Elf64_Word *p) -{ - Elf64_Word i = *p; - Elf64_Word v = (Elf64_Word)v64; - - if ((Elf64_Sxword)v64 > 0x800000-1 || - (Elf64_Sxword)v64 < -0x800000) - return obj_reloc_overflow; - - i &= ~ 0x03ff1ffd; - i |= (v & 0x00800000) >> 23 | - (v & 0x007c0000) << 3 | - (v & 0x0003e000) << 3 | - (v & 0x00001000) >> 10 | - (v & 0x00000ffc) << 1; - *p = i; - - return obj_reloc_ok; -} - - -struct obj_section * -obj_hppa64_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) -{ - hppa64_file_t *f; - f = xmalloc(sizeof(*f)); - f->got = NULL; - f->opd = NULL; - f->stub = NULL; - return &f->root; -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - hppa64_symbol_t *sym; - sym = xmalloc(sizeof(*sym)); - sym->gotent = NULL; - sym->opdent = NULL; - sym->stubent = NULL; - return &sym->root; -} - -/* This may not be needed, but does no harm (copied from ia64). - */ - -int -arch_load_proc_section(struct obj_section *sec, int fp) -{ - switch (sec->header.sh_type) - { - case SHT_PARISC_EXT : - sec->contents = NULL; - break; - - case SHT_PARISC_UNWIND : - if (sec->header.sh_size > 0) - { - sec->contents = xmalloc(sec->header.sh_size); - gzf_lseek(fp, sec->header.sh_offset, SEEK_SET); - if (gzf_read(fp, sec->contents, sec->header.sh_size) != sec->header.sh_size) - { - error("error reading ELF section data: %m"); - return -1; - } - } - else - sec->contents = NULL; - break; - default: - error("Unknown section header type: %08x", sec->header.sh_type); - return -1; - } - return 0; -} - -int -arch_create_got(struct obj_file *f) -{ - hppa64_file_t *hfile = (hppa64_file_t *)f; - int i; - int n; - int got_offset = 0; - int opd_offset = 64; - int stub_offset = 0; - - n = hfile->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 = hfile->root.sections[i]; - if (relsec->header.sh_type != SHT_RELA) - continue; - - symsec = hfile->root.sections[relsec->header.sh_link]; - strsec = hfile->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) - { - int need_got = FALSE; - int need_opd = FALSE; - int need_stub = FALSE; - - switch (ELF64_R_TYPE(rel->r_info)) - { - default: - { - unsigned r_info = ELF64_R_TYPE(rel->r_info); - printf("r_info 0x%x not handled\n", r_info); - } - continue; - case R_PARISC_LTOFF14R: - case R_PARISC_LTOFF21L: - /* These are simple indirect references to symbols through the - * DLT. We need to create a DLT entry for any symbols which - * appears in a DLTIND relocation. - */ - need_got = TRUE; - break; - case R_PARISC_PCREL22F: - /* These are function calls. Depending on their precise - * target we may need to make a stub for them. The stub - * uses the dlt, so we need to create dlt entries for - * these symbols too. - */ - need_got = TRUE; - need_stub = TRUE; - break; - case R_PARISC_DIR64: - break; - case R_PARISC_FPTR64: - /* This is a simple OPD entry (only created for local symbols, - * see below). - */ - need_opd = TRUE; - break; - } - - 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); - } - local = isym->root.secidx <= SHN_HIRESERVE; - - if (need_stub) - { - hppa64_stub_t *stub; - - for (stub = isym->stubent; stub != NULL; stub = stub->next) - if (stub->addend == rel->r_addend) - break; - if (stub == NULL) - { - stub = (hppa64_stub_t *) xmalloc(sizeof(hppa64_stub_t)); - stub->next = isym->stubent; - stub->addend = rel->r_addend; - stub->offset = stub_offset; - stub->reloc_done = FALSE; - isym->stubent = stub; - { - stub_offset += SIZEOF_STUB; - } - need_stub = FALSE; - } - } - if (need_got) - { - hppa64_got_t *got; - - for (got = isym->gotent; got != NULL; got = got->next) - if (got->addend == rel->r_addend) - break; - if (got == NULL) - { - got = (hppa64_got_t *) xmalloc(sizeof(hppa64_got_t)); - got->next = isym->gotent; - got->addend = rel->r_addend; - got->offset = got_offset; - got->reloc_done = FALSE; - isym->gotent = got; - got_offset += 8; - need_got = FALSE; - } - } - if (need_opd && local) - { - hppa64_opd_t *opd; - - if (isym->opdent == NULL) - { - opd = (hppa64_opd_t *) xmalloc(sizeof(hppa64_opd_t)); - opd->offset = opd_offset; - opd->reloc_done = FALSE; - isym->opdent = opd; - opd_offset += 32; - need_opd = FALSE; - } - } - } - } - } - - hfile->got = obj_hppa64_create_alloced_section(f, ".got", 8, got_offset, - (SHF_ALLOC | SHF_WRITE | SHF_PARISC_SHORT)); - assert(hfile->got != NULL); - - hfile->opd = obj_hppa64_create_alloced_section(f, ".opd", 16, opd_offset, - (SHF_ALLOC | SHF_WRITE | SHF_PARISC_SHORT)); - assert(hfile->opd != NULL); - - if (stub_offset > 0) - { - hfile->stub = obj_hppa64_create_alloced_section(f, ".stub", 16, - stub_offset, (SHF_ALLOC | SHF_EXECINSTR | SHF_PARISC_SHORT)); - assert(hfile->stub != NULL); - } - - return 1; -} - - -/* This is a small simple version which seems to work fine. ia64 has - * a much more complex algorithm. We point dp at the end of the .got, - * which is the start of the .opd. - */ - -int -arch_finalize_section_address(struct obj_file *f, Elf64_Addr base) -{ - hppa64_file_t *hfile = (hppa64_file_t *)f; - int n = f->header.e_shnum; - int i; - - f->baseaddr = base; - for (i = 0; i < n; ++i) - f->sections[i]->header.sh_addr += base; - - /* Pick a sensible value for gp */ - hfile->gp = hfile->got->header.sh_addr + hfile->got->header.sh_size; - - return 1; -} - - -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) -{ - hppa64_file_t *hfile = (hppa64_file_t *) f; - hppa64_symbol_t *isym = (hppa64_symbol_t *) sym; - - Elf64_Word *loc = (Elf64_Word *)(targsec->contents + rel->r_offset); - Elf64_Addr dot = (targsec->header.sh_addr + rel->r_offset) & ~0x03; - - Elf64_Addr got = hfile->got->header.sh_addr; - Elf64_Addr gp = hfile->gp; - - Elf64_Xword r_info = ELF64_R_TYPE(rel->r_info); - - enum obj_reloc ret = obj_reloc_ok; - - switch (r_info) - { - default: - ret = obj_reloc_unhandled; - break; - case R_PARISC_LTOFF14R: - case R_PARISC_LTOFF21L: - { - hppa64_got_t *ge; - - assert(isym != NULL); - for (ge = isym->gotent; ge != NULL && ge->addend != rel->r_addend; ) - ge = ge->next; - assert(ge != NULL); - if (!ge->reloc_done) - { - ge->reloc_done = TRUE; - *(Elf64_Addr *)(hfile->got->contents + ge->offset) = v; - } - v = got + ge->offset - gp; - if (r_info == R_PARISC_LTOFF14R) - ret = patch_14r(v, loc); - else - ret = patch_21l(v, loc); - } - break; - case R_PARISC_PCREL22F: - { - hppa64_got_t *ge; - - assert(isym != NULL); - for (ge = isym->gotent; ge != NULL && ge->addend != rel->r_addend; ) - ge = ge->next; - assert(ge != NULL); - if (!ge->reloc_done) - { - ge->reloc_done = TRUE; - *(Elf64_Addr *)(hfile->got->contents + ge->offset) = v; - } - if ((isym->root.secidx > SHN_HIRESERVE) || - ((Elf64_Sxword) (v - dot - 8) > 0x800000-1) || - ((Elf64_Sxword) (v - dot - 8) < -0x800000)) - { - hppa64_stub_t *se; - - for (se = isym->stubent; se != NULL && se->addend != rel->r_addend; ) - se = se->next; - assert(se != NULL); - if (!se->reloc_done) - { - /* This requires that we can get from dp to the entry in +/- 8K, - * or +/- 1000 entries. patch_14r2() will check that. - * Only need these dlt entries for calls to external/far - * functions, so should probably put them in a seperate section - * before dlt and point dp at the section. Change to that - * scheme if we hit problems with big modules. - */ - unsigned char *stub; - - if (!strncmp(isym->root.name, "$$", 2)) - stub = hppa64_stub_millicode; - 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)); - } - v = hfile->stub->header.sh_addr + se->offset; - } - v = v - dot - 8; - if (ret == obj_reloc_ok) - ret = patch_22f(v, loc); - } - break; - case R_PARISC_DIR64: - { - loc[0] = v >> 32; - loc[1] = v; - } - break; - case R_PARISC_FPTR64: - { - assert(isym != NULL); - if (isym->root.secidx <= SHN_HIRESERVE) /* local */ - { - assert(isym->opdent != NULL); - if (!isym->opdent->reloc_done) - { - isym->opdent->reloc_done = TRUE; - *(Elf64_Addr *)(hfile->opd->contents + isym->opdent->offset + 16) = v; - *(Elf64_Addr *)(hfile->opd->contents + isym->opdent->offset + 24) = gp; - } - v = hfile->opd->header.sh_addr + isym->opdent->offset; - } - loc[0] = v >> 32; - loc[1] = v; - } - break; - } - return ret; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - hppa64_file_t *hfile = (hppa64_file_t *)f; - Elf64_Addr *opd = (Elf64_Addr *)(hfile->opd->contents); - - opd[0] = 0; - opd[1] = 0; - if ((opd[2] = mod->init) != 0) - { - opd[3] = hfile->gp; - mod->init = hfile->opd->header.sh_addr; - } - - opd[4] = 0; - opd[5] = 0; - if ((opd[6] = mod->cleanup) != 0) - { - opd[7] = hfile->gp; - mod->cleanup = hfile->opd->header.sh_addr + 32; - } - - return 1; -} - -/* XXX Is this relevant to parisc? */ - -int -arch_archdata (struct obj_file *f, struct obj_section *archdata_sec) -{ - hppa64_file_t *hfile = (hppa64_file_t *)f; - struct archdata { - unsigned tgt_long unw_table; - unsigned tgt_long segment_base; - unsigned tgt_long unw_start; - unsigned tgt_long unw_end; - unsigned tgt_long gp; - } *ad; - int i; - struct obj_section *sec; - - free(archdata_sec->contents); - archdata_sec->contents = xmalloc(sizeof(struct archdata)); - memset(archdata_sec->contents, 0, sizeof(struct archdata)); - archdata_sec->header.sh_size = sizeof(struct archdata); - - ad = (struct archdata *)(archdata_sec->contents); - ad->gp = hfile->gp; - ad->unw_start = 0; - ad->unw_end = 0; - ad->unw_table = 0; - ad->segment_base = f->sections[1]->header.sh_addr; - for (i = 0; i < f->header.e_shnum; ++i) - { - sec = f->sections[i]; - if (sec->header.sh_type == SHT_PARISC_UNWIND) - { - ad->unw_start = sec->header.sh_addr; - ad->unw_end = sec->header.sh_addr + sec->header.sh_size; - break; - } - } - - return 0; -} diff --git a/mdk-stage1/insmod-modutils/obj/obj_i386.c b/mdk-stage1/insmod-modutils/obj/obj_i386.c deleted file mode 100644 index 28df3448c..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_i386.c +++ /dev/null @@ -1,245 +0,0 @@ -/* i386 specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 i386_got_entry -{ - int offset; - unsigned offset_done : 1; - unsigned reloc_done : 1; -}; - -struct i386_file -{ - struct obj_file root; - struct obj_section *got; -}; - -struct i386_symbol -{ - struct obj_symbol root; - struct i386_got_entry gotent; -}; - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - struct i386_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 i386_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, - Elf32_Rel *rel, - Elf32_Addr v) -{ - struct i386_file *ifile = (struct i386_file *)f; - struct i386_symbol *isym = (struct i386_symbol *)sym; - - 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; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_386_NONE: - break; - - case R_386_32: - *loc += v; - break; - - case R_386_PLT32: - case R_386_PC32: - *loc += v - dot; - break; - - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - *loc = v; - break; - - case R_386_RELATIVE: - *loc += f->baseaddr; - break; - - case R_386_GOTPC: - assert(got != 0); - *loc += got - dot; - break; - - case R_386_GOT32: - assert(isym != NULL); - if (!isym->gotent.reloc_done) - { - isym->gotent.reloc_done = 1; - *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v; - } - *loc += isym->gotent.offset; - break; - - case R_386_GOTOFF: - assert(got != 0); - *loc += v - got; - break; - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *f) -{ - struct i386_file *ifile = (struct i386_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; - Elf32_Rel *rel, *relend; - Elf32_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 = (Elf32_Rel *)relsec->contents; - relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel)); - symtab = (Elf32_Sym *)symsec->contents; - strtab = (const char *)strsec->contents; - - for (; rel < relend; ++rel) - { - Elf32_Sym *extsym; - struct i386_symbol *intsym; - const char *name; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_386_GOTPC: - case R_386_GOTOFF: - gotneeded = 1; - default: - continue; - - case R_386_GOT32: - 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); - - 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", 4, offset); - - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_ia64.c b/mdk-stage1/insmod-modutils/obj/obj_ia64.c deleted file mode 100644 index 4f92c5d27..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_ia64.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * ia64 specific support for Elf loading and relocation. - * Copyright 2000 Mike Stephens <mike.stephens@intel.com> - * - * 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 <stdlib.h> - -#include <module.h> -#include <obj.h> -#include <util.h> - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE ~FALSE -#endif - -/*======================================================================*/ - -typedef struct _ia64_opd_t -{ - int offset; - int reloc_done; -} ia64_opd_t; - -typedef struct _ia64_plt_t -{ - struct _ia64_plt_t *next; - Elf64_Addr addend; - int text_offset; - int data_offset; - int reloc_done; -} ia64_plt_t; - -typedef struct _ia64_got_t -{ - struct _ia64_got_t *next; - Elf64_Addr addend; - int offset; - int reloc_done; -} ia64_got_t; - -typedef struct _ia64_symbol_t -{ - struct obj_symbol root; - ia64_got_t *gotent; - ia64_opd_t *opdent; - ia64_plt_t *pltent; -} ia64_symbol_t; - -typedef struct _ia64_file_t -{ - struct obj_file root; - struct obj_section *got; - struct obj_section *opd; - struct obj_section *pltt; - struct obj_section *pltd; - Elf64_Addr gp; - Elf64_Addr text; - Elf64_Addr data; - Elf64_Addr bss; -} ia64_file_t; - -/* - * aa=gp rel address of the function descriptor in the .IA_64.pltoff section - */ -unsigned char ia64_plt_local[] = -{ - 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=aa,gp;; */ - 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */ - 0x01, 0x08, 0x00, 0x84, /* mov r14=gp;; */ - 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 gp=[r15] */ - 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */ - 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */ -}; - -unsigned char ia64_plt_extern[] = -{ - 0x0b, 0x80, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r16=aa,gp;; */ - 0xf0, 0x00, 0x40, 0x30, 0x20, 0x00, /* ld8 r15=[r16] */ - 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */ - 0x0b, 0x80, 0x20, 0x1e, 0x18, 0x14, /* [MMI] ld8 r16=[r15],8;; */ - 0x10, 0x00, 0x3c, 0x30, 0x20, 0xc0, /* ld8 gp=[r15] */ - 0x00, 0x09, 0x00, 0x07, /* mov b6=r16;; */ - 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0x0 */ - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */ - 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */ -}; - -/*======================================================================*/ - -/* - * return the instruction at slot in bundle - */ -Elf64_Xword -obj_ia64_ins_extract_from_bundle(Elf64_Addr *bundle, Elf64_Xword slot) -{ - switch (slot) - { - case 0 : - return (*bundle >> 5) & 0x1ffffffffff; - - case 1 : - return (((*bundle >> 46) & 0x3ffff) | - (*(bundle + 1) << 18)) & 0x1ffffffffff; - - case 2 : - return (*(bundle + 1) >> 23) & 0x1ffffffffff; - - default: - } - return (-1); -} - -/* - * insert a instruction at slot in bundle - */ -void -obj_ia64_ins_insert_in_bundle(Elf64_Addr *bundle, Elf64_Xword slot, Elf64_Xword ins) -{ - Elf64_Xword i; - Elf64_Xword in = ins & 0x1ffffffffff; - - switch (slot) - { - case 0 : - i = *bundle & 0xffffc0000000001f; - *bundle = i | (in << 5); - break; - - case 1 : - i = *bundle & 0x00003fffffffffff; - *bundle = i | (in << 46); - - ++bundle; - i = *bundle & 0xffffffffff800000; - *bundle = i | (in >> 18); - break; - - case 2 : - ++bundle; - i = *bundle & 0x00000000007fffff; - *bundle = i | (in << 23); - break; - } -} - -/* - * add a immediate 14 value to the instruction at slot in bundle - */ -enum obj_reloc -obj_ia64_ins_imm14(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) -{ - Elf64_Xword ins; - - ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffee07f01fff; - ins |= ((v & 0x2000) << 23) | ((v & 0x1f80) << 20) | ((v & 0x007f) << 13); - obj_ia64_ins_insert_in_bundle(bundle, slot, ins); - if (((Elf64_Sxword) v > 8191) || ((Elf64_Sxword) v < -8192)) - return obj_reloc_overflow; - return obj_reloc_ok; -} - -/* - * add a immediate 22 value to the instruction at slot in bundle - */ -enum obj_reloc -obj_ia64_ins_imm22(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) -{ - Elf64_Xword ins; - - ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffe000301fff; - ins |= ((v & 0x200000) << 15) | ((v & 0x1f0000) << 6) | - ((v & 0x00ff80) << 20) | ((v & 0x00007f) << 13); - obj_ia64_ins_insert_in_bundle(bundle, slot, ins); - if (((Elf64_Sxword) v > 2097151) || ((Elf64_Sxword) v < -2097152)) - return obj_reloc_overflow; - return obj_reloc_ok; -} - -/* - * add a immediate 21 value (form 1) to the instruction at slot in bundle - */ -enum obj_reloc -obj_ia64_ins_pcrel21b(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) -{ - Elf64_Xword ins; - - ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffee00001fff; - ins |= ((v & 0x1000000) << 12) | ((v & 0x0fffff0) << 9); - obj_ia64_ins_insert_in_bundle(bundle, slot, ins); - return obj_reloc_ok; -} - -/* - * add a immediate 21 value (form 2) to the instruction at slot in bundle - */ -enum obj_reloc -obj_ia64_ins_pcrel21m(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) -{ - Elf64_Xword ins; - - ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffee000fe03f; - ins |= ((v & 0x1000000) << 12) | ((v & 0x0fff800) << 9) | - ((v & 0x00007f0) << 2); - obj_ia64_ins_insert_in_bundle(bundle, slot, ins); - return obj_reloc_ok; -} - -/* - * add a immediate 21 value (form 3) to the instruction at slot in bundle - */ -enum obj_reloc -obj_ia64_ins_pcrel21f(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) -{ - Elf64_Xword ins; - - ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffeffc00003f; - ins |= ((v & 0x1000000) << 12) | ((v & 0x0fffff0) << 2); - obj_ia64_ins_insert_in_bundle(bundle, slot, ins); - return obj_reloc_ok; -} - -/* - * add a immediate 64 value to the instruction at slot in bundle - */ -enum obj_reloc -obj_ia64_ins_imm64(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot) -{ - Elf64_Xword ins; - - assert(slot == 1); - ins = obj_ia64_ins_extract_from_bundle(bundle, slot); - ins &= 0xffffffee000101ff; - ins |= ((v & 0x8000000000000000) >> 28) | ((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)); - return obj_reloc_ok; -} - -/* - * create a plt entry - */ -enum obj_reloc -obj_ia64_generate_plt(Elf64_Addr v, - Elf64_Addr gp, - ia64_file_t *ifile, - ia64_symbol_t *isym, - ia64_plt_t *pltent) -{ - *(Elf64_Addr *)(ifile->pltd->contents + pltent->data_offset) = v; - if (isym->root.secidx <= SHN_HIRESERVE) - { - /* local entry */ - *(Elf64_Addr *)(ifile->pltd->contents + pltent->data_offset + 8) = gp; - memcpy((Elf64_Addr *)(ifile->pltt->contents + pltent->text_offset), - ia64_plt_local, sizeof(ia64_plt_local)); - } - else - { - /* external entry */ - memcpy((Elf64_Addr *)(ifile->pltt->contents + pltent->text_offset), - ia64_plt_extern, sizeof(ia64_plt_extern)); - } - return obj_ia64_ins_imm22( - (ifile->pltd->header.sh_addr + pltent->data_offset - gp), - (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; -} - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - ia64_file_t *f; - f = xmalloc(sizeof(*f)); - f->got = NULL; - f->opd = NULL; - f->pltt = NULL; - f->pltd = NULL; - return &f->root; -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - ia64_symbol_t *sym; - sym = xmalloc(sizeof(*sym)); - sym->gotent = NULL; - sym->opdent = NULL; - sym->pltent = NULL; - return &sym->root; -} - -int -arch_load_proc_section(struct obj_section *sec, int fp) -{ - switch (sec->header.sh_type) - { - case SHT_IA_64_EXT : - sec->contents = NULL; - break; - - case SHT_IA_64_UNWIND : - if (sec->header.sh_size > 0) - { - sec->contents = xmalloc(sec->header.sh_size); - gzf_lseek(fp, sec->header.sh_offset, SEEK_SET); - if (gzf_read(fp, sec->contents, sec->header.sh_size) != sec->header.sh_size) - { - error("error reading ELF section data: %m"); - return -1; - } - } - else - sec->contents = NULL; - break; - - default: - error("Unknown section header type: %08x", sec->header.sh_type); - return -1; - } - return 0; -} - -int -arch_create_got(struct obj_file *f) -{ - ia64_file_t *ifile = (ia64_file_t *)f; - int i; - int n; - int got_offset = 0; - int opd_offset = 32; - int plt_text_offset = 0; - int plt_data_offset = 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_RELA) - 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) - { - int need_got = FALSE; - int need_opd = FALSE; - int need_plt = FALSE; - - switch (ELF64_R_TYPE(rel->r_info)) - { - default: - continue; - - case R_IA64_FPTR64I : /* @fptr(sym + add), mov imm64 */ - case R_IA64_FPTR32LSB : /* @fptr(sym + add), data4 LSB */ - case R_IA64_FPTR64LSB : /* @fptr(sym + add), data8 LSB */ - need_opd = TRUE; - break; - - case R_IA64_LTOFF22 : /* @ltoff(sym + add), add imm22 */ - case R_IA64_LTOFF22X : - case R_IA64_LTOFF64I : /* @ltoff(sym + add), mov imm64 */ - need_got = TRUE; - break; - - case R_IA64_LTOFF_FPTR22 : /* @ltoff(@fptr(s+a)), imm22 */ - case R_IA64_LTOFF_FPTR64I : /* @ltoff(@fptr(s+a)), imm64 */ - case R_IA64_LTOFF_FPTR32LSB : - case R_IA64_LTOFF_FPTR64LSB : - need_got = TRUE; - need_opd = TRUE; - break; - - case R_IA64_PLTOFF22 : /* @pltoff(sym + add), add imm22 */ - case R_IA64_PLTOFF64I : /* @pltoff(sym + add), mov imm64 */ - case R_IA64_PLTOFF64LSB : /* @pltoff(sym + add), data8 LSB */ - - case R_IA64_PCREL21B : /* @pcrel(sym + add), ptb, call */ - case R_IA64_PCREL21M : /* @pcrel(sym + add), chk.s */ - case R_IA64_PCREL21F : /* @pcrel(sym + add), fchkf */ - need_plt = TRUE; - break; - } - - 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); - } - local = isym->root.secidx <= SHN_HIRESERVE; - - if (need_plt) - { - ia64_plt_t *plt; - - for (plt = isym->pltent; plt != NULL; plt = plt->next) - if (plt->addend == rel->r_addend) - break; - if (plt == NULL) - { - plt = (ia64_plt_t *) xmalloc(sizeof(ia64_plt_t)); - plt->next = isym->pltent; - plt->addend = rel->r_addend; - plt->text_offset = plt_text_offset; - plt->data_offset = plt_data_offset; - plt->reloc_done = FALSE; - isym->pltent = plt; - if (local) - { - plt_text_offset += sizeof(ia64_plt_local); - plt_data_offset += 16; - } - else - { - plt_text_offset += sizeof(ia64_plt_extern); - plt_data_offset += 8; - } - need_plt = FALSE; - } - } - if (need_got) - { - ia64_got_t *got; - - for (got = isym->gotent; got != NULL; got = got->next) - if (got->addend == rel->r_addend) - break; - if (got == NULL) - { - got = (ia64_got_t *) xmalloc(sizeof(ia64_got_t)); - got->next = isym->gotent; - got->addend = rel->r_addend; - got->offset = got_offset; - got->reloc_done = FALSE; - isym->gotent = got; - got_offset += 8; - need_got = FALSE; - } - } - if (need_opd && local) - { - ia64_opd_t *opd; - - if (isym->opdent == NULL) - { - opd = (ia64_opd_t *) xmalloc(sizeof(ia64_opd_t)); - opd->offset = opd_offset; - opd->reloc_done = FALSE; - isym->opdent = opd; - opd_offset += 16; - need_opd = FALSE; - } - } - } - } - } - - ifile->got = obj_ia64_create_alloced_section(f, ".got", 8, got_offset, - (SHF_ALLOC | 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)); - 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)); - assert(ifile->pltt != NULL); - assert(ifile->pltd != NULL); - } - - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf64_Addr base) -{ - ia64_file_t *ifile = (ia64_file_t *)f; - Elf64_Addr min_addr = (Elf64_Addr) -1; - Elf64_Addr max_addr = 0; - Elf64_Addr min_short_addr = (Elf64_Addr) -1; - Elf64_Addr max_short_addr = 0; - Elf64_Addr gp; - Elf64_Addr text = (Elf64_Addr) -1; - Elf64_Addr data = (Elf64_Addr) -1; - Elf64_Addr bss = (Elf64_Addr) -1; - int n = f->header.e_shnum; - int i; - - /* - * Finalize the addresses of the sections, find the min and max - * address of all sections marked short, and collect min and max - * address of any type, for use in selecting a nice gp. - * - * The algorithm used for selecting set the GP value was taken from - * the ld/bfd code contributed by David Mosberger-Tang <davidm@hpl.hp.com> - */ - f->baseaddr = base; - for (i = 0; i < n; ++i) - { - Elf64_Shdr *header = &f->sections[i]->header; - Elf64_Addr lo; - Elf64_Addr hi; - - header->sh_addr += base; - if (header->sh_flags & SHF_ALLOC) - { - lo = header->sh_addr; - hi = header->sh_addr + header->sh_size; - if (hi < lo) - hi = (Elf64_Addr) -1; - - if (min_addr > lo) - min_addr = lo; - if (max_addr < hi) - max_addr = hi; - if (header->sh_flags & SHF_IA_64_SHORT) - { - if (min_short_addr > lo) - min_short_addr = lo; - if (max_short_addr < hi) - max_short_addr = hi; - } - if ((header->sh_type & SHT_NOBITS) && (lo < bss)) - bss = lo; - else if ((header->sh_flags & SHF_EXECINSTR) && (lo < text)) - text = lo; - else if (lo < data) - data = lo; - } - } - /* Pick a sensible value for gp */ - - /* Start with just the address of the .got */ - gp = ifile->got->header.sh_addr; - - /* - * If it is possible to address the entire image, but we - * don't with the choice above, adjust. - */ - if ((max_addr - min_addr < 0x400000) && (max_addr - gp <= 0x200000) && - (gp - min_addr > 0x200000)) - { - gp = min_addr + 0x200000; - } - else if (max_short_addr != 0) - { - /* If we don't cover all the short data, adjust */ - if (max_short_addr - gp >= 0x200000) - gp = min_short_addr + 0x200000; - - /* If we're addressing stuff past the end, adjust back */ - if (gp > max_addr) - gp = max_addr - 0x200000 + 8; - } - - /* - * Validate whether all SHF_IA_64_SHORT sections are within - * range of the chosen GP. - */ - if (max_short_addr != 0) - { - if (max_short_addr - min_short_addr >= 0x400000) - { - error("short data segment overflowed (0x%lx >= 0x400000)", - (unsigned long)(max_short_addr - min_short_addr)); - return 0; - } - else if (((gp > min_short_addr) && (gp - min_short_addr > 0x200000)) || - ((gp < max_short_addr) && (max_short_addr - gp >= 0x200000))) - { - error("GP does not cover short data segment"); - return 0; - } - } - ifile->gp = gp; - ifile->text = text; - ifile->data = data; - ifile->bss = bss; - return 1; -} - -/* Targets can be unaligned, use memcpy instead of assignment */ -#define COPY_64LSB(loc, v) \ - do { \ - Elf64_Xword reloc = (v); \ - memcpy((void *)(loc), &reloc, 8); \ - } while(0) -#define COPY_32LSB(loc, v) \ - do { \ - Elf32_Xword reloc = (v); \ - memcpy((void *)(loc), &reloc, 4); \ - if ((v) != reloc) \ - ret = obj_reloc_overflow; \ - } while(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) -{ - ia64_file_t *ifile = (ia64_file_t *) f; - ia64_symbol_t *isym = (ia64_symbol_t *) sym; - - Elf64_Addr loc = (Elf64_Addr)(targsec->contents + rel->r_offset); - Elf64_Addr dot = (targsec->header.sh_addr + rel->r_offset) & ~0x03; - - Elf64_Addr got = ifile->got->header.sh_addr; - Elf64_Addr gp = ifile->gp; - - Elf64_Addr *bundle = (Elf64_Addr *)(loc & ~0x03); - Elf64_Xword slot = loc & 0x03; - - Elf64_Xword r_info = ELF64_R_TYPE(rel->r_info); - - enum obj_reloc ret = obj_reloc_ok; - - /* We cannot load modules compiled with -mconstant-gp */ -#ifndef EF_IA_64_CONS_GP -#define EF_IA_64_CONS_GP 0x00000040 -#endif -#ifndef EF_IA_64_NOFUNCDESC_CONS_GP -#define EF_IA_64_NOFUNCDESC_CONS_GP 0x00000080 -#endif - if (f->header.e_flags & (EF_IA_64_CONS_GP | EF_IA_64_NOFUNCDESC_CONS_GP)) - return obj_reloc_constant_gp; - - switch (r_info) - { - case R_IA64_NONE : /* none */ - case R_IA64_LDXMOV : /* Use of LTOFF22X. */ - break; - - case R_IA64_IMM14 : /* symbol + addend, add imm14 */ - ret = obj_ia64_ins_imm14(v, bundle, slot); - break; - - case R_IA64_IMM22 : /* symbol + addend, add imm22 */ - ret = obj_ia64_ins_imm22(v, bundle, slot); - break; - - case R_IA64_IMM64 : /* symbol + addend, movl imm64 */ - ret = obj_ia64_ins_imm64(v, bundle, slot); - break; - - case R_IA64_DIR32LSB : /* symbol + addend, data4 LSB */ - COPY_32LSB(loc, v); - break; - - case R_IA64_DIR64LSB : /* symbol + addend, data8 LSB */ - COPY_64LSB(loc, v); - break; - - case R_IA64_GPREL22 : /* @gprel(sym + add), add imm22 */ - v -= gp; - ret = obj_ia64_ins_imm22(v, bundle, slot); - break; - - case R_IA64_GPREL64I : /* @gprel(sym + add), mov imm64 */ - v -= gp; - ret = obj_ia64_ins_imm64(v, bundle, slot); - break; - - case R_IA64_GPREL32LSB : /* @gprel(sym + add), data4 LSB */ - COPY_32LSB(loc, v-gp); - break; - - case R_IA64_GPREL64LSB : /* @gprel(sym + add), data8 LSB */ - COPY_64LSB(loc, v-gp); - break; - - case R_IA64_LTOFF22 : /* @ltoff(sym + add), add imm22 */ - case R_IA64_LTOFF22X : /* LTOFF22, relaxable. */ - case R_IA64_LTOFF64I : /* @ltoff(sym + add), mov imm64 */ - { - ia64_got_t *ge; - - assert(isym != NULL); - for (ge = isym->gotent; ge != NULL && ge->addend != rel->r_addend; ) - ge = ge->next; - assert(ge != NULL); - if (!ge->reloc_done) - { - ge->reloc_done = TRUE; - *(Elf64_Addr *)(ifile->got->contents + ge->offset) = v; - } - v = got + ge->offset - gp; - if (r_info == R_IA64_LTOFF64I) - ret = obj_ia64_ins_imm64(v, bundle, slot); - else - ret = obj_ia64_ins_imm22(v, bundle, slot); - } - break; - - case R_IA64_PLTOFF22 : /* @pltoff(sym + add), add imm22 */ - case R_IA64_PLTOFF64I : /* @pltoff(sym + add), mov imm64 */ - case R_IA64_PLTOFF64LSB : /* @pltoff(sym + add), data8 LSB */ - { - ia64_plt_t *pe; - - assert(isym != NULL); - for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend; ) - pe = pe->next; - assert(pe != NULL); - if (!pe->reloc_done) - { - pe->reloc_done = TRUE; - ret = obj_ia64_generate_plt(v, gp, ifile, isym, pe); - } - v = ifile->pltt->header.sh_addr + pe->text_offset - gp; - switch (r_info) - { - case R_IA64_PLTOFF22 : - ret = obj_ia64_ins_imm22(v, bundle, slot); - break; - - case R_IA64_PLTOFF64I : - ret = obj_ia64_ins_imm64(v, bundle, slot); - break; - - case R_IA64_PLTOFF64LSB : - COPY_64LSB(loc, v); - break; - } - } - break; - - case R_IA64_FPTR64I : /* @fptr(sym + add), mov imm64 */ - case R_IA64_FPTR32LSB : /* @fptr(sym + add), data4 LSB */ - case R_IA64_FPTR64LSB : /* @fptr(sym + add), data8 LSB */ - assert(isym != NULL); - if (isym->root.secidx <= SHN_HIRESERVE) - { - assert(isym->opdent != NULL); - if (!isym->opdent->reloc_done) - { - isym->opdent->reloc_done = TRUE; - *(Elf64_Addr *)(ifile->opd->contents + isym->opdent->offset) = v; - *(Elf64_Addr *)(ifile->opd->contents + isym->opdent->offset + 8) = gp; - } - v = ifile->opd->header.sh_addr + isym->opdent->offset; - } - switch (r_info) - { - case R_IA64_FPTR64I : - ret = obj_ia64_ins_imm64(v, bundle, slot); - break; - - case R_IA64_FPTR32LSB : - COPY_32LSB(loc, v); - break; - - case R_IA64_FPTR64LSB : /* @fptr(sym + add), data8 LSB */ - /* Target can be unaligned */ - COPY_64LSB(loc, v); - break; - } - break; - - case R_IA64_PCREL21B : /* @pcrel(sym + add), ptb, call */ - case R_IA64_PCREL21M : /* @pcrel(sym + add), chk.s */ - case R_IA64_PCREL21F : /* @pcrel(sym + add), fchkf */ - assert(isym != NULL); - if ((isym->root.secidx > SHN_HIRESERVE) || - ((Elf64_Sxword) (v - dot) > 16777215) || - ((Elf64_Sxword) (v - dot) < -16777216)) - { - ia64_plt_t *pe; - - for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend; ) - pe = pe->next; - assert(pe != NULL); - if (!pe->reloc_done) - { - pe->reloc_done = TRUE; - ret = obj_ia64_generate_plt(v, gp, ifile, isym, pe); - } - v = ifile->pltt->header.sh_addr + pe->text_offset; - } - v -= dot; - switch (r_info) - { - case R_IA64_PCREL21B : - ret = obj_ia64_ins_pcrel21b(v, bundle, slot); - break; - - case R_IA64_PCREL21M : - ret = obj_ia64_ins_pcrel21m(v, bundle, slot); - break; - - case R_IA64_PCREL21F : - ret = obj_ia64_ins_pcrel21f(v, bundle, slot); - break; - } - break; - - case R_IA64_PCREL32LSB : /* @pcrel(sym + add), data4 LSB */ - COPY_32LSB(loc, v-dot); - break; - - case R_IA64_PCREL64LSB : /* @pcrel(sym + add), data8 LSB */ - COPY_64LSB(loc, v-dot); - break; - - case R_IA64_LTOFF_FPTR22 : /* @ltoff(@fptr(s+a)), imm22 */ - case R_IA64_LTOFF_FPTR64I : /* @ltoff(@fptr(s+a)), imm64 */ - case R_IA64_LTOFF_FPTR32LSB : /* @ltoff(@fptr(s+a)), data4 */ - case R_IA64_LTOFF_FPTR64LSB : /* @ltoff(@fptr(s+a)), data8 */ - { - ia64_got_t *ge; - - assert(isym != NULL); - if (isym->root.secidx <= SHN_HIRESERVE) - { - assert(isym->opdent != NULL); - if (!isym->opdent->reloc_done) - { - isym->opdent->reloc_done = TRUE; - *(Elf64_Addr *)(ifile->opd->contents + isym->opdent->offset) = v; - *(Elf64_Addr *)(ifile->opd->contents + isym->opdent->offset + 8) = gp; - } - v = ifile->opd->header.sh_addr + isym->opdent->offset; - } - for (ge = isym->gotent; ge != NULL && ge->addend != rel->r_addend; ) - ge = ge->next; - assert(ge != NULL); - if (!ge->reloc_done) - { - ge->reloc_done = TRUE; - *(Elf64_Addr *)(ifile->got->contents + ge->offset) = v; - } - v = got + ge->offset - gp; - switch (r_info) - { - case R_IA64_LTOFF_FPTR22 : - ret = obj_ia64_ins_imm22(v, bundle, slot); - break; - - case R_IA64_LTOFF_FPTR64I : - ret = obj_ia64_ins_imm64(v, bundle, slot); - break; - - case R_IA64_LTOFF_FPTR32LSB : - COPY_32LSB(loc, v); - break; - - case R_IA64_LTOFF_FPTR64LSB : - COPY_64LSB(loc, v); - break; - } - } - break; - - 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; - if (r_info == R_IA64_SEGREL32LSB) - COPY_32LSB(loc, v); - else - COPY_64LSB(loc, v); - break; - - case R_IA64_SECREL32LSB : /* @secrel(sym + add), data4 LSB */ - COPY_32LSB(loc, targsec->header.sh_addr - v); - break; - - case R_IA64_SECREL64LSB : /* @secrel(sym + add), data8 LSB */ - COPY_64LSB(loc, targsec->header.sh_addr - v); - break; - - /* - * We don't handle the big-endian relocates - * - * R_IA64_DIR32MSB symbol + addend, data4 MSB - * R_IA64_DIR64MSB symbol + addend, data8 MSB - * R_IA64_GPREL32MSB @gprel(sym + add), data4 MSB - * R_IA64_GPREL64MSB @gprel(sym + add), data8 MSB - * R_IA64_PLTOFF64MSB @pltoff(sym + add), data8 MSB - * R_IA64_FPTR32MSB @fptr(sym + add), data4 MSB - * R_IA64_FPTR64MSB @fptr(sym + add), data8 MSB - * R_IA64_PCREL32MSB @pcrel(sym + add), data4 MSB - * R_IA64_PCREL64MSB @pcrel(sym + add), data8 MSB - * R_IA64_SEGREL32MSB @segrel(sym + add), data4 MSB - * R_IA64_SEGREL64MSB @segrel(sym + add), data8 MSB - * R_IA64_SECREL32MSB @secrel(sym + add), data4 MSB - * R_IA64_SECREL64MSB @secrel(sym + add), data8 MSB - * R_IA64_REL32MSB data 4 + REL - * R_IA64_REL64MSB data 8 + REL - * R_IA64_LTV32MSB symbol + addend, data4 MSB - * R_IA64_LTV64MSB symbol + addend, data8 MSB - * R_IA64_IPLTMSB dynamic reloc, imported PLT, MSB - */ - default: - case R_IA64_REL32LSB : /* data 4 + REL */ - case R_IA64_REL64LSB : /* data 8 + REL */ - case R_IA64_LTV32LSB : /* symbol + addend, data4 LSB */ - case R_IA64_LTV64LSB : /* symbol + addend, data8 LSB */ - case R_IA64_IPLTLSB : /* dynamic reloc, imported PLT, LSB */ - ret = obj_reloc_unhandled; - break; - } - return ret; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - ia64_file_t *ifile = (ia64_file_t *)f; - Elf64_Addr *opd = (Elf64_Addr *)(ifile->opd->contents); - - if ((opd[0] = mod->init) != 0) - { - opd[1] = ifile->gp; - mod->init = ifile->opd->header.sh_addr; - } - - if ((opd[2] = mod->cleanup) != 0) - { - opd[3] = ifile->gp; - mod->cleanup = ifile->opd->header.sh_addr + 16; - } - - return 1; -} - -int -arch_archdata (struct obj_file *f, struct obj_section *archdata_sec) -{ - ia64_file_t *ifile = (ia64_file_t *)f; - struct archdata { - unsigned tgt_long unw_table; - unsigned tgt_long segment_base; - unsigned tgt_long unw_start; - unsigned tgt_long unw_end; - unsigned tgt_long gp; - } *ad; - int i; - struct obj_section *sec; - - free(archdata_sec->contents); - archdata_sec->contents = xmalloc(sizeof(struct archdata)); - memset(archdata_sec->contents, 0, sizeof(struct archdata)); - archdata_sec->header.sh_size = sizeof(struct archdata); - - ad = (struct archdata *)(archdata_sec->contents); - ad->gp = ifile->gp; - ad->unw_start = 0; - ad->unw_end = 0; - ad->unw_table = 0; - ad->segment_base = f->sections[1]->header.sh_addr; - for (i = 0; i < f->header.e_shnum; ++i) - { - sec = f->sections[i]; - if (sec->header.sh_type == SHT_IA_64_UNWIND) - { - ad->unw_start = sec->header.sh_addr; - ad->unw_end = sec->header.sh_addr + sec->header.sh_size; - break; - } - } - - return 0; -} diff --git a/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c b/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c deleted file mode 100644 index 8385fb892..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c +++ /dev/null @@ -1,292 +0,0 @@ -/* Build a section containing all non-stack symbols. - Copyright 2000 Keith Owens <kaos@ocs.com.au> - - 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 <stdlib.h> -#include <string.h> -#include <malloc.h> - -#include "obj.h" -#include "kallsyms.h" -#include "util.h" - -/*======================================================================*/ - -#define EXPAND_BY 4096 /* Arbitrary */ - -/* Append a string to the big list of strings */ - -static void -append_string (const char *s, char **strings, - ElfW(Word) *strings_size, ElfW(Word) *strings_left) -{ - int l = strlen(s) + 1; - while (l > *strings_left) { - *strings = xrealloc(*strings, *strings_size += EXPAND_BY); - *strings_left += EXPAND_BY; - } - memcpy((char *)*strings+*strings_size-*strings_left, s, l); - *strings_left -= l; -} - - -/* Append a symbol to the big list of symbols */ - -static void -append_symbol (const struct kallsyms_symbol *s, - struct kallsyms_symbol **symbols, - ElfW(Word) *symbols_size, ElfW(Word) *symbols_left) -{ - int l = sizeof(*s); - while (l > *symbols_left) { - *symbols = xrealloc(*symbols, *symbols_size += EXPAND_BY); - *symbols_left += EXPAND_BY; - } - memcpy((char *)*symbols+*symbols_size-*symbols_left, s, l); - *symbols_left -= l; -} - -/* qsort compare routine to sort symbols */ - -static const char *sym_strings; - -static int -symbol_compare (const void *a, const void *b) -{ - struct kallsyms_symbol *c = (struct kallsyms_symbol *) a; - struct kallsyms_symbol *d = (struct kallsyms_symbol *) b; - - if (c->symbol_addr > d->symbol_addr) - return(1); - if (c->symbol_addr < d->symbol_addr) - return(-1); - return(strcmp(sym_strings+c->name_off, sym_strings+d->name_off)); -} - - -/* Extract all symbols from the input obj_file, ignore ones that are - * no use for debugging, build an output obj_file containing only the - * kallsyms section. - * - * The kallsyms section is a bit unusual. It deliberately has no - * relocatable data, all "pointers" are represented as byte offsets - * into the the section. This means it can be stored anywhere without - * relocation problems. In particular it can be stored within a kernel - * image, it can be stored separately from the kernel image, it can be - * appended to a module just before loading, it can be stored in a - * separate area etc. - * - * Format of the kallsyms section. - * - * Header: - * Size of header. - * Total size of kallsyms data, including strings. - * Number of loaded sections. - * Offset to first section entry from start of header. - * Size of each section entry, excluding the name string. - * Number of symbols. - * Offset to first symbol entry from start of header. - * Size of each symbol entry, excluding the name string. - * - * Section entry - one per loaded section. - * Start of section[1]. - * Size of section. - * Offset to name of section, from start of strings. - * Section flags. - * - * Symbol entry - one per symbol in the input file[2]. - * Offset of section that owns this symbol, from start of section data. - * Address of symbol within the real section[1]. - * Offset to name of symbol, from start of strings. - * - * Notes: [1] This is an exception to the "represent pointers as - * offsets" rule, it is a value, not an offset. The start - * address of a section or a symbol is extracted from the - * obj_file data which may contain absolute or relocatable - * addresses. If the addresses are relocatable then the - * caller must adjust the section and/or symbol entries in - * kallsyms after relocation. - * [2] Only symbols that fall within loaded sections are stored. - */ - -int -obj_kallsyms (struct obj_file *fin, struct obj_file **fout_result) -{ - struct obj_file *fout; - int i, loaded = 0, *fin_to_allsym_map; - struct obj_section *isec, *osec; - struct kallsyms_header *a_hdr; - struct kallsyms_section *a_sec; - ElfW(Off) sec_off; - struct kallsyms_symbol *symbols = NULL, a_sym; - ElfW(Word) symbols_size = 0, symbols_left = 0; - char *strings = NULL, *p; - ElfW(Word) strings_size = 0, strings_left = 0; - ElfW(Off) file_offset; - static char strtab[] = "\000" KALLSYMS_SEC_NAME; - - /* Create the kallsyms section. */ - fout = arch_new_file(); - memset(fout, 0, sizeof(*fout)); - fout->symbol_cmp = strcmp; - fout->symbol_hash = obj_elf_hash; - fout->load_order_search_start = &fout->load_order; - - /* Copy file characteristics from input file and modify to suit */ - memcpy(&fout->header, &fin->header, sizeof(fout->header)); - fout->header.e_type = ET_REL; /* Output is relocatable */ - fout->header.e_entry = 0; /* No entry point */ - fout->header.e_phoff = 0; /* No program header */ - file_offset = sizeof(fout->header); /* Step over Elf header */ - fout->header.e_shoff = file_offset; /* Section headers next */ - fout->header.e_phentsize = 0; /* No program header */ - fout->header.e_phnum = 0; /* No program header */ - fout->header.e_shnum = KALLSYMS_IDX+1; /* Initial, strtab, kallsyms */ - fout->header.e_shstrndx = KALLSYMS_IDX-1; /* strtab */ - file_offset += fout->header.e_shentsize * fout->header.e_shnum; - - /* Populate the section data for kallsyms itself */ - fout->sections = xmalloc(sizeof(*(fout->sections))*fout->header.e_shnum); - memset(fout->sections, 0, sizeof(*(fout->sections))*fout->header.e_shnum); - - fout->sections[0] = osec = arch_new_section(); - memset(osec, 0, sizeof(*osec)); - osec->header.sh_type = SHT_NULL; - osec->header.sh_link = SHN_UNDEF; - - fout->sections[KALLSYMS_IDX-1] = osec = arch_new_section(); - memset(osec, 0, sizeof(*osec)); - osec->name = ".strtab"; - osec->header.sh_type = SHT_STRTAB; - osec->header.sh_link = SHN_UNDEF; - osec->header.sh_offset = file_offset; - osec->header.sh_size = sizeof(strtab); - osec->contents = xmalloc(sizeof(strtab)); - memcpy(osec->contents, strtab, sizeof(strtab)); - file_offset += osec->header.sh_size; - - fout->sections[KALLSYMS_IDX] = osec = arch_new_section(); - memset(osec, 0, sizeof(*osec)); - osec->name = KALLSYMS_SEC_NAME; - osec->header.sh_name = 1; /* Offset in strtab */ - osec->header.sh_type = SHT_PROGBITS; /* Load it */ - osec->header.sh_flags = SHF_ALLOC; /* Read only data */ - osec->header.sh_link = SHN_UNDEF; - osec->header.sh_addralign = sizeof(ElfW(Word)); - file_offset = (file_offset + osec->header.sh_addralign - 1) - & -(osec->header.sh_addralign); - osec->header.sh_offset = file_offset; - - /* How many loaded sections are there? */ - for (i = 0; i < fin->header.e_shnum; ++i) { - if (fin->sections[i]->header.sh_flags & SHF_ALLOC) - ++loaded; - } - - /* Initial contents, header + one entry per input section. No strings. */ - osec->header.sh_size = sizeof(*a_hdr) + loaded*sizeof(*a_sec); - a_hdr = (struct kallsyms_header *) osec->contents = - xmalloc(osec->header.sh_size); - memset(osec->contents, 0, osec->header.sh_size); - a_hdr->size = sizeof(*a_hdr); - a_hdr->sections = loaded; - a_hdr->section_off = a_hdr->size; - a_hdr->section_size = sizeof(*a_sec); - a_hdr->symbol_off = osec->header.sh_size; - a_hdr->symbol_size = sizeof(a_sym); - a_hdr->start = (ElfW(Addr))(~0); - - /* Map input section numbers to kallsyms section offsets. */ - sec_off = 0; /* Offset to first kallsyms section entry */ - fin_to_allsym_map = xmalloc(sizeof(*fin_to_allsym_map)*fin->header.e_shnum); - for (i = 0; i < fin->header.e_shnum; ++i) { - isec = fin->sections[i]; - if (isec->header.sh_flags & SHF_ALLOC) { - fin_to_allsym_map[isec->idx] = sec_off; - sec_off += a_hdr->section_size; - } - else - fin_to_allsym_map[isec->idx] = -1; /* Ignore this section */ - } - - /* Copy the loaded section data. */ - a_sec = (struct kallsyms_section *) ((char *) a_hdr + a_hdr->section_off); - for (i = 0; i < fin->header.e_shnum; ++i) { - isec = fin->sections[i]; - if (!(isec->header.sh_flags & SHF_ALLOC)) - continue; - a_sec->start = isec->header.sh_addr; - a_sec->size = isec->header.sh_size; - a_sec->flags = isec->header.sh_flags; - a_sec->name_off = strings_size - strings_left; - append_string(isec->name, &strings, &strings_size, &strings_left); - if (a_sec->start < a_hdr->start) - a_hdr->start = a_sec->start; - if (a_sec->start+a_sec->size > a_hdr->end) - a_hdr->end = a_sec->start+a_sec->size; - ++a_sec; - } - - /* Build the kallsyms symbol table from the symbol hashes. */ - for (i = 0; i < HASH_BUCKETS; ++i) { - struct obj_symbol *sym = fin->symtab[i]; - for (sym = fin->symtab[i]; sym ; sym = sym->next) { - if (!sym || sym->secidx >= fin->header.e_shnum) - continue; - if ((a_sym.section_off = fin_to_allsym_map[sym->secidx]) == -1) - continue; - if (strcmp(sym->name, "gcc2_compiled.") == 0 || - strncmp(sym->name, "__insmod_", 9) == 0) - continue; - a_sym.symbol_addr = sym->value; - if (fin->header.e_type == ET_REL) - a_sym.symbol_addr += fin->sections[sym->secidx]->header.sh_addr; - a_sym.name_off = strings_size - strings_left; - append_symbol(&a_sym, &symbols, &symbols_size, &symbols_left); - append_string(sym->name, &strings, &strings_size, &strings_left); - ++a_hdr->symbols; - } - } - free(fin_to_allsym_map); - - /* Sort the symbols into ascending order by address and name */ - sym_strings = strings; /* For symbol_compare */ - qsort((char *) symbols, (unsigned) a_hdr->symbols, - sizeof(* symbols), symbol_compare); - sym_strings = NULL; - - /* Put the lot together */ - osec->header.sh_size = a_hdr->total_size = - a_hdr->symbol_off + - a_hdr->symbols*a_hdr->symbol_size + - strings_size - strings_left; - a_hdr = (struct kallsyms_header *) osec->contents = - xrealloc(a_hdr, a_hdr->total_size); - p = (char *)a_hdr + a_hdr->symbol_off; - memcpy(p, symbols, a_hdr->symbols*a_hdr->symbol_size); - free(symbols); - p += a_hdr->symbols*a_hdr->symbol_size; - a_hdr->string_off = p - (char *)a_hdr; - memcpy(p, strings, strings_size - strings_left); - free(strings); - - *fout_result = fout; - return 0; -} diff --git a/mdk-stage1/insmod-modutils/obj/obj_load.c b/mdk-stage1/insmod-modutils/obj/obj_load.c deleted file mode 100644 index 4db20a998..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_load.c +++ /dev/null @@ -1,354 +0,0 @@ -/* Elf file reader. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - obj_free() added by Björn Ekwall <bj0rn@blox.se> March 1999 - Support for kallsyms Keith Owens <kaos@ocs.com.au> April 2000 - - 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 <alloca.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include "obj.h" -#include "util.h" - -/*======================================================================*/ - -struct obj_file * -obj_load (int fp, Elf32_Half e_type, const char *filename) -{ - struct obj_file *f; - ElfW(Shdr) *section_headers; - int shnum, i; - char *shstrtab; - - /* Read the file header. */ - - f = arch_new_file(); - memset(f, 0, sizeof(*f)); - f->symbol_cmp = strcmp; - f->symbol_hash = obj_elf_hash; - f->load_order_search_start = &f->load_order; - - 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); - return NULL; - } - - if (f->header.e_ident[EI_MAG0] != ELFMAG0 - || f->header.e_ident[EI_MAG1] != ELFMAG1 - || f->header.e_ident[EI_MAG2] != ELFMAG2 - || f->header.e_ident[EI_MAG3] != ELFMAG3) - { - error("%s is not an ELF file", filename); - return NULL; - } - if (f->header.e_ident[EI_CLASS] != ELFCLASSM - || f->header.e_ident[EI_DATA] != ELFDATAM - || f->header.e_ident[EI_VERSION] != EV_CURRENT - || !MATCH_MACHINE(f->header.e_machine)) - { - error("ELF file %s not for this architecture", filename); - return NULL; - } - if (f->header.e_type != e_type && e_type != ET_NONE) - { - switch (e_type) { - case ET_REL: - error("ELF file %s not a relocatable object", filename); - break; - case ET_EXEC: - error("ELF file %s not an executable object", filename); - break; - default: - error("ELF file %s has wrong type, expecting %d got %d", - filename, e_type, f->header.e_type); - break; - } - return NULL; - } - - /* Read the section headers. */ - - if (f->header.e_shentsize != sizeof(ElfW(Shdr))) - { - error("section header size mismatch %s: %lu != %lu", - filename, - (unsigned long)f->header.e_shentsize, - (unsigned long)sizeof(ElfW(Shdr))); - return NULL; - } - - shnum = f->header.e_shnum; - f->sections = xmalloc(sizeof(struct obj_section *) * shnum); - memset(f->sections, 0, sizeof(struct obj_section *) * shnum); - - section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); - gzf_lseek(fp, f->header.e_shoff, SEEK_SET); - if (gzf_read(fp, section_headers, sizeof(ElfW(Shdr))*shnum) != sizeof(ElfW(Shdr))*shnum) - { - error("error reading ELF section headers %s: %m", filename); - return NULL; - } - - /* Read the section data. */ - - for (i = 0; i < shnum; ++i) - { - struct obj_section *sec; - - f->sections[i] = sec = arch_new_section(); - memset(sec, 0, sizeof(*sec)); - - sec->header = section_headers[i]; - sec->idx = i; - - switch (sec->header.sh_type) - { - case SHT_NULL: - case SHT_NOTE: - case SHT_NOBITS: - /* ignore */ - break; - - case SHT_PROGBITS: - case SHT_SYMTAB: - case SHT_STRTAB: - case SHT_RELM: - if (sec->header.sh_size > 0) - { - sec->contents = xmalloc(sec->header.sh_size); - gzf_lseek(fp, sec->header.sh_offset, SEEK_SET); - if (gzf_read(fp, sec->contents, sec->header.sh_size) != sec->header.sh_size) - { - error("error reading ELF section data %s: %m", filename); - return NULL; - } - } - else - sec->contents = NULL; - break; - -#if SHT_RELM == SHT_REL - case SHT_RELA: - if (sec->header.sh_size) { - error("RELA relocations not supported on this architecture %s", filename); - return NULL; - } - break; -#else - case SHT_REL: - if (sec->header.sh_size) { - error("REL relocations not supported on this architecture %s", filename); - return NULL; - } - break; -#endif - - default: - if (sec->header.sh_type >= SHT_LOPROC) - { - if (arch_load_proc_section(sec, fp) < 0) - return NULL; - break; - } - - error("can't handle sections of type %ld %s", - (long)sec->header.sh_type, filename); - return NULL; - } - } - - /* Do what sort of interpretation as needed by each section. */ - - shstrtab = f->sections[f->header.e_shstrndx]->contents; - - for (i = 0; i < shnum; ++i) - { - struct obj_section *sec = f->sections[i]; - sec->name = shstrtab + sec->header.sh_name; - } - - for (i = 0; i < shnum; ++i) - { - struct obj_section *sec = f->sections[i]; - - /* .modinfo and .modstring should be contents only but gcc has no - * attribute for that. The kernel may have marked these sections as - * ALLOC, ignore the allocate bit. - */ - if (strcmp(sec->name, ".modinfo") == 0 || - strcmp(sec->name, ".modstring") == 0) - sec->header.sh_flags &= ~SHF_ALLOC; - - if (sec->header.sh_flags & SHF_ALLOC) - obj_insert_section_load_order(f, sec); - - switch (sec->header.sh_type) - { - case SHT_SYMTAB: - { - unsigned long nsym, j; - char *strtab; - ElfW(Sym) *sym; - - if (sec->header.sh_entsize != sizeof(ElfW(Sym))) - { - error("symbol size mismatch %s: %lu != %lu", - filename, - (unsigned long)sec->header.sh_entsize, - (unsigned long)sizeof(ElfW(Sym))); - return NULL; - } - - nsym = sec->header.sh_size / sizeof(ElfW(Sym)); - strtab = f->sections[sec->header.sh_link]->contents; - sym = (ElfW(Sym) *) sec->contents; - - /* Allocate space for a table of local symbols. */ - j = f->local_symtab_size = sec->header.sh_info; - f->local_symtab = xmalloc(j *= sizeof(struct obj_symbol *)); - memset(f->local_symtab, 0, j); - - /* Insert all symbols into the hash table. */ - for (j = 1, ++sym; j < nsym; ++j, ++sym) - { - const char *name; - if (sym->st_name) - name = strtab+sym->st_name; - else - name = f->sections[sym->st_shndx]->name; - - obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, - sym->st_value, sym->st_size); - - } - } - break; - } - } - - /* second pass to add relocation data to symbols */ - for (i = 0; i < shnum; ++i) - { - struct obj_section *sec = f->sections[i]; - switch (sec->header.sh_type) - { - case SHT_RELM: - { - unsigned long nrel, j; - ElfW(RelM) *rel; - struct obj_section *symtab; - char *strtab; - if (sec->header.sh_entsize != sizeof(ElfW(RelM))) - { - error("relocation entry size mismatch %s: %lu != %lu", - filename, - (unsigned long)sec->header.sh_entsize, - (unsigned long)sizeof(ElfW(RelM))); - return NULL; - } - - nrel = sec->header.sh_size / sizeof(ElfW(RelM)); - rel = (ElfW(RelM) *) sec->contents; - symtab = f->sections[sec->header.sh_link]; - 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 - { - /* 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); - } - intsym->r_type = ELFW(R_TYPE)(rel->r_info); - } - } - } - break; - } - } - - f->filename = xstrdup(filename); - - return f; -} - -void obj_free(struct obj_file *f) -{ - struct obj_section *sec; - struct obj_symbol *sym; - struct obj_symbol *next; - int i; - int n; - - if (f->sections) { - n = f->header.e_shnum; - for (i = 0; i < n; ++i) { - if ((sec = f->sections[i]) != NULL) { - if (sec->contents) - free(sec->contents); - free(sec); - } - } - free(f->sections); - } - - for (i = 0; i < HASH_BUCKETS; ++i) { - for (sym = f->symtab[i]; sym; sym = next) { - next = sym->next; - free(sym); - } - } - - if (f->local_symtab) - free(f->local_symtab); - - if (f->filename) - free((char *)(f->filename)); - - if (f->persist) - free((char *)(f->persist)); - - free(f); -} diff --git a/mdk-stage1/insmod-modutils/obj/obj_m68k.c b/mdk-stage1/insmod-modutils/obj/obj_m68k.c deleted file mode 100644 index cb485aed7..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_m68k.c +++ /dev/null @@ -1,147 +0,0 @@ -/* m68k specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stddef.h> -#include <module.h> -#include <obj.h> -#include <util.h> - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - return xmalloc(sizeof(struct obj_file)); -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - return xmalloc(sizeof(struct obj_symbol)); -} - -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 *ef, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - Elf32_Rela *rel, - Elf32_Addr v) -{ - char *loc = targsec->contents + rel->r_offset; - Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_68K_NONE: - break; - - case R_68K_8: - if (v > 0xff) - ret = obj_reloc_overflow; - *(char *)loc = v; - break; - case R_68K_16: - if (v > 0xffff) - ret = obj_reloc_overflow; - *(short *)loc = v; - break; - case R_68K_32: - *(int *)loc = v; - break; - - case R_68K_PC8: - v -= dot; - if ((Elf32_Sword)v > 0x7f || (Elf32_Sword)v < -(Elf32_Sword)0x80) - ret = obj_reloc_overflow; - *(char *)loc = v; - break; - case R_68K_PC16: - v -= dot; - if ((Elf32_Sword)v > 0x7fff || (Elf32_Sword)v < -(Elf32_Sword)0x8000) - ret = obj_reloc_overflow; - *(short *)loc = v; - break; - case R_68K_PC32: - *(int *)loc = v - dot; - break; - - case R_68K_RELATIVE: - *(int *)loc += ef->baseaddr; - break; - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *ef) -{ - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_mips.c b/mdk-stage1/insmod-modutils/obj/obj_mips.c deleted file mode 100644 index c2315b659..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_mips.c +++ /dev/null @@ -1,238 +0,0 @@ -/* MIPS specific support for Elf loading and relocation. - Copyright 1997, 1998 Linux International. - Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu> - - 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 <stdlib.h> -#include <assert.h> - -#include <module.h> -#include <obj.h> -#include <util.h> - - -/*======================================================================*/ - -struct mips_hi16 -{ - struct mips_hi16 *next; - Elf32_Addr *addr; - Elf32_Addr value; -}; - -struct mips_file -{ - struct obj_file root; - struct mips_hi16 *mips_hi16_list; -}; - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - struct mips_file *mf; - - mf = xmalloc(sizeof(*mf)); - mf->mips_hi16_list = NULL; - - return (struct obj_file *) mf; -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - return xmalloc(sizeof(struct obj_symbol)); -} - -int -arch_load_proc_section(struct obj_section *sec, int fp) -{ - switch (sec->header.sh_type) - { - case SHT_MIPS_DEBUG: - case SHT_MIPS_REGINFO: - /* Actually these two sections are as useless as something can be ... */ - sec->contents = NULL; - break; - - case SHT_MIPS_LIBLIST: - case SHT_MIPS_CONFLICT: - case SHT_MIPS_GPTAB: - case SHT_MIPS_UCODE: - case SHT_MIPS_OPTIONS: - case SHT_MIPS_DWARF: - case SHT_MIPS_EVENTS: - /* These shouldn't ever be in a module file. */ - error("Unhandled section header type: %08x", sec->header.sh_type); - - default: - /* We don't even know the type. This time it might as well be a - supernova. */ - error("Unknown section header type: %08x", sec->header.sh_type); - return -1; - } - - return 0; -} - -enum obj_reloc -arch_apply_relocation (struct obj_file *f, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - Elf32_Rel *rel, - Elf32_Addr v) -{ - struct mips_file *mf = (struct mips_file *)f; - Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset); - Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; - enum obj_reloc ret = obj_reloc_ok; - - /* _gp_disp is a magic symbol for PIC which is not supported for - the kernel and loadable modules. */ - if (strcmp(sym->name, "_gp_disp") == 0) - ret = obj_reloc_unhandled; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_MIPS_NONE: - break; - - case R_MIPS_32: - *loc += v; - break; - - case R_MIPS_26: - if (v % 4) - ret = obj_reloc_dangerous; - if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000)) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) & 0x03ffffff); - break; - - case R_MIPS_HI16: - { - struct mips_hi16 *n; - - /* We cannot relocate this one now because we don't know the value - of the carry we need to add. Save the information, and let LO16 - do the actual relocation. */ - n = (struct mips_hi16 *) xmalloc (sizeof *n); - n->addr = loc; - n->value = v; - n->next = mf->mips_hi16_list; - mf->mips_hi16_list = n; - break; - } - - case R_MIPS_LO16: - { - unsigned long insnlo = *loc; - Elf32_Addr val, vallo; - - /* Sign extend the addend we extract from the lo insn. */ - vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; - - if (mf->mips_hi16_list != NULL) - { - struct mips_hi16 *l; - - l = mf->mips_hi16_list; - while (l != NULL) - { - struct mips_hi16 *next; - unsigned long insn; - - /* The value for the HI16 had best be the same. */ - assert(v == l->value); - - /* Do the HI16 relocation. Note that we actually don't - need to know anything about the LO16 itself, except where - to find the low 16 bits of the addend needed by the LO16. */ - insn = *l->addr; - val = ((insn & 0xffff) << 16) + vallo; - val += v; - - /* Account for the sign extension that will happen in the - low bits. */ - val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff; - - insn = (insn &~ 0xffff) | val; - *l->addr = insn; - - next = l->next; - free(l); - l = next; - } - - mf->mips_hi16_list = NULL; - } - - /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */ - val = v + vallo; - insnlo = (insnlo & ~0xffff) | (val & 0xffff); - *loc = insnlo; - break; - } - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *f) -{ - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_ppc.c b/mdk-stage1/insmod-modutils/obj/obj_ppc.c deleted file mode 100644 index 89bb8e46b..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_ppc.c +++ /dev/null @@ -1,255 +0,0 @@ -/* PowerPC specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. - - Adapted by Paul Mackerras <paulus@cs.anu.edu.au> from the - obj-sparc.c and obj-alpha.c files. - - 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 <stddef.h> -#include <module.h> -#include <obj.h> -#include <util.h> -#include <assert.h> - - -/*======================================================================*/ - -/* - * Unfortunately, the bl (branch-and-link) instruction used for - * procedure calls on the PowerPC can only reach +/- 32MB from the - * current instruction. If the module is loaded far enough away from - * the main kernel text (or other modules) that this limit is - * exceeded, we have to redirect procedure calls via a procedure - * linkage table (PLT). Each entry in the PLT contains instructions - * to put the address of the procedure in a register and jump to it. - */ - -typedef unsigned int instruction; /* a powerpc instruction (4 bytes) */ - -struct ppc_plt_entry -{ - struct ppc_plt_entry *next; - ElfW(Addr) addend; - int offset; - int inited; -}; - -struct ppc_file -{ - struct obj_file file; - struct obj_section *plt; -}; - -struct ppc_symbol -{ - struct obj_symbol sym; - struct ppc_plt_entry *plt_entries; -}; - -struct obj_file * -arch_new_file (void) -{ - struct ppc_file *f; - - f = xmalloc(sizeof(struct ppc_file)); - f->plt = NULL; - return &f->file; -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - struct ppc_symbol *p; - - p = xmalloc(sizeof(struct ppc_symbol)); - p->plt_entries = NULL; - return &p->sym; -} - -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 *ef, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - Elf32_Rela *rel, - Elf32_Addr v) -{ - Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset); - Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; - struct ppc_file *pf = (struct ppc_file *) ef; - struct ppc_symbol *psym = (struct ppc_symbol *) sym; - struct ppc_plt_entry *pe; - instruction *ip; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_PPC_ADDR16_HA: - *(unsigned short *)loc = (v + 0x8000) >> 16; - break; - - case R_PPC_ADDR16_HI: - *(unsigned short *)loc = v >> 16; - break; - - case R_PPC_ADDR16_LO: - *(unsigned short *)loc = v; - break; - - case R_PPC_REL24: - /* find the plt entry and initialize it if necessary */ - assert(psym != NULL); - for (pe = psym->plt_entries; pe != NULL && pe->addend != rel->r_addend; ) - pe = pe->next; - assert(pe != NULL); - if (!pe->inited) - { - ip = (instruction *) (pf->plt->contents + pe->offset); - ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */ - ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */ - ip[2] = 0x7d6903a6; /* mtctr r11 */ - ip[3] = 0x4e800420; /* bctr */ - pe->inited = 1; - } - - v -= dot; - if ((int)v < -0x02000000 || (int)v >= 0x02000000) - { - /* go via the plt */ - v = pf->plt->header.sh_addr + pe->offset - dot; - } - if (v & 3) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); - break; - - case R_PPC_REL32: - *loc = v - dot; - break; - - case R_PPC_ADDR32: - *loc = v; - break; - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *f) -{ - struct ppc_file *pf = (struct ppc_file *) f; - int i, offset; - struct obj_section *sec, *syms, *strs; - ElfW(Rela) *rel, *relend; - ElfW(Sym) *symtab, *extsym; - const char *strtab, *name; - struct ppc_symbol *intsym; - struct ppc_plt_entry *pe; - - offset = 0; - for (i = 0; i < f->header.e_shnum; ++i) - { - sec = f->sections[i]; - if (sec->header.sh_type != SHT_RELM) - continue; - syms = f->sections[sec->header.sh_link]; - strs = f->sections[syms->header.sh_link]; - - rel = (ElfW(RelM) *) sec->contents; - relend = rel + (sec->header.sh_size / sizeof(ElfW(RelM))); - symtab = (ElfW(Sym) *) syms->contents; - strtab = (const char *) strs->contents; - - for (; rel < relend; ++rel) - { - 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); - - for (pe = intsym->plt_entries; pe != NULL; pe = pe->next) - if (pe->addend == rel->r_addend) - break; - if (pe == NULL) - { - pe = xmalloc(sizeof(struct ppc_plt_entry)); - pe->next = intsym->plt_entries; - pe->addend = rel->r_addend; - pe->offset = offset; - pe->inited = 0; - intsym->plt_entries = pe; - offset += 16; - } - } - } - - pf->plt = obj_create_alloced_section(f, ".plt", 16, offset); - - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_reloc.c b/mdk-stage1/insmod-modutils/obj/obj_reloc.c deleted file mode 100644 index f5f2de90d..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_reloc.c +++ /dev/null @@ -1,435 +0,0 @@ -/* Elf relocation routines. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <alloca.h> - -#include <obj.h> -#include <util.h> - -/*======================================================================*/ - -int -obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, - const char *string) -{ - struct obj_string_patch_struct *p; - struct obj_section *strsec; - size_t len = strlen(string)+1; - char *loc; - - p = xmalloc(sizeof(*p)); - p->next = f->string_patches; - p->reloc_secidx = secidx; - p->reloc_offset = offset; - f->string_patches = p; - - strsec = obj_find_section(f, ".kstrtab"); - if (strsec == NULL) - { - strsec = obj_create_alloced_section(f, ".kstrtab", 1, len); - p->string_offset = 0; - loc = strsec->contents; - } - else - { - p->string_offset = strsec->header.sh_size; - loc = obj_extend_section(strsec, len); - } - memcpy(loc, string, len); - - return 1; -} - -int -obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, - struct obj_symbol *sym) -{ - struct obj_symbol_patch_struct *p; - - p = xmalloc(sizeof(*p)); - p->next = f->symbol_patches; - p->reloc_secidx = secidx; - p->reloc_offset = offset; - p->sym = sym; - f->symbol_patches = p; - - return 1; -} - -int -obj_check_undefineds(struct obj_file *f, int quiet) -{ - unsigned long i; - int ret = 1; - - for (i = 0; i < HASH_BUCKETS; ++i) - { - struct obj_symbol *sym; - for (sym = f->symtab[i]; sym ; sym = sym->next) - if (sym->secidx == SHN_UNDEF) - { - if (ELFW(ST_BIND)(sym->info) == STB_WEAK) - { - sym->secidx = SHN_ABS; - sym->value = 0; - } - else if (sym->r_type) /* assumes R_arch_NONE is 0 on all arch */ - { - if (!quiet) - error("unresolved symbol %s", sym->name); - ret = 0; - } - } - } - - return ret; -} - -void -obj_clear_undefineds(struct obj_file *f) -{ - unsigned long i; - struct obj_symbol *sym; - for (i = 0; i < HASH_BUCKETS; ++i) - { - for (sym = f->symtab[i]; sym ; sym = sym->next) - if (sym->secidx == SHN_UNDEF) - { - sym->secidx = SHN_ABS; - sym->value = 0; - } - } -} - -void -obj_allocate_commons(struct obj_file *f) -{ - struct common_entry - { - struct common_entry *next; - struct obj_symbol *sym; - } *common_head = NULL; - - unsigned long i; - - for (i = 0; i < HASH_BUCKETS; ++i) - { - struct obj_symbol *sym; - for (sym = f->symtab[i]; sym ; sym = sym->next) - if (sym->secidx == SHN_COMMON) - { - /* Collect all COMMON symbols and sort them by size so as to - minimize space wasted by alignment requirements. */ - { - struct common_entry **p, *n; - for (p = &common_head; *p ; p = &(*p)->next) - if (sym->size <= (*p)->sym->size) - break; - - n = alloca(sizeof(*n)); - n->next = *p; - n->sym = sym; - *p = n; - } - } - } - - for (i = 1; i < f->local_symtab_size; ++i) - { - struct obj_symbol *sym = f->local_symtab[i]; - if (sym && sym->secidx == SHN_COMMON) - { - struct common_entry **p, *n; - for (p = &common_head; *p ; p = &(*p)->next) - if (sym == (*p)->sym) - break; - else if (sym->size < (*p)->sym->size) - { - n = alloca(sizeof(*n)); - n->next = *p; - n->sym = sym; - *p = n; - break; - } - } - } - - if (common_head) - { - /* Find the bss section. */ - for (i = 0; i < f->header.e_shnum; ++i) - if (f->sections[i]->header.sh_type == SHT_NOBITS) - break; - - /* If for some reason there hadn't been one, create one. */ - if (i == f->header.e_shnum) - { - struct obj_section *sec; - - f->sections = xrealloc(f->sections, (i+1) * sizeof(sec)); - f->sections[i] = sec = arch_new_section(); - f->header.e_shnum = i+1; - - memset(sec, 0, sizeof(*sec)); - sec->header.sh_type = SHT_PROGBITS; - sec->header.sh_flags = SHF_WRITE|SHF_ALLOC; - sec->name = ".bss"; - sec->idx = i; - } - - /* Allocate the COMMONS. */ - { - ElfW(Addr) bss_size = f->sections[i]->header.sh_size; - ElfW(Addr) max_align = f->sections[i]->header.sh_addralign; - struct common_entry *c; - - for (c = common_head; c ; c = c->next) - { - ElfW(Addr) align = c->sym->value; - - if (align > max_align) - max_align = align; - if (bss_size & (align - 1)) - bss_size = (bss_size | (align - 1)) + 1; - - c->sym->secidx = i; - c->sym->value = bss_size; - - bss_size += c->sym->size; - } - - f->sections[i]->header.sh_size = bss_size; - f->sections[i]->header.sh_addralign = max_align; - } - } - - /* For the sake of patch relocation and parameter initialization, - allocate zeroed data for NOBITS sections now. Note that after - this we cannot assume NOBITS are really empty. */ - for (i = 0; i < f->header.e_shnum; ++i) - { - struct obj_section *s = f->sections[i]; - if (s->header.sh_type == SHT_NOBITS) - { - if (s->header.sh_size) - s->contents = memset(xmalloc(s->header.sh_size), - 0, s->header.sh_size); - else - s->contents = NULL; - s->header.sh_type = SHT_PROGBITS; - } - } -} - -unsigned long -obj_load_size (struct obj_file *f) -{ - unsigned long dot = 0; - struct obj_section *sec; - - /* Finalize the positions of the sections relative to one another. */ - - for (sec = f->load_order; sec ; sec = sec->load_next) - { - ElfW(Addr) align; - - align = sec->header.sh_addralign; - if (align && (dot & (align - 1))) - dot = (dot | (align - 1)) + 1; - - sec->header.sh_addr = dot; - dot += sec->header.sh_size; - } - - return dot; -} - -int -obj_relocate (struct obj_file *f, ElfW(Addr) base) -{ - int i, n = f->header.e_shnum; - int ret = 1; - - /* Finalize the addresses of the sections. */ - - arch_finalize_section_address(f, base); - - /* And iterate over all of the relocations. */ - - for (i = 0; i < n; ++i) - { - struct obj_section *relsec, *symsec, *targsec, *strsec; - ElfW(RelM) *rel, *relend; - ElfW(Sym) *symtab; - const char *strtab; - - relsec = f->sections[i]; - if (relsec->header.sh_type != SHT_RELM) - continue; - - symsec = f->sections[relsec->header.sh_link]; - targsec = f->sections[relsec->header.sh_info]; - strsec = f->sections[symsec->header.sh_link]; - - rel = (ElfW(RelM) *)relsec->contents; - relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM))); - symtab = (ElfW(Sym) *)symsec->contents; - strtab = (const char *)strsec->contents; - - for (; rel < relend; ++rel) - { - 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. */ - - symndx = ELFW(R_SYM)(rel->r_info); - if (symndx) - { - /* 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 - { - /* 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); - } - - 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 - - /* Do it! */ - switch (arch_apply_relocation(f,targsec,symsec,intsym,rel,value)) - { - case obj_reloc_ok: - break; - - case obj_reloc_overflow: - errmsg = "Relocation overflow"; - goto bad_reloc; - case obj_reloc_dangerous: - errmsg = "Dangerous relocation"; - goto bad_reloc; - case obj_reloc_unhandled: - errmsg = "Unhandled relocation"; - goto bad_reloc; - case obj_reloc_constant_gp: - 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)); - } - ret = 0; - break; - } - } - } - - /* Finally, take care of the patches. */ - - if (f->string_patches) - { - struct obj_string_patch_struct *p; - struct obj_section *strsec; - ElfW(Addr) strsec_base; - strsec = obj_find_section(f, ".kstrtab"); - strsec_base = strsec->header.sh_addr; - - for (p = f->string_patches; p ; p = p->next) - { - struct obj_section *targsec = f->sections[p->reloc_secidx]; - *(ElfW(Addr) *)(targsec->contents + p->reloc_offset) - = strsec_base + p->string_offset; - } - } - - if (f->symbol_patches) - { - struct obj_symbol_patch_struct *p; - - for (p = f->symbol_patches; p; p = p->next) - { - struct obj_section *targsec = f->sections[p->reloc_secidx]; - *(ElfW(Addr) *)(targsec->contents + p->reloc_offset) - = obj_symbol_final_value(f, p->sym); - } - } - - return ret; -} - -int -obj_create_image (struct obj_file *f, char *image) -{ - struct obj_section *sec; - ElfW(Addr) base = f->baseaddr; - - for (sec = f->load_order; sec ; sec = sec->load_next) - { - char *secimg; - - if (sec->contents == 0) - continue; - - secimg = image + (sec->header.sh_addr - base); - - /* Note that we allocated data for NOBITS sections earlier. */ - memcpy(secimg, sec->contents, sec->header.sh_size); - } - - return 1; -} diff --git a/mdk-stage1/insmod-modutils/obj/obj_s390.c b/mdk-stage1/insmod-modutils/obj/obj_s390.c deleted file mode 100644 index 3da72e771..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_s390.c +++ /dev/null @@ -1,245 +0,0 @@ -/* S/390 specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 s390_got_entry -{ - int offset; - unsigned offset_done : 1; - unsigned reloc_done : 1; -}; - -struct s390_file -{ - struct obj_file root; - struct obj_section *got; -}; - -struct s390_symbol -{ - struct obj_symbol root; - struct s390_got_entry gotent; -}; - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - struct s390_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 s390_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, - Elf32_Rela *rel, - Elf32_Addr v) -{ - struct s390_file *ifile = (struct s390_file *)f; - struct s390_symbol *isym = (struct s390_symbol *)sym; - - 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; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_390_NONE: - break; - - case R_390_32: - *loc += v; - break; - - case R_390_PLT32: - case R_390_PC32: - *loc += v - dot; - break; - - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - *loc = v; - break; - - case R_390_RELATIVE: - *loc += f->baseaddr; - break; - - case R_390_GOTPC: - assert(got != 0); - *loc += got - dot; - break; - - case R_390_GOT32: - assert(isym != NULL); - if (!isym->gotent.reloc_done) - { - isym->gotent.reloc_done = 1; - *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v; - } - *loc += isym->gotent.offset; - break; - - case R_390_GOTOFF: - assert(got != 0); - *loc += v - got; - break; - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *f) -{ - struct s390_file *ifile = (struct s390_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; - Elf32_Rel *rel, *relend; - Elf32_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 = (Elf32_Rel *)relsec->contents; - relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel)); - 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)) - { - case R_390_GOTPC: - case R_390_GOTOFF: - gotneeded = 1; - default: - continue; - - case R_390_GOT32: - 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; - } - } - } - - if (offset > 0 || gotneeded) - ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset); - - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *m) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_sparc.c b/mdk-stage1/insmod-modutils/obj/obj_sparc.c deleted file mode 100644 index 1a03c9090..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_sparc.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Sparc specific support for Elf loading and relocation. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stddef.h> -#include <module.h> -#include <obj.h> -#include <util.h> - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - return xmalloc(sizeof(struct obj_file)); -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - return xmalloc(sizeof(struct obj_symbol)); -} - -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 *ef, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - Elf32_Rela *rel, - Elf32_Addr v) -{ - Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset); - Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF32_R_TYPE(rel->r_info)) - { - case R_SPARC_NONE: - break; - case R_SPARC_8: - if (v > 0xff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xff) | (v & 0xff); - break; - case R_SPARC_16: - if (v > 0xffff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xffff) | (v & 0xffff); - break; - case R_SPARC_32: - *loc = v; - break; - case R_SPARC_DISP8: - v -= dot; - if (v > 0xff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xff) | (v & 0xff); - break; - case R_SPARC_DISP16: - v -= dot; - if (v > 0xffff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xffff) | (v & 0xffff); - break; - case R_SPARC_DISP32: - v -= dot; - *loc = v; - break; - case R_SPARC_WDISP30: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x3fffffff) | (v >> 2); - break; - case R_SPARC_WDISP22: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x3fffff) | ((v >> 2) & 0x3fffff); - break; - case R_SPARC_HI22: - *loc = (*loc & ~0x3fffff) | (v >> 10); - break; - case R_SPARC_22: - if (v > 0x3fffff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x3fffff) | (v & 0x3fffff); - break; - case R_SPARC_13: - if (v > 0x1fff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x1fff) | (v & 0x1fff); - break; - case R_SPARC_LO10: - *loc = (*loc & ~0x3ff) | (v & 0x3ff); - break; - - case R_SPARC_PC10: - v -= dot; - *loc = (*loc & ~0x3ff) | (v & 0x3ff); - break; - case R_SPARC_PC22: - v -= dot; - *loc = (*loc & ~0x3fffff) | (v >> 10); - break; - - case R_SPARC_UA32: - *(((char *)loc) + 0) = (char)(v >> 24); - *(((char *)loc) + 1) = (char)(v >> 16); - *(((char *)loc) + 2) = (char)(v >> 8); - *(((char *)loc) + 3) = (char)v; - break; - -#ifdef R_SPARC_10 - case R_SPARC_10: - if (v > 0x3ff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x3ff) | (v & 0x3ff); - break; - case R_SPARC_11: - if (v > 0x7ff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x7ff) | (v & 0x7ff); - break; - case R_SPARC_WDISP16: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x303fff) | ((v << 4) & 0x300000) | ((v >> 2) & 0x3fff); - break; - case R_SPARC_WDISP19: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x7ffff) | ((v >> 2) & 0x7ffff); - break; - case R_SPARC_7: - if (v > 0x7f) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x7f) | (v & 0x7f); - break; - case R_SPARC_5: - if (v > 0x1f) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x1f) | (v & 0x1f); - break; - case R_SPARC_6: - if (v > 0x3f) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x3f) | (v & 0x3f); - break; -#endif /* R_SPARC_10 */ - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *ef) -{ - return 1; -} - -int -arch_init_module (struct obj_file *f, struct module *mod) -{ - return 1; -} - -int -arch_finalize_section_address(struct obj_file *f, Elf32_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/obj/obj_sparc64.c b/mdk-stage1/insmod-modutils/obj/obj_sparc64.c deleted file mode 100644 index 84e8d18a0..000000000 --- a/mdk-stage1/insmod-modutils/obj/obj_sparc64.c +++ /dev/null @@ -1,352 +0,0 @@ -/* Sparc64 specific support for Elf loading and relocation. - Copyright 1997 Linux International. - - Contributed by Jakub Jelinek <jj@sunsite.mff.cuni.cz> - - 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 <stddef.h> -#include <module.h> -#include <obj.h> -#include <util.h> - - -/*======================================================================*/ - -struct obj_file * -arch_new_file (void) -{ - return xmalloc(sizeof(struct obj_file)); -} - -struct obj_section * -arch_new_section (void) -{ - return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol * -arch_new_symbol (void) -{ - return xmalloc(sizeof(struct obj_symbol)); -} - -#ifdef BROKEN_SPARC64_RELOCS - -#undef R_SPARC_PLT32 -#undef R_SPARC_HIPLT22 -#undef R_SPARC_LOPLT10 -#undef R_SPARC_PCPLT32 -#undef R_SPARC_PCPLT22 -#undef R_SPARC_PCPLT10 -#undef R_SPARC_10 -#undef R_SPARC_11 -#undef R_SPARC_64 -#undef R_SPARC_OLO10 -#undef R_SPARC_HH22 -#undef R_SPARC_HM10 -#undef R_SPARC_LM22 -#undef R_SPARC_PC_HH22 -#undef R_SPARC_PC_HM10 -#undef R_SPARC_PC_LM22 -#undef R_SPARC_WDISP16 -#undef R_SPARC_WDISP19 -#undef R_SPARC_GLOB_JMP -#undef R_SPARC_7 -#undef R_SPARC_5 -#undef R_SPARC_6 - -#define R_SPARC_10 24 -#define R_SPARC_11 25 -#define R_SPARC_64 26 -#define R_SPARC_OLO10 27 -#define R_SPARC_HH22 28 -#define R_SPARC_HM10 29 -#define R_SPARC_LM22 30 -#define R_SPARC_PC_HH22 31 -#define R_SPARC_PC_HM10 32 -#define R_SPARC_PC_LM22 33 -#define R_SPARC_WDISP16 34 -#define R_SPARC_WDISP19 35 -#define R_SPARC_GLOB_JMP 36 -#define R_SPARC_7 37 -#define R_SPARC_5 38 -#define R_SPARC_6 39 - -#else - -#ifndef R_SPARC_64 - -#define R_SPARC_64 32 -#define R_SPARC_OLO10 33 -#define R_SPARC_HH22 34 -#define R_SPARC_HM10 35 -#define R_SPARC_LM22 36 -#define R_SPARC_PC_HH22 37 -#define R_SPARC_PC_HM10 38 -#define R_SPARC_PC_LM22 39 - -#endif - -#endif - -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; -} - -#define ELF64_R_TYPE_ID(info) ((info) & 0xff) -#define ELF64_R_TYPE_DATA(info) ((info) >> 8) - -enum obj_reloc -arch_apply_relocation (struct obj_file *ef, - struct obj_section *targsec, - struct obj_section *symsec, - struct obj_symbol *sym, - Elf64_Rela *rel, - Elf64_Addr v) -{ - unsigned int *loc = (unsigned int *)(targsec->contents + rel->r_offset); - unsigned int dot = targsec->header.sh_addr + rel->r_offset; - - enum obj_reloc ret = obj_reloc_ok; - - switch (ELF64_R_TYPE_ID(rel->r_info)) - { - case R_SPARC_NONE: - break; - - case R_SPARC_64: - case R_SPARC_UA64: - if (! ((long) loc & 3)) { - /* Common in .eh_frame */ - ((unsigned int *) loc) [0] = v >> 32; - ((unsigned int *) loc) [1] = v; - break; - } - ((unsigned char *) loc) [0] = v >> 56; - ((unsigned char *) loc) [1] = v >> 48; - ((unsigned char *) loc) [2] = v >> 40; - ((unsigned char *) loc) [3] = v >> 32; - ((unsigned char *) loc) [4] = v >> 24; - ((unsigned char *) loc) [5] = v >> 16; - ((unsigned char *) loc) [6] = v >> 8; - ((unsigned char *) loc) [7] = v; - break; - case R_SPARC_32: - case R_SPARC_UA32: - if (! ((long) loc & 3)) { - *loc = v; - break; - } - ((unsigned char *) loc) [0] = v >> 24; - ((unsigned char *) loc) [1] = v >> 16; - ((unsigned char *) loc) [2] = v >> 8; - ((unsigned char *) loc) [3] = v; - break; - case R_SPARC_16: - if (v > 0xffff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xffff) | (v & 0xffff); - break; - case R_SPARC_8: - if (v > 0xff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xff) | (v & 0xff); - break; - - case R_SPARC_DISP32: - v -= dot; - *loc = v; - break; - case R_SPARC_DISP16: - v -= dot; - if (v > 0xffff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xffff) | (v & 0xffff); - break; - case R_SPARC_DISP8: - v -= dot; - if (v > 0xff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0xff) | (v & 0xff); - break; - case R_SPARC_WDISP30: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x3fffffff) | ((v >> 2) & 0x3fffffff); - break; - - /* MEDLOW code model relocs */ - case R_SPARC_LO10: - *loc = (*loc & ~0x3ff) | (v & 0x3ff); - break; - case R_SPARC_HI22: - *loc = (*loc & ~0x3fffff) | (v >> 10); - break; - case R_SPARC_OLO10: - *loc = (*loc & ~0x1fff) | (((v & 0x3ff) + ELF64_R_TYPE_DATA (rel->r_info)) & 0x1fff); - break; - - /* MEDMID code model relocs */ - case R_SPARC_H44: - *loc = (*loc & ~0x3fffff) | (v >> 22); - break; - case R_SPARC_M44: - *loc = (*loc & ~0x3ff) | ((v >> 12) & 0x3ff); - break; - case R_SPARC_L44: - *loc = (*loc & ~0xfff) | (v & 0xfff); - break; - - /* MEDANY code model relocs */ - case R_SPARC_HH22: - *loc = (*loc & ~0x3fffff) | (v >> 42); - break; - case R_SPARC_HM10: - *loc = (*loc & ~0x3ff) | ((v >> 32) & 0x3ff); - break; - case R_SPARC_LM22: - *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff); - break; - - case R_SPARC_WDISP22: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x3fffff) | ((v >> 2) & 0x3fffff); - break; - case R_SPARC_22: - if (v > 0x3fffff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x3fffff) | (v & 0x3fffff); - break; - case R_SPARC_13: - if (v > 0x1fff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x1fff) | (v & 0x1fff); - break; - - case R_SPARC_PC10: - v -= dot; - *loc = (*loc & ~0x3ff) | (v & 0x3ff); - break; - case R_SPARC_PC22: - v -= dot; - *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff); - break; - -#ifdef R_SPARC_10 - case R_SPARC_10: - if (v > 0x3ff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x3ff) | (v & 0x3ff); - break; - case R_SPARC_11: - if (v > 0x7ff) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x7ff) | (v & 0x7ff); - break; - -#ifdef R_SPARC_64 - case R_SPARC_PC_HH22: - v -= dot; - *loc = (*loc & ~0x3fffff) | (v >> 42); - break; - case R_SPARC_PC_HM10: - v -= dot; - *loc = (*loc & ~0x3ff) | ((v >> 32) & 0x3ff); - break; - case R_SPARC_PC_LM22: - v -= dot; - *loc = (*loc & ~0x3fffff) | ((v >> 10) & 0x3fffff); - break; -#endif - - case R_SPARC_WDISP16: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x303fff) | ((v << 4) & 0x300000) | ((v >> 2) & 0x3fff); - break; - case R_SPARC_WDISP19: - v -= dot; - if (v % 4) - ret = obj_reloc_dangerous; - *loc = (*loc & ~0x7ffff) | ((v >> 2) & 0x7ffff); - break; - case R_SPARC_7: - if (v > 0x7f) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x7f) | (v & 0x7f); - break; - case R_SPARC_5: - if (v > 0x1f) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x1f) | (v & 0x1f); - break; - case R_SPARC_6: - if (v > 0x3f) - ret = obj_reloc_overflow; - *loc = (*loc & ~0x3f) | (v & 0x3f); - break; -#endif /* R_SPARC_10 */ - - default: - ret = obj_reloc_unhandled; - break; - } - - return ret; -} - -int -arch_create_got (struct obj_file *ef) -{ - 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/Makefile b/mdk-stage1/insmod-modutils/util/Makefile deleted file mode 100644 index 763f046f2..000000000 --- a/mdk-stage1/insmod-modutils/util/Makefile +++ /dev/null @@ -1,42 +0,0 @@ - #****************************************************************************** - # - # insmod from modutils (generic) - # - # $Id$ - # - # Copyright 1996, 1997 Linux International. - # - #***************************************************************************** - -top_dir = ../.. - -include $(top_dir)/Makefile.common - - -all: libutil.a libutil-STANDALONE.a #libutil-DIET.a - -clean: - rm -f *.o *.a - - -INCS = -I./../include - -DEFS = -Wno-error -D_GNU_SOURCE -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) -DHAVE_WORDEXP=1 -DHAVE_GLOB=1 -DCONFIG_ROOT_CHECK_OFF=0 - - -OBJS = xmalloc.o xrealloc.o xstrcat.o xstrdup.o xsystem.o xftw.o \ - modstat.o meta_expand.o config.o snap_shot.o arch64.o gzfiles.o sys_nim.o sys_oim.o - -libutil.a: $(OBJS) logger.o - ar cru $@ $^ - ranlib $@ - -libutil-STANDALONE.a: $(OBJS) logger-standalone.o - ar cru $@ $^ - ranlib $@ - -logger-standalone.o: logger.c - gcc $(CFLAGS) $(DEFS) $(INCS) $(GLIBC_INCLUDES) -o $@ -D_STANDALONE_ -c logger.c - -.c.o: - gcc $(CFLAGS) $(DEFS) $(INCS) $(GLIBC_INCLUDES) -c $< diff --git a/mdk-stage1/insmod-modutils/util/alias.h b/mdk-stage1/insmod-modutils/util/alias.h deleted file mode 100644 index c925a04f3..000000000 --- a/mdk-stage1/insmod-modutils/util/alias.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * This file is split out from config.c for easier editing - */ - -/* - * tbpath and tbtype are used to build the complete set of paths for finding - * modules, but only when we search for individual directories, they are not - * used for [boot] and [toplevel] searches. - */ -static char *tbpath[] = -{ - "/lib/modules", - NULL /* marks the end of the list! */ -}; - -char *tbtype[] = -{ - "kernel", /* as of 2.3.14 this must be first */ - "fs", - "net", - "scsi", - "block", - "cdrom", - "ipv4", - "ipv6", - "sound", - "fc4", - "video", - "misc", - "pcmcia", - "atm", - "usb", - "ide", - "ieee1394", - "mtd", - NULL /* marks the end of the list! */ -}; - -/* - * This is the list of pre-defined aliases. - * Each entry can be overridden by an entry in /etc/modules.conf - */ -char *aliaslist[] = -{ - "binfmt-204 binfmt_aout", - "binfmt-263 binfmt_aout", - "binfmt-264 binfmt_aout", - "binfmt-267 binfmt_aout", - "binfmt-387 binfmt_aout", - "binfmt-332 iBCS", - "binfmt--310 binfmt_java", - - "block-major-1 rd", - "block-major-2 floppy", - "block-major-3 ide-probe-mod", - "block-major-7 loop", - "block-major-8 sd_mod", - "block-major-9 md", /* For modular RAID */ - "block-major-11 sr_mod", - "block-major-13 xd", - "block-major-15 cdu31a", - "block-major-16 gscd", - "block-major-17 optcd", - "block-major-18 sjcd", - "block-major-20 mcdx", - "block-major-22 ide-probe-mod", - "block-major-23 mcd", - "block-major-24 sonycd535", - "block-major-25 sbpcd", - "block-major-26 sbpcd", - "block-major-27 sbpcd", - "block-major-29 aztcd", - "block-major-32 cm206", - "block-major-33 ide-probe-mod", - "block-major-34 ide-probe-mod", - "block-major-37 ide-tape", - "block-major-44 ftl", /* from David Woodhouse <dwmw2@infradead.org> */ - "block-major-56 ide-probe-mod", - "block-major-57 ide-probe-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> */ - - "char-major-4 serial", - "char-major-5 serial", - "char-major-6 lp", - "char-major-9 st", - "char-major-10 off", /* was: mouse, was: misc */ - "char-major-10-0 busmouse", /* /dev/logibm Logitech bus mouse */ - "char-major-10-1 off", /* /dev/psaux PS/2-style mouse port */ - "char-major-10-2 msbusmouse", /* /dev/inportbm Microsoft Inport bus mouse */ - "char-major-10-3 atixlmouse", /* /dev/atibm ATI XL bus mouse */ - /* /dev/jbm J-mouse */ - /* /dev/amigamouse Amiga mouse (68k/Amiga) */ - /* /dev/atarimouse Atari mouse */ - /* /dev/sunmouse Sun mouse */ - /* /dev/beep Fancy beep device */ - /* /dev/modreq Kernel module load request */ - "char-major-10-130 wdt", /* /dev/watchdog Watchdog timer port */ - "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-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-14 soundcore", - "char-major-19 cyclades", - "char-major-20 cyclades", - "char-major-21 sg", - "char-major-22 pcxx", /* ?? */ - "char-major-23 pcxx", /* ?? */ - "char-major-27 ftape", - "char-major-34 scc", - "char-major-35 tclmidi", - "char-major-36 netlink", - "char-major-37 ide-tape", - "char-major-48 riscom8", - "char-major-49 riscom8", - "char-major-57 esp", - "char-major-58 esp", - "char-major-63 kdebug", - "char-major-90 mtdchar", /* from David Woodhouse <dwmw2@infradead.org> */ - "char-major-99 ppdev", - "char-major-107 3dfx", /* from Tigran Aivazian <tigran@sco.COM> */ - "char-major-161 ircomm-tty", - - "dos msdos", - "dummy0 dummy", - "dummy1 dummy", - "eth0 off", - "iso9660 isofs", - "md-personality-1 linear", - "md-personality-2 raid0", - "md-personality-3 raid1", - "md-personality-4 raid5", - - "net-pf-1 unix", /* PF_UNIX 1 Unix domain sockets */ - "net-pf-2 ipv4", /* PF_INET 2 Internet IP Protocol */ - "net-pf-3 off", /* PF_AX25 3 Amateur Radio AX.25 */ - "net-pf-4 ipx", /* PF_IPX 4 Novell IPX */ - "net-pf-5 appletalk", /* PF_APPLETALK 5 Appletalk DDP */ - "net-pf-6 off", /* PF_NETROM 6 Amateur radio NetROM */ - /* 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 */ - - /* next two from <dairiki@matthews.dairiki.org> Thanks! */ - "net-pf-17 af_packet", - "net-pf-19 off", /* acorn econet */ - - "netalias-2 ip_alias", - "plip0 plip", - "plip1 plip", - "cipcb0 cipcb", - "cipcb1 cipcb", - "cipcb2 cipcb", - "cipcb3 cipcb", - "ppp0 ppp", - "ppp1 ppp", - "scsi_hostadapter off", /* if not in config file */ - "slip0 slip", - "slip1 slip", - "tty-ldisc-1 slip", - "tty-ldisc-3 ppp", - "ppp-compress-21 bsd_comp", - "ppp-compress-24 ppp_deflate", - "ppp-compress-26 ppp_deflate", - -#ifndef __sparc__ - "parport_lowlevel parport_pc", -#else - "parport_lowlevel parport_ax", -#endif - - "tty-ldisc-11 irtty", - - "usbdevfs usbcore", - - NULL /* marks the end of the list! */ -}; - -/* - * This is the list of pre-defined options. - * Each entry can be overridden by an entry in /etc/modules.conf - */ -char *optlist[] = -{ - "dummy0 -o dummy0", - "dummy1 -o dummy1", - "sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330", - NULL /* marks the end of the list! */ -}; - -/* - * This is the list of pre-defined "above"s, - * used for pull-in of additional modules - * Each entry can be overridden by an entry in /etc/modules.conf - */ -char *above[] = -{ - NULL /* marks the end of the list! */ -}; - -/* - * This is the list of pre-defined "below"s, - * used for push-in of additional modules - * Each entry can be overridden by an entry in /etc/modules.conf - */ -char *below[] = -{ - NULL /* marks the end of the list! */ -}; - -/* - * 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.generic_string", - "modules.pcimap", - "modules.isapnpmap", - "modules.usbmap", - "modules.parportmap", - "System.map", - ".config", - "build", /* symlink to source tree */ - "vmlinux", - "vmlinuz", - "bzImage", - "zImage", - ".rhkmvtag", /* wish RedHat had told me before they did this */ - NULL /* marks the end of the list! */ -}; diff --git a/mdk-stage1/insmod-modutils/util/arch64.c b/mdk-stage1/insmod-modutils/util/arch64.c deleted file mode 100644 index 4d5ace223..000000000 --- a/mdk-stage1/insmod-modutils/util/arch64.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Misc utility functions. - Copyright 1996, 1997 Linux International. - Written by Keith Owens <kaos@ocs.com.au> - - 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 <stdlib.h> -#include <string.h> -#include <sys/utsname.h> -#include "util.h" - -/*======================================================================*/ - -/* Indicate if the current machine uses 64 bit architecture */ -int arch64(void) -{ - struct utsname u; - return(!uname(&u) && strstr(u.machine, "64")); -} diff --git a/mdk-stage1/insmod-modutils/util/config.c b/mdk-stage1/insmod-modutils/util/config.c deleted file mode 100644 index a860920f6..000000000 --- a/mdk-stage1/insmod-modutils/util/config.c +++ /dev/null @@ -1,1591 +0,0 @@ -/* - * Handle the configuration, including /etc/modules.conf - * - * Copyright 1994, 1995, 1996, 1997: - * Jacques Gelinas <jack@solucorp.qc.ca> - * Björn Ekwall <bj0rn@blox.se> February 1999 - * Keith Owens <kaos@ocs.com.au> October 1999 - * - * "kernelversion" idea from the Debian release via: - * Wichert Akkerman <wakkerma@cs.leidenuniv.nl> - * - * Björn, inspired by Richard Henderson <rth@twiddle.net>, cleaned up - * the wildcard handling and started using ftw in March 1999 - * Cleanup of hardcoded arrays: Björn Ekwall <bj0rn@blox.se> March 1999 - * Many additional keywords: Björn Ekwall <bj0rn@blox.se> (C) March 1999 - * Standardize on /etc/modules.conf Keith Owens <kaos@ocs.com.au> October 1999 - * - * Alpha typecast:Michal Jaegermann <michal@ellpspace.math.ualberta.ca> - * - * 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. - */ - -/* - * Specification: /etc/modules.conf / format - * Modules may be located at different places in the filesystem. - * - * The file /etc/modules.conf contains different definitions to - * control the manipulation of modules. - * - * Standard Unix style comments and continuation line are supported. - * Comments begin with a # and continue until the end of the line. - * A line continues on the next one if the last non-white character - * is a \. - */ -/* #Specification: /etc/modules.conf / format / official name */ - -#include <stdio.h> -#include <stdarg.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <ctype.h> -#include <sys/stat.h> -#include <signal.h> -#include <limits.h> -#include <sys/param.h> -#include <errno.h> - -#include "util.h" -#include "config.h" -#include "alias.h" - -int flag_autoclean; /* set/used by modprobe and insmod */ - -struct utsname uts_info; - -struct PATH_TYPE *modpath; -int nmodpath = 0; -static int maxpath = 0; - -struct EXEC_TYPE *execs; -int nexecs = 0; -static int maxexecs = 0; - -OPT_LIST *opt_list; -static int n_opt_list; - -OPT_LIST *abovelist; -static int n_abovelist; - -OPT_LIST *belowlist; -static int n_belowlist; - -OPT_LIST *prunelist; -static int n_prunelist; - -OPT_LIST *probe_list; -static int n_probe_list; - -OPT_LIST *probeall_list; -static int n_probeall_list; - -OPT_LIST *aliases; -static int n_aliases; - -char *persistdir = "/var/lib/modules/persist"; - -const char symprefix[] = SYMPREFIX; - -char *insmod_opt = NULL; -char *config_file = NULL; /* Which file was actually used */ -time_t config_mtime; -int root_check_off = CONFIG_ROOT_CHECK_OFF; /* Default is modules must be owned by root */ -static char *config_version; /* Hack for config_add */ -int quick = 0; /* Option -A */ - -/* The initialization order must match the gen_file_enum order in config.h */ -struct gen_files gen_file[] = { - {"generic_string", NULL, 0}, - {"pcimap", NULL, 0}, - {"isapnpmap", NULL, 0}, - {"usbmap", NULL, 0}, - {"parportmap", NULL, 0}, - {"dep", NULL, 0}, -}; - -const int gen_file_count = sizeof(gen_file)/sizeof(gen_file[0]); - -int flag_verbose; - -unsigned long safemode; - -void verbose(const char *ctl,...) -{ - if (flag_verbose) { - va_list list; - va_start(list, ctl); - vprintf(ctl, list); - va_end(list); - fflush(stdout); - } -} - - -/* - * Check to see if the existing modules.xxx files need updating, - * based on the timestamps of the modules and the config file. - */ -static int check_update (const char *file, const struct stat *sb) -{ - int len = strlen(file); - int i; - - if (!S_ISREG(sb->st_mode)) - return 0; - for (i = 0; i < gen_file_count; ++i) { - if (sb->st_mtime > gen_file[i].mtime) - break; - } - if (i == gen_file_count) - return 0; /* All generated files are up to date */ - - if (len > 2 && !strcmp(file + len - 2, ".o")) - return 1; - else if (len > 4 && !strcmp(file + len - 4, ".mod")) - return 1; -#ifdef CONFIG_USE_ZLIB - else if (len > 5 && !strcmp(file + len - 5, ".o.gz")) - return 1; -#endif - return 0; -} - -static int need_update (const char *force_ver, const char *base_dir) -{ - struct stat tmp; - char dep[PATH_MAX]; - int i; - uname (&uts_info); - if (!force_ver) - force_ver = uts_info.release; - - if (strlen (force_ver) > 50) - /* That's just silly. */ - return 1; - - for (i = 0; i < gen_file_count; ++i) { - if (stat(gen_file[i].name, &tmp)) - return 1; /* No dependency file yet, so we need to build it. */ - gen_file[i].mtime = tmp.st_mtime; - } - - if (stat ("/etc/modules.conf", &tmp) && - stat ("/etc/conf.modules", &tmp)) - return 1; - - for (i = 0; i < gen_file_count; ++i) { - if (tmp.st_mtime > gen_file[i].mtime) - return 1; /* Config file is newer. */ - } - - snprintf (dep, sizeof(dep), "%s/lib/modules/%s", base_dir, force_ver); - return xftw (dep, check_update); -} - - -/* - * Strip white char at the end of a string. - * Return the address of the last non white char + 1 (point on the '\0'). - */ -static char *strip_end(char *str) -{ - int len = strlen(str); - - for (str += len - 1; len > 0 && (isspace(*str)); --len, --str) - *str = '\0'; - return str + 1; -} - -/* - * Read a line of a configuration file and process continuation lines. - * Return buf, or NULL if EOF. - * Blank at the end of line are always stripped. - * Everything on a line following comchar is a comment. - * - * Continuation character is \ - * Comment character is # - */ -char *fgets_strip(char *buf, int sizebuf, FILE * fin, int *lineno) -{ - int nocomment = 1; /* No comments found ? */ - int contline = 0; - char *start = buf; - char *ret = NULL; - char comchar = '#'; - char contchar = '\\'; - - *buf = '\0'; - - while (fgets(buf, sizebuf, fin) != NULL) { - char *end = strip_end(buf); - char *pt = strchr(buf, comchar); - - if (pt != NULL) { - nocomment = 0; - *pt = '\0'; - end = strip_end(buf); - } - - if (lineno != NULL) - (*lineno)++; - ret = start; - if (contline) { - char *pt = buf; - - while (isspace(*pt)) - pt++; - if (pt > buf + 1) { - strcpy(buf + 1, pt); /* safe, backward copy */ - buf[0] = ' '; - end -= (int) (pt - buf) - 1; - } else if (pt == buf + 1) { - buf[0] = ' '; - } - } - if (end > buf && *(end - 1) == contchar) { - if (end == buf + 1 || *(end - 2) != contchar) { - /* Continuation */ - contline = 1; - end--; - *end = '\0'; - buf = end; - } else { - *(end - 1) = '\0'; - break; - } - } else { - break; - } - } - - return ret; -} - -static char *next_word(char *pt) -{ - char *match; - char *pt2; - - /* find end of word */ - for (pt2 = pt; *pt2 && !(isspace(*pt2)); ++pt2) { - if ((match = strchr("\"'`", *pt2)) != NULL) { - for (++pt2; *pt2 && *pt2 != *match; ++pt2) { - if (*pt2 == '\\' && *(pt2 + 1) == *match) - ++pt2; - } - } - } - - /* skip leading whitespace before next word */ - if (*pt2) { - *pt2++ = '\0'; /* terminate last word */ - while (*pt2 && isspace(*pt2)) - ++pt2; - } - return pt2; -} - -static GLOB_LIST *addlist(GLOB_LIST *orig, GLOB_LIST *add) -{ - if (!orig) - return add; - /* else */ - orig->pathv = (char **)xrealloc(orig->pathv, - (orig->pathc + add->pathc + 1) * - sizeof(char *)); - memcpy(orig->pathv + orig->pathc, add->pathv, - add->pathc * sizeof(char *)); - orig->pathc += add->pathc; - orig->pathv[orig->pathc] = NULL; - /* - free(add->pathv); - free(add); - */ - return orig; -} - -static void decode_list(int *n, OPT_LIST **list, char *arg, int adding, - char *version, int opts) -{ - GLOB_LIST *pg; - GLOB_LIST *prevlist = NULL; - int i, autoclean = 1; - int where = *n; - char *arg2 = next_word(arg); - - if (opts && !strcmp (arg, "-k")) { - if (!*arg2) - error("Missing module argument after -k\n"); - arg = arg2; - arg2 = next_word(arg); - autoclean = 0; - } - - for (i = 0; i < *n; ++i) { - if (strcmp((*list)[i].name, arg) == 0) { - if (adding) - prevlist = (*list)[i].opts; - else - free((*list)[i].opts); - (*list)[i].opts = NULL; - where = i; - break; - } - } - if (where == *n) { - (*list) = (OPT_LIST *)xrealloc((*list), - (*n + 2) * sizeof(OPT_LIST)); - (*list)[*n].name = xstrdup(arg); - (*list)[*n].autoclean = autoclean; - *n += 1; - memset(&(*list)[*n], 0, sizeof(OPT_LIST)); - } else if (!autoclean) - (*list)[where].autoclean = 0; - pg = (GLOB_LIST *)xmalloc(sizeof(GLOB_LIST)); - meta_expand(arg2, pg, NULL, version, ME_ALL); - (*list)[where].opts = addlist(prevlist, pg); -} - -static void decode_exec(char *arg, int type) -{ - char *arg2; - - execs[nexecs].when = type; - arg2 = next_word(arg); - execs[nexecs].module = xstrdup(arg); - execs[nexecs].cmd = xstrdup(arg2); - if (++nexecs >= maxexecs) { - maxexecs += 10; - execs = (struct EXEC_TYPE *)xrealloc(execs, - maxexecs * sizeof(struct EXEC_TYPE)); - } -} - -static int build_list(char **in, OPT_LIST **out, char *version, int opts) -{ - GLOB_LIST *pg; - int i; - - for (i = 0; in[i]; ++i) { - char *p = xstrdup(in[i]); - char *pt = next_word(p); - char *pn = p; - - *out = (OPT_LIST *)xrealloc(*out, (i + 2) * sizeof(OPT_LIST)); - (*out)[i].autoclean = 1; - if (opts && !strcmp (p, "-k")) { - pn = pt; - pt = next_word(pn); - (*out)[i].autoclean = 0; - } - pg = (GLOB_LIST *)xmalloc(sizeof(GLOB_LIST)); - meta_expand(pt, pg, NULL, version, ME_ALL); - (*out)[i].name = xstrdup(pn); - (*out)[i].opts = pg; - free(p); - } - memset(&(*out)[i], 0, sizeof(OPT_LIST)); - - return i; -} - -/* Environment variables can override defaults, testing only */ -static void gen_file_env(struct gen_files *gf) -{ - if (!safemode) { - char *e = xmalloc(strlen(gf->base)+5), *p1 = gf->base, *p2 = e; - while ((*p2++ = toupper(*p1++))) ; - strcpy(p2-1, "PATH"); /* safe, xmalloc */ - if ((p2 = getenv(e)) != NULL) { - free(gf->name); - gf->name = xstrdup(p2); - } - free(e); - } -} - -/* Read a config option for a generated filename */ -static int gen_file_conf(struct gen_files *gf, int assgn, const char *parm, const char *arg) -{ - - int l = strlen(gf->base); - if (assgn && - strncmp(parm, gf->base, l) == 0 && - strcmp(parm+l, "file") == 0 && - !gf->name) { - gf->name = xstrdup(arg); - return(0); - } - return(1); -} - -/* Check we have a name for a generated file */ -static int gen_file_check(struct gen_files *gf, GLOB_LIST *g, - char *base_dir, char *version) -{ - char tmp[PATH_MAX]; - int ret = 0; - if (!gf->name) { - /* - * Specification: config file / no xxxfile parameter - * The default value for generated filename xxx is: - * - * xxxfile=/lib/modules/`uname -r`/modules.xxx - * - * If the config file exists but lacks an xxxfile - * specification, the default value is used since - * the system can't work without one. - */ - snprintf(tmp, sizeof(tmp), "%s/lib/modules/%s/modules.%s", - base_dir, version, gf->base); - gf->name = xstrdup(tmp); - } else { /* xxxfile defined in modules.conf */ - /* - * If we have a xxxfile definition in the configuration file - * we must resolve any shell meta-chars in its value. - */ - if (meta_expand(gf->name, g, base_dir, version, ME_ALL)) - ret = -1; - else if (!g->pathv || g->pathv[0] == NULL) - ret = -1; - else { - free(gf->name); - gf->name = xstrdup(g->pathv[0]); - } - } - return(ret); -} - -/* - * Read the configuration file. - * If parameter "all" == 0 then ignore everything except path info - * Return -1 if any error. - * Error messages generated. - */ -static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, int depth) -{ - #define MAX_LEVEL 20 - FILE *fin; - GLOB_LIST g; - int i; - int assgn; - int drop_default_paths = 1; - int lineno = 0; - int ret = 0; - int state[MAX_LEVEL + 1]; /* nested "if" */ - int level = 0; - char buf[3000]; - char tmpline[100]; - char **pathp; - char *envpath; - char *version; - char *type; - char **glb; - char old_name[] = "/etc/conf.modules"; - int conf_file_specified = 0; - - /* - * The configuration file is optional. - * No error is printed if it is missing. - * If it is missing the following content is assumed. - * - * path[boot]=/lib/modules/boot - * - * path[toplevel]=/lib/modules/`uname -r` - * - * path[toplevel]=/lib/modules/`kernelversion` - * (where kernelversion gives the major kernel version: "2.0", "2.2"...) - * - * path[toplevel]=/lib/modules/default - * - * path[kernel]=/lib/modules/kernel - * path[fs]=/lib/modules/fs - * path[net]=/lib/modules/net - * path[scsi]=/lib/modules/scsi - * path[block]=/lib/modules/block - * path[cdrom]=/lib/modules/cdrom - * path[ipv4]=/lib/modules/ipv4 - * path[ipv6]=/lib/modules/ipv6 - * path[sound]=/lib/modules/sound - * path[fc4]=/lib/modules/fc4 - * path[video]=/lib/modules/video - * path[misc]=/lib/modules/misc - * path[pcmcia]=/lib/modules/pcmcia - * path[atm]=/lib/modules/atm - * path[usb]=/lib/modules/usb - * path[ide]=/lib/modules/ide - * path[ieee1394]=/lib/modules/ieee1394 - * path[mtd]=/lib/modules/mtd - * - * The idea is that modprobe will look first if the - * modules are compiled for the current release of the kernel. - * If not found, it will look for modules that fit for the - * general kernelversion (2.0, 2.2 and so on). - * If still not found, it will look into the default release. - * And if still not found, it will look in the other directories. - * - * The strategy should be like this: - * When you install a new linux kernel, the modules should go - * into a directory related to the release (version) of the kernel. - * Then you can do a symlink "default" to this directory. - * - * Each time you compile a new kernel, the make modules_install - * will create a new directory, but it won't change thee default. - * - * When you get a module unrelated to the kernel distribution - * you can place it in one of the last three directory types. - * - * This is the default strategy. Of course you can overide - * this in /etc/modules.conf. - * - * 2.3.15 added a new file tree walk algorithm which made it possible to - * point at a top level directory and get the same behaviour as earlier - * versions of modutils. 2.3.16 takes this one stage further, it - * removes all the individual directory names from most of the scans, - * only pointing at the top level directory. The only exception is the - * last ditch scan, scanning all of /lib/modules would be a bad idea(TM) - * so the last ditch scan still runs individual directory names under - * /lib/modules. - * - * Additional syntax: - * - * [add] above module module1 ... - * Specify additional modules to pull in on top of a module - * - * [add] below module module1 ... - * Specify additional modules needed to be able to load a module - * - * [add] prune filename ... - * - * [add] probe name module1 ... - * When "name" is requested, modprobe tries to install each - * module in the list until it succeeds. - * - * [add] probeall name module1 ... - * When "name" is requested, modprobe tries to install all - * modules in the list. - * If any module is installed, the command has succeeded. - * - * [add] options module option_list - * - * For all of the above, the optional "add" prefix is used to - * add to a list instead of replacing the contents. - * - * include FILE_TO_INCLUDE - * This does what you expect. No limitation on include levels. - * - * persistdir=persist_directory - * Name the directory to save persistent data from modules. - * - * In the following WORD is a sequence if non-white characters. - * If ' " or ` is found in the string, all characters up to the - * matching ' " or ` will also be included, even whitespace. - * Every WORD will then be expanded w.r.t. meta-characters. - * If the expanded result gives more than one word, then only - * the first word of the result will be used. - * - * - * define CODE WORD - * Do a putenv("CODE=WORD") - * - * EXPRESSION below can be: - * WORD compare_op WORD - * where compare_op is one of == != < <= >= > - * The string values of the WORDs are compared - * or - * -n WORD compare_op WORD - * where compare_op is one of == != < <= >= > - * The numeric values of the WORDs are compared - * or - * WORD - * if the expansion of WORD fails, or if the - * expansion is "0" (zero), "false" or "" (empty) - * then the expansion has the value FALSE. - * Otherwise the expansion has the value TRUE - * or - * -f FILENAME - * Test if the file FILENAME exists - * or - * -k - * Test if "autoclean" (i.e. called from the kernel) - * or - * ! EXPRESSION - * A negated expression is also an expression - * - * if EXPRESSION - * any config line - * ... - * elseif EXPRESSION - * any config line - * ... - * else - * any config line - * ... - * endif - * - * The else and elseif keywords are optional. - * "if"-statements nest up to 20 levels. - */ - - state[0] = 1; - - if (force_ver) - version = force_ver; - else - version = uts_info.release; - - config_version = xstrdup(version); - - /* Only read the default entries on the first file */ - if (depth == 0) { - maxpath = 100; - modpath = (struct PATH_TYPE *)xmalloc(maxpath * sizeof(struct PATH_TYPE)); - nmodpath = 0; - - maxexecs = 10; - execs = (struct EXEC_TYPE *)xmalloc(maxexecs * sizeof(struct EXEC_TYPE)); - nexecs = 0; - - /* - * Build predef options - */ - if (all && optlist[0]) - n_opt_list = build_list(optlist, &opt_list, version, 1); - - /* - * Build predef above - */ - if (all && above[0]) - n_abovelist = build_list(above, &abovelist, version, 0); - - /* - * Build predef below - */ - if (all && below[0]) - n_belowlist = build_list(below, &belowlist, version, 0); - - /* - * Build predef prune list - */ - if (prune[0]) - n_prunelist = build_list(prune, &prunelist, version, 0); - - /* - * Build predef aliases - */ - if (all && aliaslist[0]) - n_aliases = build_list(aliaslist, &aliases, version, 0); - - /* Order and priority is now: (MODPATH + modules.conf) || (predefs + modules.conf) */ - if ((envpath = getenv("MODPATH")) != NULL && !safemode) { - size_t len; - char *p; - char *path; - - /* Make a copy so's we can mung it with strtok. */ - len = strlen(envpath) + 1; - p = alloca(len); - memcpy(p, envpath, len); - path = alloca(PATH_MAX); - - for (p = strtok(p, ":"); p != NULL; p = strtok(NULL, ":")) { - len = snprintf(path, PATH_MAX, p, version); - modpath[nmodpath].path = xstrdup(path); - if ((type = strrchr(path, '/')) != NULL) - type += 1; - else - type = "misc"; - modpath[nmodpath].type = xstrdup(type); - if (++nmodpath >= maxpath) { - maxpath += 100; - modpath = (struct PATH_TYPE *)xrealloc(modpath, - maxpath * sizeof(struct PATH_TYPE)); - } - - } - } else { - /* - * Build the default "path[type]" configuration - */ - int n; - char *k; - - /* The first entry in the path list */ - modpath[nmodpath].type = xstrdup("boot"); - snprintf(tmpline, sizeof(tmpline), "%s/lib/modules/boot", base_dir); - modpath[nmodpath].path = xstrdup(tmpline); - ++nmodpath; - - /* The second entry in the path list, `uname -r` */ - modpath[nmodpath].type = xstrdup("toplevel"); - snprintf(tmpline, sizeof(tmpline), "%s/lib/modules/%s", base_dir, version); - modpath[nmodpath].path = xstrdup(tmpline); - ++nmodpath; - - /* The third entry in the path list, `kernelversion` */ - modpath[nmodpath].type = xstrdup("toplevel"); - for (n = 0, k = version; *k; ++k) { - if (*k == '.' && ++n == 2) - break; - } - snprintf(tmpline, sizeof(tmpline), "%s/lib/modules/%.*s", base_dir, - (/* typecast for Alpha */ int)(k - version), version); - modpath[nmodpath].path = xstrdup(tmpline); - ++nmodpath; - - /* The rest of the entries in the path list */ - for (pathp = tbpath; *pathp; ++pathp) { - char **type; - - for (type = tbtype; *type; ++type) { - char path[PATH_MAX]; - - snprintf(path, sizeof(path), "%s%s/%s", base_dir, *pathp, *type); - if (meta_expand(path, &g, NULL, version, ME_ALL)) - return -1; - - for (glb = g.pathv; glb && *glb; ++glb) { - modpath[nmodpath].type = xstrdup(*type); - modpath[nmodpath].path = *glb; - if (++nmodpath >= maxpath) { - maxpath += 100; - modpath = (struct PATH_TYPE *)xrealloc(modpath, - maxpath * sizeof(struct PATH_TYPE)); - } - } - } - } - } - - /* Environment overrides for testing only, undocumented */ - for (i = 0; i < gen_file_count; ++i) - gen_file_env(gen_file+i); - - } /* End of depth == 0 */ - - if (conf_file || - ((conf_file = getenv("MODULECONFIG")) != NULL && *conf_file && !safemode)) { - if (!(fin = fopen(conf_file, "r"))) { - error("Can't open %s", conf_file); - return -1; - } - conf_file_specified = 1; - } else { - if (!(fin = fopen((conf_file = ETC_MODULES_CONF), "r"))) { - /* Fall back to non-standard name */ - if ((fin = fopen((conf_file = old_name), "r"))) { - fprintf(stderr, - "Warning: modutils is reading from %s because\n" - " %s does not exist. The use of %s is\n" - " deprecated, please rename %s to %s\n" - " as soon as possible. Command\n" - " mv %s %s\n", - old_name, ETC_MODULES_CONF, - old_name, old_name, ETC_MODULES_CONF, - old_name, ETC_MODULES_CONF); - } - /* So what... use the default configuration */ - } - } - - if (fin) { - struct stat statbuf1, statbuf2; - if (fstat(fileno(fin), &statbuf1) == 0) - config_mtime = statbuf1.st_mtime; - config_file = xstrdup(conf_file); /* Save name actually used */ - if (!conf_file_specified && - stat(ETC_MODULES_CONF, &statbuf1) == 0 && - stat(old_name, &statbuf2) == 0) { - /* Both /etc files exist */ - if (statbuf1.st_dev == statbuf2.st_dev && - statbuf1.st_ino == statbuf2.st_ino) { - if (lstat(ETC_MODULES_CONF, &statbuf1) == 0 && - S_ISLNK(statbuf1.st_mode)) - fprintf(stderr, - "Warning: You do not need a link from %s to\n" - " %s. The use of %s is deprecated,\n" - " please remove %s and rename %s\n" - " to %s as soon as possible. Commands.\n" - " rm %s\n" - " mv %s %s\n", - ETC_MODULES_CONF, old_name, - old_name, ETC_MODULES_CONF, old_name, ETC_MODULES_CONF, - ETC_MODULES_CONF, - old_name, ETC_MODULES_CONF); - else { -#ifndef NO_WARN_ON_OLD_LINK - fprintf(stderr, - "Warning: You do not need a link from %s to\n" - " %s. The use of %s is deprecated,\n" - " please remove %s as soon as possible. Command\n" - " rm %s\n", - old_name, ETC_MODULES_CONF, - old_name, old_name, - old_name); -#endif - } - } - else - fprintf(stderr, - "Warning: modutils is reading from %s and\n" - " ignoring %s. The use of %s is deprecated,\n" - " please remove %s as soon as possible. Command\n" - " rm %s\n", - ETC_MODULES_CONF, old_name, - old_name, old_name, - old_name); - } - } - - /* - * Finally, decode the file - */ - while (fin && fgets_strip(buf, sizeof(buf) - 1, fin, &lineno) != NULL) { - char *arg2; - char *parm = buf; - char *arg; - int one_err = 0; - int adding; - - while (isspace(*parm)) - parm++; - - if (strncmp(parm, "add", 3) == 0) { - adding = 1; - parm += 3; - while (isspace(*parm)) - parm++; - } else - adding = 0; - - arg = parm; - - if (*parm == '\0') - continue; - - one_err = 1; - - while (*arg > ' ' && *arg != '=') - arg++; - - if (*arg == '=') - assgn = 1; - else - assgn = 0; - *arg++ = '\0'; - while (isspace(*arg)) - arg++; - - /* - * endif - */ - if (!assgn && strcmp(parm, "endif") == 0) { - if (level > 0) - --level; - else { - error("unmatched endif in line %d", lineno); - return -1; - } - continue; - } - - /* - * else - */ - if (!assgn && strcmp(parm, "else") == 0) { - if (level <= 0) { - error("else without if in line %d", lineno); - return -1; - } - state[level] = !state[level]; - continue; - } - - /* - * elseif - */ - if (!assgn && strcmp(parm, "elseif") == 0) { - if (level <= 0) { - error("elseif without if in line %d", lineno); - return -1; - } - if (state[level] != 0) { - /* - * We have already found a TRUE - * if statement in this "chain". - * That's what "2" means. - */ - state[level] = 2; - continue; - } - /* else: No TRUE if has been found, cheat */ - /* - * The "if" handling increments level, - * but this is the _same_ level as before. - * So, compensate for it. - */ - --level; - parm = "if"; - /* Fallthru to "if" */ - } - - /* - * if - */ - if (strcmp(parm, "if") == 0) { - char *cmp; - int not = 0; - int numeric = 0; - - if (level >= MAX_LEVEL) { - error("Too many nested if's in line %d\n", lineno); - return -1; - } - state[++level] = 0; /* default false */ - - if (*arg == '!') { - not = 1; - arg = next_word(arg); - } - - if (strncmp(arg, "-k", 2) == 0) { - state[level] = flag_autoclean; - continue; - } - - if (strncmp(arg, "-f", 2) == 0) { - char *file = next_word(arg); - meta_expand(file, &g, NULL, version, ME_ALL); - if (access(g.pathc ? g.pathv[0] : file, R_OK) == 0) - state[level] = !not; - else - state[level] = not; - continue; - } - - if (strncmp(arg, "-n", 2) == 0) { - numeric = 1; - arg = next_word(arg); - } - - - cmp = next_word(arg); - if (*cmp) { - GLOB_LIST g2; - long n1 = 0; - long n2 = 0; - char *w1 = ""; - char *w2 = ""; - - arg2 = next_word(cmp); - - meta_expand(arg, &g, NULL, version, ME_ALL); - if (g.pathc && g.pathv[0]) - w1 = g.pathv[0]; - - meta_expand(arg2, &g2, NULL, version, ME_ALL); - if (g2.pathc && g2.pathv[0]) - w2 = g2.pathv[0]; - - if (numeric) { - n1 = strtol(w1, NULL, 0); - n2 = strtol(w2, NULL, 0); - } - - if (strcmp(cmp, "==") == 0 || - strcmp(cmp, "=") == 0) { - if (numeric) - state[level] = (n1 == n2); - else - state[level] = strcmp(w1, w2) == 0; - } else if (strcmp(cmp, "!=") == 0) { - if (numeric) - state[level] = (n1 != n2); - else - state[level] = strcmp(w1, w2) != 0; - } else if (strcmp(cmp, ">=") == 0) { - if (numeric) - state[level] = (n1 >= n2); - else - state[level] = strcmp(w1, w2) >= 0; - } else if (strcmp(cmp, "<=") == 0) { - if (numeric) - state[level] = (n1 <= n2); - else - state[level] = strcmp(w1, w2) <= 0; - } else if (strcmp(cmp, ">") == 0) { - if (numeric) - state[level] = (n1 > n2); - else - state[level] = strcmp(w1, w2) > 0; - } else if (strcmp(cmp, "<") == 0) { - if (numeric) - state[level] = (n1 < n2); - else - state[level] = strcmp(w1, w2) < 0; - } - } else { /* Check defined value, if any */ - /* undef or defined as - * "" or "0" or "false" => false - * defined => true - */ - if (!meta_expand(arg, &g, NULL, version, ME_ALL) && - g.pathc > 0 && - strcmp(g.pathv[0], "0") != 0 && - strcmp(g.pathv[0], "false") != 0 && - strlen(g.pathv[0]) != 0) - state[level] = 1; /* true */ - } - if (not) - state[level] = !state[level]; - - continue; - } - - /* - * Should we bother? - */ - if (state[level] != 1) - continue; - - /* - * define - */ - if (!assgn && strcmp(parm, "define") == 0) { - char env[PATH_MAX]; - - 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); - one_err = 0; - } - - /* - * include - */ - if (!assgn && strcmp(parm, "include") == 0) { - meta_expand(arg, &g, NULL, version, ME_ALL); - - if (!do_read(all, version, base_dir, g.pathc ? g.pathv[0] : arg, depth+1)) - one_err = 0; - else - error("include %s failed\n", arg); - } - - /* - * above - */ - else if (all && !assgn && strcmp(parm, "above") == 0) { - decode_list(&n_abovelist, &abovelist, arg, adding, version, 0); - one_err = 0; - } - - /* - * below - */ - else if (all && !assgn && strcmp(parm, "below") == 0) { - decode_list(&n_belowlist, &belowlist, arg, adding, version, 0); - one_err = 0; - } - - /* - * prune - */ - else if (all && !assgn && strcmp(parm, "prune") == 0) { - decode_list(&n_prunelist, &prunelist, arg, adding, version, 0); - one_err = 0; - } - - /* - * probe - */ - else if (all && !assgn && strcmp(parm, "probe") == 0) { - decode_list(&n_probe_list, &probe_list, arg, adding, version, 0); - one_err = 0; - } - - /* - * probeall - */ - else if (all && !assgn && strcmp(parm, "probeall") == 0) { - decode_list(&n_probeall_list, &probeall_list, arg, adding, version, 0); - one_err = 0; - } - - /* - * options - */ - else if (all && !assgn && strcmp(parm, "options") == 0) { - decode_list(&n_opt_list, &opt_list, arg, adding, version, 1); - one_err = 0; - } - - /* - * alias - */ - else if (all && !assgn && strcmp(parm, "alias") == 0) { - /* - * Replace any previous (default) definitions - * for the same module - */ - decode_list(&n_aliases, &aliases, arg, 0, version, 0); - one_err = 0; - } - - /* - * Specification: /etc/modules.conf - * The format of the commands in /etc/modules.conf are: - * - * pre-install module command - * install module command - * post-install module command - * pre-remove module command - * remove module command - * post-remove module command - * - * The different words are separated by tabs or spaces. - */ - /* - * pre-install - */ - else if (all && !assgn && (strcmp(parm, "pre-install") == 0)) { - decode_exec(arg, EXEC_PRE_INSTALL); - one_err = 0; - } - - /* - * install - */ - else if (all && !assgn && (strcmp(parm, "install") == 0)) { - decode_exec(arg, EXEC_INSTALL); - one_err = 0; - } - - /* - * post-install - */ - else if (all && !assgn && (strcmp(parm, "post-install") == 0)) { - decode_exec(arg, EXEC_POST_INSTALL); - one_err = 0; - } - - /* - * pre-remove - */ - else if (all && !assgn && (strcmp(parm, "pre-remove") == 0)) { - decode_exec(arg, EXEC_PRE_REMOVE); - one_err = 0; - } - - /* - * remove - */ - else if (all && !assgn && (strcmp(parm, "remove") == 0)) { - decode_exec(arg, EXEC_REMOVE); - one_err = 0; - } - - /* - * post-remove - */ - else if (all && !assgn && (strcmp(parm, "post-remove") == 0)) { - decode_exec(arg, EXEC_POST_REMOVE); - one_err = 0; - } - - /* - * insmod_opt= - */ - else if (assgn && (strcmp(parm, "insmod_opt") == 0)) { - insmod_opt = xstrdup(arg); - one_err = 0; - } - - /* - * keep - */ - else if (!assgn && (strcmp(parm, "keep") == 0)) { - drop_default_paths = 0; - one_err = 0; - } - - /* - * path...= - */ - else if (assgn && strncmp(parm, "path", 4) == 0) { - /* - * Specification: config file / path parameter - * The path parameter specifies a directory to - * search for modules. - * This parameter may be repeated multiple times. - * - * Note that the actual path may be defined using - * wildcards and other shell meta-chars, such as "*?`". - * For example: - * path[misc]=/lib/modules/1.1.5?/misc - * - * Optionally the path keyword carries a tag. - * This tells us a little more about the purpose of - * this directory and allows some automated operations. - * A path is marked with a tag by adding the tag, - * enclosed in square brackets, to the path keyword: - * # - * path[boot]=/lib/modules/boot - * # - * This case identifies the path a of directory - * holding modules loadable a boot time. - */ - - if (drop_default_paths) { - int n; - - /* - * Specification: config file / path / default - * - * Whenever there is a path[] specification - * in the config file, all the default - * path are reset. - * - * If one instead wants to _add_ to the default - * set of paths, one has to have the option - * keep - * before the first path[]-specification line - * in the configuration file. - */ - drop_default_paths = 0; - for (n = 0; n < nmodpath; n++) { - free(modpath[n].path); - free(modpath[n].type); - } - nmodpath = 0; - } - - /* - * Get (the optional) tag - * If the tag is missing, the word "misc" - * is assumed. - */ - type = "misc"; - - if (parm[4] == '[') { - char *pt_type = parm + 5; - - while (*pt_type != '\0' && *pt_type != ']') - pt_type++; - - if (*pt_type == ']' && pt_type[1] == '\0') { - *pt_type = '\0'; - type = parm + 5; - } /* else CHECKME */ - } - - /* - * Handle the actual path description - */ - if (meta_expand(arg, &g, base_dir, version, ME_ALL)) - return -1; - for (glb = g.pathv; glb && *glb; ++glb) { - modpath[nmodpath].type = xstrdup(type); - modpath[nmodpath].path = *glb; - if (++nmodpath >= maxpath) { - maxpath += 100; - modpath = (struct PATH_TYPE *)xrealloc(modpath, - maxpath * sizeof(struct PATH_TYPE)); - } - } - one_err = 0; - } - - /* - * persistdir - */ - else if (assgn && strcmp(parm, "persistdir") == 0) { - meta_expand(arg, &g, NULL, version, ME_ALL); - persistdir = xstrdup(g.pathc ? g.pathv[0] : arg); - one_err = 0; - } - - /* Names for generated files in config file */ - for (i = 0; one_err && i < gen_file_count; ++i) - one_err = gen_file_conf(gen_file+i, assgn, parm, arg); - - /* - * any errors so far? - */ - if (all == 0) - one_err = 0; - else if (one_err) { - error("Invalid line %d in %s\n\t%s", - lineno, conf_file, buf); - ret = -1; - } - } - if (fin) - fclose(fin); - - if (level) { - error("missing endif at %s EOF", conf_file); - ret = -1; - } - - if (ret) - return ret; - /* else */ - - /* 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; -} - -int config_read(int all, char *force_ver, char *base_dir, char *conf_file) -{ - int r; - if (modpath != NULL) - return 0; /* already initialized */ - - if (uname(&uts_info) < 0) { - error("Failed to find kernel name information"); - return -1; - } - - r = do_read(all, force_ver, base_dir, conf_file, 0); - - if (quick && !r && !need_update (force_ver, base_dir)) - exit (0); - - return r; -} - -/****************************************************************************/ -/* - * FIXME: Far too much global state. KAO. - */ -static int found; -static int favail; -static int one_only; -static int meta_expand_type; -char **list; -static const char *filter_by_file; -static char *filter_by_dir; - -/* - * Add a file name if it exist - */ -static int config_add(const char *file, const struct stat *sb) -{ - int i; - int npaths = 0; - char **paths = NULL; - - if (meta_expand_type) { - GLOB_LIST g; - char **p; - char full[PATH_MAX]; - - snprintf(full, sizeof(full), "%s/%s", file, filter_by_file); - - if (filter_by_dir && !strstr(full, filter_by_dir)) - return 0; - - if (meta_expand(full, &g, NULL, config_version, meta_expand_type)) - return 1; - for (p = g.pathv; p && *p; ++p) { - paths = (char **)xrealloc(paths, - (npaths + 1) * sizeof(char *)); - paths[npaths++] = *p; - } - } else { /* normal path match or match with "*" */ - if (!S_ISREG(sb->st_mode)) - return 0; - - if (strcmp(filter_by_file, "*")) { - char *p; - - if ((p = strrchr(file, '/')) == NULL) - p = (char *)file; - else - p += 1; - - if (strcmp(p, filter_by_file)) - return 0; - } - if (filter_by_dir && !strstr(file, filter_by_dir)) - return 0; - paths = (char **)xmalloc(sizeof(char **)); - *paths = xstrdup(file); - npaths = 1; - } - - for (i = 0; i < npaths; ++i) { - struct stat sbuf; - - if (S_ISDIR(sb->st_mode)) { - if (stat(paths[i], &sbuf) == 0) - sb = &sbuf; - } - if (S_ISREG(sb->st_mode) && sb->st_mode & S_IRUSR) { - int j; - char **this; - - if (!root_check_off) { - if (sb->st_uid != 0) { - error("%s is not owned by root", paths[i]); - continue; - } - } - - /* avoid duplicates */ - for (j = 0, this = list; j < found; ++j, ++this) { - if (strcmp(*this, paths[i]) == 0) { - free(paths[i]); - goto next; - } - } - - list[found] = paths[i]; - if (++found >= favail) - list = (char **)xrealloc(list, - (favail += 100) * sizeof(char *)); - - if (one_only) { - for (j = i + 1; j < npaths; ++j) - free(paths[j]); - free(paths); - return 1; /* finish xftw */ - } - } - next: - } - - if (npaths > 0) - free(paths); - - return 0; -} - -/* - * Find modules matching the name "match" in directory of type "type" - * (type == NULL matches all) - * - * Return a pointer to the list of modules found (or NULL if error). - * Update the counter (sent as parameter). - */ -GLOB_LIST *config_lstmod(const char *match, const char *type, int first_only) -{ - /* - * Note: - * There are _no_ wildcards remaining in the path descriptions! - */ - struct stat sb; - int i; - int ret = 0; - char *path = NULL; - char this[PATH_MAX]; - - if (!match) - match = "*"; - one_only = first_only; - found = 0; - filter_by_file = match; - filter_by_dir = NULL; - if (type) { - char tmpdir[PATH_MAX]; - snprintf(tmpdir, sizeof(tmpdir), "/%s/", type); - filter_by_dir = xstrdup(tmpdir); - } - /* In safe mode, the module name is always handled as is, without meta - * expansion. It might have come from an end user via kmod and must - * not be trusted. Even in unsafe mode, only apply globbing to the - * module name, not command expansion. We trust config file input so - * applying command expansion is safe, we do not trust command line input. - * This assumes that the only time the user can specify -C config file - * is when they run under their own authority. In particular all - * mechanisms that call modprobe as root on behalf of the user must - * run in safe mode, without letting the user supply a config filename. - */ - meta_expand_type = 0; - if (strpbrk(match, SHELL_META) && strcmp(match, "*") && !safemode) - meta_expand_type = ME_GLOB|ME_BUILTIN_COMMAND; - - list = (char **)xmalloc((favail = 100) * sizeof(char *)); - - for (i = 0; i < nmodpath; i++) { - path = modpath[i].path; - /* Special case: insmod: handle single, non-wildcard match */ - if (first_only && strpbrk(match, SHELL_META) == NULL) { - /* Fix for "2.1.121 syntax */ - snprintf(this, sizeof(this), "%s/%s/%s", path, - modpath[i].type, match); - if (stat(this, &sb) == 0 && - config_add(this, &sb)) - break; - /* End fix for "2.1.121 syntax */ - - snprintf(this, sizeof(this), "%s/%s", path, match); - if (stat(this, &sb) == 0 && - config_add(this, &sb)) - break; - } - - /* Start looking */ - if ((ret = xftw(path, config_add))) { - break; - } - } - if (ret >= 0) { - GLOB_LIST *g = (GLOB_LIST *)xmalloc(sizeof(GLOB_LIST)); - g->pathc = found; - g->pathv = list; - free(filter_by_dir); - return g; - } - free(list); - free(filter_by_dir); - return NULL; -} - -/* Given a bare module name, poke through the module path to find the file. */ -char *search_module_path(const char *base) -{ - GLOB_LIST *g; - - if (config_read(0, NULL, "", NULL) < 0) - return NULL; - /* else */ - g = config_lstmod(base, NULL, 1); - if (g == NULL || g->pathc == 0) { - char base_o[PATH_MAX]; - - snprintf(base_o, sizeof(base_o), "%s.o", base); - g = config_lstmod(base_o, NULL, 1); -#ifdef CONFIG_USE_ZLIB - if (g == NULL || g->pathc == 0) { - snprintf(base_o, sizeof(base_o), "%s.o.gz", base); - g = config_lstmod(base_o, NULL, 1); - } -#endif - } - if (g == NULL || g->pathc == 0) - return NULL; - /* else */ - return g->pathv[0]; -} diff --git a/mdk-stage1/insmod-modutils/util/gzfiles.c b/mdk-stage1/insmod-modutils/util/gzfiles.c deleted file mode 100644 index 8d02253bb..000000000 --- a/mdk-stage1/insmod-modutils/util/gzfiles.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This simple library intends to make it transparent to read gzipped and/or - * standard files. This is simple enough to fit modutils' needs, but may be - * easily adapted to anyone's needs. It's completely free, do what you want - * with it . - Willy Tarreau <willy@meta-x.org> - 2000/05/05 - - */ - -#ifdef CONFIG_USE_ZLIB - -#include <stdio.h> -#include <zlib.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> - -/* redefinition of gz_stream which isn't exported by zlib */ -typedef struct gz_stream { - z_stream stream; - int z_err; /* error code for last stream operation */ - int z_eof; /* set if end of input file */ - FILE *file; /* .gz file */ - Byte *inbuf; /* input buffer */ - Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ - char *msg; /* error message */ - char *path; /* path name for debugging only */ - int transparent; /* 1 if input file is not a .gz file */ - char mode; /* 'w' or 'r' */ - long startpos; /* start of compressed data in file (header skipped) */ -} gz_stream; - -/* maximum number of simultaneous open files, also greater file descriptor number */ -#define MAXFD 64 - -/* this static list is assumed to be filled with NULLs at runtime */ -static gzFile gzf_fds[MAXFD]; - -/* returns the filedesc of the opened file. */ -int gzf_open(const char *name, int mode) { - int fd; - gzFile g; - - if ((g=gzopen(name, "rb")) != NULL) { - fd=fileno(((gz_stream*)g)->file); - gzf_fds[fd]=g; - } - else if ((fd=open(name, mode)) != -1) { - gzf_fds[fd]=NULL; /* NULL means not GZ mode */ - } - return fd; -} - -off_t gzf_lseek(int fd, off_t offset, int whence) { - if (fd<0 || fd>=MAXFD || gzf_fds[fd]==NULL) - return lseek(fd, offset, whence); - else - return gzseek(gzf_fds[fd], offset, whence); -} - -int gzf_read(int fd, void *buf, size_t count) { - if (fd<0 || fd>=MAXFD || gzf_fds[fd]==NULL) - return read(fd, buf, count); - else - return gzread(gzf_fds[fd], buf, count); -} - -void gzf_close(int fd) { - if (fd<0 || fd>=MAXFD || gzf_fds[fd]==NULL) - close(fd); - else - gzclose(gzf_fds[fd]); -} -#endif - diff --git a/mdk-stage1/insmod-modutils/util/logger.c b/mdk-stage1/insmod-modutils/util/logger.c deleted file mode 100644 index 3b790df5a..000000000 --- a/mdk-stage1/insmod-modutils/util/logger.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Error logging facilities. - Copyright 1996, 1997 Linux International. - - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <errno.h> -#include <syslog.h> - -#include "util.h" - -/*======================================================================*/ - -int errors; -const char *error_file; -int log; - -#define STOREMSG -#ifdef STOREMSG -struct cbuf { - struct cbuf *next; - int type; - 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); -} - -void setsyslog(const char *program) -{ - openlog(program, LOG_CONS, LOG_DAEMON); -#ifdef STOREMSG - atexit(dumpmsg); -#endif - log = 1; -} - - - -#ifdef _STANDALONE_ -static int silent; - -const char *program_name; - -void error(const char *fmt,...) -{ - va_list args; - - if (silent) - ; - else if (log) { - char buf[1024]; - int n; - - if (error_file) - n = snprintf(buf, sizeof(buf), "%s: ", error_file); - else - n = 0; - va_start(args, fmt); - vsnprintf(buf + n, sizeof(buf) - n, fmt, args); - va_end(args); -#ifdef STOREMSG - savemsg(LOG_ERR, buf); -#else - syslog(LOG_ERR, "%s", buf); -#endif - } else { - if (error_file) - fprintf(stderr, "%s: ", error_file); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - putc('\n', stderr); - } - - errors++; -} - -void lprintf(const char *fmt,...) -{ - va_list args; - - if (silent); - else if (log) { - char buf[1024]; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); -#ifdef STOREMSG - savemsg(LOG_INFO, buf); -#else - syslog(LOG_INFO, "%s", buf); -#endif - } else { - va_start(args, fmt); - vfprintf(stdout, fmt, args); - va_end(args); - putchar('\n'); - } -} - -#else /* _STANDALONE_ */ -#include "../../log.h" -void error(const char *s, ...) -{ - va_list p; - - va_start(p, s); - vlog_message(s, p); - va_end(p); -} - -void lprintf(const char *s, ...) -{ - va_list p; - - va_start(p, s); - vlog_message(s, p); - va_end(p); -} -#endif diff --git a/mdk-stage1/insmod-modutils/util/meta_expand.c b/mdk-stage1/insmod-modutils/util/meta_expand.c deleted file mode 100644 index 41fb4024c..000000000 --- a/mdk-stage1/insmod-modutils/util/meta_expand.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Handle expansion of meta charaters - * - * Copyright 1999 Björn Ekwall <bj0rn@blox.se> - * - * "kernelversion" idea from the Debian release via: - * Wichert Akkerman <wakkerma@cs.leidenuniv.nl> - * - * Use wordexp(): idea from Tim Waugh <tim@cyberelk.demon.co.uk> - * - * Alpha typecast: Michal Jaegermann <michal@ellpspace.math.ualberta.ca> - * - * 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. - */ - -#ifdef HAVE_WORDEXP -#undef HAVE_WORDEXP -#define HAVE_WORDEXP 0 -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <ctype.h> -#if HAVE_WORDEXP -#include <wordexp.h> -#elif HAVE_GLOB -#include <glob.h> -#endif -#include "util.h" - -/* - * Split into words delimited by whitespace, - * handle remaining quotes though... - * If strip_quotes != 0 then strip one level of quotes from the line. - */ -static void split_line(GLOB_LIST *g, char *line, int strip_quotes) -{ - int len; - char *d; - char *e; - char *p; - char tmpline[PATH_MAX]; - - for (p = line; *p; p = e) { - /* Skip leading whitespace */ - while (*p && isspace(*p)) - ++p; - - /* find end of word */ - d = tmpline; - for (e = p; *e && !(isspace(*e)); ++e) { - char match; - - /* Quote handling */ - switch (*e) { - case '\\': - if (!strip_quotes) - *d++ = *e; - break; - - case '"': - case '\'': - match = *e; - if (!strip_quotes) - *d++ = *e; - for (++e; *e && *e != match; ++e) { - *d++ = *e; - if (*e == '\\' && *(e + 1) == match) - *d++ = *++e; - } - if (!strip_quotes) - *d++ = *e; - break; - - default: - *d++ = *e; - break; - } - } - - if ((len = (int)(d - tmpline)) > 0) { - char *str = xmalloc(len + 1); - strncpy(str, tmpline, len); - str[len] = '\0'; - g->pathv = (char **)xrealloc(g->pathv, - (g->pathc + 2) * sizeof(char *)); - g->pathv[g->pathc++] = str; - } - } - - if (g->pathc) - g->pathv[g->pathc] = NULL; -} - -static int glob_it(char *pt, GLOB_LIST *g) -{ -#if HAVE_WORDEXP - wordexp_t w; - - memset(&w, 0, sizeof(w)); - if (wordexp(pt, &w, WRDE_UNDEF)) { - /* - error("wordexp %s failed", pt); - */ - return -1; - } - /* else */ - g->pathc = w.we_wordc; - g->pathv = w.we_wordv; - - return 0; -#elif HAVE_GLOB /* but not wordexp */ - glob_t w; - - memset(&w, 0, sizeof(w)); - if (glob(pt, GLOB_NOSORT, NULL, &w)) { - /* - error("glob %s failed", pt); - */ - return -1; - } - /* else */ - if (w.gl_pathc && strpbrk(w.gl_pathv[0], SHELL_META)) { - globfree(&w); - return -1; - } - g->pathc = w.gl_pathc; - g->pathv = w.gl_pathv; - - return 0; -#else /* Neither wordexp nor glob */ - return -1; -#endif -} - -/* - * Expand the string (including meta-character) to a list of matches - * - * Return 0 if OK else -1 - */ -int meta_expand(char *pt, GLOB_LIST *g, char *base_dir, char *version, int type) -{ - FILE *fin; - int len = 0; - char *line = NULL; - char *p, *p1; - char tmpline[PATH_MAX + 1]; - char wrk[sizeof(tmpline)]; - char tmpcmd[2*sizeof(tmpline)+20]; /* room for /bin/echo "text" */ - - g->pathc = 0; - g->pathv = NULL; - - /* - * Take care of version dependent expansions - * Needed for forced version handling - */ - if ((p = strchr(pt, '`')) != NULL && (type & ME_BUILTIN_COMMAND)) { - do { - char *s; - - for (s = p + 1; isspace(*s); ++s) - ; - - if (strncmp(s, "uname -r", 8) == 0) { - while (*s && (*s != '`')) - ++s; - if (*s == '`') { - *p = '\0'; - snprintf(wrk, sizeof(wrk), "%s%s%s", - pt, - version, - s + 1); - *p = '`'; - } - strcpy(tmpline, wrk); /* safe, same size */ - pt = tmpline; - } else if (strncmp(s, "kernelversion", 13) == 0) { - while (*s && (*s != '`')) - ++s; - if (*s == '`') { - int n; - char *k; - - *p = '\0'; - for (n = 0, k = version; *k; ++k) { - if (*k == '.' && ++n == 2) - break; - } - snprintf(wrk, sizeof(wrk), "%s%.*s%s", - pt, - /* typecast for Alpha */ - (int)(k - version), - version, - s + 1); - *p = '`'; - strcpy(tmpline, wrk); /* safe, same size */ - pt = tmpline; - } - } else - break; - } while ((p = strchr(pt, '`')) != NULL); - } - - /* - * Any remaining meta-chars? - */ - if (strpbrk(pt, SHELL_META) == NULL) { - /* - * No meta-chars. - * Split into words, delimited by whitespace. - */ - snprintf(wrk, sizeof(wrk), "%s%s", (base_dir ? base_dir : ""), pt); - strcpy(tmpline, wrk); /* safe, same size */ - if ((p = strtok(tmpline, " \t\n")) != NULL) { - while (p) { - g->pathv = (char **)xrealloc(g->pathv, - (g->pathc + 2) * sizeof(char *)); - g->pathv[g->pathc++] = xstrdup(p); - p = strtok(NULL, " \t\n"); - } - } - if (g->pathc) - g->pathv[g->pathc] = NULL; - return 0; - } - /* else */ - /* - * Handle remaining meta-chars - */ - - /* - * Just plain quotes? - */ - if (strpbrk(pt, "&();|<>$`!{}[]~=+:?*") == NULL && - (p = strpbrk(pt, "\"'\\"))) { - split_line(g, pt, 1); - return 0; - } - - if (strpbrk(pt, "&();|<>$`\"'\\!{}~+:[]~?*") == NULL) { - /* Only "=" remaining, should be module options */ - split_line(g, pt, 0); - return 0; - } - - /* - * If there are meta-characters and - * if they are only shell glob meta-characters: do globbing - */ -#if HAVE_WORDEXP - if (strpbrk(pt, "&();|<>`\"'\\!{}~=+:") == NULL && - strpbrk(pt, "$[]~?*")) -#else - if (strpbrk(pt, "&();|<>$`\"'\\!{}~=+:") == NULL && - strpbrk(pt, "[]~?*")) -#endif - if ((type & ME_GLOB) && glob_it(pt, g) == 0) - return 0; - - if (strpbrk(pt, "&();|<>$`\"'\\!{}~+:[]~?*") == NULL) { - /* Only "=" remaining, should be module options */ - split_line(g, pt, 0); - return 0; - } - - /* - * Last resort: Use "echo". - * DANGER: Applying shell expansion to user supplied input is a - * major security risk. Modutils code should only do meta - * expansion via shell commands for trusted data. Basically - * this means only for data in the config file. Even that - * assumes that the user cannot run modprobe as root with - * their own config file. Programs (including the kernel) - * that invoke modprobe as root with user supplied input must - * pass exactly one user supplied parameter and must set - * safe mode. - */ - if (!(type & ME_SHELL_COMMAND)) - return 0; - snprintf(wrk, sizeof(wrk), "%s%s", (base_dir ? base_dir : ""), pt); - strcpy(tmpline, wrk); /* safe, same size */ - snprintf(tmpcmd, sizeof(tmpcmd), "/bin/echo \""); - for (p = tmpline, p1 = tmpcmd + strlen(tmpcmd); *p; ++p, ++p1) { - if (*p == '"' || *p == '\\') - *p1++ = '\\'; - *p1 = *p; - } - *p1++ = '"'; - *p1++ = '\0'; - if (p1 - tmpcmd > sizeof(tmpcmd)) { - error("tmpcmd overflow, should never happen"); - exit(1); - } - if ((fin = popen(tmpcmd, "r")) == NULL) { - error("Can't execute: %s", tmpcmd); - return -1; - } - /* else */ - - /* - * Collect the result - */ - while (fgets(tmpcmd, PATH_MAX, fin) != NULL) { - int l = strlen(tmpcmd); - - line = (char *)xrealloc(line, len + l + 1); - line[len] = '\0'; - strcat(line + len, tmpcmd); /* safe, realloc */ - len += l; - } - pclose(fin); - - if (line) { - /* shell used to strip one set of quotes. Paranoia code in - * 2.3.20 stops that strip so we do it ourselves. - */ - split_line(g, line, 1); - free(line); - } - - return 0; -} diff --git a/mdk-stage1/insmod-modutils/util/modstat.c b/mdk-stage1/insmod-modutils/util/modstat.c deleted file mode 100644 index ad82306c0..000000000 --- a/mdk-stage1/insmod-modutils/util/modstat.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Get kernel symbol table(s) and other relevant module info. - * - * Add module_name_list and l_module_name_list. - * Keith Owens <kaos@ocs.com.au> November 1999. - * Björn Ekwall <bj0rn@blox.se> in February 1999 (C) - * Initial work contributed by Richard Henderson <rth@tamu.edu> - * - * 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 <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include "util.h" -#include "module.h" -#include "obj.h" -#include "modstat.h" - -struct module_stat *module_stat; -size_t n_module_stat; -char *module_name_list; -size_t l_module_name_list; -struct module_symbol *ksyms; -size_t nksyms; -int k_new_syscalls; - -static void *old_kernsym; - -/************************************************************************/ -static void drop(void) -{ - /* - * Clean the slate for multiple runs - */ - if (module_stat) { - struct module_stat *m; - int i; - - for (i = 0, m = module_stat; i < n_module_stat; ++i, ++m) { - if (m->syms) - free(m->syms); - if (m->refs) - free(m->refs); - } - free(module_stat); - module_stat = NULL; - n_module_stat = 0; - } - if (module_name_list) { - free(module_name_list); - module_name_list = NULL; - l_module_name_list = 0; - } - if (ksyms) { - free(ksyms); - ksyms = NULL; - nksyms = 0; - } - if (old_kernsym) { - free(old_kernsym); - old_kernsym = NULL; - } -} - -static int new_get_kernel_info(int type) -{ - struct module_stat *modules; - struct module_stat *m; - struct module_symbol *syms; - struct module_symbol *s; - size_t ret; - size_t bufsize; - size_t nmod; - size_t nsyms; - size_t i; - size_t j; - char *module_names; - char *mn; - - drop(); - - /* - * Collect the loaded modules - */ - module_names = xmalloc(bufsize = 256); - while (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { - if (errno != ENOSPC) { - error("QM_MODULES: %m\n"); - return 0; - } - module_names = xrealloc(module_names, bufsize = ret); - } - module_name_list = module_names; - l_module_name_list = bufsize; - n_module_stat = nmod = ret; - module_stat = modules = xmalloc(nmod * sizeof(struct module_stat)); - memset(modules, 0, nmod * sizeof(struct module_stat)); - - /* Collect the info from the modules */ - for (i = 0, mn = module_names, m = modules; - i < nmod; - ++i, ++m, mn += strlen(mn) + 1) { - struct module_info info; - - m->name = mn; - if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) { - if (errno == ENOENT) { - /* The module was removed out from underneath us. */ - m->flags = NEW_MOD_DELETED; - continue; - } - /* else oops */ - error("module %s: QM_INFO: %m", mn); - return 0; - } - - m->addr = info.addr; - - if (type & K_INFO) { - m->size = info.size; - m->flags = info.flags; - m->usecount = info.usecount; - m->modstruct = info.addr; - } - - if (type & K_REFS) { - int mm; - char *mrefs; - char *mr; - - mrefs = xmalloc(bufsize = 64); - while (query_module(mn, QM_REFS, mrefs, bufsize, &ret)) { - if (errno != ENOSPC) { - error("QM_REFS: %m"); - return 1; - } - mrefs = xrealloc(mrefs, bufsize = ret); - } - for (j = 0, mr = mrefs; - j < ret; - ++j, mr += strlen(mr) + 1) { - for (mm = 0; mm < i; ++mm) { - if (strcmp(mr, module_stat[mm].name) == 0) { - m->nrefs += 1; - m->refs = xrealloc(m->refs, m->nrefs * sizeof(struct module_stat **)); - m->refs[m->nrefs - 1] = module_stat + mm; - break; - } - } - } - free(mrefs); - } - - if (type & K_SYMBOLS) { /* Want info about symbols */ - syms = xmalloc(bufsize = 1024); - while (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { - if (errno == ENOSPC) { - syms = xrealloc(syms, bufsize = ret); - continue; - } - if (errno == ENOENT) { - /* - * The module was removed out - * from underneath us. - */ - m->flags = NEW_MOD_DELETED; - free(syms); - goto next; - } else { - error("module %s: QM_SYMBOLS: %m", mn); - return 0; - } - } - nsyms = ret; - - m->nsyms = nsyms; - m->syms = syms; - - /* Convert string offsets to string pointers */ - for (j = 0, s = syms; j < nsyms; ++j, ++s) - s->name += (unsigned long) syms; - } - next: - } - - if (type & K_SYMBOLS) { /* Want info about symbols */ - /* Collect the kernel's symbols. */ - syms = xmalloc(bufsize = 16 * 1024); - while (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { - if (errno != ENOSPC) { - error("kernel: QM_SYMBOLS: %m"); - return 0; - } - syms = xrealloc(syms, bufsize = ret); - } - nksyms = nsyms = ret; - ksyms = syms; - - /* Convert string offsets to string pointers */ - for (j = 0, s = syms; j < nsyms; ++j, ++s) - s->name += (unsigned long) syms; - } - - return 1; -} - -#ifdef COMPAT_2_0 -/************************************************************************/ - -#define mscan(offs,siz,ptr) \ - if (lseek(kmem_fd, (off_t)(offs), SEEK_SET) == -1 || \ - read(kmem_fd, (ptr), (siz)) != (siz)) { \ - if (kmem_fd != -1) \ - close(kmem_fd); \ - error("kmem: %m"); \ - return 0; \ - } - -#define OLD_MOD_RUNNING 1 -#define OLD_MOD_DELETED 2 -#define OLD_MOD_VISITED 0x20000000 - -/* Fetch all the symbols and divvy them up as appropriate for the modules. */ -static int old_get_kernel_info(int type) -{ - struct old_kernel_sym *kernsym; - struct old_kernel_sym *k; - struct module_stat *module; - struct module_stat *mod; - struct module_symbol *s = NULL; - int kmem_fd = -1; - int nkernsym; - int nmod; - int nm; - int nms; - int i; - - drop(); - module_name_list = xmalloc(1); - *module_name_list = '\0'; - - if ((nkernsym = get_kernel_syms(NULL)) < 0) { - error("get_kernel_syms: %m"); - return 0; - } - kernsym = k = xmalloc(nkernsym * sizeof(struct old_kernel_sym)); - old_kernsym = kernsym; - if (get_kernel_syms(kernsym) != nkernsym) { - error("inconsistency with get_kernel_syms -- is someone else " - "playing with modules?"); - free(kernsym); - return 0; - } - - /* Number of modules */ - for (k = kernsym, nmod = 0, i = 0; i < nkernsym; ++i, ++k) { - if (k->name[0] == '#') { - if (k->name[1]) { - ++nmod; - i = strlen(k->name+1) + 1; - module_name_list = - xrealloc(module_name_list, - l_module_name_list + i); - strcpy(module_name_list+l_module_name_list, /* safe, xrealloc */ - k->name+1); - l_module_name_list += i; /* NUL separated strings */ - } - else - break; - } - } - module_stat = mod = module = xmalloc(nmod * sizeof(struct module_stat)); - memset(module, 0, nmod * sizeof(struct module_stat)); - n_module_stat = nmod; - - /* - * Will we need kernel internal info? - */ - if ((type & K_INFO) || (type & K_REFS)) { - if ((kmem_fd = open("/dev/kmem", O_RDONLY)) < 0) { - perror("ksyms: open /dev/kmem"); - return 0; - } - } - - /* - * Collect the module information. - */ - for (k = kernsym, nm = 0, i = 0; i < nkernsym; ++i, ++k) { - if (k->name[0] == '#') { - struct old_kernel_sym *p; - struct old_module info; - - if (k->name[1] == '\0') - break; /* kernel resident symbols follow */ - /* else normal module */ - - module = mod++; - ++nm; - module->name = k->name + 1; - module->modstruct = k->value; - - if ((type & K_INFO) || (type & K_REFS)) { - long tmp; - /* - * k->value is the address of the - * struct old_module - * in the kernel (for use via /dev/kmem) - */ - mscan(k->value, sizeof(info), &info); - module->addr = info.addr; - module->size = info.size * getpagesize(); - - mscan(info.addr, sizeof(long), &tmp); - module->flags = info.state & - (OLD_MOD_RUNNING | OLD_MOD_DELETED); - module->flags |= NEW_MOD_USED_ONCE; /* Cheat */ - if (tmp & OLD_MOD_AUTOCLEAN) - module->flags |= NEW_MOD_AUTOCLEAN; - if (tmp & OLD_MOD_VISITED) - module->flags |= NEW_MOD_VISITED; - - module->usecount = tmp & ~(OLD_MOD_AUTOCLEAN | OLD_MOD_VISITED); - } - - if ((type & K_REFS) && info.ref) { - struct old_module_ref mr; - int j; - unsigned long ref = info.ref; - - do { - mscan(ref, sizeof(struct old_module_ref), &mr); - for (j = 0; j < nm -1; ++j) { - if (mr.module == module_stat[j].modstruct) { - module->nrefs += 1; - module->refs = xrealloc(module->refs, module->nrefs * sizeof(struct module_stat **)); - module->refs[module->nrefs - 1] = module_stat + j; - break; - } - } - } while ((ref = mr.next) != 0); - } - - if (!(type & K_SYMBOLS)) - continue; - /* - * Find out how many symbols this module has. - */ - for (nms = 0, p = k+1; p->name[0] != '#'; ++p) - ++nms; - s = xmalloc(nms * sizeof(struct module_symbol)); - module->syms = s; - module->nsyms = nms; - } else if (type & K_SYMBOLS) { /* Want info about symbols */ - s->name = (unsigned long) k->name; - s->value = k->value; - ++s; - } - } - if ((type & K_INFO) || (type & K_REFS)) { - if (kmem_fd != -1) - close(kmem_fd); - } - - /* - * Kernel resident symbols follows - */ - if (type & K_SYMBOLS) { /* Want info about symbols */ - if (k->name[0] == '#') - ++k; - nksyms = nkernsym - (k - kernsym); - if (nksyms) { - ksyms = s = xmalloc(nksyms * sizeof(struct module_symbol)); - for (i = 0; i < nksyms; ++i, ++k) { - if (k->name[0] != '#') { - s->name = (unsigned long) k->name; - s->value = k->value; - ++s; - } - } - nksyms = s - ksyms; - } else - ksyms = NULL; - } - - return 1; -} -#endif /* COMPAT_2_0 */ - -int get_kernel_info(int type) -{ - k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL); - -#ifdef COMPAT_2_0 - if (!k_new_syscalls) - return old_get_kernel_info(type); -#endif /* COMPAT_2_0 */ - - return new_get_kernel_info(type); -} diff --git a/mdk-stage1/insmod-modutils/util/snap_shot.c b/mdk-stage1/insmod-modutils/util/snap_shot.c deleted file mode 100644 index ae0cc7c79..000000000 --- a/mdk-stage1/insmod-modutils/util/snap_shot.c +++ /dev/null @@ -1,154 +0,0 @@ -/* Take a snap shot of ksyms and modules for Oops debugging - Copyright 1999 Linux International. - - Contributed by Keith Owens <kaos@ocs.com.au> - - 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 <errno.h> -#include <stdio.h> -#include <stdarg.h> -#include <time.h> -#include <unistd.h> -#include <string.h> - -#include "module.h" -#include "obj.h" -#include "modstat.h" -#include "util.h" - -static char snap_dir[] = "/var/log/ksymoops"; - -/* If snap_dir exists, take a snap shot of ksyms and modules to snap_dir. - * Prefix the files with the equivalent of - * date +%Y%m%d%T%M%S | sed -e 's/://g' - */ -void snap_shot(const char *module_names, int n_module_names) -{ - char file[] = "ccyymmddhhmmss.modules", buffer[4096]; - static char *infile[] = { "/proc/ksyms", "/proc/modules" }; - static char *suffix[] = { "ksyms", "modules" }; - struct tm *local; - time_t t; - int i, l; - FILE *in, *out; - - if (module_names) { - /* Only snap shot if the list of modules has changed. - * Otherwise auto cleanup takes a snap shot every time - * and ends up with a large snap shot directory. - */ - char *new_module_names; - size_t n_new_module_names; - get_kernel_info(0); - new_module_names = module_name_list; - n_new_module_names = n_module_stat; - if (n_module_names && n_new_module_names == n_module_names) { - while (n_module_names) { - if (strcmp(module_names, new_module_names)) - break; /* difference detected */ - i = strlen(module_names) + 1; - module_names += i; - new_module_names += i; - --n_module_names; - } - } - if (!n_module_names) - return; /* no difference, no need for snap shot */ - } - - if (chdir(snap_dir)) - return; - t = time(NULL); - local = localtime(&t); - for (i = 0; i < sizeof(infile)/sizeof(infile[0]); ++i) { - snprintf(file, sizeof(file), "%04d%02d%02d%02d%02d%02d.%s", - local->tm_year+1900, - local->tm_mon + 1, - local->tm_mday, - local->tm_hour, - local->tm_min, - local->tm_sec, - suffix[i]); - out = fopen(file, "w"); - if (!out) { - error("cannot create %s/%s %m", snap_dir, file); - return; - } - in = fopen(infile[i], "r"); - if (!in) { - error("cannot open %s %m", infile[i]); - return; - } - while ((l = fread(buffer, 1, sizeof(buffer), in)) > 0) { - if (fwrite(buffer, l, 1, out) != 1) { - error("unable to write to %s %m", file); - fclose(in); - fclose(out); - return; - } - } - if (ferror(in)) - error("unable to read from %s %m", infile[i]); - fclose(in); - fclose(out); - } -} - -/* If snap_dir exists, log a message to snap_dir. The log file is called the - * equivalent of date +%Y%m%d | sed -e 's/://g'. Each line is prefixed with - * timestamp down to seconds and followed by a newline. - */ -void snap_shot_log(const char *fmt,...) -{ - char date[] = "ccyymmdd", file[] = "ccyymmdd.log", stamp[] = "ccyymmdd hhmmss"; - struct tm *local; - time_t t; - FILE *log; - va_list args; - int save_errno = errno; - - if (chdir(snap_dir)) - return; - t = time(NULL); - local = localtime(&t); - snprintf(date, sizeof(date), "%04d%02d%02d", - local->tm_year+1900, - local->tm_mon + 1, - local->tm_mday); - snprintf(file, sizeof(file), "%s.log", date); - log = fopen(file, "a"); - if (!log) { - error("cannot create %s/%s %m", snap_dir, file); - return; - } - snprintf(stamp, sizeof(stamp), "%s %02d%02d%02d", - date, - local->tm_hour, - local->tm_min, - local->tm_sec); - fprintf(log, "%s ", stamp); - va_start(args, fmt); - errno = save_errno; /* fmt may use %m */ - vfprintf(log, fmt, args); - va_end(args); - fprintf(log, "\n"); - fclose(log); -} diff --git a/mdk-stage1/insmod-modutils/util/sys_cm.c b/mdk-stage1/insmod-modutils/util/sys_cm.c deleted file mode 100644 index 851fb709e..000000000 --- a/mdk-stage1/insmod-modutils/util/sys_cm.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Functions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <errno.h> - -#include "module.h" - -/* Kernel headers before 2.1.mumble need this on the Alpha to get - _syscall* defined. */ -#define __LIBRARY__ - -#include <asm/unistd.h> - - -/*======================================================================*/ - -#if defined(__i386__) || defined(__m68k__) || defined(__arm__) - -#define __NR__create_module __NR_create_module -static inline _syscall2(long, _create_module, const char *, name, size_t, size) - -unsigned long create_module(const char *name, size_t size) -{ - /* Why all this fuss? - - In linux 2.1, the address returned by create module point in - kernel space which is now mapped at the top of user space (at - 0xc0000000 on i386). This looks like a negative number for a - long. The normal syscall macro of linux 2.0 (and all libc compile - with linux 2.0 or below) consider that the return value is a - negative number and consider it is an error number (A kernel - convention, return value are positive or negative, indicating the - error number). - - By checking the value of errno, we know if we have been fooled by - the syscall2 macro and we fix it. */ - - long ret = _create_module(name, size); - if (ret == -1 && errno > 125) - { - ret = -errno; - errno = 0; - } - return ret; -} - -#elif defined(__alpha__) - -/* Alpha doesn't have the same problem, exactly, but a bug in older - kernels fails to clear the error flag. Clear it here explicitly. */ - -#define __NR__create_module __NR_create_module -static inline _syscall4(unsigned long, _create_module, const char *, name, - size_t, size, size_t, dummy, size_t, err); - -unsigned long create_module(const char *name, size_t size) -{ - return _create_module(name, size, 0, 0); -} - -#else - -/* Sparc, MIPS, (and Alpha, but that's another problem) don't mistake - return values for errors due to the nature of the system call. */ - -_syscall2(unsigned long, create_module, const char *, name, size_t, size) - -#endif diff --git a/mdk-stage1/insmod-modutils/util/sys_dm.c b/mdk-stage1/insmod-modutils/util/sys_dm.c deleted file mode 100644 index a166a30f4..000000000 --- a/mdk-stage1/insmod-modutils/util/sys_dm.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Functions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <errno.h> - -#include "module.h" - -/* Kernel headers before 2.1.mumble need this on the Alpha to get - _syscall* defined. */ -#define __LIBRARY__ - -#include <asm/unistd.h> - - -/*======================================================================*/ - -_syscall1(int, delete_module, const char *, name) diff --git a/mdk-stage1/insmod-modutils/util/sys_gks.c b/mdk-stage1/insmod-modutils/util/sys_gks.c deleted file mode 100644 index f71772c71..000000000 --- a/mdk-stage1/insmod-modutils/util/sys_gks.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Functions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <errno.h> - -#include "module.h" - -/* Kernel headers before 2.1.mumble need this on the Alpha to get - _syscall* defined. */ -#define __LIBRARY__ - -#include <asm/unistd.h> - - -/*======================================================================*/ - -_syscall1(int, get_kernel_syms, struct old_kernel_sym *, ksyms) diff --git a/mdk-stage1/insmod-modutils/util/sys_nim.c b/mdk-stage1/insmod-modutils/util/sys_nim.c deleted file mode 100644 index bbe42135c..000000000 --- a/mdk-stage1/insmod-modutils/util/sys_nim.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Functions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <errno.h> - -#include "module.h" - -/* Kernel headers before 2.1.mumble need this on the Alpha to get - _syscall* defined. */ -#define __LIBRARY__ - -#include <asm/unistd.h> - - -/*======================================================================*/ - -#ifndef CONFIG_USE_SYSCALL - -extern int init_module(const char *name, const struct module *info); - -int -sys_init_module(const char *name, const struct module *info) -{ - return init_module(name, info); -} - -#else - -#define __NR_sys_init_module __NR_init_module -_syscall2(int, sys_init_module, const char *, name, - const struct module *, info) - -#endif diff --git a/mdk-stage1/insmod-modutils/util/sys_oim.c b/mdk-stage1/insmod-modutils/util/sys_oim.c deleted file mode 100644 index 73ac6be52..000000000 --- a/mdk-stage1/insmod-modutils/util/sys_oim.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Functions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <errno.h> - -#include "module.h" - -/* Kernel headers before 2.1.mumble need this on the Alpha to get - _syscall* defined. */ -#define __LIBRARY__ - -#include <asm/unistd.h> - - -/*======================================================================*/ - -#define __NR_old_sys_init_module __NR_init_module -_syscall5(int, old_sys_init_module, const char *, name, char *, code, - unsigned, codesize, struct old_mod_routines *, routines, - struct old_symbol_table *, symtab) diff --git a/mdk-stage1/insmod-modutils/util/sys_qm.c b/mdk-stage1/insmod-modutils/util/sys_qm.c deleted file mode 100644 index 119a219a2..000000000 --- a/mdk-stage1/insmod-modutils/util/sys_qm.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Functions for the Linux module syscall interface. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <errno.h> - -#include "module.h" - -/* Kernel headers before 2.1.mumble need this on the Alpha to get - _syscall* defined. */ -#define __LIBRARY__ - -#include <asm/unistd.h> - - -/*======================================================================*/ - -/* I am fucking tired of the "this doesn't build on 2.0.x" questions. - But if you ask, we still officially require 2.1.x to build. */ -#if !defined(__NR_query_module) -# if defined(__i386__) -# define __NR_query_module 167 -# elif defined(__alpha__) -# define __NR_query_module 347 -# elif defined(__sparc__) -# define __NR_query_module 184 -# elif defined(__mc68000__) -# define __NR_query_module 167 -# elif defined(__arm__) -# define __NR_query_module (__NR_SYSCALL_BASE + 167) -# elif defined(__mips__) -# define __NR_query_module 4187 -# endif -#endif - -_syscall5(int, query_module, const char *, name, int, which, - void *, buf, size_t, bufsize, size_t *, ret); diff --git a/mdk-stage1/insmod-modutils/util/xftw.c b/mdk-stage1/insmod-modutils/util/xftw.c deleted file mode 100644 index fe764a63c..000000000 --- a/mdk-stage1/insmod-modutils/util/xftw.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * modutils specific implementation of ftw(). - * - * Copyright 2000: - * Keith Owens <kaos@ocs.com.au> August 2000 - * - * 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. - */ - -/* - modutils requires special processing during the file tree walk - of /lib/modules/<version> and any paths that the user specifies. - The standard ftw() does a blind walk of all paths and can end - up following the build symlink down the kernel source tree. - Although nftw() has the option to get more control such as not - automatically following symbolic links, even that is not enough - for modutils. The requirements are: - - Paths must be directories or symlinks to directories. - - Each directory is read and sorted into alphabetical order - before processing. - - A directory is type 1 iff it was specified on a path statement - (either explicit or default) and the directory contains a - subdirectory with one of the known names and the directory name - does not end with "/kernel". Otherwise it is type 2. - - In a type 1 directory, walk the kernel subdirectory if it exists, - then the old known names in their historical order then any - remaining directory entries in alphabetical order and finally any - non-directory entries in alphabetical order. - - Entries in a type 1 directory are filtered against the "prune" - list. A type 1 directory can contain additional files which - are not modules nor symlinks to modules. The prune list skips - known additional files, if a distribution wants to store - additional text files in the top level directory they should be - added to the prune list. - - A type 2 directory must contain only modules or symlinks to - modules. They are processed in alphabetical order, without - pruning. Symlinks to directories are an error in type 2 - directories. - - The user function is not called for type 1 directories, nor for - pruned entries. It is called for type 2 directories and their - contents. It is also called for any files left in a type 1 - directory after pruning and processing type 2 subdirectories. - The user function never sees symlinks, they are resolved before - calling the function. - - Why have different directory types? The original file tree - walk was not well defined. Some users specified each directory - individually, others just pointed at the top level directory. - Either version worked until the "build" symlink was added. Now - users who specify the top level directory end up running the - entire kernel source tree looking for modules, not nice. We - cannot just ignore symlinks because pcmcia uses symlinks to - modules for backwards compatibility. - - Type 1 is when a user specifies the top level directory which needs - special processing, type 2 is individual subdirectories. But the - only way to tell the difference is by looking at the contents. The - "/kernel" directory introduced in 2.3.12 either contains nothing - (old make modules_install) or contains all the kernel modules using - the same tree structure as the source. Because "/kernel" can - contain old names but is really a type 2 directory, it is detected - as a special case. - */ - -#include <dirent.h> -#include <errno.h> -#include <limits.h> -#include <malloc.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> - -#include "util.h" -#include "config.h" - -extern char *tbpath[]; - -extern OPT_LIST *prune_list; -extern int n_prune_list; - -extern char *tbtype[]; - -struct xftw_dirent { - struct stat statbuf; - char *name; - char *fullname; -}; - -#define XFTW_MAXDEPTH 64 /* Maximum directory depth handled */ - -typedef struct { - struct xftw_dirent *contents; - int size; - int used; -} xftw_tree_t; - -static xftw_tree_t tree[XFTW_MAXDEPTH]; - -/* Free all data for one tree level */ -static void xftw_free_tree(int depth) -{ - int i; - xftw_tree_t *t = tree+depth; - for (i = 0; i < t->size; ++i) { - free(t->contents[i].name); - free(t->contents[i].fullname); - } - free(t->contents); - t->contents = NULL; - t->size = 0; - t->used = 0; -} - -/* Increment dirents used at this depth, resizing if necessary */ -static void xftw_add_dirent(int depth) -{ - xftw_tree_t *t = tree+depth; - int i, size = t->size; - if (++t->used < size) - return; - size += 10; /* arbitrary increment */ - t->contents = xrealloc(t->contents, size*sizeof(*(t->contents))); - for (i = t->size; i < size; ++i) { - memset(&(t->contents[i].statbuf), 0, sizeof(t->contents[i].statbuf)); - t->contents[i].name = NULL; - t->contents[i].fullname = NULL; - } - t->size = size; -} - -/* Concatenate directory name and entry name into one string. - * Note: caller must free result or leak. - */ -static char *xftw_dir_name(const char *directory, const char *entry) -{ - int i = strlen(directory); - char *name; - if (entry) - i += strlen(entry); - i += 2; - name = xmalloc(i); - strcpy(name, directory); /* safe, xmalloc */ - if (*directory && entry) - strcat(name, "/"); /* safe, xmalloc */ - if (entry) - strcat(name, entry); /* safe, xmalloc */ - return(name); -} - -/* Call the user function for a directory entry */ -static int xftw_do_name(const char *directory, const char *entry, struct stat *sb, xftw_func_t funcptr) -{ - int ret = 0; - char *name = xftw_dir_name(directory, entry); - - if (S_ISLNK(sb->st_mode)) { - char real[PATH_MAX], *newname; - verbose("resolving %s symlink to ", name); - if (!(newname = realpath(name, real))) { - if (errno == ENOENT) { - verbose("%s: does not exist, dangling symlink ignored\n", real); - goto cleanup; - } - perror("... failed"); - goto cleanup; - } - verbose("%s ", newname); - if (lstat(newname, sb)) { - error("lstat on %s failed ", newname); - perror(""); - goto cleanup; - } - free(name); - name = xstrdup(newname); - } - - if (!S_ISREG(sb->st_mode) && - !S_ISDIR(sb->st_mode)) { - error("%s is not plain file nor directory\n", name); - goto cleanup; - } - - verbose("user function %s\n", name); - ret = (*funcptr)(name, sb); -cleanup: - free(name); - return(ret); -} - -/* Sort directory entries into alphabetical order */ -static int xftw_sortdir(const void *a, const void *b) -{ - return(strcmp(((struct xftw_dirent *)a)->name, ((struct xftw_dirent *)b)->name)); -} - -/* Read a directory and sort it, ignoring "." and ".." */ -static int xftw_readdir(const char *directory, int depth) -{ - DIR *d; - struct dirent *ent; - verbose("xftw_readdir %s\n", directory); - if (!(d = opendir(directory))) { - perror(directory); - return(1); - } - while ((ent = readdir(d))) { - char *name; - struct xftw_dirent *f; - if (strcmp(ent->d_name, ".") == 0 || - strcmp(ent->d_name, "..") == 0) - continue; - name = xftw_dir_name(directory, ent->d_name); - xftw_add_dirent(depth); - f = tree[depth].contents+tree[depth].used-1; - f->name = xstrdup(ent->d_name); - f->fullname = name; /* do not free name, it is in use */ - if (lstat(name, &(f->statbuf))) { - perror(name); - return(1); - } - } - closedir(d); - qsort(tree[depth].contents, tree[depth].used, sizeof(*(tree[0].contents)), &xftw_sortdir); - return(0); -} - -/* Process a type 2 directory */ -int xftw_type2(const char *directory, const char *entry, int depth, xftw_func_t funcptr) -{ - int ret, i; - xftw_tree_t *t = tree+depth; - struct stat statbuf; - char *dirname = xftw_dir_name(directory, entry); - - verbose("type 2 %s\n", dirname); - if (depth > XFTW_MAXDEPTH) { - error("xftw_type2 exceeded maxdepth\n"); - ret = 1; - goto cleanup; - } - if ((ret = xftw_readdir(dirname, depth))) - goto cleanup; - - t = tree+depth; - /* user function sees type 2 directories */ - if ((ret = lstat(dirname, &statbuf)) || - (ret = xftw_do_name("", dirname, &statbuf, funcptr))) - goto cleanup; - - /* user sees all contents of type 2 directory, no pruning */ - for (i = 0; i < t->used; ++i) { - struct xftw_dirent *c = t->contents+i; - if (S_ISLNK(c->statbuf.st_mode)) { - if (!stat(c->name, &(c->statbuf))) { - if (S_ISDIR(c->statbuf.st_mode)) { - error("symlink to directory is not allowed, %s ignored\n", c->name); - *(c->name) = '\0'; /* ignore it */ - } - } - } - if (!*(c->name)) - continue; - if (S_ISDIR(c->statbuf.st_mode)) { - /* recursion is the curse of the programming classes */ - ret = xftw_type2(dirname, c->name, depth+1, funcptr); - if (ret) - goto cleanup; - } - else if ((ret = xftw_do_name(dirname, c->name, &(c->statbuf), funcptr))) - goto cleanup; - *(c->name) = '\0'; /* processed */ - } - - ret = 0; -cleanup: - free(dirname); - return(ret); -} - -/* Only external visible function. Decide on the type of directory and - * process accordingly. - */ -int xftw(const char *directory, xftw_func_t funcptr) -{ - struct stat statbuf; - int ret, i, j, type; - xftw_tree_t *t; - struct xftw_dirent *c; - - verbose("xftw starting at %s ", directory); - if (lstat(directory, &statbuf)) { - verbose("lstat on %s failed\n", directory); - return(0); - } - if (S_ISLNK(statbuf.st_mode)) { - char real[PATH_MAX]; - verbose("resolving symlink to "); - if (!(directory = realpath(directory, real))) { - if (errno == ENOENT) { - verbose("%s: does not exist, dangling symlink ignored\n", real); - return(0); - } - perror("... failed"); - return(-1); - } - verbose("%s ", directory); - if (lstat(directory, &statbuf)) { - error("lstat on %s failed ", directory); - perror(""); - return(-1); - } - } - if (!S_ISDIR(statbuf.st_mode)) { - error("%s is not a directory\n", directory); - return(-1); - } - verbose("\n"); - - /* All returns after this point must be via cleanup */ - - if ((ret = xftw_readdir(directory, 0))) - goto cleanup; - - t = tree; /* depth 0 */ - type = 2; - for (i = 0 ; type == 2 && i < t->used; ++i) { - c = t->contents+i; - for (j = 0; tbtype[j]; ++j) { - if (strcmp(c->name, tbtype[j]) == 0 && - S_ISDIR(c->statbuf.st_mode)) { - const char *p = directory + strlen(directory) - 1; - if (*p == '/') - --p; - if (p - directory >= 6 && strncmp(p-6, "/kernel", 7) == 0) - continue; /* "/kernel" path is a special case, type 2 */ - type = 1; /* known subdirectory */ - break; - } - } - } - - if (type == 1) { - OPT_LIST *p; - /* prune entries in type 1 directories only */ - for (i = 0 ; i < t->used; ++i) { - for (p = prunelist; p->name; ++p) { - c = t->contents+i; - if (strcmp(p->name, c->name) == 0) { - verbose("pruned %s\n", c->name); - *(c->name) = '\0'; /* ignore */ - } - } - } - /* run known subdirectories first in historical order, "kernel" is now top of list */ - for (i = 0 ; i < t->used; ++i) { - c = t->contents+i; - for (j = 0; tbtype[j]; ++j) { - if (*(c->name) && - strcmp(c->name, tbtype[j]) == 0 && - S_ISDIR(c->statbuf.st_mode)) { - if ((ret = xftw_type2(directory, c->name, 1, funcptr))) - goto cleanup; - *(c->name) = '\0'; /* processed */ - } - } - } - /* any other directories left, in alphabetical order */ - for (i = 0 ; i < t->used; ++i) { - c = t->contents+i; - if (*(c->name) && - S_ISDIR(c->statbuf.st_mode)) { - if ((ret = xftw_type2(directory, c->name, 1, funcptr))) - goto cleanup; - *(c->name) = '\0'; /* processed */ - } - } - /* anything else is passed to the user function */ - for (i = 0 ; i < t->used; ++i) { - c = t->contents+i; - if (*(c->name)) { - verbose("%s found in type 1 directory %s\n", c->name, directory); - if ((ret = xftw_do_name(directory, c->name, &(c->statbuf), funcptr))) - goto cleanup; - *(c->name) = '\0'; /* processed */ - } - } - } - else { - /* type 2 */ - xftw_free_tree(0); - if ((ret = xftw_type2(directory, NULL, 0, funcptr))) - goto cleanup; - } - - /* amazing, it all worked */ - ret = 0; -cleanup: - for (i = 0; i < XFTW_MAXDEPTH; ++i) - xftw_free_tree(i); - return(ret); -} diff --git a/mdk-stage1/insmod-modutils/util/xmalloc.c b/mdk-stage1/insmod-modutils/util/xmalloc.c deleted file mode 100644 index 9113d47fe..000000000 --- a/mdk-stage1/insmod-modutils/util/xmalloc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Misc utility functions. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include "util.h" - - -/*======================================================================*/ - -void * -xmalloc(size_t size) -{ - void *ptr = malloc(size); - if (!ptr) - { - error("Out of memory"); - exit(1); - } - return ptr; -} diff --git a/mdk-stage1/insmod-modutils/util/xrealloc.c b/mdk-stage1/insmod-modutils/util/xrealloc.c deleted file mode 100644 index d287486f7..000000000 --- a/mdk-stage1/insmod-modutils/util/xrealloc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Misc utility functions. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include "util.h" - - -/*======================================================================*/ - -void * -xrealloc(void *old, size_t size) -{ - void *ptr = realloc(old, size); - if (!ptr) - { - error("Out of memory"); - exit(1); - } - return ptr; -} diff --git a/mdk-stage1/insmod-modutils/util/xstrcat.c b/mdk-stage1/insmod-modutils/util/xstrcat.c deleted file mode 100644 index abb075c83..000000000 --- a/mdk-stage1/insmod-modutils/util/xstrcat.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Misc utility functions. - Copyright 2000 Keith Owens <kaos@ocs.com.au> - - 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 <stdlib.h> -#include <string.h> -#include "util.h" - - -/*======================================================================*/ - -char * -xstrcat(char *dest, const char *src, size_t size) -{ - int ldest = strlen(dest); - int lsrc = strlen(src); - if ((size - ldest - 1) < lsrc) { - error("xstrcat: destination overflow"); - exit(1); - } - memcpy(dest+ldest, src, lsrc+1); - return(dest); -} diff --git a/mdk-stage1/insmod-modutils/util/xstrdup.c b/mdk-stage1/insmod-modutils/util/xstrdup.c deleted file mode 100644 index 11b289eb0..000000000 --- a/mdk-stage1/insmod-modutils/util/xstrdup.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Misc utility functions. - Copyright 1996, 1997 Linux International. - Contributed by Richard Henderson <rth@tamu.edu> - - 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 <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "util.h" - - -/*======================================================================*/ - -char * -xstrdup(const char *s) -{ - char *n = strdup(s); - if (!n) - { - error("Out of memory"); - exit(1); - } - return n; -} diff --git a/mdk-stage1/insmod-modutils/util/xsystem.c b/mdk-stage1/insmod-modutils/util/xsystem.c deleted file mode 100644 index edb995268..000000000 --- a/mdk-stage1/insmod-modutils/util/xsystem.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Misc utility functions. - Copyright 2000 Keith Owens <kaos@ocs.com.au> - - 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 <sys/types.h> -#include <sys/wait.h> -#include <errno.h> -#include <unistd.h> - - -/*======================================================================*/ - -/* Clone of the system() function From Steven's Advanced Programming in a Unix - * Environment. Modified to use *argv[] and execvp to avoid shell expansion - * problems, modutils runs as root so system() is unsafe. - */ - -int -xsystem(const char *file, char *const argv[]) -{ - pid_t pid; - int status; - if ((pid = fork()) < 0) - return(-1); - if (pid == 0) { - execvp(file, argv); - _exit(127); - } - while (waitpid(pid, &status, 0) < 0) { - if (errno != EINTR) - return(-1); - } - return(status); -} |