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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include <sys/procfs.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
27 #include <search.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
28 #include <stdlib.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #include <string.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #include "symtab.h"
a61af66fc99e Initial load
duke
parents:
diff changeset
31 #include "salibelf.h"
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // ----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // functions for symbol lookups
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // ----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 struct elf_section {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 ELF_SHDR *c_shdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 void *c_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 };
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 struct elf_symbol {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 char *name;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 uintptr_t offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 uintptr_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 };
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 typedef struct symtab {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 char *strs;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 size_t num_symbols;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 struct elf_symbol *symbols;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 struct hsearch_data *hash_table;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 } symtab_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
324 ELF_EHDR ehdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 char *names = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 struct symtab* symtab = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Reading of elf header
a61af66fc99e Initial load
duke
parents:
diff changeset
329 struct elf_section *scn_cache = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 int cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 ELF_SHDR* shbuf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 ELF_SHDR* cursct = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 ELF_PHDR* phbuf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 uintptr_t baseaddr = (uintptr_t)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 lseek(fd, (off_t)0L, SEEK_SET);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 if (! read_elf_header(fd, &ehdr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // not an elf
a61af66fc99e Initial load
duke
parents:
diff changeset
342 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // read ELF header
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 goto quit;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 baseaddr = find_base_address(fd, &ehdr);
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 scn_cache = (struct elf_section *)
a61af66fc99e Initial load
duke
parents:
diff changeset
353 calloc(ehdr.e_shnum * sizeof(struct elf_section), 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 if (scn_cache == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 goto quit;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 goto quit;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
370 cursct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
377 ELF_SYM *syms;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 int j, n, rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // FIXME: there could be multiple data buffers associated with the
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // same ELF section. Here we can handle only one buffer. See man page
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // for elf_getdata on Solaris.
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // guarantee(symtab == NULL, "multiple symtab");
a61af66fc99e Initial load
duke
parents:
diff changeset
386 symtab = (struct symtab*)calloc(1, sizeof(struct symtab));
a61af66fc99e Initial load
duke
parents:
diff changeset
387 if (symtab == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 goto quit;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // the symbol table
a61af66fc99e Initial load
duke
parents:
diff changeset
391 syms = (ELF_SYM *)scn_cache[cnt].c_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // number of symbols
a61af66fc99e Initial load
duke
parents:
diff changeset
394 n = shdr->sh_size / shdr->sh_entsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // manipulate the hash table.
a61af66fc99e Initial load
duke
parents:
diff changeset
398 symtab->hash_table = (struct hsearch_data*) calloc(1, sizeof(struct hsearch_data));
a61af66fc99e Initial load
duke
parents:
diff changeset
399 rslt = hcreate_r(n, symtab->hash_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // guarantee(rslt, "unexpected failure: hcreate_r");
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // shdr->sh_link points to the section that contains the actual strings
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // for symbol names. the st_name field in ELF_SYM is just the
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // string table index. we make a copy of the string table so the
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // strings will not be destroyed by elf_end.
a61af66fc99e Initial load
duke
parents:
diff changeset
406 size = scn_cache[shdr->sh_link].c_shdr->sh_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
407 symtab->strs = (char *)malloc(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // allocate memory for storing symbol offset and size;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 symtab->num_symbols = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 symtab->symbols = (struct elf_symbol *)calloc(n , sizeof(struct elf_symbol));
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // copy symbols info our symtab and enter them info the hash table
a61af66fc99e Initial load
duke
parents:
diff changeset
415 for (j = 0; j < n; j++, syms++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 ENTRY item, *ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 char *sym_name = symtab->strs + syms->st_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // skip non-object and non-function symbols
a61af66fc99e Initial load
duke
parents:
diff changeset
420 int st_type = ELF_ST_TYPE(syms->st_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if ( st_type != STT_FUNC && st_type != STT_OBJECT)
a61af66fc99e Initial load
duke
parents:
diff changeset
422 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // skip empty strings and undefined symbols
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 symtab->symbols[j].name = sym_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
427 symtab->symbols[j].offset = syms->st_value - baseaddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 symtab->symbols[j].size = syms->st_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 item.key = sym_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
431 item.data = (void *)&(symtab->symbols[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 hsearch_r(item, ENTER, &ret, symtab->hash_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
477 quit:
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (shbuf) free(shbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (phbuf) free(phbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 if (scn_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 if (scn_cache[cnt].c_data != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 free(scn_cache[cnt].c_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 free(scn_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 return symtab;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
496 void destroy_symtab(struct symtab* symtab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (!symtab) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if (symtab->strs) free(symtab->strs);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (symtab->symbols) free(symtab->symbols);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 if (symtab->hash_table) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 hdestroy_r(symtab->hash_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 free(symtab->hash_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504 free(symtab);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
a61af66fc99e Initial load
duke
parents:
diff changeset
508 const char *sym_name, int *sym_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 ENTRY item;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 ENTRY* ret = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // library does not have symbol table
a61af66fc99e Initial load
duke
parents:
diff changeset
513 if (!symtab || !symtab->hash_table)
a61af66fc99e Initial load
duke
parents:
diff changeset
514 return (uintptr_t)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 item.key = (char*) strdup(sym_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 hsearch_r(item, FIND, &ret, symtab->hash_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (ret) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 struct elf_symbol * sym = (struct elf_symbol *)(ret->data);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 if (sym_size) *sym_size = sym->size;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 free(item.key);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 return rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 quit:
a61af66fc99e Initial load
duke
parents:
diff changeset
527 free(item.key);
a61af66fc99e Initial load
duke
parents:
diff changeset
528 return (uintptr_t) NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
532 uintptr_t* poffset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 int n = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 if (!symtab) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 for (; n < symtab->num_symbols; n++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 struct elf_symbol* sym = &(symtab->symbols[n]);
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (sym->name != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
538 offset >= sym->offset && offset < sym->offset + sym->size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (poffset) *poffset = (offset - sym->offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 return sym->name;
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }