Mercurial > hg > truffle
annotate agent/src/os/linux/symtab.c @ 3011:f00918f35c7f
inlining and runtime interface related changes:
added codeSize() and compilerStorage() to RiMethod
HotSpotMethodResolved uses reflective methods instead of vmIds and survives compilations
HotSpotResolvedType.isInitialized not represented as field (can change)
inlining stores graphs into method objects and reuses them
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Thu, 16 Jun 2011 20:36:17 +0200 |
parents | 0a8e0d4345b3 |
children | f2512d89ad0c |
rev | line source |
---|---|
0 | 1 /* |
2042
0a8e0d4345b3
7010068: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - first pass
trims
parents:
1552
diff
changeset
|
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1294
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1294
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1294
diff
changeset
|
21 * questions. |
0 | 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 | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
56 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
57 // Directory that contains global debuginfo files. In theory it |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
58 // should be possible to change this, but in a Java environment there |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
59 // is no obvious place to put a user interface to do it. Maybe this |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
60 // could be set with an environment variable. |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
61 static const char debug_file_directory[] = "/usr/lib/debug"; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
62 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
63 /* The CRC used in gnu_debuglink, retrieved from |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
64 http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
65 unsigned int gnu_debuglink_crc32 (unsigned int crc, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
66 unsigned char *buf, size_t len) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
67 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
68 static const unsigned int crc32_table[256] = |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
69 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
70 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
71 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
72 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
73 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
74 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
75 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
76 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
77 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
78 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
79 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
80 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
81 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
82 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
83 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
84 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
85 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
86 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
87 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
88 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
89 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
90 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
91 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
92 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
93 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
94 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
95 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
96 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
97 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
98 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
99 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
100 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
101 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
102 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
103 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
104 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
105 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
106 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
107 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
108 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
109 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
110 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
111 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
112 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
113 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
114 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
115 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
116 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
117 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
118 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
119 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
120 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
121 0x2d02ef8d |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
122 }; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
123 unsigned char *end; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
124 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
125 crc = ~crc & 0xffffffff; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
126 for (end = buf + len; buf < end; ++buf) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
127 crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
128 return ~crc & 0xffffffff; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
129 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
130 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
131 /* Open a debuginfo file and check its CRC. If it exists and the CRC |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
132 matches return its fd. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
133 static int |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
134 open_debug_file (const char *pathname, unsigned int crc) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
135 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
136 unsigned int file_crc = 0; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
137 unsigned char buffer[8 * 1024]; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
138 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
139 int fd = pathmap_open(pathname); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
140 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
141 if (fd < 0) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
142 return -1; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
143 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
144 lseek(fd, 0, SEEK_SET); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
145 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
146 for (;;) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
147 int len = read(fd, buffer, sizeof buffer); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
148 if (len <= 0) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
149 break; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
150 file_crc = gnu_debuglink_crc32(file_crc, buffer, len); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
151 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
152 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
153 if (crc == file_crc) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
154 return fd; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
155 else { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
156 close(fd); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
157 return -1; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
158 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
159 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
160 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
161 /* Find an ELF section. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
162 static struct elf_section *find_section_by_name(char *name, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
163 int fd, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
164 ELF_EHDR *ehdr, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
165 ELF_SHDR *shbuf, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
166 struct elf_section *scn_cache) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
167 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
168 ELF_SHDR* cursct = NULL; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
169 char *strtab; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
170 int cnt; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
171 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
172 if (scn_cache[ehdr->e_shstrndx].c_data == NULL) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
173 if ((scn_cache[ehdr->e_shstrndx].c_data |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
174 = read_section_data(fd, ehdr, cursct)) == NULL) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
175 return NULL; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
176 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
177 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
178 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
179 strtab = scn_cache[ehdr->e_shstrndx].c_data; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
180 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
181 for (cursct = shbuf, cnt = 0; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
182 cnt < ehdr->e_shnum; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
183 cnt++, cursct++) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
184 if (strcmp(cursct->sh_name + strtab, name) == 0) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
185 scn_cache[cnt].c_data = read_section_data(fd, ehdr, cursct); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
186 return &scn_cache[cnt]; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
187 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
188 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
189 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
190 return NULL; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
191 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
192 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
193 /* Look for a ".gnu_debuglink" section. If one exists, try to open a |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
194 suitable debuginfo file. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
195 static int open_file_from_debug_link(const char *name, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
196 int fd, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
197 ELF_EHDR *ehdr, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
198 ELF_SHDR *shbuf, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
199 struct elf_section *scn_cache) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
200 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
201 int debug_fd; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
202 struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
203 shbuf, scn_cache); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
204 if (debug_link == NULL) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
205 return -1; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
206 char *debug_filename = debug_link->c_data; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
207 int offset = (strlen(debug_filename) + 4) >> 2; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
208 static unsigned int crc; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
209 crc = ((unsigned int*)debug_link->c_data)[offset]; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
210 char *debug_pathname = malloc(strlen(debug_filename) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
211 + strlen(name) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
212 + strlen(".debug/") |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
213 + strlen(debug_file_directory) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
214 + 2); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
215 strcpy(debug_pathname, name); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
216 char *last_slash = strrchr(debug_pathname, '/'); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
217 if (last_slash == NULL) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
218 return -1; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
219 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
220 /* Look in the same directory as the object. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
221 strcpy(last_slash+1, debug_filename); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
222 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
223 debug_fd = open_debug_file(debug_pathname, crc); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
224 if (debug_fd >= 0) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
225 free(debug_pathname); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
226 return debug_fd; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
227 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
228 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
229 /* Look in a subdirectory named ".debug". */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
230 strcpy(last_slash+1, ".debug/"); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
231 strcat(last_slash, debug_filename); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
232 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
233 debug_fd = open_debug_file(debug_pathname, crc); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
234 if (debug_fd >= 0) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
235 free(debug_pathname); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
236 return debug_fd; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
237 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
238 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
239 /* Look in /usr/lib/debug + the full pathname. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
240 strcpy(debug_pathname, debug_file_directory); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
241 strcat(debug_pathname, name); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
242 last_slash = strrchr(debug_pathname, '/'); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
243 strcpy(last_slash+1, debug_filename); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
244 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
245 debug_fd = open_debug_file(debug_pathname, crc); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
246 if (debug_fd >= 0) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
247 free(debug_pathname); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
248 return debug_fd; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
249 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
250 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
251 free(debug_pathname); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
252 return -1; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
253 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
254 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
255 static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
256 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
257 /* Look for a ".gnu_debuglink" section. If one exists, try to open a |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
258 suitable debuginfo file and read a symbol table from it. */ |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
259 static struct symtab *build_symtab_from_debug_link(const char *name, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
260 int fd, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
261 ELF_EHDR *ehdr, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
262 ELF_SHDR *shbuf, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
263 struct elf_section *scn_cache) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
264 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
265 fd = open_file_from_debug_link(name, fd, ehdr, shbuf, scn_cache); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
266 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
267 if (fd >= 0) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
268 struct symtab *symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
269 close(fd); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
270 return symtab; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
271 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
272 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
273 return NULL; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
274 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
275 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
276 // Given a build_id, find the associated debuginfo file |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
277 static char * |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
278 build_id_to_debug_filename (size_t size, unsigned char *data) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
279 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
280 char *filename, *s; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
281 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
282 filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
283 + 2 * size + (sizeof ".debug" - 1) + 1); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
284 s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
285 if (size > 0) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
286 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
287 size--; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
288 s += sprintf (s, "%02x", *data++); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
289 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
290 if (size > 0) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
291 *s++ = '/'; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
292 while (size-- > 0) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
293 s += sprintf (s, "%02x", *data++); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
294 strcpy (s, ".debug"); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
295 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
296 return filename; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
297 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
298 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
299 // Read a build ID note. Try to open any associated debuginfo file |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
300 // and return its symtab |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
301 static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
302 { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
303 int fd; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
304 struct symtab *symtab = NULL; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
305 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
306 unsigned char *bytes |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
307 = (unsigned char*)(note+1) + note->n_namesz; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
308 unsigned char *filename |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
309 = (build_id_to_debug_filename (note->n_descsz, bytes)); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
310 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
311 fd = pathmap_open(filename); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
312 if (fd >= 0) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
313 symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
314 close(fd); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
315 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
316 free(filename); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
317 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
318 return symtab; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
319 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
320 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
321 // read symbol table from given fd. If try_debuginfo) is true, also |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
322 // try to open an associated debuginfo file |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
323 static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) { |
0 | 324 ELF_EHDR ehdr; |
325 char *names = NULL; | |
326 struct symtab* symtab = NULL; | |
327 | |
328 // Reading of elf header | |
329 struct elf_section *scn_cache = NULL; | |
330 int cnt = 0; | |
331 ELF_SHDR* shbuf = NULL; | |
332 ELF_SHDR* cursct = NULL; | |
333 ELF_PHDR* phbuf = NULL; | |
334 ELF_PHDR* phdr = NULL; | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
335 int sym_section = SHT_DYNSYM; |
0 | 336 |
337 uintptr_t baseaddr = (uintptr_t)-1; | |
338 | |
339 lseek(fd, (off_t)0L, SEEK_SET); | |
340 if (! read_elf_header(fd, &ehdr)) { | |
341 // not an elf | |
342 return NULL; | |
343 } | |
344 | |
345 // read ELF header | |
346 if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) { | |
347 goto quit; | |
348 } | |
349 | |
350 baseaddr = find_base_address(fd, &ehdr); | |
351 | |
352 scn_cache = (struct elf_section *) | |
353 calloc(ehdr.e_shnum * sizeof(struct elf_section), 1); | |
354 if (scn_cache == NULL) { | |
355 goto quit; | |
356 } | |
357 | |
358 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) { | |
359 scn_cache[cnt].c_shdr = cursct; | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
360 if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
361 || cursct->sh_type == SHT_NOTE || cursct->sh_type == SHT_DYNSYM) { |
0 | 362 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) { |
363 goto quit; | |
364 } | |
365 } | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
366 if (cursct->sh_type == SHT_SYMTAB) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
367 // Full symbol table available so use that |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
368 sym_section = cursct->sh_type; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
369 } |
0 | 370 cursct++; |
371 } | |
372 | |
373 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) { | |
374 ELF_SHDR *shdr = scn_cache[cnt].c_shdr; | |
375 | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
376 if (shdr->sh_type == sym_section) { |
0 | 377 ELF_SYM *syms; |
378 int j, n, rslt; | |
379 size_t size; | |
380 | |
381 // FIXME: there could be multiple data buffers associated with the | |
382 // same ELF section. Here we can handle only one buffer. See man page | |
383 // for elf_getdata on Solaris. | |
384 | |
385 // guarantee(symtab == NULL, "multiple symtab"); | |
386 symtab = (struct symtab*)calloc(1, sizeof(struct symtab)); | |
387 if (symtab == NULL) { | |
388 goto quit; | |
389 } | |
390 // the symbol table | |
391 syms = (ELF_SYM *)scn_cache[cnt].c_data; | |
392 | |
393 // number of symbols | |
394 n = shdr->sh_size / shdr->sh_entsize; | |
395 | |
396 // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to | |
397 // manipulate the hash table. | |
398 symtab->hash_table = (struct hsearch_data*) calloc(1, sizeof(struct hsearch_data)); | |
399 rslt = hcreate_r(n, symtab->hash_table); | |
400 // guarantee(rslt, "unexpected failure: hcreate_r"); | |
401 | |
402 // shdr->sh_link points to the section that contains the actual strings | |
403 // for symbol names. the st_name field in ELF_SYM is just the | |
404 // string table index. we make a copy of the string table so the | |
405 // strings will not be destroyed by elf_end. | |
406 size = scn_cache[shdr->sh_link].c_shdr->sh_size; | |
407 symtab->strs = (char *)malloc(size); | |
408 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size); | |
409 | |
410 // allocate memory for storing symbol offset and size; | |
411 symtab->num_symbols = n; | |
412 symtab->symbols = (struct elf_symbol *)calloc(n , sizeof(struct elf_symbol)); | |
413 | |
414 // copy symbols info our symtab and enter them info the hash table | |
415 for (j = 0; j < n; j++, syms++) { | |
416 ENTRY item, *ret; | |
417 char *sym_name = symtab->strs + syms->st_name; | |
418 | |
419 // skip non-object and non-function symbols | |
420 int st_type = ELF_ST_TYPE(syms->st_info); | |
421 if ( st_type != STT_FUNC && st_type != STT_OBJECT) | |
422 continue; | |
423 // skip empty strings and undefined symbols | |
424 if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue; | |
425 | |
426 symtab->symbols[j].name = sym_name; | |
427 symtab->symbols[j].offset = syms->st_value - baseaddr; | |
428 symtab->symbols[j].size = syms->st_size; | |
429 | |
430 item.key = sym_name; | |
431 item.data = (void *)&(symtab->symbols[j]); | |
432 | |
433 hsearch_r(item, ENTER, &ret, symtab->hash_table); | |
434 } | |
435 } | |
436 } | |
437 | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
438 // Look for a separate debuginfo file. |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
439 if (try_debuginfo) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
440 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
441 // We prefer a debug symtab to an object's own symtab, so look in |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
442 // the debuginfo file. We stash a copy of the old symtab in case |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
443 // there is no debuginfo. |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
444 struct symtab* prev_symtab = symtab; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
445 symtab = NULL; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
446 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
447 #ifdef NT_GNU_BUILD_ID |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
448 // First we look for a Build ID |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
449 for (cursct = shbuf, cnt = 0; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
450 symtab == NULL && cnt < ehdr.e_shnum; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
451 cnt++) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
452 if (cursct->sh_type == SHT_NOTE) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
453 Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
454 if (note->n_type == NT_GNU_BUILD_ID) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
455 symtab = build_symtab_from_build_id(note); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
456 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
457 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
458 cursct++; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
459 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
460 #endif |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
461 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
462 // Then, if that doesn't work, the debug link |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
463 if (symtab == NULL) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
464 symtab = build_symtab_from_debug_link(filename, fd, &ehdr, shbuf, |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
465 scn_cache); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
466 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
467 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
468 // If we still haven't found a symtab, use the object's own symtab. |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
469 if (symtab != NULL) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
470 if (prev_symtab != NULL) |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
471 destroy_symtab(prev_symtab); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
472 } else { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
473 symtab = prev_symtab; |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
474 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
475 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
476 |
0 | 477 quit: |
478 if (shbuf) free(shbuf); | |
479 if (phbuf) free(phbuf); | |
480 if (scn_cache) { | |
481 for (cnt = 0; cnt < ehdr.e_shnum; cnt++) { | |
482 if (scn_cache[cnt].c_data != NULL) { | |
483 free(scn_cache[cnt].c_data); | |
484 } | |
485 } | |
486 free(scn_cache); | |
487 } | |
488 return symtab; | |
489 } | |
490 | |
1294
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
491 struct symtab* build_symtab(int fd, const char *filename) { |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
492 return build_symtab_internal(fd, filename, /* try_debuginfo */ true); |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
493 } |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
494 |
7de45b5044c3
6932270: Allow Java's ELF symtab reader to use separate debuginfo files
never
parents:
0
diff
changeset
|
495 |
0 | 496 void destroy_symtab(struct symtab* symtab) { |
497 if (!symtab) return; | |
498 if (symtab->strs) free(symtab->strs); | |
499 if (symtab->symbols) free(symtab->symbols); | |
500 if (symtab->hash_table) { | |
501 hdestroy_r(symtab->hash_table); | |
502 free(symtab->hash_table); | |
503 } | |
504 free(symtab); | |
505 } | |
506 | |
507 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, | |
508 const char *sym_name, int *sym_size) { | |
509 ENTRY item; | |
510 ENTRY* ret = NULL; | |
511 | |
512 // library does not have symbol table | |
513 if (!symtab || !symtab->hash_table) | |
514 return (uintptr_t)NULL; | |
515 | |
516 item.key = (char*) strdup(sym_name); | |
517 hsearch_r(item, FIND, &ret, symtab->hash_table); | |
518 if (ret) { | |
519 struct elf_symbol * sym = (struct elf_symbol *)(ret->data); | |
520 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset); | |
521 if (sym_size) *sym_size = sym->size; | |
522 free(item.key); | |
523 return rslt; | |
524 } | |
525 | |
526 quit: | |
527 free(item.key); | |
528 return (uintptr_t) NULL; | |
529 } | |
530 | |
531 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset, | |
532 uintptr_t* poffset) { | |
533 int n = 0; | |
534 if (!symtab) return NULL; | |
535 for (; n < symtab->num_symbols; n++) { | |
536 struct elf_symbol* sym = &(symtab->symbols[n]); | |
537 if (sym->name != NULL && | |
538 offset >= sym->offset && offset < sym->offset + sym->size) { | |
539 if (poffset) *poffset = (offset - sym->offset); | |
540 return sym->name; | |
541 } | |
542 } | |
543 return NULL; | |
544 } |