ruby-oci8 2.2.3 → 2.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/ChangeLog +427 -0
 - data/NEWS +335 -42
 - data/README.md +20 -9
 - data/dist-files +9 -3
 - data/docs/bind-array-to-in_cond.md +2 -2
 - data/docs/conflicts-local-connections-and-processes.md +7 -4
 - data/docs/hanging-after-inactivity.md +63 -0
 - data/docs/install-binary-package.md +15 -11
 - data/docs/install-full-client.md +18 -21
 - data/docs/install-instant-client.md +45 -27
 - data/docs/install-on-osx.md +31 -120
 - data/docs/ldap-auth-and-function-interposition.md +123 -0
 - data/docs/number-type-mapping.md +79 -0
 - data/docs/platform-specific-issues.md +17 -50
 - data/docs/report-installation-issue.md +3 -0
 - data/docs/timeout-parameters.md +3 -0
 - data/ext/oci8/apiwrap.c.tmpl +2 -5
 - data/ext/oci8/apiwrap.rb +6 -1
 - data/ext/oci8/apiwrap.yml +34 -22
 - data/ext/oci8/attr.c +4 -2
 - data/ext/oci8/bind.c +366 -6
 - data/ext/oci8/connection_pool.c +3 -3
 - data/ext/oci8/encoding.c +5 -5
 - data/ext/oci8/env.c +8 -2
 - data/ext/oci8/error.c +24 -16
 - data/ext/oci8/extconf.rb +8 -4
 - data/ext/oci8/hook_funcs.c +274 -61
 - data/ext/oci8/lob.c +31 -75
 - data/ext/oci8/metadata.c +2 -2
 - data/ext/oci8/object.c +72 -27
 - data/ext/oci8/oci8.c +45 -132
 - data/ext/oci8/oci8.h +32 -88
 - data/ext/oci8/oci8lib.c +178 -38
 - data/ext/oci8/ocihandle.c +37 -37
 - data/ext/oci8/ocinumber.c +23 -18
 - data/ext/oci8/oraconf.rb +158 -339
 - data/ext/oci8/oradate.c +19 -19
 - data/ext/oci8/plthook.h +10 -0
 - data/ext/oci8/plthook_elf.c +433 -268
 - data/ext/oci8/plthook_osx.c +40 -9
 - data/ext/oci8/plthook_win32.c +9 -0
 - data/ext/oci8/stmt.c +52 -17
 - data/ext/oci8/win32.c +4 -22
 - data/lib/oci8/bindtype.rb +1 -15
 - data/lib/oci8/check_load_error.rb +57 -10
 - data/lib/oci8/cursor.rb +57 -25
 - data/lib/oci8/metadata.rb +9 -1
 - data/lib/oci8/object.rb +10 -0
 - data/lib/oci8/oci8.rb +33 -28
 - data/lib/oci8/oracle_version.rb +11 -1
 - data/lib/oci8/properties.rb +22 -0
 - data/lib/oci8/version.rb +1 -1
 - data/lib/oci8.rb +48 -4
 - data/lib/ruby-oci8.rb +0 -3
 - data/pre-distclean.rb +1 -3
 - data/ruby-oci8.gemspec +3 -8
 - data/setup.rb +11 -2
 - data/test/README.md +37 -0
 - data/test/config.rb +1 -1
 - data/test/setup_test_object.sql +21 -13
 - data/test/setup_test_package.sql +59 -0
 - data/test/test_all.rb +2 -0
 - data/test/test_bind_boolean.rb +99 -0
 - data/test/test_bind_integer.rb +47 -0
 - data/test/test_break.rb +11 -9
 - data/test/test_clob.rb +4 -16
 - data/test/test_connstr.rb +29 -13
 - data/test/test_datetime.rb +8 -3
 - data/test/test_object.rb +27 -9
 - data/test/test_oci8.rb +170 -46
 - data/test/test_oranumber.rb +12 -6
 - data/test/test_package_type.rb +15 -3
 - data/test/test_properties.rb +17 -0
 - metadata +40 -54
 - data/docs/osx-install-dev-tools.png +0 -0
 - data/test/README +0 -42
 
    
        data/ext/oci8/plthook_elf.c
    CHANGED
    
    | 
         @@ -6,7 +6,7 @@ 
     | 
|
| 
       6 
6 
     | 
    
         
             
             *
         
     | 
| 
       7 
7 
     | 
    
         
             
             * ------------------------------------------------------
         
     | 
| 
       8 
8 
     | 
    
         
             
             *
         
     | 
| 
       9 
     | 
    
         
            -
             * Copyright 2013- 
     | 
| 
      
 9 
     | 
    
         
            +
             * Copyright 2013-2016 Kubo Takehiro <kubo@jiubao.org>
         
     | 
| 
       10 
10 
     | 
    
         
             
             *
         
     | 
| 
       11 
11 
     | 
    
         
             
             * Redistribution and use in source and binary forms, with or without modification, are
         
     | 
| 
       12 
12 
     | 
    
         
             
             * permitted provided that the following conditions are met:
         
     | 
| 
         @@ -33,22 +33,30 @@ 
     | 
|
| 
       33 
33 
     | 
    
         
             
             * or implied, of the authors.
         
     | 
| 
       34 
34 
     | 
    
         
             
             *
         
     | 
| 
       35 
35 
     | 
    
         
             
             */
         
     | 
| 
      
 36 
     | 
    
         
            +
            #if defined(__sun) && defined(_XOPEN_SOURCE) && !defined(__EXTENSIONS__)
         
     | 
| 
      
 37 
     | 
    
         
            +
            #define __EXTENSIONS__
         
     | 
| 
      
 38 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 39 
     | 
    
         
            +
            #if defined(__linux__) && !defined(_GNU_SOURCE)
         
     | 
| 
       36 
40 
     | 
    
         
             
            #define _GNU_SOURCE
         
     | 
| 
      
 41 
     | 
    
         
            +
            #endif
         
     | 
| 
       37 
42 
     | 
    
         
             
            #include <stdio.h>
         
     | 
| 
       38 
43 
     | 
    
         
             
            #include <stdarg.h>
         
     | 
| 
       39 
44 
     | 
    
         
             
            #include <stdlib.h>
         
     | 
| 
       40 
45 
     | 
    
         
             
            #include <unistd.h>
         
     | 
| 
       41 
46 
     | 
    
         
             
            #include <string.h>
         
     | 
| 
       42 
47 
     | 
    
         
             
            #include <limits.h>
         
     | 
| 
       43 
     | 
    
         
            -
            #include <sys/ 
     | 
| 
       44 
     | 
    
         
            -
            #include <sys/stat.h>
         
     | 
| 
       45 
     | 
    
         
            -
            #include <fcntl.h>
         
     | 
| 
      
 48 
     | 
    
         
            +
            #include <sys/mman.h>
         
     | 
| 
       46 
49 
     | 
    
         
             
            #include <errno.h>
         
     | 
| 
       47 
50 
     | 
    
         
             
            #include <dlfcn.h>
         
     | 
| 
       48 
51 
     | 
    
         
             
            #ifdef __sun
         
     | 
| 
       49 
     | 
    
         
            -
            #include < 
     | 
| 
      
 52 
     | 
    
         
            +
            #include <sys/auxv.h>
         
     | 
| 
       50 
53 
     | 
    
         
             
            #define ELF_TARGET_ALL
         
     | 
| 
       51 
54 
     | 
    
         
             
            #endif /* __sun */
         
     | 
| 
      
 55 
     | 
    
         
            +
            #ifdef __FreeBSD__
         
     | 
| 
      
 56 
     | 
    
         
            +
            #include <sys/types.h>
         
     | 
| 
      
 57 
     | 
    
         
            +
            #include <sys/user.h>
         
     | 
| 
      
 58 
     | 
    
         
            +
            #include <libutil.h>
         
     | 
| 
      
 59 
     | 
    
         
            +
            #endif
         
     | 
| 
       52 
60 
     | 
    
         
             
            #include <elf.h>
         
     | 
| 
       53 
61 
     | 
    
         
             
            #include <link.h>
         
     | 
| 
       54 
62 
     | 
    
         
             
            #include "plthook.h"
         
     | 
| 
         @@ -57,39 +65,47 @@ 
     | 
|
| 
       57 
65 
     | 
    
         
             
            #define __attribute__(arg)
         
     | 
| 
       58 
66 
     | 
    
         
             
            #endif
         
     | 
| 
       59 
67 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
            #if defined  
     | 
| 
       61 
     | 
    
         
            -
            #define ELF_OSABI     ELFOSABI_SYSV
         
     | 
| 
       62 
     | 
    
         
            -
            #elif defined __sun
         
     | 
| 
       63 
     | 
    
         
            -
            #define ELF_OSABI     ELFOSABI_SOLARIS
         
     | 
| 
       64 
     | 
    
         
            -
            #elif defined __FreeBSD__
         
     | 
| 
       65 
     | 
    
         
            -
            #define ELF_OSABI     ELFOSABI_FREEBSD
         
     | 
| 
       66 
     | 
    
         
            -
            #if defined __i386__ && __ELF_WORD_SIZE == 64
         
     | 
| 
      
 68 
     | 
    
         
            +
            #if defined __FreeBSD__ && defined __i386__ && __ELF_WORD_SIZE == 64
         
     | 
| 
       67 
69 
     | 
    
         
             
            #error 32-bit application on 64-bit OS is not supported.
         
     | 
| 
       68 
70 
     | 
    
         
             
            #endif
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
            # 
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            #if !defined(R_X86_64_JUMP_SLOT) && defined(R_X86_64_JMP_SLOT)
         
     | 
| 
      
 73 
     | 
    
         
            +
            #define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
         
     | 
| 
       71 
74 
     | 
    
         
             
            #endif
         
     | 
| 
       72 
75 
     | 
    
         | 
| 
       73 
76 
     | 
    
         
             
            #if defined __x86_64__ || defined __x86_64
         
     | 
| 
       74 
     | 
    
         
            -
            #define ELF_DATA      ELFDATA2LSB
         
     | 
| 
       75 
     | 
    
         
            -
            #define E_MACHINE     EM_X86_64
         
     | 
| 
       76 
     | 
    
         
            -
            #ifdef R_X86_64_JUMP_SLOT
         
     | 
| 
       77 
77 
     | 
    
         
             
            #define R_JUMP_SLOT   R_X86_64_JUMP_SLOT
         
     | 
| 
       78 
     | 
    
         
            -
            #else
         
     | 
| 
       79 
     | 
    
         
            -
            #define R_JUMP_SLOT   R_X86_64_JMP_SLOT
         
     | 
| 
       80 
     | 
    
         
            -
            #endif
         
     | 
| 
       81 
     | 
    
         
            -
            #define SHT_PLT_REL   SHT_RELA
         
     | 
| 
       82 
78 
     | 
    
         
             
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
       83 
     | 
    
         
            -
            #define  
     | 
| 
      
 79 
     | 
    
         
            +
            #define PLT_DT_REL    DT_RELA
         
     | 
| 
      
 80 
     | 
    
         
            +
            #define R_GLOBAL_DATA R_X86_64_GLOB_DAT
         
     | 
| 
       84 
81 
     | 
    
         
             
            #elif defined __i386__ || defined __i386
         
     | 
| 
       85 
     | 
    
         
            -
            #define ELF_DATA      ELFDATA2LSB
         
     | 
| 
       86 
     | 
    
         
            -
            #define E_MACHINE     EM_386
         
     | 
| 
       87 
82 
     | 
    
         
             
            #define R_JUMP_SLOT   R_386_JMP_SLOT
         
     | 
| 
       88 
     | 
    
         
            -
            #define SHT_PLT_REL   SHT_REL
         
     | 
| 
       89 
83 
     | 
    
         
             
            #define Elf_Plt_Rel   Elf_Rel
         
     | 
| 
       90 
     | 
    
         
            -
            #define  
     | 
| 
      
 84 
     | 
    
         
            +
            #define PLT_DT_REL    DT_REL
         
     | 
| 
      
 85 
     | 
    
         
            +
            #define R_GLOBAL_DATA R_386_GLOB_DAT
         
     | 
| 
      
 86 
     | 
    
         
            +
            #elif defined __arm__ || defined __arm
         
     | 
| 
      
 87 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_ARM_JUMP_SLOT
         
     | 
| 
      
 88 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rel
         
     | 
| 
      
 89 
     | 
    
         
            +
            #elif defined __aarch64__ || defined __aarch64 /* ARM64 */
         
     | 
| 
      
 90 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_AARCH64_JUMP_SLOT
         
     | 
| 
      
 91 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
      
 92 
     | 
    
         
            +
            #elif defined __powerpc64__
         
     | 
| 
      
 93 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_PPC64_JMP_SLOT
         
     | 
| 
      
 94 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
      
 95 
     | 
    
         
            +
            #elif defined __powerpc__
         
     | 
| 
      
 96 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_PPC_JMP_SLOT
         
     | 
| 
      
 97 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
      
 98 
     | 
    
         
            +
            #elif 0 /* disabled because not tested */ && (defined __sparcv9 || defined __sparc_v9__)
         
     | 
| 
      
 99 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_SPARC_JMP_SLOT
         
     | 
| 
      
 100 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
      
 101 
     | 
    
         
            +
            #elif 0 /* disabled because not tested */ && (defined __sparc || defined __sparc__)
         
     | 
| 
      
 102 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_SPARC_JMP_SLOT
         
     | 
| 
      
 103 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
      
 104 
     | 
    
         
            +
            #elif 0 /* disabled because not tested */ && (defined __ia64 || defined __ia64__)
         
     | 
| 
      
 105 
     | 
    
         
            +
            #define R_JUMP_SLOT   R_IA64_IPLTMSB
         
     | 
| 
      
 106 
     | 
    
         
            +
            #define Elf_Plt_Rel   Elf_Rela
         
     | 
| 
       91 
107 
     | 
    
         
             
            #else
         
     | 
| 
       92 
     | 
    
         
            -
            #error  
     | 
| 
      
 108 
     | 
    
         
            +
            #error unsupported OS
         
     | 
| 
       93 
109 
     | 
    
         
             
            #endif
         
     | 
| 
       94 
110 
     | 
    
         | 
| 
       95 
111 
     | 
    
         
             
            #if defined __LP64__
         
     | 
| 
         @@ -97,12 +113,16 @@ 
     | 
|
| 
       97 
113 
     | 
    
         
             
            #define ELF_CLASS     ELFCLASS64
         
     | 
| 
       98 
114 
     | 
    
         
             
            #endif
         
     | 
| 
       99 
115 
     | 
    
         
             
            #define SIZE_T_FMT "lu"
         
     | 
| 
      
 116 
     | 
    
         
            +
            #define ELF_WORD_FMT "u"
         
     | 
| 
      
 117 
     | 
    
         
            +
            #define ELF_XWORD_FMT "lu"
         
     | 
| 
      
 118 
     | 
    
         
            +
            #define ELF_SXWORD_FMT "ld"
         
     | 
| 
       100 
119 
     | 
    
         
             
            #define Elf_Half Elf64_Half
         
     | 
| 
       101 
     | 
    
         
            -
            #define  
     | 
| 
      
 120 
     | 
    
         
            +
            #define Elf_Xword Elf64_Xword
         
     | 
| 
      
 121 
     | 
    
         
            +
            #define Elf_Sxword Elf64_Sxword
         
     | 
| 
       102 
122 
     | 
    
         
             
            #define Elf_Ehdr Elf64_Ehdr
         
     | 
| 
       103 
123 
     | 
    
         
             
            #define Elf_Phdr Elf64_Phdr
         
     | 
| 
       104 
     | 
    
         
            -
            #define Elf_Shdr Elf64_Shdr
         
     | 
| 
       105 
124 
     | 
    
         
             
            #define Elf_Sym  Elf64_Sym
         
     | 
| 
      
 125 
     | 
    
         
            +
            #define Elf_Dyn  Elf64_Dyn
         
     | 
| 
       106 
126 
     | 
    
         
             
            #define Elf_Rel  Elf64_Rel
         
     | 
| 
       107 
127 
     | 
    
         
             
            #define Elf_Rela Elf64_Rela
         
     | 
| 
       108 
128 
     | 
    
         
             
            #ifndef ELF_R_SYM
         
     | 
| 
         @@ -116,12 +136,22 @@ 
     | 
|
| 
       116 
136 
     | 
    
         
             
            #define ELF_CLASS     ELFCLASS32
         
     | 
| 
       117 
137 
     | 
    
         
             
            #endif
         
     | 
| 
       118 
138 
     | 
    
         
             
            #define SIZE_T_FMT "u"
         
     | 
| 
      
 139 
     | 
    
         
            +
            #ifdef __sun
         
     | 
| 
      
 140 
     | 
    
         
            +
            #define ELF_WORD_FMT "lu"
         
     | 
| 
      
 141 
     | 
    
         
            +
            #define ELF_XWORD_FMT "lu"
         
     | 
| 
      
 142 
     | 
    
         
            +
            #define ELF_SXWORD_FMT "ld"
         
     | 
| 
      
 143 
     | 
    
         
            +
            #else
         
     | 
| 
      
 144 
     | 
    
         
            +
            #define ELF_WORD_FMT "u"
         
     | 
| 
      
 145 
     | 
    
         
            +
            #define ELF_XWORD_FMT "u"
         
     | 
| 
      
 146 
     | 
    
         
            +
            #define ELF_SXWORD_FMT "d"
         
     | 
| 
      
 147 
     | 
    
         
            +
            #endif
         
     | 
| 
       119 
148 
     | 
    
         
             
            #define Elf_Half Elf32_Half
         
     | 
| 
       120 
     | 
    
         
            -
            #define  
     | 
| 
      
 149 
     | 
    
         
            +
            #define Elf_Xword Elf32_Word
         
     | 
| 
      
 150 
     | 
    
         
            +
            #define Elf_Sxword Elf32_Sword
         
     | 
| 
       121 
151 
     | 
    
         
             
            #define Elf_Ehdr Elf32_Ehdr
         
     | 
| 
       122 
152 
     | 
    
         
             
            #define Elf_Phdr Elf32_Phdr
         
     | 
| 
       123 
     | 
    
         
            -
            #define Elf_Shdr Elf32_Shdr
         
     | 
| 
       124 
153 
     | 
    
         
             
            #define Elf_Sym  Elf32_Sym
         
     | 
| 
      
 154 
     | 
    
         
            +
            #define Elf_Dyn  Elf32_Dyn
         
     | 
| 
       125 
155 
     | 
    
         
             
            #define Elf_Rel  Elf32_Rel
         
     | 
| 
       126 
156 
     | 
    
         
             
            #define Elf_Rela Elf32_Rela
         
     | 
| 
       127 
157 
     | 
    
         
             
            #ifndef ELF_R_SYM
         
     | 
| 
         @@ -132,29 +162,41 @@ 
     | 
|
| 
       132 
162 
     | 
    
         
             
            #endif
         
     | 
| 
       133 
163 
     | 
    
         
             
            #endif /* __LP64__ */
         
     | 
| 
       134 
164 
     | 
    
         | 
| 
      
 165 
     | 
    
         
            +
            #if defined(PT_GNU_RELRO) && !defined(__sun)
         
     | 
| 
      
 166 
     | 
    
         
            +
            #define SUPPORT_RELRO /* RELRO (RELocation Read-Only) */
         
     | 
| 
      
 167 
     | 
    
         
            +
            #if !defined(DF_1_NOW) && defined(DF_1_BIND_NOW)
         
     | 
| 
      
 168 
     | 
    
         
            +
            #define DF_1_NOW DF_1_BIND_NOW
         
     | 
| 
      
 169 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 170 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
       135 
172 
     | 
    
         
             
            struct plthook {
         
     | 
| 
       136 
     | 
    
         
            -
                const char *base;
         
     | 
| 
       137 
     | 
    
         
            -
                const Elf_Phdr *phdr;
         
     | 
| 
       138 
     | 
    
         
            -
                size_t phnum;
         
     | 
| 
       139 
     | 
    
         
            -
                Elf_Shdr *shdr;
         
     | 
| 
       140 
     | 
    
         
            -
                size_t shnum;
         
     | 
| 
       141 
     | 
    
         
            -
                char *shstrtab;
         
     | 
| 
       142 
     | 
    
         
            -
                size_t shstrtab_size;
         
     | 
| 
       143 
173 
     | 
    
         
             
                const Elf_Sym *dynsym;
         
     | 
| 
       144 
     | 
    
         
            -
                size_t dynsym_cnt;
         
     | 
| 
       145 
174 
     | 
    
         
             
                const char *dynstr;
         
     | 
| 
       146 
175 
     | 
    
         
             
                size_t dynstr_size;
         
     | 
| 
      
 176 
     | 
    
         
            +
                const char *plt_addr_base;
         
     | 
| 
       147 
177 
     | 
    
         
             
                const Elf_Plt_Rel *plt;
         
     | 
| 
       148 
178 
     | 
    
         
             
                size_t plt_cnt;
         
     | 
| 
      
 179 
     | 
    
         
            +
                Elf_Xword r_type;
         
     | 
| 
      
 180 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 181 
     | 
    
         
            +
                const char *relro_start;
         
     | 
| 
      
 182 
     | 
    
         
            +
                const char *relro_end;
         
     | 
| 
      
 183 
     | 
    
         
            +
            #endif
         
     | 
| 
       149 
184 
     | 
    
         
             
            };
         
     | 
| 
       150 
185 
     | 
    
         | 
| 
       151 
186 
     | 
    
         
             
            static char errmsg[512];
         
     | 
| 
       152 
187 
     | 
    
         | 
| 
      
 188 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 189 
     | 
    
         
            +
            static size_t page_size;
         
     | 
| 
      
 190 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
       153 
192 
     | 
    
         
             
            static int plthook_open_executable(plthook_t **plthook_out);
         
     | 
| 
       154 
193 
     | 
    
         
             
            static int plthook_open_shared_library(plthook_t **plthook_out, const char *filename);
         
     | 
| 
       155 
     | 
    
         
            -
            static  
     | 
| 
      
 194 
     | 
    
         
            +
            static const Elf_Dyn *find_dyn_by_tag(const Elf_Dyn *dyn, Elf_Sxword tag);
         
     | 
| 
      
 195 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 196 
     | 
    
         
            +
            static int set_relro_members(plthook_t *plthook, struct link_map *lmap);
         
     | 
| 
      
 197 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 198 
     | 
    
         
            +
            static int plthook_open_real(plthook_t **plthook_out, struct link_map *lmap);
         
     | 
| 
       156 
199 
     | 
    
         
             
            static int check_elf_header(const Elf_Ehdr *ehdr);
         
     | 
| 
       157 
     | 
    
         
            -
            static int find_section(plthook_t *image, const char *name, const Elf_Shdr **out);
         
     | 
| 
       158 
200 
     | 
    
         
             
            static void set_errmsg(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
         
     | 
| 
       159 
201 
     | 
    
         | 
| 
       160 
202 
     | 
    
         
             
            int plthook_open(plthook_t **plthook_out, const char *filename)
         
     | 
| 
         @@ -167,69 +209,71 @@ int plthook_open(plthook_t **plthook_out, const char *filename) 
     | 
|
| 
       167 
209 
     | 
    
         
             
                }
         
     | 
| 
       168 
210 
     | 
    
         
             
            }
         
     | 
| 
       169 
211 
     | 
    
         | 
| 
      
 212 
     | 
    
         
            +
            int plthook_open_by_handle(plthook_t **plthook_out, void *hndl)
         
     | 
| 
      
 213 
     | 
    
         
            +
            {
         
     | 
| 
      
 214 
     | 
    
         
            +
                struct link_map *lmap = NULL;
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                if (hndl == NULL) {
         
     | 
| 
      
 217 
     | 
    
         
            +
                    set_errmsg("NULL handle");
         
     | 
| 
      
 218 
     | 
    
         
            +
                    return PLTHOOK_FILE_NOT_FOUND;
         
     | 
| 
      
 219 
     | 
    
         
            +
                }
         
     | 
| 
      
 220 
     | 
    
         
            +
                if (dlinfo(hndl, RTLD_DI_LINKMAP, &lmap) != 0) {
         
     | 
| 
      
 221 
     | 
    
         
            +
                    set_errmsg("dlinfo error");
         
     | 
| 
      
 222 
     | 
    
         
            +
                    return PLTHOOK_FILE_NOT_FOUND;
         
     | 
| 
      
 223 
     | 
    
         
            +
                }
         
     | 
| 
      
 224 
     | 
    
         
            +
                return plthook_open_real(plthook_out, lmap);
         
     | 
| 
      
 225 
     | 
    
         
            +
            }
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
       170 
227 
     | 
    
         
             
            int plthook_open_by_address(plthook_t **plthook_out, void *address)
         
     | 
| 
       171 
228 
     | 
    
         
             
            {
         
     | 
| 
      
 229 
     | 
    
         
            +
            #if defined __FreeBSD__
         
     | 
| 
      
 230 
     | 
    
         
            +
                return PLTHOOK_NOT_IMPLEMENTED;
         
     | 
| 
      
 231 
     | 
    
         
            +
            #else
         
     | 
| 
       172 
232 
     | 
    
         
             
                Dl_info info;
         
     | 
| 
      
 233 
     | 
    
         
            +
                struct link_map *lmap = NULL;
         
     | 
| 
       173 
234 
     | 
    
         | 
| 
       174 
235 
     | 
    
         
             
                *plthook_out = NULL;
         
     | 
| 
       175 
     | 
    
         
            -
                if ( 
     | 
| 
      
 236 
     | 
    
         
            +
                if (dladdr1(address, &info, (void**)&lmap, RTLD_DL_LINKMAP) == 0) {
         
     | 
| 
       176 
237 
     | 
    
         
             
                    set_errmsg("dladdr error");
         
     | 
| 
       177 
238 
     | 
    
         
             
                    return PLTHOOK_FILE_NOT_FOUND;
         
     | 
| 
       178 
239 
     | 
    
         
             
                }
         
     | 
| 
       179 
     | 
    
         
            -
                return plthook_open_real(plthook_out,  
     | 
| 
      
 240 
     | 
    
         
            +
                return plthook_open_real(plthook_out, lmap);
         
     | 
| 
      
 241 
     | 
    
         
            +
            #endif
         
     | 
| 
       180 
242 
     | 
    
         
             
            }
         
     | 
| 
       181 
243 
     | 
    
         | 
| 
       182 
244 
     | 
    
         
             
            static int plthook_open_executable(plthook_t **plthook_out)
         
     | 
| 
       183 
245 
     | 
    
         
             
            {
         
     | 
| 
       184 
246 
     | 
    
         
             
            #if defined __linux__
         
     | 
| 
       185 
     | 
    
         
            -
                 
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                 
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
      
 247 
     | 
    
         
            +
                return plthook_open_real(plthook_out, _r_debug.r_map);
         
     | 
| 
      
 248 
     | 
    
         
            +
            #elif defined __sun
         
     | 
| 
      
 249 
     | 
    
         
            +
                const char *auxv_file = "/proc/self/auxv";
         
     | 
| 
      
 250 
     | 
    
         
            +
            #define NUM_AUXV_CNT 10
         
     | 
| 
      
 251 
     | 
    
         
            +
                FILE *fp = fopen(auxv_file, "r");
         
     | 
| 
      
 252 
     | 
    
         
            +
                auxv_t auxv;
         
     | 
| 
      
 253 
     | 
    
         
            +
                struct r_debug *r_debug = NULL;
         
     | 
| 
       189 
254 
     | 
    
         | 
| 
       190 
255 
     | 
    
         
             
                if (fp == NULL) {
         
     | 
| 
       191 
     | 
    
         
            -
                    set_errmsg("Could not open  
     | 
| 
      
 256 
     | 
    
         
            +
                    set_errmsg("Could not open %s: %s", auxv_file,
         
     | 
| 
       192 
257 
     | 
    
         
             
                               strerror(errno));
         
     | 
| 
       193 
258 
     | 
    
         
             
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       194 
259 
     | 
    
         
             
                }
         
     | 
| 
       195 
     | 
    
         
            -
                 
     | 
| 
       196 
     | 
    
         
            -
                     
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
                     
     | 
| 
      
 260 
     | 
    
         
            +
                while (fread(&auxv, sizeof(auxv_t), 1, fp) == 1) {
         
     | 
| 
      
 261 
     | 
    
         
            +
                    if (auxv.a_type == AT_SUN_LDDATA) {
         
     | 
| 
      
 262 
     | 
    
         
            +
                        r_debug = (struct r_debug *)auxv.a_un.a_ptr;
         
     | 
| 
      
 263 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 264 
     | 
    
         
            +
                    }
         
     | 
| 
       200 
265 
     | 
    
         
             
                }
         
     | 
| 
       201 
266 
     | 
    
         
             
                fclose(fp);
         
     | 
| 
       202 
     | 
    
         
            -
                if ( 
     | 
| 
       203 
     | 
    
         
            -
                    set_errmsg(" 
     | 
| 
       204 
     | 
    
         
            -
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       205 
     | 
    
         
            -
                }
         
     | 
| 
       206 
     | 
    
         
            -
                return plthook_open_real(plthook_out, (const char*)base, "/proc/self/exe");
         
     | 
| 
       207 
     | 
    
         
            -
            #elif defined __sun
         
     | 
| 
       208 
     | 
    
         
            -
                prmap_t prmap;
         
     | 
| 
       209 
     | 
    
         
            -
                pid_t pid = getpid();
         
     | 
| 
       210 
     | 
    
         
            -
                char fname[128];
         
     | 
| 
       211 
     | 
    
         
            -
                int fd;
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
                sprintf(fname, "/proc/%d/map", pid);
         
     | 
| 
       214 
     | 
    
         
            -
                fd = open(fname, O_RDONLY);
         
     | 
| 
       215 
     | 
    
         
            -
                if (fd == -1) {
         
     | 
| 
       216 
     | 
    
         
            -
                    set_errmsg("Could not open %s: %s", fname,
         
     | 
| 
       217 
     | 
    
         
            -
                               strerror(errno));
         
     | 
| 
      
 267 
     | 
    
         
            +
                if (r_debug == NULL) {
         
     | 
| 
      
 268 
     | 
    
         
            +
                    set_errmsg("Could not find r_debug");
         
     | 
| 
       218 
269 
     | 
    
         
             
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       219 
270 
     | 
    
         
             
                }
         
     | 
| 
       220 
     | 
    
         
            -
                 
     | 
| 
       221 
     | 
    
         
            -
                    set_errmsg("Could not read %s: %s", fname,
         
     | 
| 
       222 
     | 
    
         
            -
                               strerror(errno));
         
     | 
| 
       223 
     | 
    
         
            -
                    close(fd);
         
     | 
| 
       224 
     | 
    
         
            -
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       225 
     | 
    
         
            -
                }
         
     | 
| 
       226 
     | 
    
         
            -
                close(fd);
         
     | 
| 
       227 
     | 
    
         
            -
                sprintf(fname, "/proc/%d/object/a.out", pid);
         
     | 
| 
       228 
     | 
    
         
            -
                return plthook_open_real(plthook_out, (const char*)prmap.pr_vaddr, fname);
         
     | 
| 
      
 271 
     | 
    
         
            +
                return plthook_open_real(plthook_out, r_debug->r_map);
         
     | 
| 
       229 
272 
     | 
    
         
             
            #elif defined __FreeBSD__
         
     | 
| 
       230 
273 
     | 
    
         
             
                return plthook_open_shared_library(plthook_out, NULL);
         
     | 
| 
       231 
274 
     | 
    
         
             
            #else
         
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
      
 275 
     | 
    
         
            +
                set_errmsg("Opening the main program is not supported on this platform.");
         
     | 
| 
      
 276 
     | 
    
         
            +
                return PLTHOOK_NOT_IMPLEMENTED;
         
     | 
| 
       233 
277 
     | 
    
         
             
            #endif
         
     | 
| 
       234 
278 
     | 
    
         
             
            }
         
     | 
| 
       235 
279 
     | 
    
         | 
| 
         @@ -248,161 +292,339 @@ static int plthook_open_shared_library(plthook_t **plthook_out, const char *file 
     | 
|
| 
       248 
292 
     | 
    
         
             
                    return PLTHOOK_FILE_NOT_FOUND;
         
     | 
| 
       249 
293 
     | 
    
         
             
                }
         
     | 
| 
       250 
294 
     | 
    
         
             
                dlclose(hndl);
         
     | 
| 
       251 
     | 
    
         
            -
                return plthook_open_real(plthook_out,  
     | 
| 
      
 295 
     | 
    
         
            +
                return plthook_open_real(plthook_out, lmap);
         
     | 
| 
       252 
296 
     | 
    
         
             
            }
         
     | 
| 
       253 
297 
     | 
    
         | 
| 
       254 
     | 
    
         
            -
            static  
     | 
| 
      
 298 
     | 
    
         
            +
            static const Elf_Dyn *find_dyn_by_tag(const Elf_Dyn *dyn, Elf_Sxword tag)
         
     | 
| 
       255 
299 
     | 
    
         
             
            {
         
     | 
| 
       256 
     | 
    
         
            -
                 
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
       259 
     | 
    
         
            -
             
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
                 
     | 
| 
       262 
     | 
    
         
            -
                 
     | 
| 
      
 300 
     | 
    
         
            +
                while (dyn->d_tag != DT_NULL) {
         
     | 
| 
      
 301 
     | 
    
         
            +
                    if (dyn->d_tag == tag) {
         
     | 
| 
      
 302 
     | 
    
         
            +
                        return dyn;
         
     | 
| 
      
 303 
     | 
    
         
            +
                    }
         
     | 
| 
      
 304 
     | 
    
         
            +
                    dyn++;
         
     | 
| 
      
 305 
     | 
    
         
            +
                }
         
     | 
| 
      
 306 
     | 
    
         
            +
                return NULL;
         
     | 
| 
      
 307 
     | 
    
         
            +
            }
         
     | 
| 
       263 
308 
     | 
    
         | 
| 
       264 
     | 
    
         
            -
             
     | 
| 
       265 
     | 
    
         
            -
             
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
      
 309 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 310 
     | 
    
         
            +
            #if defined __linux__
         
     | 
| 
      
 311 
     | 
    
         
            +
            static const char *get_mapped_file(const void *address, char *buf, int *err)
         
     | 
| 
      
 312 
     | 
    
         
            +
            {
         
     | 
| 
      
 313 
     | 
    
         
            +
                unsigned long addr = (unsigned long)address;
         
     | 
| 
      
 314 
     | 
    
         
            +
                FILE *fp;
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
                fp = fopen("/proc/self/maps", "r");
         
     | 
| 
      
 317 
     | 
    
         
            +
                if (fp == NULL) {
         
     | 
| 
      
 318 
     | 
    
         
            +
                    set_errmsg("failed to open /proc/self/maps");
         
     | 
| 
      
 319 
     | 
    
         
            +
                    *err = PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 320 
     | 
    
         
            +
                    return NULL;
         
     | 
| 
       267 
321 
     | 
    
         
             
                }
         
     | 
| 
      
 322 
     | 
    
         
            +
                while (fgets(buf, PATH_MAX, fp) != NULL) {
         
     | 
| 
      
 323 
     | 
    
         
            +
                    unsigned long start, end;
         
     | 
| 
      
 324 
     | 
    
         
            +
                    int offset = 0;
         
     | 
| 
       268 
325 
     | 
    
         | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
                     
     | 
| 
       271 
     | 
    
         
            -
             
     | 
| 
      
 326 
     | 
    
         
            +
                    sscanf(buf, "%lx-%lx %*s %*x %*x:%*x %*u %n", &start, &end, &offset);
         
     | 
| 
      
 327 
     | 
    
         
            +
                    if (offset == 0) {
         
     | 
| 
      
 328 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 329 
     | 
    
         
            +
                    }
         
     | 
| 
      
 330 
     | 
    
         
            +
                    if (start < addr && addr < end) {
         
     | 
| 
      
 331 
     | 
    
         
            +
                        char *p = buf + offset;
         
     | 
| 
      
 332 
     | 
    
         
            +
                        while (*p == ' ') {
         
     | 
| 
      
 333 
     | 
    
         
            +
                            p++;
         
     | 
| 
      
 334 
     | 
    
         
            +
                        }
         
     | 
| 
      
 335 
     | 
    
         
            +
                        if (*p != '/') {
         
     | 
| 
      
 336 
     | 
    
         
            +
                            continue;
         
     | 
| 
      
 337 
     | 
    
         
            +
                        }
         
     | 
| 
      
 338 
     | 
    
         
            +
                        p[strlen(p) - 1] = '\0'; /* remove '\n' */
         
     | 
| 
      
 339 
     | 
    
         
            +
                        fclose(fp);
         
     | 
| 
      
 340 
     | 
    
         
            +
                        return p;
         
     | 
| 
      
 341 
     | 
    
         
            +
                    }
         
     | 
| 
       272 
342 
     | 
    
         
             
                }
         
     | 
| 
      
 343 
     | 
    
         
            +
                fclose(fp);
         
     | 
| 
      
 344 
     | 
    
         
            +
                set_errmsg("Could not find a mapped file reagion containing %p", address);
         
     | 
| 
      
 345 
     | 
    
         
            +
                *err = PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 346 
     | 
    
         
            +
                return NULL;
         
     | 
| 
      
 347 
     | 
    
         
            +
            }
         
     | 
| 
      
 348 
     | 
    
         
            +
            #elif defined __FreeBSD__
         
     | 
| 
      
 349 
     | 
    
         
            +
            static const char *get_mapped_file(const void *address, char *buf, int *err)
         
     | 
| 
      
 350 
     | 
    
         
            +
            {
         
     | 
| 
      
 351 
     | 
    
         
            +
                uint64_t addr = (uint64_t)address;
         
     | 
| 
      
 352 
     | 
    
         
            +
                struct kinfo_vmentry *top;
         
     | 
| 
      
 353 
     | 
    
         
            +
                int i, cnt;
         
     | 
| 
      
 354 
     | 
    
         
            +
             
     | 
| 
      
 355 
     | 
    
         
            +
                top = kinfo_getvmmap(getpid(), &cnt);
         
     | 
| 
      
 356 
     | 
    
         
            +
                if (top == NULL) {
         
     | 
| 
      
 357 
     | 
    
         
            +
                    fprintf(stderr, "failed to call kinfo_getvmmap()\n");
         
     | 
| 
      
 358 
     | 
    
         
            +
                    *err = PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 359 
     | 
    
         
            +
                    return NULL;
         
     | 
| 
      
 360 
     | 
    
         
            +
                }
         
     | 
| 
      
 361 
     | 
    
         
            +
                for (i = 0; i < cnt; i++) {
         
     | 
| 
      
 362 
     | 
    
         
            +
                    struct kinfo_vmentry *kve = top + i;
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
                    if (kve->kve_start < addr && addr < kve->kve_end) {
         
     | 
| 
      
 365 
     | 
    
         
            +
                        strncpy(buf, kve->kve_path, PATH_MAX);
         
     | 
| 
      
 366 
     | 
    
         
            +
                        free(top);
         
     | 
| 
      
 367 
     | 
    
         
            +
                        return buf;
         
     | 
| 
      
 368 
     | 
    
         
            +
                    }
         
     | 
| 
      
 369 
     | 
    
         
            +
                }
         
     | 
| 
      
 370 
     | 
    
         
            +
                free(top);
         
     | 
| 
      
 371 
     | 
    
         
            +
                set_errmsg("Could not find a mapped file reagion containing %p", address);
         
     | 
| 
      
 372 
     | 
    
         
            +
                *err = PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 373 
     | 
    
         
            +
                return NULL;
         
     | 
| 
      
 374 
     | 
    
         
            +
            }
         
     | 
| 
      
 375 
     | 
    
         
            +
            #else
         
     | 
| 
      
 376 
     | 
    
         
            +
            static const char *get_mapped_file(const void *address, char *buf, int *err)
         
     | 
| 
      
 377 
     | 
    
         
            +
            {
         
     | 
| 
      
 378 
     | 
    
         
            +
                set_errmsg("Could not find a mapped file reagion containing %p", address);
         
     | 
| 
      
 379 
     | 
    
         
            +
                *err = PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 380 
     | 
    
         
            +
                return NULL;
         
     | 
| 
      
 381 
     | 
    
         
            +
            }
         
     | 
| 
      
 382 
     | 
    
         
            +
            #endif
         
     | 
| 
       273 
383 
     | 
    
         | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
      
 384 
     | 
    
         
            +
            static int set_relro_members(plthook_t *plthook, struct link_map *lmap)
         
     | 
| 
      
 385 
     | 
    
         
            +
            {
         
     | 
| 
      
 386 
     | 
    
         
            +
                char fnamebuf[PATH_MAX];
         
     | 
| 
      
 387 
     | 
    
         
            +
                const char *fname;
         
     | 
| 
      
 388 
     | 
    
         
            +
                FILE *fp;
         
     | 
| 
      
 389 
     | 
    
         
            +
                Elf_Ehdr ehdr;
         
     | 
| 
      
 390 
     | 
    
         
            +
                Elf_Half idx;
         
     | 
| 
      
 391 
     | 
    
         
            +
                int rv;
         
     | 
| 
      
 392 
     | 
    
         
            +
             
     | 
| 
      
 393 
     | 
    
         
            +
                if (lmap->l_name[0] == '/') {
         
     | 
| 
      
 394 
     | 
    
         
            +
                    fname = lmap->l_name;
         
     | 
| 
      
 395 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 396 
     | 
    
         
            +
                    int err;
         
     | 
| 
      
 397 
     | 
    
         
            +
             
     | 
| 
      
 398 
     | 
    
         
            +
                    fname = get_mapped_file(plthook->dynstr, fnamebuf, &err);
         
     | 
| 
      
 399 
     | 
    
         
            +
                    if (fname == NULL) {
         
     | 
| 
      
 400 
     | 
    
         
            +
                        return err;
         
     | 
| 
      
 401 
     | 
    
         
            +
                    }
         
     | 
| 
      
 402 
     | 
    
         
            +
                }
         
     | 
| 
      
 403 
     | 
    
         
            +
                fp = fopen(fname, "r");
         
     | 
| 
      
 404 
     | 
    
         
            +
                if (fp == NULL) {
         
     | 
| 
      
 405 
     | 
    
         
            +
                    set_errmsg("failed to open %s", fname);
         
     | 
| 
      
 406 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 407 
     | 
    
         
            +
                }
         
     | 
| 
      
 408 
     | 
    
         
            +
                if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
         
     | 
| 
      
 409 
     | 
    
         
            +
                    set_errmsg("failed to read the ELF header.");
         
     | 
| 
      
 410 
     | 
    
         
            +
                    fclose(fp);
         
     | 
| 
      
 411 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 412 
     | 
    
         
            +
                }
         
     | 
| 
      
 413 
     | 
    
         
            +
                rv = check_elf_header(&ehdr);
         
     | 
| 
      
 414 
     | 
    
         
            +
                if (rv != 0) {
         
     | 
| 
      
 415 
     | 
    
         
            +
                    fclose(fp);
         
     | 
| 
      
 416 
     | 
    
         
            +
                    return rv;
         
     | 
| 
       278 
417 
     | 
    
         
             
                }
         
     | 
| 
       279 
418 
     | 
    
         | 
| 
       280 
     | 
    
         
            -
                 
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
      
 419 
     | 
    
         
            +
                fseek(fp, ehdr.e_phoff, SEEK_SET);
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
                for (idx = 0; idx < ehdr.e_phnum; idx++) {
         
     | 
| 
      
 422 
     | 
    
         
            +
                    Elf_Phdr phdr;
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
                    if (fread(&phdr, sizeof(phdr), 1, fp) != 1) {
         
     | 
| 
      
 425 
     | 
    
         
            +
                        set_errmsg("failed to read the program header table.");
         
     | 
| 
      
 426 
     | 
    
         
            +
                        fclose(fp);
         
     | 
| 
      
 427 
     | 
    
         
            +
                        return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 428 
     | 
    
         
            +
                    }
         
     | 
| 
      
 429 
     | 
    
         
            +
                    if (phdr.p_type == PT_GNU_RELRO) {
         
     | 
| 
      
 430 
     | 
    
         
            +
                        plthook->relro_start = plthook->plt_addr_base + phdr.p_vaddr;
         
     | 
| 
      
 431 
     | 
    
         
            +
                        plthook->relro_end = plthook->relro_start + phdr.p_memsz;
         
     | 
| 
      
 432 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 433 
     | 
    
         
            +
                    }
         
     | 
| 
      
 434 
     | 
    
         
            +
                }
         
     | 
| 
      
 435 
     | 
    
         
            +
                fclose(fp);
         
     | 
| 
      
 436 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 437 
     | 
    
         
            +
            }
         
     | 
| 
      
 438 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
            static int plthook_open_real(plthook_t **plthook_out, struct link_map *lmap)
         
     | 
| 
      
 441 
     | 
    
         
            +
            {
         
     | 
| 
      
 442 
     | 
    
         
            +
                plthook_t plthook = {NULL,};
         
     | 
| 
      
 443 
     | 
    
         
            +
                const Elf_Dyn *dyn;
         
     | 
| 
      
 444 
     | 
    
         
            +
                const char *dyn_addr_base = NULL;
         
     | 
| 
      
 445 
     | 
    
         
            +
             
     | 
| 
      
 446 
     | 
    
         
            +
            #if defined __linux__
         
     | 
| 
      
 447 
     | 
    
         
            +
                plthook.plt_addr_base = (char*)lmap->l_addr;
         
     | 
| 
      
 448 
     | 
    
         
            +
            #elif defined __FreeBSD__ || defined __sun
         
     | 
| 
      
 449 
     | 
    
         
            +
                const Elf_Ehdr *ehdr = (const Elf_Ehdr*)lmap->l_addr;
         
     | 
| 
      
 450 
     | 
    
         
            +
                int rv = check_elf_header(ehdr);
         
     | 
| 
       282 
451 
     | 
    
         
             
                if (rv != 0) {
         
     | 
| 
       283 
     | 
    
         
            -
                     
     | 
| 
      
 452 
     | 
    
         
            +
                    return rv;
         
     | 
| 
       284 
453 
     | 
    
         
             
                }
         
     | 
| 
       285 
454 
     | 
    
         
             
                if (ehdr->e_type == ET_DYN) {
         
     | 
| 
       286 
     | 
    
         
            -
                     
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
                 
     | 
| 
       289 
     | 
    
         
            -
             
     | 
| 
       290 
     | 
    
         
            -
             
     | 
| 
       291 
     | 
    
         
            -
             
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
       293 
     | 
    
         
            -
             
     | 
| 
       294 
     | 
    
         
            -
             
     | 
| 
       295 
     | 
    
         
            -
                 
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
     | 
    
         
            -
                if (plthook->shdr == NULL) {
         
     | 
| 
       299 
     | 
    
         
            -
                    set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", shdr_size);
         
     | 
| 
       300 
     | 
    
         
            -
                    rv = PLTHOOK_OUT_OF_MEMORY;
         
     | 
| 
       301 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
       302 
     | 
    
         
            -
                }
         
     | 
| 
       303 
     | 
    
         
            -
                offset = ehdr->e_shoff;
         
     | 
| 
       304 
     | 
    
         
            -
                if ((rv = lseek(fd, offset, SEEK_SET)) != offset) {
         
     | 
| 
       305 
     | 
    
         
            -
                    set_errmsg("failed to seek to the section header table.");
         
     | 
| 
       306 
     | 
    
         
            -
                    rv = PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       307 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
       308 
     | 
    
         
            -
                }
         
     | 
| 
       309 
     | 
    
         
            -
                if (read(fd, plthook->shdr, shdr_size) != shdr_size) {
         
     | 
| 
       310 
     | 
    
         
            -
                    set_errmsg("failed to read the section header table.");
         
     | 
| 
       311 
     | 
    
         
            -
                    rv = PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       312 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
       313 
     | 
    
         
            -
                }
         
     | 
| 
       314 
     | 
    
         
            -
                plthook->shnum = ehdr->e_shnum;
         
     | 
| 
       315 
     | 
    
         
            -
                plthook->shstrtab_size = plthook->shdr[ehdr->e_shstrndx].sh_size;
         
     | 
| 
       316 
     | 
    
         
            -
                plthook->shstrtab = malloc(plthook->shstrtab_size);
         
     | 
| 
       317 
     | 
    
         
            -
                if (plthook->shstrtab == NULL) {
         
     | 
| 
       318 
     | 
    
         
            -
                    set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", plthook->shstrtab_size);
         
     | 
| 
       319 
     | 
    
         
            -
                    rv = PLTHOOK_OUT_OF_MEMORY;
         
     | 
| 
       320 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
       321 
     | 
    
         
            -
                }
         
     | 
| 
       322 
     | 
    
         
            -
                offset = plthook->shdr[ehdr->e_shstrndx].sh_offset;
         
     | 
| 
       323 
     | 
    
         
            -
                if (lseek(fd, offset, SEEK_SET) != offset) {
         
     | 
| 
       324 
     | 
    
         
            -
                    set_errmsg("failed to seek to the section header string table.");
         
     | 
| 
       325 
     | 
    
         
            -
                    rv = PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       326 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
       327 
     | 
    
         
            -
                }
         
     | 
| 
       328 
     | 
    
         
            -
                if (read(fd, plthook->shstrtab, plthook->shstrtab_size) != plthook->shstrtab_size) {
         
     | 
| 
       329 
     | 
    
         
            -
                    set_errmsg("failed to read the section header string table.");
         
     | 
| 
       330 
     | 
    
         
            -
                    rv = PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       331 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
       332 
     | 
    
         
            -
                }
         
     | 
| 
       333 
     | 
    
         
            -
                close(fd);
         
     | 
| 
       334 
     | 
    
         
            -
                fd = -1;
         
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
       336 
     | 
    
         
            -
                rv = find_section(plthook, ".dynsym", &shdr);
         
     | 
| 
       337 
     | 
    
         
            -
                if (rv != 0) {
         
     | 
| 
       338 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
      
 455 
     | 
    
         
            +
                    dyn_addr_base = (const char*)lmap->l_addr;
         
     | 
| 
      
 456 
     | 
    
         
            +
                    plthook.plt_addr_base = (const char*)lmap->l_addr;
         
     | 
| 
      
 457 
     | 
    
         
            +
                }
         
     | 
| 
      
 458 
     | 
    
         
            +
            #else
         
     | 
| 
      
 459 
     | 
    
         
            +
            #error unsupported OS
         
     | 
| 
      
 460 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 461 
     | 
    
         
            +
             
     | 
| 
      
 462 
     | 
    
         
            +
                /* get .dynsym section */
         
     | 
| 
      
 463 
     | 
    
         
            +
                dyn = find_dyn_by_tag(lmap->l_ld, DT_SYMTAB);
         
     | 
| 
      
 464 
     | 
    
         
            +
                if (dyn == NULL) {
         
     | 
| 
      
 465 
     | 
    
         
            +
                    set_errmsg("failed to find DT_SYMTAB");
         
     | 
| 
      
 466 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       339 
467 
     | 
    
         
             
                }
         
     | 
| 
       340 
     | 
    
         
            -
                 
     | 
| 
       341 
     | 
    
         
            -
             
     | 
| 
       342 
     | 
    
         
            -
             
     | 
| 
       343 
     | 
    
         
            -
             
     | 
| 
      
 468 
     | 
    
         
            +
                plthook.dynsym = (const Elf_Sym*)(dyn_addr_base + dyn->d_un.d_ptr);
         
     | 
| 
      
 469 
     | 
    
         
            +
             
     | 
| 
      
 470 
     | 
    
         
            +
                /* Check sizeof(Elf_Sym) */
         
     | 
| 
      
 471 
     | 
    
         
            +
                dyn = find_dyn_by_tag(lmap->l_ld, DT_SYMENT);
         
     | 
| 
      
 472 
     | 
    
         
            +
                if (dyn == NULL) {
         
     | 
| 
      
 473 
     | 
    
         
            +
                    set_errmsg("failed to find DT_SYMTAB");
         
     | 
| 
      
 474 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       344 
475 
     | 
    
         
             
                }
         
     | 
| 
       345 
     | 
    
         
            -
                if ( 
     | 
| 
       346 
     | 
    
         
            -
                    set_errmsg(" 
     | 
| 
       347 
     | 
    
         
            -
             
     | 
| 
       348 
     | 
    
         
            -
                    rv = PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       349 
     | 
    
         
            -
                    goto error_exit;
         
     | 
| 
      
 476 
     | 
    
         
            +
                if (dyn->d_un.d_val != sizeof(Elf_Sym)) {
         
     | 
| 
      
 477 
     | 
    
         
            +
                    set_errmsg("DT_SYMENT size %" ELF_XWORD_FMT " != %" SIZE_T_FMT, dyn->d_un.d_val, sizeof(Elf_Sym));
         
     | 
| 
      
 478 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       350 
479 
     | 
    
         
             
                }
         
     | 
| 
       351 
     | 
    
         
            -
                plthook->dynsym = (const Elf_Sym*)(plthook->base + shdr->sh_addr);
         
     | 
| 
       352 
     | 
    
         
            -
                plthook->dynsym_cnt = shdr->sh_size / shdr->sh_entsize;
         
     | 
| 
       353 
480 
     | 
    
         | 
| 
       354 
     | 
    
         
            -
                 
     | 
| 
       355 
     | 
    
         
            -
                 
     | 
| 
       356 
     | 
    
         
            -
             
     | 
| 
      
 481 
     | 
    
         
            +
                /* get .dynstr section */
         
     | 
| 
      
 482 
     | 
    
         
            +
                dyn = find_dyn_by_tag(lmap->l_ld, DT_STRTAB);
         
     | 
| 
      
 483 
     | 
    
         
            +
                if (dyn == NULL) {
         
     | 
| 
      
 484 
     | 
    
         
            +
                    set_errmsg("failed to find DT_STRTAB");
         
     | 
| 
      
 485 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       357 
486 
     | 
    
         
             
                }
         
     | 
| 
       358 
     | 
    
         
            -
                 
     | 
| 
       359 
     | 
    
         
            -
             
     | 
| 
       360 
     | 
    
         
            -
             
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
      
 487 
     | 
    
         
            +
                plthook.dynstr = dyn_addr_base + dyn->d_un.d_ptr;
         
     | 
| 
      
 488 
     | 
    
         
            +
             
     | 
| 
      
 489 
     | 
    
         
            +
                /* get .dynstr size */
         
     | 
| 
      
 490 
     | 
    
         
            +
                dyn = find_dyn_by_tag(lmap->l_ld, DT_STRSZ);
         
     | 
| 
      
 491 
     | 
    
         
            +
                if (dyn == NULL) {
         
     | 
| 
      
 492 
     | 
    
         
            +
                    set_errmsg("failed to find DT_STRSZ");
         
     | 
| 
      
 493 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       362 
494 
     | 
    
         
             
                }
         
     | 
| 
       363 
     | 
    
         
            -
                plthook 
     | 
| 
       364 
     | 
    
         
            -
                plthook->dynstr_size = shdr->sh_size;
         
     | 
| 
      
 495 
     | 
    
         
            +
                plthook.dynstr_size = dyn->d_un.d_val;
         
     | 
| 
       365 
496 
     | 
    
         | 
| 
       366 
     | 
    
         
            -
                 
     | 
| 
       367 
     | 
    
         
            -
                 
     | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
      
 497 
     | 
    
         
            +
                /* get .rela.plt or .rel.plt section */
         
     | 
| 
      
 498 
     | 
    
         
            +
                dyn = find_dyn_by_tag(lmap->l_ld, DT_JMPREL);
         
     | 
| 
      
 499 
     | 
    
         
            +
                plthook.r_type = R_JUMP_SLOT;
         
     | 
| 
      
 500 
     | 
    
         
            +
            #ifdef PLT_DT_REL
         
     | 
| 
      
 501 
     | 
    
         
            +
                if (dyn == NULL) {
         
     | 
| 
      
 502 
     | 
    
         
            +
                    /* get .rela.dyn or .rel.dyn section */
         
     | 
| 
      
 503 
     | 
    
         
            +
                    dyn = find_dyn_by_tag(lmap->l_ld, PLT_DT_REL);
         
     | 
| 
      
 504 
     | 
    
         
            +
                    plthook.r_type = R_GLOBAL_DATA;
         
     | 
| 
       369 
505 
     | 
    
         
             
                }
         
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
             
     | 
| 
       372 
     | 
    
         
            -
                     
     | 
| 
       373 
     | 
    
         
            -
                     
     | 
| 
      
 506 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 507 
     | 
    
         
            +
                if (dyn == NULL) {
         
     | 
| 
      
 508 
     | 
    
         
            +
                    set_errmsg("failed to find DT_JMPREL");
         
     | 
| 
      
 509 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       374 
510 
     | 
    
         
             
                }
         
     | 
| 
       375 
     | 
    
         
            -
                plthook 
     | 
| 
       376 
     | 
    
         
            -
             
     | 
| 
      
 511 
     | 
    
         
            +
                plthook.plt = (const Elf_Plt_Rel *)(dyn_addr_base + dyn->d_un.d_ptr);
         
     | 
| 
      
 512 
     | 
    
         
            +
             
     | 
| 
      
 513 
     | 
    
         
            +
                if (plthook.r_type == R_JUMP_SLOT) {
         
     | 
| 
      
 514 
     | 
    
         
            +
                    /* get total size of .rela.plt or .rel.plt */
         
     | 
| 
      
 515 
     | 
    
         
            +
                    dyn = find_dyn_by_tag(lmap->l_ld, DT_PLTRELSZ);
         
     | 
| 
      
 516 
     | 
    
         
            +
                    if (dyn == NULL) {
         
     | 
| 
      
 517 
     | 
    
         
            +
                        set_errmsg("failed to find DT_PLTRELSZ");
         
     | 
| 
      
 518 
     | 
    
         
            +
                        return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 519 
     | 
    
         
            +
                    }
         
     | 
| 
       377 
520 
     | 
    
         | 
| 
       378 
     | 
    
         
            -
             
     | 
| 
      
 521 
     | 
    
         
            +
                    plthook.plt_cnt = dyn->d_un.d_val / sizeof(Elf_Plt_Rel);
         
     | 
| 
      
 522 
     | 
    
         
            +
            #ifdef PLT_DT_REL
         
     | 
| 
      
 523 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 524 
     | 
    
         
            +
                    int total_size_tag = PLT_DT_REL == DT_RELA ? DT_RELASZ : DT_RELSZ;
         
     | 
| 
      
 525 
     | 
    
         
            +
                    int elem_size_tag = PLT_DT_REL == DT_RELA ? DT_RELAENT : DT_RELENT;
         
     | 
| 
      
 526 
     | 
    
         
            +
                    size_t total_size, elem_size;
         
     | 
| 
      
 527 
     | 
    
         
            +
             
     | 
| 
      
 528 
     | 
    
         
            +
                    dyn = find_dyn_by_tag(lmap->l_ld, total_size_tag);
         
     | 
| 
      
 529 
     | 
    
         
            +
                    if (dyn == NULL) {
         
     | 
| 
      
 530 
     | 
    
         
            +
                        set_errmsg("failed to find 0x%x", total_size_tag);
         
     | 
| 
      
 531 
     | 
    
         
            +
                        return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 532 
     | 
    
         
            +
                    }
         
     | 
| 
      
 533 
     | 
    
         
            +
                    total_size = dyn->d_un.d_ptr;
         
     | 
| 
      
 534 
     | 
    
         
            +
             
     | 
| 
      
 535 
     | 
    
         
            +
                    dyn = find_dyn_by_tag(lmap->l_ld, elem_size_tag);
         
     | 
| 
      
 536 
     | 
    
         
            +
                    if (dyn == NULL) {
         
     | 
| 
      
 537 
     | 
    
         
            +
                        set_errmsg("failed to find 0x%x", elem_size_tag);
         
     | 
| 
      
 538 
     | 
    
         
            +
                        return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 539 
     | 
    
         
            +
                    }
         
     | 
| 
      
 540 
     | 
    
         
            +
                    elem_size = dyn->d_un.d_ptr;
         
     | 
| 
      
 541 
     | 
    
         
            +
                    plthook.plt_cnt = total_size / elem_size;
         
     | 
| 
      
 542 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 543 
     | 
    
         
            +
                }
         
     | 
| 
      
 544 
     | 
    
         
            +
             
     | 
| 
      
 545 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 546 
     | 
    
         
            +
                dyn = find_dyn_by_tag(lmap->l_ld, DT_FLAGS_1);
         
     | 
| 
      
 547 
     | 
    
         
            +
                if (dyn != NULL && (dyn->d_un.d_val & DF_1_NOW)) {
         
     | 
| 
      
 548 
     | 
    
         
            +
                    int rv = set_relro_members(&plthook, lmap);
         
     | 
| 
      
 549 
     | 
    
         
            +
                    if (rv != 0) {
         
     | 
| 
      
 550 
     | 
    
         
            +
                        return rv;
         
     | 
| 
      
 551 
     | 
    
         
            +
                    }
         
     | 
| 
      
 552 
     | 
    
         
            +
                    if (page_size == 0) {
         
     | 
| 
      
 553 
     | 
    
         
            +
                        page_size = sysconf(_SC_PAGESIZE);
         
     | 
| 
      
 554 
     | 
    
         
            +
                    }
         
     | 
| 
      
 555 
     | 
    
         
            +
                }
         
     | 
| 
      
 556 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
                *plthook_out = malloc(sizeof(plthook_t));
         
     | 
| 
      
 559 
     | 
    
         
            +
                if (*plthook_out == NULL) {
         
     | 
| 
      
 560 
     | 
    
         
            +
                    set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", sizeof(plthook_t));
         
     | 
| 
      
 561 
     | 
    
         
            +
                    return PLTHOOK_OUT_OF_MEMORY;
         
     | 
| 
      
 562 
     | 
    
         
            +
                }
         
     | 
| 
      
 563 
     | 
    
         
            +
                **plthook_out = plthook;
         
     | 
| 
       379 
564 
     | 
    
         
             
                return 0;
         
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
             
     | 
| 
      
 565 
     | 
    
         
            +
            }
         
     | 
| 
      
 566 
     | 
    
         
            +
             
     | 
| 
      
 567 
     | 
    
         
            +
            static int check_elf_header(const Elf_Ehdr *ehdr)
         
     | 
| 
      
 568 
     | 
    
         
            +
            {
         
     | 
| 
      
 569 
     | 
    
         
            +
                static const unsigned short s = 1;
         
     | 
| 
      
 570 
     | 
    
         
            +
                /* Check endianness at runtime. */
         
     | 
| 
      
 571 
     | 
    
         
            +
                unsigned char elfdata = (*(const char*)&s) ? ELFDATA2LSB : ELFDATA2MSB;
         
     | 
| 
      
 572 
     | 
    
         
            +
             
     | 
| 
      
 573 
     | 
    
         
            +
                if (ehdr == NULL) {
         
     | 
| 
      
 574 
     | 
    
         
            +
                    set_errmsg("invalid elf header address: NULL");
         
     | 
| 
      
 575 
     | 
    
         
            +
                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
       383 
576 
     | 
    
         
             
                }
         
     | 
| 
       384 
     | 
    
         
            -
             
     | 
| 
       385 
     | 
    
         
            -
                 
     | 
| 
      
 577 
     | 
    
         
            +
             
     | 
| 
      
 578 
     | 
    
         
            +
                if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
         
     | 
| 
      
 579 
     | 
    
         
            +
                    set_errmsg("invalid file signature: 0x%02x,0x%02x,0x%02x,0x%02x",
         
     | 
| 
      
 580 
     | 
    
         
            +
                               ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
         
     | 
| 
      
 581 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 582 
     | 
    
         
            +
                }
         
     | 
| 
      
 583 
     | 
    
         
            +
                if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
         
     | 
| 
      
 584 
     | 
    
         
            +
                    set_errmsg("invalid elf class: 0x%02x", ehdr->e_ident[EI_CLASS]);
         
     | 
| 
      
 585 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 586 
     | 
    
         
            +
                }
         
     | 
| 
      
 587 
     | 
    
         
            +
                if (ehdr->e_ident[EI_DATA] != elfdata) {
         
     | 
| 
      
 588 
     | 
    
         
            +
                    set_errmsg("invalid elf data: 0x%02x", ehdr->e_ident[EI_DATA]);
         
     | 
| 
      
 589 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 590 
     | 
    
         
            +
                }
         
     | 
| 
      
 591 
     | 
    
         
            +
                if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
         
     | 
| 
      
 592 
     | 
    
         
            +
                    set_errmsg("invalid elf version: 0x%02x", ehdr->e_ident[EI_VERSION]);
         
     | 
| 
      
 593 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 594 
     | 
    
         
            +
                }
         
     | 
| 
      
 595 
     | 
    
         
            +
                if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
         
     | 
| 
      
 596 
     | 
    
         
            +
                    set_errmsg("invalid file type: 0x%04x", ehdr->e_type);
         
     | 
| 
      
 597 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 598 
     | 
    
         
            +
                }
         
     | 
| 
      
 599 
     | 
    
         
            +
                if (ehdr->e_version != EV_CURRENT) {
         
     | 
| 
      
 600 
     | 
    
         
            +
                    set_errmsg("invalid object file version: %" ELF_WORD_FMT, ehdr->e_version);
         
     | 
| 
      
 601 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 602 
     | 
    
         
            +
                }
         
     | 
| 
      
 603 
     | 
    
         
            +
                if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) {
         
     | 
| 
      
 604 
     | 
    
         
            +
                    set_errmsg("invalid elf header size: %u", ehdr->e_ehsize);
         
     | 
| 
      
 605 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 606 
     | 
    
         
            +
                }
         
     | 
| 
      
 607 
     | 
    
         
            +
                if (ehdr->e_phentsize != sizeof(Elf_Phdr)) {
         
     | 
| 
      
 608 
     | 
    
         
            +
                    set_errmsg("invalid program header table entry size: %u", ehdr->e_phentsize);
         
     | 
| 
      
 609 
     | 
    
         
            +
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
      
 610 
     | 
    
         
            +
                }
         
     | 
| 
      
 611 
     | 
    
         
            +
                return 0;
         
     | 
| 
       386 
612 
     | 
    
         
             
            }
         
     | 
| 
       387 
613 
     | 
    
         | 
| 
       388 
614 
     | 
    
         
             
            int plthook_enum(plthook_t *plthook, unsigned int *pos, const char **name_out, void ***addr_out)
         
     | 
| 
       389 
615 
     | 
    
         
             
            {
         
     | 
| 
       390 
616 
     | 
    
         
             
                while (*pos < plthook->plt_cnt) {
         
     | 
| 
       391 
617 
     | 
    
         
             
                    const Elf_Plt_Rel *plt = plthook->plt + *pos;
         
     | 
| 
       392 
     | 
    
         
            -
                    if (ELF_R_TYPE(plt->r_info) ==  
     | 
| 
      
 618 
     | 
    
         
            +
                    if (ELF_R_TYPE(plt->r_info) == plthook->r_type) {
         
     | 
| 
       393 
619 
     | 
    
         
             
                        size_t idx = ELF_R_SYM(plt->r_info);
         
     | 
| 
       394 
620 
     | 
    
         | 
| 
       395 
     | 
    
         
            -
                        if (idx >= plthook->dynsym_cnt) {
         
     | 
| 
       396 
     | 
    
         
            -
                            set_errmsg(".dynsym index %" SIZE_T_FMT " should be less than %" SIZE_T_FMT ".", idx, plthook->dynsym_cnt);
         
     | 
| 
       397 
     | 
    
         
            -
                            return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       398 
     | 
    
         
            -
                        }
         
     | 
| 
       399 
621 
     | 
    
         
             
                        idx = plthook->dynsym[idx].st_name;
         
     | 
| 
       400 
622 
     | 
    
         
             
                        if (idx + 1 > plthook->dynstr_size) {
         
     | 
| 
       401 
623 
     | 
    
         
             
                            set_errmsg("too big section header string table index: %" SIZE_T_FMT, idx);
         
     | 
| 
       402 
624 
     | 
    
         
             
                            return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       403 
625 
     | 
    
         
             
                        }
         
     | 
| 
       404 
626 
     | 
    
         
             
                        *name_out = plthook->dynstr + idx;
         
     | 
| 
       405 
     | 
    
         
            -
                        *addr_out = (void**)(plthook-> 
     | 
| 
      
 627 
     | 
    
         
            +
                        *addr_out = (void**)(plthook->plt_addr_base + plt->r_offset);
         
     | 
| 
       406 
628 
     | 
    
         
             
                        (*pos)++;
         
     | 
| 
       407 
629 
     | 
    
         
             
                        return 0;
         
     | 
| 
       408 
630 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -428,10 +650,26 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo 
     | 
|
| 
       428 
650 
     | 
    
         
             
                while ((rv = plthook_enum(plthook, &pos, &name, &addr)) == 0) {
         
     | 
| 
       429 
651 
     | 
    
         
             
                    if (strncmp(name, funcname, funcnamelen) == 0) {
         
     | 
| 
       430 
652 
     | 
    
         
             
                        if (name[funcnamelen] == '\0' || name[funcnamelen] == '@') {
         
     | 
| 
      
 653 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 654 
     | 
    
         
            +
                            void *maddr = NULL;
         
     | 
| 
      
 655 
     | 
    
         
            +
                            if (plthook->relro_start <= (char*)addr && (char*)addr < plthook->relro_end) {
         
     | 
| 
      
 656 
     | 
    
         
            +
                                maddr = (void*)((size_t)addr & ~(page_size - 1));
         
     | 
| 
      
 657 
     | 
    
         
            +
                                if (mprotect(maddr, page_size, PROT_READ | PROT_WRITE) != 0) {
         
     | 
| 
      
 658 
     | 
    
         
            +
                                    set_errmsg("Could not change the process memory protection at %p: %s",
         
     | 
| 
      
 659 
     | 
    
         
            +
                                               maddr, strerror(errno));
         
     | 
| 
      
 660 
     | 
    
         
            +
                                    return PLTHOOK_INTERNAL_ERROR;
         
     | 
| 
      
 661 
     | 
    
         
            +
                                }
         
     | 
| 
      
 662 
     | 
    
         
            +
                            }
         
     | 
| 
      
 663 
     | 
    
         
            +
            #endif
         
     | 
| 
       431 
664 
     | 
    
         
             
                            if (oldfunc) {
         
     | 
| 
       432 
665 
     | 
    
         
             
                                *oldfunc = *addr;
         
     | 
| 
       433 
666 
     | 
    
         
             
                            }
         
     | 
| 
       434 
667 
     | 
    
         
             
                            *addr = funcaddr;
         
     | 
| 
      
 668 
     | 
    
         
            +
            #ifdef SUPPORT_RELRO
         
     | 
| 
      
 669 
     | 
    
         
            +
                            if (maddr != NULL) {
         
     | 
| 
      
 670 
     | 
    
         
            +
                                mprotect(maddr, page_size, PROT_READ);
         
     | 
| 
      
 671 
     | 
    
         
            +
                            }
         
     | 
| 
      
 672 
     | 
    
         
            +
            #endif
         
     | 
| 
       435 
673 
     | 
    
         
             
                            return 0;
         
     | 
| 
       436 
674 
     | 
    
         
             
                        }
         
     | 
| 
       437 
675 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -446,8 +684,6 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo 
     | 
|
| 
       446 
684 
     | 
    
         
             
            void plthook_close(plthook_t *plthook)
         
     | 
| 
       447 
685 
     | 
    
         
             
            {
         
     | 
| 
       448 
686 
     | 
    
         
             
                if (plthook != NULL) {
         
     | 
| 
       449 
     | 
    
         
            -
                    free(plthook->shdr);
         
     | 
| 
       450 
     | 
    
         
            -
                    free(plthook->shstrtab);
         
     | 
| 
       451 
687 
     | 
    
         
             
                    free(plthook);
         
     | 
| 
       452 
688 
     | 
    
         
             
                }
         
     | 
| 
       453 
689 
     | 
    
         
             
            }
         
     | 
| 
         @@ -457,77 +693,6 @@ const char *plthook_error(void) 
     | 
|
| 
       457 
693 
     | 
    
         
             
                return errmsg;
         
     | 
| 
       458 
694 
     | 
    
         
             
            }
         
     | 
| 
       459 
695 
     | 
    
         | 
| 
       460 
     | 
    
         
            -
            static int check_elf_header(const Elf_Ehdr *ehdr)
         
     | 
| 
       461 
     | 
    
         
            -
            {
         
     | 
| 
       462 
     | 
    
         
            -
                if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
         
     | 
| 
       463 
     | 
    
         
            -
                    set_errmsg("invalid file signature: 0x%02x,0x%02x,0x%02x,0x%02x",
         
     | 
| 
       464 
     | 
    
         
            -
                               ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
         
     | 
| 
       465 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       466 
     | 
    
         
            -
                }
         
     | 
| 
       467 
     | 
    
         
            -
                if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
         
     | 
| 
       468 
     | 
    
         
            -
                    set_errmsg("invalid elf class: 0x%02x", ehdr->e_ident[EI_CLASS]);
         
     | 
| 
       469 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       470 
     | 
    
         
            -
                }
         
     | 
| 
       471 
     | 
    
         
            -
                if (ehdr->e_ident[EI_DATA] != ELF_DATA) {
         
     | 
| 
       472 
     | 
    
         
            -
                    set_errmsg("invalid elf data: 0x%02x", ehdr->e_ident[EI_DATA]);
         
     | 
| 
       473 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       474 
     | 
    
         
            -
                }
         
     | 
| 
       475 
     | 
    
         
            -
                if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
         
     | 
| 
       476 
     | 
    
         
            -
                    set_errmsg("invalid elf version: 0x%02x", ehdr->e_ident[EI_VERSION]);
         
     | 
| 
       477 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       478 
     | 
    
         
            -
                }
         
     | 
| 
       479 
     | 
    
         
            -
                if (ehdr->e_ident[EI_OSABI] != ELF_OSABI) {
         
     | 
| 
       480 
     | 
    
         
            -
                    set_errmsg("invalid OS ABI: 0x%02x", ehdr->e_ident[EI_OSABI]);
         
     | 
| 
       481 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       482 
     | 
    
         
            -
                }
         
     | 
| 
       483 
     | 
    
         
            -
                if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
         
     | 
| 
       484 
     | 
    
         
            -
                    set_errmsg("invalid file type: 0x%04x", ehdr->e_type);
         
     | 
| 
       485 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       486 
     | 
    
         
            -
                }
         
     | 
| 
       487 
     | 
    
         
            -
                if (ehdr->e_machine != E_MACHINE) {
         
     | 
| 
       488 
     | 
    
         
            -
                    set_errmsg("invalid machine type: %u", ehdr->e_machine);
         
     | 
| 
       489 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       490 
     | 
    
         
            -
                }
         
     | 
| 
       491 
     | 
    
         
            -
                if (ehdr->e_version != EV_CURRENT) {
         
     | 
| 
       492 
     | 
    
         
            -
                    set_errmsg("invalid object file version: %u", ehdr->e_version);
         
     | 
| 
       493 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       494 
     | 
    
         
            -
                }
         
     | 
| 
       495 
     | 
    
         
            -
                if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) {
         
     | 
| 
       496 
     | 
    
         
            -
                    set_errmsg("invalid elf header size: %u", ehdr->e_ehsize);
         
     | 
| 
       497 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       498 
     | 
    
         
            -
                }
         
     | 
| 
       499 
     | 
    
         
            -
                if (ehdr->e_phentsize != sizeof(Elf_Phdr)) {
         
     | 
| 
       500 
     | 
    
         
            -
                    set_errmsg("invalid program header table entry size: %u", ehdr->e_phentsize);
         
     | 
| 
       501 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       502 
     | 
    
         
            -
                }
         
     | 
| 
       503 
     | 
    
         
            -
                if (ehdr->e_shentsize != sizeof(Elf_Shdr)) {
         
     | 
| 
       504 
     | 
    
         
            -
                    set_errmsg("invalid section header table entry size: %u", ehdr->e_shentsize);
         
     | 
| 
       505 
     | 
    
         
            -
                    return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       506 
     | 
    
         
            -
                }
         
     | 
| 
       507 
     | 
    
         
            -
                return 0;
         
     | 
| 
       508 
     | 
    
         
            -
            }
         
     | 
| 
       509 
     | 
    
         
            -
             
     | 
| 
       510 
     | 
    
         
            -
            static int find_section(plthook_t *image, const char *name, const Elf_Shdr **out)
         
     | 
| 
       511 
     | 
    
         
            -
            {
         
     | 
| 
       512 
     | 
    
         
            -
                const Elf_Shdr *shdr = image->shdr;
         
     | 
| 
       513 
     | 
    
         
            -
                const Elf_Shdr *shdr_end = shdr + image->shnum;
         
     | 
| 
       514 
     | 
    
         
            -
                size_t namelen = strlen(name);
         
     | 
| 
       515 
     | 
    
         
            -
             
     | 
| 
       516 
     | 
    
         
            -
                while (shdr < shdr_end) {
         
     | 
| 
       517 
     | 
    
         
            -
                    if (shdr->sh_name + namelen >= image->shstrtab_size) {
         
     | 
| 
       518 
     | 
    
         
            -
                        set_errmsg("too big section header string table index: %u", shdr->sh_name);
         
     | 
| 
       519 
     | 
    
         
            -
                        return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       520 
     | 
    
         
            -
                    }
         
     | 
| 
       521 
     | 
    
         
            -
                    if (strcmp(image->shstrtab + shdr->sh_name, name) == 0) {
         
     | 
| 
       522 
     | 
    
         
            -
                        *out = shdr;
         
     | 
| 
       523 
     | 
    
         
            -
                        return 0;
         
     | 
| 
       524 
     | 
    
         
            -
                    }
         
     | 
| 
       525 
     | 
    
         
            -
                    shdr++;
         
     | 
| 
       526 
     | 
    
         
            -
                }
         
     | 
| 
       527 
     | 
    
         
            -
                set_errmsg("failed to find the section header: %s", name);
         
     | 
| 
       528 
     | 
    
         
            -
                return PLTHOOK_INVALID_FILE_FORMAT;
         
     | 
| 
       529 
     | 
    
         
            -
            }
         
     | 
| 
       530 
     | 
    
         
            -
             
     | 
| 
       531 
696 
     | 
    
         
             
            static void set_errmsg(const char *fmt, ...)
         
     | 
| 
       532 
697 
     | 
    
         
             
            {
         
     | 
| 
       533 
698 
     | 
    
         
             
                va_list ap;
         
     |