2005-04-17 02:20:36 +04:00
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <string.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/mman.h>
# include <fcntl.h>
# include <unistd.h>
# include <elf.h>
# include "elfconfig.h"
# if KERNEL_ELFCLASS == ELFCLASS32
2006-03-03 18:46:04 +03:00
# define Elf_Ehdr Elf32_Ehdr
# define Elf_Shdr Elf32_Shdr
2005-04-17 02:20:36 +04:00
# define Elf_Sym Elf32_Sym
2006-02-18 00:42:02 +03:00
# define Elf_Addr Elf32_Addr
2008-01-18 23:04:34 +03:00
# define Elf_Sword Elf64_Sword
2007-08-13 01:17:54 +04:00
# define Elf_Section Elf32_Half
2005-04-17 02:20:36 +04:00
# define ELF_ST_BIND ELF32_ST_BIND
# define ELF_ST_TYPE ELF32_ST_TYPE
2006-05-21 02:00:26 +04:00
# define Elf_Rel Elf32_Rel
2006-02-18 00:42:02 +03:00
# define Elf_Rela Elf32_Rela
# define ELF_R_SYM ELF32_R_SYM
# define ELF_R_TYPE ELF32_R_TYPE
2005-04-17 02:20:36 +04:00
# else
2006-03-03 18:46:04 +03:00
# define Elf_Ehdr Elf64_Ehdr
# define Elf_Shdr Elf64_Shdr
2005-04-17 02:20:36 +04:00
# define Elf_Sym Elf64_Sym
2006-02-18 00:42:02 +03:00
# define Elf_Addr Elf64_Addr
2008-01-18 23:04:34 +03:00
# define Elf_Sword Elf64_Sxword
2007-08-13 01:17:54 +04:00
# define Elf_Section Elf64_Half
2005-04-17 02:20:36 +04:00
# define ELF_ST_BIND ELF64_ST_BIND
# define ELF_ST_TYPE ELF64_ST_TYPE
2006-05-21 02:00:26 +04:00
# define Elf_Rel Elf64_Rel
2006-02-18 00:42:02 +03:00
# define Elf_Rela Elf64_Rela
# define ELF_R_SYM ELF64_R_SYM
# define ELF_R_TYPE ELF64_R_TYPE
2005-04-17 02:20:36 +04:00
# endif
2006-05-21 02:00:28 +04:00
/* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
typedef struct
{
Elf32_Word r_sym ; /* Symbol index */
unsigned char r_ssym ; /* Special symbol for 2nd relocation */
unsigned char r_type3 ; /* 3rd relocation type */
unsigned char r_type2 ; /* 2nd relocation type */
unsigned char r_type1 ; /* 1st relocation type */
} _Elf64_Mips_R_Info ;
typedef union
{
Elf64_Xword r_info_number ;
_Elf64_Mips_R_Info r_info_fields ;
} _Elf64_Mips_R_Info_union ;
# define ELF64_MIPS_R_SYM(i) \
( ( __extension__ ( _Elf64_Mips_R_Info_union ) ( i ) ) . r_info_fields . r_sym )
2007-05-22 13:27:39 +04:00
# define ELF64_MIPS_R_TYPE(i) \
( ( __extension__ ( _Elf64_Mips_R_Info_union ) ( i ) ) . r_info_fields . r_type1 )
2005-04-17 02:20:36 +04:00
# if KERNEL_ELFDATA != HOST_ELFDATA
static inline void __endian ( const void * src , void * dest , unsigned int size )
{
unsigned int i ;
for ( i = 0 ; i < size ; i + + )
( ( unsigned char * ) dest ) [ i ] = ( ( unsigned char * ) src ) [ size - i - 1 ] ;
}
# define TO_NATIVE(x) \
( { \
typeof ( x ) __x ; \
__endian ( & ( x ) , & ( __x ) , sizeof ( __x ) ) ; \
__x ; \
} )
# else /* endianness matches */
# define TO_NATIVE(x) (x)
# endif
# define NOFAIL(ptr) do_nofail((ptr), #ptr)
void * do_nofail ( void * ptr , const char * expr ) ;
struct buffer {
char * p ;
int pos ;
int size ;
} ;
void __attribute__ ( ( format ( printf , 2 , 3 ) ) )
buf_printf ( struct buffer * buf , const char * fmt , . . . ) ;
void
buf_write ( struct buffer * buf , const char * s , int len ) ;
struct module {
struct module * next ;
const char * name ;
2006-06-09 23:53:55 +04:00
int gpl_compatible ;
2005-04-17 02:20:36 +04:00
struct symbol * unres ;
int seen ;
int skip ;
int has_init ;
int has_cleanup ;
struct buffer dev_table_buf ;
char srcversion [ 25 ] ;
} ;
struct elf_info {
unsigned long size ;
Elf_Ehdr * hdr ;
Elf_Shdr * sechdrs ;
Elf_Sym * symtab_start ;
Elf_Sym * symtab_stop ;
2006-06-09 09:12:53 +04:00
Elf_Section export_sec ;
2006-07-01 13:44:23 +04:00
Elf_Section export_unused_sec ;
2006-06-09 09:12:53 +04:00
Elf_Section export_gpl_sec ;
2006-07-01 13:44:23 +04:00
Elf_Section export_unused_gpl_sec ;
2006-06-09 09:12:53 +04:00
Elf_Section export_gpl_future_sec ;
2005-04-17 02:20:36 +04:00
const char * strtab ;
char * modinfo ;
unsigned int modinfo_len ;
2010-07-29 03:47:53 +04:00
/* support for 32bit section numbers */
unsigned int num_sections ; /* max_secindex + 1 */
unsigned int secindex_strings ;
/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
* take shndx from symtab_shndx_start [ N ] instead */
Elf32_Word * symtab_shndx_start ;
Elf32_Word * symtab_shndx_stop ;
2005-04-17 02:20:36 +04:00
} ;
2010-07-29 03:47:53 +04:00
static inline int is_shndx_special ( unsigned int i )
{
return i ! = SHN_XINDEX & & i > = SHN_LORESERVE & & i < = SHN_HIRESERVE ;
}
2011-05-20 02:55:27 +04:00
/*
* Move reserved section indices SHN_LORESERVE . . SHN_HIRESERVE out of
* the way to - 256. . - 1 , to avoid conflicting with real section
* indices .
2010-07-29 03:47:53 +04:00
*/
2011-05-20 02:55:27 +04:00
# define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
2010-07-29 03:47:53 +04:00
/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
static inline unsigned int get_secindex ( const struct elf_info * info ,
const Elf_Sym * sym )
{
2011-05-20 02:55:27 +04:00
if ( is_shndx_special ( sym - > st_shndx ) )
return SPECIAL ( sym - > st_shndx ) ;
2010-07-29 03:47:53 +04:00
if ( sym - > st_shndx ! = SHN_XINDEX )
return sym - > st_shndx ;
2011-05-20 02:55:27 +04:00
return info - > symtab_shndx_start [ sym - info - > symtab_start ] ;
2010-07-29 03:47:53 +04:00
}
2006-01-28 18:57:26 +03:00
/* file2alias.c */
2008-03-23 23:38:54 +03:00
extern unsigned int cross_build ;
2005-04-17 02:20:36 +04:00
void handle_moddevtable ( struct module * mod , struct elf_info * info ,
Elf_Sym * sym , const char * symname ) ;
void add_moddevtable ( struct buffer * buf , struct module * mod ) ;
2006-01-28 18:57:26 +03:00
/* sumversion.c */
2005-04-17 02:20:36 +04:00
void maybe_frob_rcs_version ( const char * modfilename ,
char * version ,
void * modinfo ,
unsigned long modinfo_offset ) ;
void get_src_version ( const char * modname , char sum [ ] , unsigned sumlen ) ;
2006-01-28 18:57:26 +03:00
/* from modpost.c */
2005-04-17 02:20:36 +04:00
void * grab_file ( const char * filename , unsigned long * size ) ;
char * get_next_line ( unsigned long * pos , void * file , unsigned long size ) ;
void release_file ( void * file , unsigned long size ) ;
2006-01-28 18:57:26 +03:00
void fatal ( const char * fmt , . . . ) ;
void warn ( const char * fmt , . . . ) ;
2006-10-07 15:35:32 +04:00
void merror ( const char * fmt , . . . ) ;