Print this page
10812 ctf tools shouldn't add blank labels
10813 ctf symbol mapping needs work
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
@@ -22,17 +22,17 @@
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
- * Copyright (c) 2015, Joyent, Inc.
+ * Copyright (c) 2019, Joyent, Inc.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
-#include <ctf_impl.h>
+#include <libctf_impl.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <dlfcn.h>
#include <gelf.h>
@@ -745,22 +745,111 @@
/*
* A utility function for folks debugging CTF conversion and merging.
*/
void
-ctf_phase_dump(ctf_file_t *fp, const char *phase)
+ctf_phase_dump(ctf_file_t *fp, const char *phase, const char *name)
{
int fd;
static char *base;
char path[MAXPATHLEN];
if (base == NULL && (base = getenv("LIBCTF_WRITE_PHASES")) == NULL)
return;
- (void) snprintf(path, sizeof (path), "%s/libctf.%s.%d.ctf", base,
+ if (name == NULL)
+ name = "libctf";
+
+ (void) snprintf(path, sizeof (path), "%s/%s.%s.%d.ctf", base, name,
phase != NULL ? phase : "",
ctf_phase);
if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0777)) < 0)
return;
(void) ctf_write(fp, fd);
(void) close(fd);
+}
+
+void
+ctf_phase_bump(void)
+{
+ ctf_phase++;
+}
+
+int
+ctf_symtab_iter(ctf_file_t *fp, ctf_symtab_f func, void *arg)
+{
+ ulong_t i;
+ uintptr_t symbase;
+ uintptr_t strbase;
+ const char *file = NULL;
+ boolean_t primary = B_TRUE;
+
+ if (fp->ctf_symtab.cts_data == NULL ||
+ fp->ctf_strtab.cts_data == NULL) {
+ return (ECTF_NOSYMTAB);
+ }
+
+ symbase = (uintptr_t)fp->ctf_symtab.cts_data;
+ strbase = (uintptr_t)fp->ctf_strtab.cts_data;
+
+ for (i = 0; i < fp->ctf_nsyms; i++) {
+ const char *name;
+ int ret;
+ uint_t type;
+ Elf64_Sym sym;
+
+ /*
+ * The CTF library has historically tried to handle large file
+ * offsets itself so that way clients can be unaware of such
+ * isseus. Therefore, we translate everything to a 64-bit ELF
+ * symbol, this is done to make it so that the rest of the
+ * library doesn't have to know about these differences. For
+ * more information see, lib/libctf/common/ctf_lib.c.
+ */
+ if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
+ const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
+ uint_t bind, itype;
+
+ sym.st_name = symp->st_name;
+ sym.st_value = symp->st_value;
+ sym.st_size = symp->st_size;
+ bind = ELF32_ST_BIND(symp->st_info);
+ itype = ELF32_ST_TYPE(symp->st_info);
+ sym.st_info = ELF64_ST_INFO(bind, itype);
+ sym.st_other = symp->st_other;
+ sym.st_shndx = symp->st_shndx;
+ } else {
+ const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
+
+ sym = *symp;
+ }
+
+ type = ELF64_ST_TYPE(sym.st_info);
+ name = (const char *)(strbase + sym.st_name);
+
+ /*
+ * Check first if we have an STT_FILE entry. This is used to
+ * distinguish between various local symbols when merging.
+ */
+ if (type == STT_FILE) {
+ if (file != NULL) {
+ primary = B_FALSE;
+ }
+ file = name;
+ continue;
+ }
+
+ /*
+ * Check if this is a symbol that we care about.
+ */
+ if (!ctf_sym_valid(strbase, type, sym.st_shndx, sym.st_value,
+ sym.st_name)) {
+ continue;
+ }
+
+ if ((ret = func(&sym, i, file, name, primary, arg)) != 0) {
+ return (ret);
+ }
+ }
+
+ return (0);
}