Bug Summary

File:jdk/src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c
Warning:line 475, column 13
Access to field 'n_type' results in a dereference of a null pointer (loaded from variable 'note')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name symtab.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D _FILE_OFFSET_BITS=64 -I /home/daniel/Projects/java/jdk/src/jdk.hotspot.agent/linux/native/libsaproc -I /home/daniel/Projects/java/jdk/src/jdk.hotspot.agent/share/native/libsaproc -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/jdk.hotspot.agent -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wno-unused -Wno-sign-compare -Wno-pointer-arith -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/jdk.hotspot.agent/linux/native/libsaproc/symtab.c
1/*
2 * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include <unistd.h>
26#include <sys/procfs.h>
27#include <search.h>
28#include <stdlib.h>
29#include <string.h>
30#include "symtab.h"
31#include "salibelf.h"
32
33
34// ----------------------------------------------------
35// functions for symbol lookups
36// ----------------------------------------------------
37
38struct elf_symbol {
39 char *name;
40 uintptr_t offset;
41 uintptr_t size;
42};
43
44typedef struct symtab {
45 char *strs;
46 size_t num_symbols;
47 struct elf_symbol *symbols;
48 struct hsearch_data *hash_table;
49} symtab_t;
50
51
52// Directory that contains global debuginfo files. In theory it
53// should be possible to change this, but in a Java environment there
54// is no obvious place to put a user interface to do it. Maybe this
55// could be set with an environment variable.
56static const char debug_file_directory[] = "/usr/lib/debug";
57
58/* The CRC used in gnu_debuglink, retrieved from
59 http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files. */
60unsigned int gnu_debuglink_crc32 (unsigned int crc,
61 unsigned char *buf, size_t len)
62{
63 static const unsigned int crc32_table[256] =
64 {
65 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
66 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
67 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
68 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
69 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
70 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
71 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
72 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
73 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
74 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
75 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
76 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
77 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
78 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
79 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
80 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
81 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
82 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
83 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
84 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
85 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
86 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
87 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
88 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
89 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
90 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
91 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
92 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
93 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
94 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
95 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
96 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
97 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
98 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
99 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
100 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
101 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
102 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
103 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
104 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
105 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
106 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
107 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
108 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
109 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
110 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
111 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
112 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
113 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
114 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
115 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
116 0x2d02ef8d
117 };
118 unsigned char *end;
119
120 crc = ~crc & 0xffffffff;
121 for (end = buf + len; buf < end; ++buf)
122 crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
123 return ~crc & 0xffffffff;
124}
125
126/* Open a debuginfo file and check its CRC. If it exists and the CRC
127 matches return its fd. */
128static int
129open_debug_file (const char *pathname, unsigned int crc)
130{
131 unsigned int file_crc = 0;
132 unsigned char buffer[8 * 1024];
133
134 int fd = pathmap_open(pathname);
135
136 if (fd < 0)
137 return -1;
138
139 lseek(fd, 0, SEEK_SET0);
140
141 for (;;) {
142 int len = read(fd, buffer, sizeof buffer);
143 if (len <= 0)
144 break;
145 file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
146 }
147
148 if (crc == file_crc)
149 return fd;
150 else {
151 close(fd);
152 return -1;
153 }
154}
155
156/* Look for a ".gnu_debuglink" section. If one exists, try to open a
157 suitable debuginfo file. */
158static int open_file_from_debug_link(const char *name,
159 int fd,
160 ELF_EHDRElf64_Ehdr *ehdr,
161 struct elf_section *scn_cache)
162{
163 int debug_fd;
164 struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr,
165 scn_cache);
166 if (debug_link == NULL((void*)0))
167 return -1;
168 char *debug_filename = debug_link->c_data;
169 int offset = (strlen(debug_filename) + 4) >> 2;
170 static unsigned int crc;
171 crc = ((unsigned int*)debug_link->c_data)[offset];
172 char *debug_pathname = malloc(strlen(debug_filename)
173 + strlen(name)
174 + strlen(".debug/")
175 + strlen(debug_file_directory)
176 + 2);
177 if (debug_pathname == NULL((void*)0)) {
178 return -1;
179 }
180 strcpy(debug_pathname, name);
181 char *last_slash = strrchr(debug_pathname, '/');
182 if (last_slash == NULL((void*)0)) {
183 free(debug_pathname);
184 return -1;
185 }
186
187 /* Look in the same directory as the object. */
188 strcpy(last_slash+1, debug_filename);
189 debug_fd = open_debug_file(debug_pathname, crc);
190 if (debug_fd >= 0) {
191 free(debug_pathname);
192 return debug_fd;
193 }
194
195 /* Look in a subdirectory named ".debug". */
196 strcpy(last_slash+1, ".debug/");
197 strcat(last_slash, debug_filename);
198
199 debug_fd = open_debug_file(debug_pathname, crc);
200 if (debug_fd >= 0) {
201 free(debug_pathname);
202 return debug_fd;
203 }
204
205 /* Look in /usr/lib/debug + the full pathname. */
206 strcpy(debug_pathname, debug_file_directory);
207 strcat(debug_pathname, name);
208 last_slash = strrchr(debug_pathname, '/');
209 strcpy(last_slash+1, debug_filename);
210
211 debug_fd = open_debug_file(debug_pathname, crc);
212 if (debug_fd >= 0) {
213 free(debug_pathname);
214 return debug_fd;
215 }
216
217 free(debug_pathname);
218 return -1;
219}
220
221static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo);
222
223/* Look for a ".gnu_debuglink" section. If one exists, try to open a
224 suitable debuginfo file and read a symbol table from it. */
225static struct symtab *build_symtab_from_debug_link(const char *name,
226 int fd,
227 ELF_EHDRElf64_Ehdr *ehdr,
228 struct elf_section *scn_cache)
229{
230 fd = open_file_from_debug_link(name, fd, ehdr, scn_cache);
231
232 if (fd >= 0) {
233 struct symtab *symtab = build_symtab_internal(fd, NULL((void*)0), /* try_debuginfo */ false0);
234 close(fd);
235 return symtab;
236 }
237
238 return NULL((void*)0);
239}
240
241// Given a build_id, find the associated debuginfo file
242static char *
243build_id_to_debug_filename (size_t size, unsigned char *data)
244{
245 char *filename, *s;
246
247 filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
248 + 2 * size + (sizeof ".debug" - 1) + 1);
249 if (filename == NULL((void*)0)) {
250 return NULL((void*)0);
251 }
252 s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory)__builtin___sprintf_chk (filename, 2 - 1, __builtin_object_size
(filename, 2 > 1), "%s/.build-id/", debug_file_directory)
;
253 if (size > 0)
254 {
255 size--;
256 s += sprintf (s, "%02x", *data++)__builtin___sprintf_chk (s, 2 - 1, __builtin_object_size (s, 2
> 1), "%02x", *data++)
;
257 }
258 if (size > 0)
259 *s++ = '/';
260 while (size-- > 0)
261 s += sprintf (s, "%02x", *data++)__builtin___sprintf_chk (s, 2 - 1, __builtin_object_size (s, 2
> 1), "%02x", *data++)
;
262 strcpy (s, ".debug");
263
264 return filename;
265}
266
267// Read a build ID note. Try to open any associated debuginfo file
268// and return its symtab
269static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note)
270{
271 int fd;
272 struct symtab *symtab = NULL((void*)0);
273
274 unsigned char *bytes
275 = (unsigned char*)(note+1) + note->n_namesz;
276 char *filename
277 = (build_id_to_debug_filename (note->n_descsz, bytes));
278 if (filename == NULL((void*)0)) {
279 return NULL((void*)0);
280 }
281 fd = pathmap_open(filename);
282 if (fd >= 0) {
283 symtab = build_symtab_internal(fd, NULL((void*)0), /* try_debuginfo */ false0);
284 close(fd);
285 }
286 free(filename);
287
288 return symtab;
289}
290
291// read symbol table from given fd. If try_debuginfo) is true, also
292// try to open an associated debuginfo file
293static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) {
294 ELF_EHDRElf64_Ehdr ehdr;
295 char *names = NULL((void*)0);
296 struct symtab* symtab = NULL((void*)0);
297
298 // Reading of elf header
299 struct elf_section *scn_cache = NULL((void*)0);
300#if defined(ppc64) && !defined(ABI_ELFv2)
301 // Only big endian ppc64 (i.e. ABI_ELFv1) has 'official procedure descriptors' in ELF files
302 // see: http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html
303 struct elf_section *opd_sect = NULL((void*)0);
304 ELF_SHDRElf64_Shdr *opd = NULL((void*)0);
305#endif
306 int cnt = 0;
307 ELF_SHDRElf64_Shdr* shbuf = NULL((void*)0);
308 ELF_SHDRElf64_Shdr* cursct = NULL((void*)0);
309 ELF_PHDRElf64_Phdr* phbuf = NULL((void*)0);
310 ELF_PHDRElf64_Phdr* phdr = NULL((void*)0);
311 int sym_section = SHT_DYNSYM11;
312
313 uintptr_t baseaddr = (uintptr_t)-1;
314
315 lseek(fd, (off_t)0L, SEEK_SET0);
316 if (! read_elf_header(fd, &ehdr)) {
2
Assuming the condition is false
3
Taking false branch
317 // not an elf
318 return NULL((void*)0);
319 }
320
321 // read ELF header
322 if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL((void*)0)) {
4
Assuming the condition is false
5
Taking false branch
323 goto quit;
324 }
325
326 baseaddr = find_base_address(fd, &ehdr);
327
328 scn_cache = (struct elf_section *)
329 calloc(ehdr.e_shnum * sizeof(struct elf_section), 1);
6
Null pointer value stored to field 'c_data'
330 if (scn_cache == NULL((void*)0)) {
7
Assuming 'scn_cache' is not equal to NULL
8
Taking false branch
331 goto quit;
332 }
333
334 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
9
Assuming 'cnt' is < field 'e_shnum'
10
Loop condition is true. Entering loop body
17
Assuming 'cnt' is < field 'e_shnum'
18
Loop condition is true. Entering loop body
24
Assuming 'cnt' is >= field 'e_shnum'
25
Loop condition is false. Execution continues on line 357
335 scn_cache[cnt].c_shdr = cursct;
336 if (cursct->sh_type == SHT_SYMTAB2 || cursct->sh_type == SHT_STRTAB3
11
Assuming field 'sh_type' is not equal to SHT_SYMTAB
12
Assuming field 'sh_type' is not equal to SHT_STRTAB
15
Taking false branch
19
Assuming field 'sh_type' is equal to SHT_SYMTAB
337 || cursct->sh_type == SHT_NOTE7 || cursct->sh_type == SHT_DYNSYM11) {
13
Assuming field 'sh_type' is not equal to SHT_NOTE
14
Assuming field 'sh_type' is not equal to SHT_DYNSYM
338 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL((void*)0)) {
20
Assuming the condition is false
21
Taking false branch
339 goto quit;
340 }
341 }
342 if (cursct->sh_type
15.1
Field 'sh_type' is not equal to SHT_SYMTAB
== SHT_SYMTAB2
) {
16
Taking false branch
22
Assuming field 'sh_type' is not equal to SHT_SYMTAB
23
Taking false branch
343 // Full symbol table available so use that
344 sym_section = cursct->sh_type;
345 }
346 cursct++;
347 }
348
349#if defined(ppc64) && !defined(ABI_ELFv2)
350 opd_sect = find_section_by_name(".opd", fd, &ehdr, scn_cache);
351 if (opd_sect != NULL((void*)0) && opd_sect->c_data != NULL((void*)0) && opd_sect->c_shdr != NULL((void*)0)) {
352 // plausibility check
353 opd = opd_sect->c_shdr;
354 }
355#endif
356
357 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
26
Assuming 'cnt' is >= field 'e_shnum'
27
Loop condition is false. Execution continues on line 461
358 ELF_SHDRElf64_Shdr *shdr = scn_cache[cnt].c_shdr;
359
360 if (shdr->sh_type == sym_section) {
361 ELF_SYMElf64_Sym *syms;
362 int rslt;
363 size_t size, n, j, htab_sz;
364
365 // FIXME: there could be multiple data buffers associated with the
366 // same ELF section. Here we can handle only one buffer. See man page
367 // for elf_getdata on Solaris.
368
369 // guarantee(symtab == NULL, "multiple symtab");
370 symtab = (struct symtab*)calloc(1, sizeof(struct symtab));
371 if (symtab == NULL((void*)0)) {
372 goto quit;
373 }
374 // the symbol table
375 syms = (ELF_SYMElf64_Sym *)scn_cache[cnt].c_data;
376
377 // number of symbols
378 n = shdr->sh_size / shdr->sh_entsize;
379
380 // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to
381 // manipulate the hash table.
382
383 // NOTES section in the man page of hcreate_r says
384 // "Hash table implementations are usually more efficient when
385 // the table contains enough free space to minimize collisions.
386 // Typically, this means that nel should be at least 25% larger
387 // than the maximum number of elements that the caller expects
388 // to store in the table."
389 htab_sz = n*1.25;
390
391 symtab->hash_table = (struct hsearch_data*) calloc(1, sizeof(struct hsearch_data));
392 if (symtab->hash_table == NULL((void*)0)) {
393 goto bad;
394 }
395
396 rslt = hcreate_r(n, symtab->hash_table);
397 // guarantee(rslt, "unexpected failure: hcreate_r");
398
399 // shdr->sh_link points to the section that contains the actual strings
400 // for symbol names. the st_name field in ELF_SYM is just the
401 // string table index. we make a copy of the string table so the
402 // strings will not be destroyed by elf_end.
403 size = scn_cache[shdr->sh_link].c_shdr->sh_size;
404 symtab->strs = (char *)malloc(size);
405 if (symtab->strs == NULL((void*)0)) {
406 goto bad;
407 }
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 if (symtab->symbols == NULL((void*)0)) {
414 goto bad;
415 }
416
417 // copy symbols info our symtab and enter them info the hash table
418 for (j = 0; j < n; j++, syms++) {
419 ENTRY item, *ret;
420 uintptr_t sym_value;
421 char *sym_name = symtab->strs + syms->st_name;
422
423 // skip non-object and non-function symbols
424 int st_type = ELF_ST_TYPE(syms->st_info)((syms->st_info) & 0xf);
425 if ( st_type != STT_FUNC2 && st_type != STT_OBJECT1)
426 continue;
427 // skip empty strings and undefined symbols
428 if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF0) continue;
429
430 symtab->symbols[j].name = sym_name;
431 symtab->symbols[j].size = syms->st_size;
432 sym_value = syms->st_value;
433
434#if defined(ppc64) && !defined(ABI_ELFv2)
435 // see hotspot/src/share/vm/utilities/elfFuncDescTable.hpp for a detailed description
436 // of why we have to go this extra way via the '.opd' section on big endian ppc64
437 if (opd != NULL((void*)0) && *sym_name != '.' &&
438 (opd->sh_addr <= sym_value && sym_value <= opd->sh_addr + opd->sh_size)) {
439 sym_value = ((ELF_ADDRElf64_Addr*)opd_sect->c_data)[(sym_value - opd->sh_addr) / sizeof(ELF_ADDRElf64_Addr*)];
440 }
441#endif
442
443 symtab->symbols[j].offset = sym_value - baseaddr;
444 item.key = sym_name;
445 item.data = (void *)&(symtab->symbols[j]);
446 hsearch_r(item, ENTER, &ret, symtab->hash_table);
447 }
448 }
449 }
450
451#if defined(ppc64) && !defined(ABI_ELFv2)
452 // On Linux/PPC64 the debuginfo files contain an empty function descriptor
453 // section (i.e. '.opd' section) which makes the resolution of symbols
454 // with the above algorithm impossible (we would need the have both, the
455 // .opd section from the library and the symbol table from the debuginfo
456 // file which doesn't match with the current workflow.)
457 goto quit;
458#endif
459
460 // Look for a separate debuginfo file.
461 if (try_debuginfo
27.1
'try_debuginfo' is 1
) {
28
Taking true branch
462 // We prefer a debug symtab to an object's own symtab, so look in
463 // the debuginfo file. We stash a copy of the old symtab in case
464 // there is no debuginfo.
465 struct symtab* prev_symtab = symtab;
466 symtab = NULL((void*)0);
467
468#ifdef NT_GNU_BUILD_ID3
469 // First we look for a Build ID
470 for (cursct = shbuf, cnt = 0;
30
Loop condition is true. Entering loop body
471 symtab
28.1
'symtab' is equal to NULL
== NULL((void*)0) && cnt < ehdr.e_shnum;
29
Assuming 'cnt' is < field 'e_shnum'
472 cnt++) {
473 if (cursct->sh_type == SHT_NOTE7) {
31
Assuming field 'sh_type' is equal to SHT_NOTE
32
Taking true branch
474 Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data;
33
'note' initialized to a null pointer value
475 if (note->n_type == NT_GNU_BUILD_ID3) {
34
Access to field 'n_type' results in a dereference of a null pointer (loaded from variable 'note')
476 symtab = build_symtab_from_build_id(note);
477 }
478 }
479 cursct++;
480 }
481#endif
482
483 // Then, if that doesn't work, the debug link
484 if (symtab == NULL((void*)0)) {
485 symtab = build_symtab_from_debug_link(filename, fd, &ehdr,
486 scn_cache);
487 }
488
489 // If we still haven't found a symtab, use the object's own symtab.
490 if (symtab != NULL((void*)0)) {
491 if (prev_symtab != NULL((void*)0))
492 destroy_symtab(prev_symtab);
493 } else {
494 symtab = prev_symtab;
495 }
496 }
497 goto quit;
498
499bad:
500 destroy_symtab(symtab);
501 symtab = NULL((void*)0);
502
503quit:
504 if (shbuf) free(shbuf);
505 if (phbuf) free(phbuf);
506 if (scn_cache) {
507 for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
508 if (scn_cache[cnt].c_data != NULL((void*)0)) {
509 free(scn_cache[cnt].c_data);
510 }
511 }
512 free(scn_cache);
513 }
514 return symtab;
515}
516
517struct symtab* build_symtab(int fd, const char *filename) {
518 return build_symtab_internal(fd, filename, /* try_debuginfo */ true1);
1
Calling 'build_symtab_internal'
519}
520
521
522void destroy_symtab(struct symtab* symtab) {
523 if (!symtab) return;
524 if (symtab->strs) free(symtab->strs);
525 if (symtab->symbols) free(symtab->symbols);
526 if (symtab->hash_table) {
527 hdestroy_r(symtab->hash_table);
528 free(symtab->hash_table);
529 }
530 free(symtab);
531}
532
533uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
534 const char *sym_name, int *sym_size) {
535 ENTRY item;
536 ENTRY* ret = NULL((void*)0);
537
538 // library does not have symbol table
539 if (!symtab || !symtab->hash_table)
540 return (uintptr_t)NULL((void*)0);
541
542 item.key = (char*) strdup(sym_name);
543 item.data = NULL((void*)0);
544 hsearch_r(item, FIND, &ret, symtab->hash_table);
545 if (ret) {
546 struct elf_symbol * sym = (struct elf_symbol *)(ret->data);
547 uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
548 if (sym_size) *sym_size = sym->size;
549 free(item.key);
550 return rslt;
551 }
552
553quit:
554 free(item.key);
555 return (uintptr_t) NULL((void*)0);
556}
557
558const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
559 uintptr_t* poffset) {
560 int n = 0;
561 if (!symtab) return NULL((void*)0);
562 for (; n < symtab->num_symbols; n++) {
563 struct elf_symbol* sym = &(symtab->symbols[n]);
564 if (sym->name != NULL((void*)0) &&
565 offset >= sym->offset && offset < sym->offset + sym->size) {
566 if (poffset) *poffset = (offset - sym->offset);
567 return sym->name;
568 }
569 }
570 return NULL((void*)0);
571}