hotspot/src/jdk.aot/unix/native/libjelfshim/shim_functions.c
changeset 46327 91576389a517
parent 44203 d2d435372329
parent 46326 70de7011f79a
child 46328 6061df52d610
equal deleted inserted replaced
44203:d2d435372329 46327:91576389a517
     1 /*
       
     2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #include <libelf.h>
       
    25 #include <stdio.h>
       
    26 #include <stdlib.h>
       
    27 
       
    28 /**
       
    29  * TODO: This is an intial and crude attempt to access structure
       
    30  * fields of some ELF structrures. Need to figure out a way to access the
       
    31  * given field of a given structure instead of writing one shim function
       
    32  * per access of each of the structure field.
       
    33  **/
       
    34 
       
    35 #define STRINGIFYHELPER(x) #x
       
    36 #define STRINGIFY(x) STRINGIFYHELPER(x)
       
    37 #define FUNC_NAME(S, F) set_ ## S ## _ ## F
       
    38 #define CAST_STRUCT(S, F) ((Elf_ ## S *) structPtr)
       
    39 #define CAST_STRUCT32(S, F) ((Elf32_ ## S *) structPtr)
       
    40 #define CAST_STRUCT64(S, F) ((Elf64_ ## S *) structPtr)
       
    41 #define ACCESS_FIELD(S, F) CAST_STRUCT(S, F)-> F
       
    42 #define ACCESS_FIELD32(S, F) CAST_STRUCT32(S, F)-> F
       
    43 #define ACCESS_FIELD64(S, F) CAST_STRUCT64(S, F)-> F
       
    44 
       
    45 /*
       
    46    Example:
       
    47    SET_TYPE_BASED_FIELD(Ehdr, e_machine, int)
       
    48    expands to
       
    49    set_Ehdr_e_machine(int elfclass, void * strPtr, int val) {
       
    50 }
       
    51 */
       
    52 
       
    53 #define SET_TYPE_BASED_FIELD(S, F, T)                               \
       
    54     void FUNC_NAME(S, F)(int elfclass, void * structPtr, T val) {   \
       
    55        if (elfclass == ELFCLASS32)  {                               \
       
    56            ACCESS_FIELD32(S, F) = val;                    \
       
    57        } else if (elfclass == ELFCLASS64) {               \
       
    58            ACCESS_FIELD64(S, F) = val;                    \
       
    59        } else {                                           \
       
    60            printf("%s: Unknown ELF Class %d provided\n", STRINGIFY(FUNC_NAME(S, F)), elfclass); \
       
    61     }  \
       
    62     return; \
       
    63 }
       
    64 
       
    65 /*
       
    66    Example:
       
    67    SET_FIELD(Ehdr, e_machine, int)
       
    68    expands to
       
    69    set_Ehdr_e_machine(void * strPtr, int val) {
       
    70 }
       
    71 */
       
    72 
       
    73 #define SET_FIELD(S, F, T)                               \
       
    74     void FUNC_NAME(S, F)(void * structPtr, T val) {      \
       
    75        ACCESS_FIELD(S, F) = val;                         \
       
    76        return; \
       
    77 }
       
    78 
       
    79 int size_of_Sym(int elfclass) {
       
    80     if (elfclass == ELFCLASS32)  {
       
    81         return sizeof(Elf32_Sym);
       
    82     } else if (elfclass == ELFCLASS64) {
       
    83         return sizeof(Elf64_Sym);
       
    84     } else {
       
    85         printf("Unknown ELF Class %d provided\n", elfclass);
       
    86     }
       
    87     return -1;
       
    88 }
       
    89 
       
    90 int size_of_Rela(int elfclass) {
       
    91     if (elfclass == ELFCLASS32)  {
       
    92         return sizeof(Elf32_Rela);
       
    93     } else if (elfclass == ELFCLASS64) {
       
    94         return sizeof(Elf64_Rela);
       
    95     } else {
       
    96         printf("Unknown ELF Class %d provided\n", elfclass);
       
    97     }
       
    98     return -1;
       
    99 }
       
   100 
       
   101 int size_of_Rel(int elfclass) {
       
   102     if (elfclass == ELFCLASS32)  {
       
   103         return sizeof(Elf32_Rel);
       
   104     } else if (elfclass == ELFCLASS64) {
       
   105         return sizeof(Elf64_Rel);
       
   106     } else {
       
   107         printf("Unknown ELF Class %d provided\n", elfclass);
       
   108     }
       
   109     return -1;
       
   110 }
       
   111 
       
   112 /* ELF Header field access */
       
   113 
       
   114 void ehdr_set_data_encoding(void * ehdr, int val)  {
       
   115     ((Elf32_Ehdr *) ehdr)->e_ident[EI_DATA] = val;
       
   116     return;
       
   117 }
       
   118 
       
   119 SET_TYPE_BASED_FIELD(Ehdr, e_machine, int)
       
   120 SET_TYPE_BASED_FIELD(Ehdr, e_type, int)
       
   121 SET_TYPE_BASED_FIELD(Ehdr, e_version, int)
       
   122 SET_TYPE_BASED_FIELD(Ehdr, e_shstrndx, int)
       
   123 
       
   124 /* Data descriptor field access */
       
   125 SET_FIELD(Data, d_align, int)
       
   126 SET_FIELD(Data, d_off, int)
       
   127 SET_FIELD(Data, d_buf, void*)
       
   128 SET_FIELD(Data, d_type, int)
       
   129 SET_FIELD(Data, d_size, int)
       
   130 SET_FIELD(Data, d_version, int)
       
   131 
       
   132 /* Section Header Access functions */
       
   133 SET_TYPE_BASED_FIELD(Shdr, sh_name, int)
       
   134 SET_TYPE_BASED_FIELD(Shdr, sh_type, int)
       
   135 SET_TYPE_BASED_FIELD(Shdr, sh_flags, int)
       
   136 SET_TYPE_BASED_FIELD(Shdr, sh_entsize, int)
       
   137 SET_TYPE_BASED_FIELD(Shdr, sh_link, int)
       
   138 SET_TYPE_BASED_FIELD(Shdr, sh_info, int)
       
   139 
       
   140 /* Set the Program Header to be of PH_PHDR type and initialize other
       
   141    related fields of the program header.
       
   142 */
       
   143 void phdr_set_type_self(int elfclass, void * ehdr, void * phdr)  {
       
   144     if (elfclass == ELFCLASS32) {
       
   145         Elf32_Ehdr * ehdr32 = (Elf32_Ehdr *) ehdr;
       
   146         Elf32_Phdr * phdr32 = (Elf32_Phdr *) phdr;
       
   147         phdr32->p_type = PT_PHDR;
       
   148         phdr32->p_offset = ehdr32->e_phoff;
       
   149         phdr32->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT);
       
   150     } else if (elfclass == ELFCLASS64) {
       
   151         Elf64_Ehdr * ehdr64 = (Elf64_Ehdr *) ehdr;
       
   152         Elf64_Phdr * phdr64 = (Elf64_Phdr *) phdr;
       
   153         phdr64->p_type = PT_PHDR;
       
   154         phdr64->p_offset = ehdr64->e_phoff;
       
   155         phdr64->p_filesz = elf64_fsize(ELF_T_PHDR, 1, EV_CURRENT);
       
   156     } else {
       
   157         printf("phdr_set_type_self: Unknown ELF Class %d provided\n", elfclass);
       
   158     }
       
   159     return;
       
   160 }
       
   161 
       
   162 /*
       
   163   Create symbol table entry with given type and binding
       
   164 */
       
   165 void * create_sym_entry(int elfclass, int index, int type, int bind,
       
   166                         int shndx, int size, int value) {
       
   167   void * symentry = NULL;
       
   168     if (elfclass == ELFCLASS32) {
       
   169       Elf32_Sym * sym32 = (Elf32_Sym *) malloc(sizeof(Elf32_Sym));
       
   170       sym32->st_name = index;
       
   171       sym32->st_value = value;
       
   172       sym32->st_size = size;
       
   173       sym32->st_info = ELF32_ST_INFO(bind, type);
       
   174       sym32->st_other = 0;  // TODO: Add an argument to get this value ??
       
   175       sym32->st_shndx = shndx;
       
   176       symentry = sym32;
       
   177     } else if (elfclass == ELFCLASS64) {
       
   178       Elf64_Sym * sym64 = (Elf64_Sym *) malloc(sizeof(Elf64_Sym));
       
   179       sym64->st_name = index;
       
   180       sym64->st_value = value;
       
   181       sym64->st_size = size;
       
   182       sym64->st_info = ELF64_ST_INFO(bind, type);
       
   183       sym64->st_other = 0;  // TODO: Add an argument to get this value ??
       
   184       sym64->st_shndx = shndx;
       
   185       symentry = sym64;
       
   186     } else {
       
   187         printf("create_sym_entry: Unknown ELF Class %d provided\n", elfclass);
       
   188     }
       
   189     return (void *) symentry;
       
   190 }
       
   191 
       
   192 // Create a reloc (or reloca entry if argument reloca is non-zero)
       
   193 void * create_reloc_entry(int elfclass, int roffset, int symtabIdx,
       
   194                           int relocType, int raddend, int reloca) {
       
   195   void * relocentry = NULL;
       
   196   if (elfclass == ELFCLASS32) {
       
   197     if (reloca) {
       
   198       Elf32_Rela * rela32 = (Elf32_Rela *) malloc(sizeof(Elf32_Rela));
       
   199       rela32->r_offset = roffset;
       
   200       rela32->r_info = ELF32_R_INFO(symtabIdx, relocType);
       
   201       rela32->r_addend = raddend;
       
   202       relocentry = rela32;
       
   203     } else {
       
   204       Elf32_Rel * rel32 = (Elf32_Rel *) malloc(sizeof(Elf32_Rel));
       
   205       rel32->r_offset = roffset;
       
   206       rel32->r_info = ELF32_R_INFO(symtabIdx, relocType);
       
   207       relocentry = rel32;
       
   208     }
       
   209   } else if (elfclass == ELFCLASS64) {
       
   210     if (reloca) {
       
   211       Elf64_Rela * rela64 = (Elf64_Rela *) malloc(sizeof(Elf64_Rela));
       
   212       rela64->r_offset = roffset;
       
   213       rela64->r_info = ELF64_R_INFO(symtabIdx, relocType);
       
   214       rela64->r_addend = raddend;
       
   215       relocentry = rela64;
       
   216     } else {
       
   217       Elf64_Rel * rel64 = (Elf64_Rel *) malloc(sizeof(Elf64_Rel));
       
   218       rel64->r_offset = roffset;
       
   219       rel64->r_info = ELF64_R_INFO(symtabIdx, relocType);
       
   220       relocentry = rel64;
       
   221     }
       
   222   } else {
       
   223     printf("create_reloc_entry: Unknown ELF Class %d provided\n", elfclass);
       
   224   }
       
   225   return (void *) relocentry;
       
   226 }