Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #include <stdbool.h>
0003 #include <stdio.h>
0004 #include <stdlib.h>
0005 #include <stdarg.h>
0006 #include <string.h>
0007 #include <sys/types.h>
0008 #include <sys/stat.h>
0009 #include <sys/mman.h>
0010 #include <fcntl.h>
0011 #include <unistd.h>
0012 #include <elf.h>
0013 
0014 #include "list.h"
0015 #include "elfconfig.h"
0016 
0017 /* On BSD-alike OSes elf.h defines these according to host's word size */
0018 #undef ELF_ST_BIND
0019 #undef ELF_ST_TYPE
0020 #undef ELF_R_SYM
0021 #undef ELF_R_TYPE
0022 
0023 #if KERNEL_ELFCLASS == ELFCLASS32
0024 
0025 #define Elf_Ehdr    Elf32_Ehdr
0026 #define Elf_Shdr    Elf32_Shdr
0027 #define Elf_Sym     Elf32_Sym
0028 #define Elf_Addr    Elf32_Addr
0029 #define Elf_Section Elf32_Half
0030 #define ELF_ST_BIND ELF32_ST_BIND
0031 #define ELF_ST_TYPE ELF32_ST_TYPE
0032 
0033 #define Elf_Rel     Elf32_Rel
0034 #define Elf_Rela    Elf32_Rela
0035 #define ELF_R_SYM   ELF32_R_SYM
0036 #define ELF_R_TYPE  ELF32_R_TYPE
0037 #else
0038 
0039 #define Elf_Ehdr    Elf64_Ehdr
0040 #define Elf_Shdr    Elf64_Shdr
0041 #define Elf_Sym     Elf64_Sym
0042 #define Elf_Addr    Elf64_Addr
0043 #define Elf_Section Elf64_Half
0044 #define ELF_ST_BIND ELF64_ST_BIND
0045 #define ELF_ST_TYPE ELF64_ST_TYPE
0046 
0047 #define Elf_Rel     Elf64_Rel
0048 #define Elf_Rela    Elf64_Rela
0049 #define ELF_R_SYM   ELF64_R_SYM
0050 #define ELF_R_TYPE  ELF64_R_TYPE
0051 #endif
0052 
0053 /* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
0054 typedef struct
0055 {
0056     Elf32_Word    r_sym;    /* Symbol index */
0057     unsigned char r_ssym;   /* Special symbol for 2nd relocation */
0058     unsigned char r_type3;  /* 3rd relocation type */
0059     unsigned char r_type2;  /* 2nd relocation type */
0060     unsigned char r_type1;  /* 1st relocation type */
0061 } _Elf64_Mips_R_Info;
0062 
0063 typedef union
0064 {
0065     Elf64_Xword     r_info_number;
0066     _Elf64_Mips_R_Info  r_info_fields;
0067 } _Elf64_Mips_R_Info_union;
0068 
0069 #define ELF64_MIPS_R_SYM(i) \
0070   ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
0071 
0072 #define ELF64_MIPS_R_TYPE(i) \
0073   ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
0074 
0075 #if KERNEL_ELFDATA != HOST_ELFDATA
0076 
0077 static inline void __endian(const void *src, void *dest, unsigned int size)
0078 {
0079     unsigned int i;
0080     for (i = 0; i < size; i++)
0081         ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
0082 }
0083 
0084 #define TO_NATIVE(x)                        \
0085 ({                              \
0086     typeof(x) __x;                      \
0087     __endian(&(x), &(__x), sizeof(__x));            \
0088     __x;                            \
0089 })
0090 
0091 #else /* endianness matches */
0092 
0093 #define TO_NATIVE(x) (x)
0094 
0095 #endif
0096 
0097 #define NOFAIL(ptr)   do_nofail((ptr), #ptr)
0098 
0099 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
0100 
0101 void *do_nofail(void *ptr, const char *expr);
0102 
0103 struct buffer {
0104     char *p;
0105     int pos;
0106     int size;
0107 };
0108 
0109 void __attribute__((format(printf, 2, 3)))
0110 buf_printf(struct buffer *buf, const char *fmt, ...);
0111 
0112 void
0113 buf_write(struct buffer *buf, const char *s, int len);
0114 
0115 struct module {
0116     struct list_head list;
0117     struct list_head exported_symbols;
0118     struct list_head unresolved_symbols;
0119     bool is_gpl_compatible;
0120     bool from_dump;     /* true if module was loaded from *.symvers */
0121     bool is_vmlinux;
0122     bool seen;
0123     bool has_init;
0124     bool has_cleanup;
0125     struct buffer dev_table_buf;
0126     char         srcversion[25];
0127     // Missing namespace dependencies
0128     struct list_head missing_namespaces;
0129     // Actual imported namespaces
0130     struct list_head imported_namespaces;
0131     char name[];
0132 };
0133 
0134 struct elf_info {
0135     size_t size;
0136     Elf_Ehdr     *hdr;
0137     Elf_Shdr     *sechdrs;
0138     Elf_Sym      *symtab_start;
0139     Elf_Sym      *symtab_stop;
0140     char         *strtab;
0141     char         *modinfo;
0142     unsigned int modinfo_len;
0143 
0144     /* support for 32bit section numbers */
0145 
0146     unsigned int num_sections; /* max_secindex + 1 */
0147     unsigned int secindex_strings;
0148     /* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
0149      * take shndx from symtab_shndx_start[N] instead */
0150     Elf32_Word   *symtab_shndx_start;
0151     Elf32_Word   *symtab_shndx_stop;
0152 };
0153 
0154 static inline int is_shndx_special(unsigned int i)
0155 {
0156     return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
0157 }
0158 
0159 /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
0160 static inline unsigned int get_secindex(const struct elf_info *info,
0161                     const Elf_Sym *sym)
0162 {
0163     unsigned int index = sym->st_shndx;
0164 
0165     /*
0166      * Elf{32,64}_Sym::st_shndx is 2 byte. Big section numbers are available
0167      * in the .symtab_shndx section.
0168      */
0169     if (index == SHN_XINDEX)
0170         return info->symtab_shndx_start[sym - info->symtab_start];
0171 
0172     /*
0173      * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
0174      * the way to UINT_MAX-255..UINT_MAX, to avoid conflicting with real
0175      * section indices.
0176      */
0177     if (index >= SHN_LORESERVE && index <= SHN_HIRESERVE)
0178         return index - SHN_HIRESERVE - 1;
0179 
0180     return index;
0181 }
0182 
0183 /* file2alias.c */
0184 void handle_moddevtable(struct module *mod, struct elf_info *info,
0185             Elf_Sym *sym, const char *symname);
0186 void add_moddevtable(struct buffer *buf, struct module *mod);
0187 
0188 /* sumversion.c */
0189 void get_src_version(const char *modname, char sum[], unsigned sumlen);
0190 
0191 /* from modpost.c */
0192 char *read_text_file(const char *filename);
0193 char *get_line(char **stringp);
0194 void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
0195 
0196 enum loglevel {
0197     LOG_WARN,
0198     LOG_ERROR,
0199     LOG_FATAL
0200 };
0201 
0202 void modpost_log(enum loglevel loglevel, const char *fmt, ...);
0203 
0204 /*
0205  * warn - show the given message, then let modpost continue running, still
0206  *        allowing modpost to exit successfully. This should be used when
0207  *        we still allow to generate vmlinux and modules.
0208  *
0209  * error - show the given message, then let modpost continue running, but fail
0210  *         in the end. This should be used when we should stop building vmlinux
0211  *         or modules, but we can continue running modpost to catch as many
0212  *         issues as possible.
0213  *
0214  * fatal - show the given message, and bail out immediately. This should be
0215  *         used when there is no point to continue running modpost.
0216  */
0217 #define warn(fmt, args...)  modpost_log(LOG_WARN, fmt, ##args)
0218 #define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
0219 #define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args)