summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2019-11-07 13:39:09 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2019-11-07 13:39:09 +0000
commit63b8ebac4fa702863e64aa2c7f712ac943708969 (patch)
treec081fccc4f8991d58ac63a90364fe5525c186fa5
parentb87454b461e623030df29af565243fa1f0c70e00 (diff)
Do a better job at guessing the name of localy defined static variables.
Handle the "varname.id" schema used by gcc(1) and "funcname.varname" used by clang(1). Fix a shadowing issue with clang(1).
-rw-r--r--usr.bin/ctfconv/ctfconv.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/usr.bin/ctfconv/ctfconv.c b/usr.bin/ctfconv/ctfconv.c
index 8337cd8a2fe..f47af91541d 100644
--- a/usr.bin/ctfconv/ctfconv.c
+++ b/usr.bin/ctfconv/ctfconv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ctfconv.c,v 1.17 2018/08/08 20:15:17 mestre Exp $ */
+/* $OpenBSD: ctfconv.c,v 1.18 2019/11/07 13:39:08 mpi Exp $ */
/*
* Copyright (c) 2016-2017 Martin Pieuchot
@@ -27,6 +27,7 @@
#include <elf.h>
#include <err.h>
#include <fcntl.h>
+#include <limits.h>
#include <locale.h>
#include <stdio.h>
#include <stdint.h>
@@ -51,6 +52,7 @@ int convert(const char *);
int generate(const char *, const char *, int);
int elf_convert(char *, size_t);
void elf_sort(void);
+char *guess_static_local_name(char *);
struct itype *find_symb(struct itype *, size_t);
void dump_type(struct itype *);
void dump_func(struct itype *, int *);
@@ -261,6 +263,50 @@ elf_convert(char *p, size_t filesize)
return 0;
}
+/*
+ * Guess which part of a local symbol name correspond to the variable
+ * name.
+ *
+ * gcc 4.2.1 emits:
+ *
+ * varname.id
+ *
+ * clang 8 emits:
+ *
+ * funcname.varname
+ *
+ */
+char *
+guess_static_local_name(char *sname)
+{
+ const char *errstr;
+ char *first, *second;
+
+ first = strtok(sname, ".");
+ if (first == NULL)
+ return NULL;
+
+ /* Skip meta symbols - gcc style. */
+ if (strncmp(first, "__func__", sizeof("__func__") - 1) == 0 ||
+ strncmp(first, "__FUNCTION__", sizeof("__FUNCTION__") - 1) == 0 ||
+ strncmp(first, "__warned", sizeof("__warned") - 1) == 0)
+ return NULL;
+
+ second = strtok(NULL, "\0");
+ if (second == NULL)
+ return first;
+
+ /* Skip meta symbols - clang style. */
+ if (strncmp(second, "__warned", sizeof("__warned") - 1) == 0)
+ return NULL;
+
+ /* If `second' isn't a number, assume clang-style name. */
+ if (strtonum(second, 1, INT_MAX, &errstr) == 0)
+ return second;
+
+ return first;
+}
+
struct itype *
find_symb(struct itype *tmp, size_t stroff)
{
@@ -270,13 +316,8 @@ find_symb(struct itype *tmp, size_t stroff)
if (strtab == NULL || stroff >= strtabsz)
return NULL;
- /*
- * Skip local suffix
- *
- * FIXME: only skip local copies.
- */
sname = xstrdup(strtab + stroff);
- if ((p = strtok(sname, ".")) == NULL) {
+ if ((p = guess_static_local_name(sname)) == NULL) {
free(sname);
return NULL;
}