The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/scripts/sortextable.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * sortextable.h
    3  *
    4  * Copyright 2011 - 2012 Cavium, Inc.
    5  *
    6  * Some of this code was taken out of recordmcount.h written by:
    7  *
    8  * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>.  All rights reserved.
    9  * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
   10  *
   11  *
   12  * Licensed under the GNU General Public License, version 2 (GPLv2).
   13  */
   14 
   15 #undef extable_ent_size
   16 #undef compare_extable
   17 #undef do_func
   18 #undef Elf_Addr
   19 #undef Elf_Ehdr
   20 #undef Elf_Shdr
   21 #undef Elf_Rel
   22 #undef Elf_Rela
   23 #undef Elf_Sym
   24 #undef ELF_R_SYM
   25 #undef Elf_r_sym
   26 #undef ELF_R_INFO
   27 #undef Elf_r_info
   28 #undef ELF_ST_BIND
   29 #undef ELF_ST_TYPE
   30 #undef fn_ELF_R_SYM
   31 #undef fn_ELF_R_INFO
   32 #undef uint_t
   33 #undef _r
   34 #undef _w
   35 
   36 #ifdef SORTEXTABLE_64
   37 # define extable_ent_size       16
   38 # define compare_extable        compare_extable_64
   39 # define do_func                do64
   40 # define Elf_Addr               Elf64_Addr
   41 # define Elf_Ehdr               Elf64_Ehdr
   42 # define Elf_Shdr               Elf64_Shdr
   43 # define Elf_Rel                Elf64_Rel
   44 # define Elf_Rela               Elf64_Rela
   45 # define Elf_Sym                Elf64_Sym
   46 # define ELF_R_SYM              ELF64_R_SYM
   47 # define Elf_r_sym              Elf64_r_sym
   48 # define ELF_R_INFO             ELF64_R_INFO
   49 # define Elf_r_info             Elf64_r_info
   50 # define ELF_ST_BIND            ELF64_ST_BIND
   51 # define ELF_ST_TYPE            ELF64_ST_TYPE
   52 # define fn_ELF_R_SYM           fn_ELF64_R_SYM
   53 # define fn_ELF_R_INFO          fn_ELF64_R_INFO
   54 # define uint_t                 uint64_t
   55 # define _r                     r8
   56 # define _w                     w8
   57 #else
   58 # define extable_ent_size       8
   59 # define compare_extable        compare_extable_32
   60 # define do_func                do32
   61 # define Elf_Addr               Elf32_Addr
   62 # define Elf_Ehdr               Elf32_Ehdr
   63 # define Elf_Shdr               Elf32_Shdr
   64 # define Elf_Rel                Elf32_Rel
   65 # define Elf_Rela               Elf32_Rela
   66 # define Elf_Sym                Elf32_Sym
   67 # define ELF_R_SYM              ELF32_R_SYM
   68 # define Elf_r_sym              Elf32_r_sym
   69 # define ELF_R_INFO             ELF32_R_INFO
   70 # define Elf_r_info             Elf32_r_info
   71 # define ELF_ST_BIND            ELF32_ST_BIND
   72 # define ELF_ST_TYPE            ELF32_ST_TYPE
   73 # define fn_ELF_R_SYM           fn_ELF32_R_SYM
   74 # define fn_ELF_R_INFO          fn_ELF32_R_INFO
   75 # define uint_t                 uint32_t
   76 # define _r                     r
   77 # define _w                     w
   78 #endif
   79 
   80 static int compare_extable(const void *a, const void *b)
   81 {
   82         Elf_Addr av = _r(a);
   83         Elf_Addr bv = _r(b);
   84 
   85         if (av < bv)
   86                 return -1;
   87         if (av > bv)
   88                 return 1;
   89         return 0;
   90 }
   91 
   92 static void
   93 do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort)
   94 {
   95         Elf_Shdr *shdr;
   96         Elf_Shdr *shstrtab_sec;
   97         Elf_Shdr *strtab_sec = NULL;
   98         Elf_Shdr *symtab_sec = NULL;
   99         Elf_Shdr *extab_sec = NULL;
  100         Elf_Sym *sym;
  101         Elf_Sym *sort_needed_sym;
  102         Elf_Shdr *sort_needed_sec;
  103         Elf_Rel *relocs = NULL;
  104         int relocs_size;
  105         uint32_t *sort_done_location;
  106         const char *secstrtab;
  107         const char *strtab;
  108         char *extab_image;
  109         int extab_index = 0;
  110         int i;
  111         int idx;
  112 
  113         shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
  114         shstrtab_sec = shdr + r2(&ehdr->e_shstrndx);
  115         secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset);
  116         for (i = 0; i < r2(&ehdr->e_shnum); i++) {
  117                 idx = r(&shdr[i].sh_name);
  118                 if (strcmp(secstrtab + idx, "__ex_table") == 0) {
  119                         extab_sec = shdr + i;
  120                         extab_index = i;
  121                 }
  122                 if ((r(&shdr[i].sh_type) == SHT_REL ||
  123                      r(&shdr[i].sh_type) == SHT_RELA) &&
  124                     r(&shdr[i].sh_info) == extab_index) {
  125                         relocs = (void *)ehdr + _r(&shdr[i].sh_offset);
  126                         relocs_size = _r(&shdr[i].sh_size);
  127                 }
  128                 if (strcmp(secstrtab + idx, ".symtab") == 0)
  129                         symtab_sec = shdr + i;
  130                 if (strcmp(secstrtab + idx, ".strtab") == 0)
  131                         strtab_sec = shdr + i;
  132         }
  133         if (strtab_sec == NULL) {
  134                 fprintf(stderr, "no .strtab in  file: %s\n", fname);
  135                 fail_file();
  136         }
  137         if (symtab_sec == NULL) {
  138                 fprintf(stderr, "no .symtab in  file: %s\n", fname);
  139                 fail_file();
  140         }
  141         if (extab_sec == NULL) {
  142                 fprintf(stderr, "no __ex_table in  file: %s\n", fname);
  143                 fail_file();
  144         }
  145         strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
  146 
  147         extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
  148 
  149         if (custom_sort) {
  150                 custom_sort(extab_image, _r(&extab_sec->sh_size));
  151         } else {
  152                 int num_entries = _r(&extab_sec->sh_size) / extable_ent_size;
  153                 qsort(extab_image, num_entries,
  154                       extable_ent_size, compare_extable);
  155         }
  156         /* If there were relocations, we no longer need them. */
  157         if (relocs)
  158                 memset(relocs, 0, relocs_size);
  159 
  160         /* find main_extable_sort_needed */
  161         sort_needed_sym = NULL;
  162         for (i = 0; i < _r(&symtab_sec->sh_size) / sizeof(Elf_Sym); i++) {
  163                 sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
  164                 sym += i;
  165                 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
  166                         continue;
  167                 idx = r(&sym->st_name);
  168                 if (strcmp(strtab + idx, "main_extable_sort_needed") == 0) {
  169                         sort_needed_sym = sym;
  170                         break;
  171                 }
  172         }
  173         if (sort_needed_sym == NULL) {
  174                 fprintf(stderr,
  175                         "no main_extable_sort_needed symbol in  file: %s\n",
  176                         fname);
  177                 fail_file();
  178         }
  179         sort_needed_sec = &shdr[r2(&sort_needed_sym->st_shndx)];
  180         sort_done_location = (void *)ehdr +
  181                 _r(&sort_needed_sec->sh_offset) +
  182                 _r(&sort_needed_sym->st_value) -
  183                 _r(&sort_needed_sec->sh_addr);
  184 
  185 #if 1
  186         printf("sort done marker at %lx\n",
  187                (unsigned long)((char *)sort_done_location - (char *)ehdr));
  188 #endif
  189         /* We sorted it, clear the flag. */
  190         w(0, sort_done_location);
  191 }

Cache object: 0238d4dc6b938ab6f41ed304dde9a1b6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.