< prev index next >

src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c

Print this page


   1 /*
   2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <unistd.h>
  26 #include <sys/procfs.h>
  27 #include <search.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include "symtab.h"
  31 #include "salibelf.h"
  32 
  33 
  34 // ----------------------------------------------------
  35 // functions for symbol lookups
  36 // ----------------------------------------------------
  37 
  38 struct elf_section {
  39   ELF_SHDR   *c_shdr;
  40   void       *c_data;
  41 };
  42 
  43 struct elf_symbol {
  44   char *name;
  45   uintptr_t offset;
  46   uintptr_t size;
  47 };
  48 
  49 typedef struct symtab {
  50   char *strs;
  51   size_t num_symbols;
  52   struct elf_symbol *symbols;
  53   struct hsearch_data *hash_table;
  54 } symtab_t;
  55 
  56 
  57 // Directory that contains global debuginfo files.  In theory it
  58 // should be possible to change this, but in a Java environment there
  59 // is no obvious place to put a user interface to do it.  Maybe this
  60 // could be set with an environment variable.
  61 static const char debug_file_directory[] = "/usr/lib/debug";
  62 


 139   int fd = pathmap_open(pathname);
 140 
 141   if (fd < 0)
 142     return -1;
 143 
 144   lseek(fd, 0, SEEK_SET);
 145 
 146   for (;;) {
 147     int len = read(fd, buffer, sizeof buffer);
 148     if (len <= 0)
 149       break;
 150     file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
 151   }
 152 
 153   if (crc == file_crc)
 154     return fd;
 155   else {
 156     close(fd);
 157     return -1;
 158   }
 159 }
 160 
 161 /* Find an ELF section.  */
 162 static struct elf_section *find_section_by_name(char *name,
 163                                                 int fd,
 164                                                 ELF_EHDR *ehdr,
 165                                                 struct elf_section *scn_cache)
 166 {
 167   char *strtab;
 168   int cnt;
 169   int strtab_size;
 170 
 171   // Section cache have to already contain data for e_shstrndx section.
 172   // If it's not true - elf file is broken, so just bail out
 173   if (scn_cache[ehdr->e_shstrndx].c_data == NULL) {
 174     return NULL;
 175   }
 176 
 177   strtab = scn_cache[ehdr->e_shstrndx].c_data;
 178   strtab_size = scn_cache[ehdr->e_shstrndx].c_shdr->sh_size;
 179 
 180   for (cnt = 0; cnt < ehdr->e_shnum; ++cnt) {
 181     if (scn_cache[cnt].c_shdr->sh_name < strtab_size) {
 182       if (strcmp(scn_cache[cnt].c_shdr->sh_name + strtab, name) == 0) {
 183         scn_cache[cnt].c_data = read_section_data(fd, ehdr, scn_cache[cnt].c_shdr);
 184         return &scn_cache[cnt];
 185       }
 186     }
 187   }
 188 
 189   return NULL;
 190 }
 191 
 192 /* Look for a ".gnu_debuglink" section.  If one exists, try to open a
 193    suitable debuginfo file.  */
 194 static int open_file_from_debug_link(const char *name,
 195                                      int fd,
 196                                      ELF_EHDR *ehdr,
 197                                      struct elf_section *scn_cache)
 198 {
 199   int debug_fd;
 200   struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr,
 201                                                          scn_cache);
 202   if (debug_link == NULL)
 203     return -1;
 204   char *debug_filename = debug_link->c_data;
 205   int offset = (strlen(debug_filename) + 4) >> 2;
 206   static unsigned int crc;
 207   crc = ((unsigned int*)debug_link->c_data)[offset];
 208   char *debug_pathname = malloc(strlen(debug_filename)
 209                                 + strlen(name)


   1 /*
   2  * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <unistd.h>
  26 #include <sys/procfs.h>
  27 #include <search.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include "symtab.h"
  31 #include "salibelf.h"
  32 
  33 
  34 // ----------------------------------------------------
  35 // functions for symbol lookups
  36 // ----------------------------------------------------
  37 





  38 struct elf_symbol {
  39   char *name;
  40   uintptr_t offset;
  41   uintptr_t size;
  42 };
  43 
  44 typedef struct symtab {
  45   char *strs;
  46   size_t num_symbols;
  47   struct elf_symbol *symbols;
  48   struct hsearch_data *hash_table;
  49 } symtab_t;
  50 
  51 
  52 // Directory that contains global debuginfo files.  In theory it
  53 // should be possible to change this, but in a Java environment there
  54 // is no obvious place to put a user interface to do it.  Maybe this
  55 // could be set with an environment variable.
  56 static const char debug_file_directory[] = "/usr/lib/debug";
  57 


 134   int fd = pathmap_open(pathname);
 135 
 136   if (fd < 0)
 137     return -1;
 138 
 139   lseek(fd, 0, SEEK_SET);
 140 
 141   for (;;) {
 142     int len = read(fd, buffer, sizeof buffer);
 143     if (len <= 0)
 144       break;
 145     file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
 146   }
 147 
 148   if (crc == file_crc)
 149     return fd;
 150   else {
 151     close(fd);
 152     return -1;
 153   }































 154 }
 155 
 156 /* Look for a ".gnu_debuglink" section.  If one exists, try to open a
 157    suitable debuginfo file.  */
 158 static int open_file_from_debug_link(const char *name,
 159                                      int fd,
 160                                      ELF_EHDR *ehdr,
 161                                      struct elf_section *scn_cache)
 162 {
 163   int debug_fd;
 164   struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr,
 165                                                          scn_cache);
 166   if (debug_link == NULL)
 167     return -1;
 168   char *debug_filename = debug_link->c_data;
 169   int offset = (strlen(debug_filename) + 4) >> 2;
 170   static unsigned int crc;
 171   crc = ((unsigned int*)debug_link->c_data)[offset];
 172   char *debug_pathname = malloc(strlen(debug_filename)
 173                                 + strlen(name)


< prev index next >