diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2019-11-07 13:39:09 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2019-11-07 13:39:09 +0000 |
commit | 63b8ebac4fa702863e64aa2c7f712ac943708969 (patch) | |
tree | c081fccc4f8991d58ac63a90364fe5525c186fa5 | |
parent | b87454b461e623030df29af565243fa1f0c70e00 (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.c | 55 |
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; } |