From: Ian Campbell <ian.campbell@citrix.com>
To: Jan Beulich <JBeulich@suse.com>,
xen-devel <xen-devel@lists.xenproject.org>,
julien.grall@citrix.com, stefano.stabellini@citrix.com
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
Keir Fraser <keir@xen.org>,
Ian Jackson <Ian.Jackson@eu.citrix.com>, Tim Deegan <tim@xen.org>
Subject: Re: [PATCH 01/10] symbols: prefix static symbols with their source file name
Date: Wed, 21 Oct 2015 09:43:00 +0100 [thread overview]
Message-ID: <1445416980.9563.41.camel@citrix.com> (raw)
In-Reply-To: <562635BC02000078000ACB31@prv-mh.provo.novell.com>
On Tue, 2015-10-20 at 04:38 -0600, Jan Beulich wrote:
> This requires adjustments to the tool generating the symbol table and
> its as well as nm's invocation.
>
> Note: Not warning about duplicate symbols in the EFI case for now, as
> a binutils bug causes misnamed file name entries to appear in EFI
> binaries' symbol tables when the file name is longer than 18 chars.
> (Not doing so also avoids other duplicates getting printed twice.)
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> ---
> No changing ARM for now, as xSplice isn't targeted at it just yet.
The improved information from e.g. stack traces (which I'm supposing this
also enables) seems valuable on ARM too. Is this something you plan to add
or shall we ARM folks add it to our todo?
I suspect the answer is no, but do you think there is much scope for making
some of these complex linker runes common instead of arch specific?
>From what I can tell the actual arch change here is s/-n/-pa/ on the NM
invocation (numeric sort => no sort + include debugger symbols) and then
add --sysv --sort and optionally --want-dup to the tools/symbols
invocation. Is it really as simple as that?
Given we don't do a special EFI build/link I think on ARM we do want --warn
-dup if at all possible.
Ian.
> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -106,11 +106,13 @@ $(BASEDIR)/common/symbols-dummy.o:
> $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o
> $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \
> $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0
> - $(NM) -n $(@D)/.$(@F).0 | $(BASEDIR)/tools/symbols
> >$(@D)/.$(@F).0.S
> + $(NM) -pa --format=sysv $(@D)/.$(@F).0 \
> + | $(BASEDIR)/tools/symbols --sysv --sort
> >$(@D)/.$(@F).0.S
> $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o
> $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \
> $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1
> - $(NM) -n $(@D)/.$(@F).1 | $(BASEDIR)/tools/symbols
> >$(@D)/.$(@F).1.S
> + $(NM) -pa --format=sysv $(@D)/.$(@F).1 \
> + | $(BASEDIR)/tools/symbols --sysv --sort --warn-dup
> >$(@D)/.$(@F).1.S
> $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o
> $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \
> $(@D)/.$(@F).1.o -o $@
> @@ -133,13 +135,15 @@ $(TARGET).efi: prelink-efi.o efi.lds efi
> $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds
> -N $< efi/relocs-dummy.o \
> $(BASEDIR)/common/symbols-dummy.o -o
> $(@D)/.$(@F).$(base).0 &&) :
> $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE)
> $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S
> - $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).0 | $(guard)
> $(BASEDIR)/tools/symbols >$(@D)/.$(@F).0s.S
> + $(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).0 \
> + | $(guard) $(BASEDIR)/tools/symbols --sysv --sort
> >$(@D)/.$(@F).0s.S
> $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o
> $(@D)/.$(@F).0s.o
> $(foreach base, $(VIRT_BASE) $(ALT_BASE), \
> $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds
> -N $< \
> $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o -o
> $(@D)/.$(@F).$(base).1 &&) :
> $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE)
> $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S
> - $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).1 | $(guard)
> $(BASEDIR)/tools/symbols >$(@D)/.$(@F).1s.S
> + $(guard) $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).1 \
> + | $(guard) $(BASEDIR)/tools/symbols --sysv --sort
> >$(@D)/.$(@F).1s.S
> $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o
> $(@D)/.$(@F).1s.o
> $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $<
> \
> $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o -o $@
> --- a/xen/tools/symbols.c
> +++ b/xen/tools/symbols.c
> @@ -30,6 +30,7 @@
> #include <stdlib.h>
> #include <string.h>
> #include <stdint.h>
> +#include <stdbool.h>
> #include <ctype.h>
>
> #define KSYM_NAME_LEN 127
> @@ -40,13 +41,14 @@ struct sym_entry {
> unsigned int len;
> unsigned char *sym;
> };
> -
> +#define SYMBOL_NAME(s) ((char *)(s)->sym + 1)
>
> static struct sym_entry *table;
> static unsigned int table_size, table_cnt;
> static unsigned long long _stext, _etext, _sinittext, _einittext,
> _sextratext, _eextratext;
> static int all_symbols = 0;
> static char symbol_prefix_char = '\0';
> +static enum { fmt_bsd, fmt_sysv } input_format;
>
> int token_profit[0x10000];
>
> @@ -73,11 +75,25 @@ static inline int is_arm_mapping_symbol(
>
> static int read_symbol(FILE *in, struct sym_entry *s)
> {
> - char str[500];
> + char str[500], type[20] = "";
> char *sym, stype;
> - int rc;
> -
> - rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
> + static enum { symbol, source_file, object_file } last;
> + static char *filename;
> + int rc = -1;
> +
> + switch (input_format) {
> + case fmt_bsd:
> + rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype,
> str);
> + break;
> + case fmt_sysv:
> + while (fscanf(in, "\n") == 1)
> + /* nothing */;
> + rc = fscanf(in, "%499[^ |] |%llx | %c |",
> + str, &s->addr, &stype);
> + if (rc == 3 && fscanf(in, " %19[^ |] |", type) != 1)
> + *type = '\0';
> + break;
> + }
> if (rc != 3) {
> if (rc != EOF) {
> /* skip line */
> @@ -87,6 +103,28 @@ static int read_symbol(FILE *in, struct
> return -1;
> }
>
> + sym = strrchr(str, '.');
> + if (strcasecmp(type, "FILE") == 0 ||
> + (/* GNU nm prior to XXX doesn't produce a type for EFI
> binaries. */
> + input_format == fmt_sysv && !*type && stype == '?' && sym
> &&
> + sym[1] && strchr("cSsoh", sym[1]) && !sym[2])) {
> + /*
> + * gas prior to XXX outputs symbol table entries
> resulting
> + * from .file in reverse order. If we get two
> consecutive file
> + * symbols, prefer the first one if that names an object
> file
> + * (to cover multiply compiled files).
> + */
> + if ((sym && sym[1] == 'o') || last != object_file) {
> + free(filename);
> + filename = *str ? strdup(str) : NULL;
> + }
> + last = !sym || sym[1] != 'o' ? source_file :
> object_file;
> + goto skip_tail;
> + }
> +
> + last = symbol;
> + rc = -1;
> +
> sym = str;
> /* skip prefix char */
> if (symbol_prefix_char && str[0] == symbol_prefix_char)
> @@ -109,24 +147,37 @@ static int read_symbol(FILE *in, struct
> {
> /* Keep these useful absolute symbols */
> if (strcmp(sym, "__gp"))
> - return -1;
> -
> + goto skip_tail;
> }
> else if (toupper((uint8_t)stype) == 'U' ||
> + toupper((uint8_t)stype) == 'N' ||
> is_arm_mapping_symbol(sym))
> - return -1;
> + goto skip_tail;
> /* exclude also MIPS ELF local symbols ($L123 instead of .L123)
> */
> else if (str[0] == '$')
> - return -1;
> + goto skip_tail;
>
> /* include the type field in the symbol name, so that it gets
> * compressed together */
> s->len = strlen(str) + 1;
> + if (islower(stype) && filename)
> + s->len += strlen(filename) + 1;
> s->sym = malloc(s->len + 1);
> - strcpy((char *)s->sym + 1, str);
> + sym = SYMBOL_NAME(s);
> + if (islower(stype) && filename) {
> + sym = stpcpy(sym, filename);
> + *sym++ = '#';
> + }
> + strcpy(sym, str);
> s->sym[0] = stype;
>
> - return 0;
> + rc = 0;
> +
> + skip_tail:
> + if (input_format == fmt_sysv)
> + fgets(str, 500, in); /* discard rest of line */
> +
> + return rc;
> }
>
> static int symbol_valid(struct sym_entry *s)
> @@ -460,11 +512,37 @@ static void optimize_token_table(void)
> optimize_result();
> }
>
> +static int compare_value(const void *p1, const void *p2)
> +{
> + const struct sym_entry *sym1 = p1;
> + const struct sym_entry *sym2 = p2;
> +
> + if (sym1->addr < sym2->addr)
> + return -1;
> + if (sym1->addr > sym2->addr)
> + return +1;
> + /* Prefer global symbols. */
> + if (isupper(*sym1->sym))
> + return -1;
> + if (isupper(*sym2->sym))
> + return +1;
> + return 0;
> +}
> +
> +static int compare_name(const void *p1, const void *p2)
> +{
> + const struct sym_entry *sym1 = p1;
> + const struct sym_entry *sym2 = p2;
> +
> + return strcmp(SYMBOL_NAME(sym1), SYMBOL_NAME(sym2));
> +}
>
> int main(int argc, char **argv)
> {
> + unsigned int i;
> + bool unsorted = false, warn_dup = false;
> +
> if (argc >= 2) {
> - int i;
> for (i = 1; i < argc; i++) {
> if(strcmp(argv[i], "--all-symbols") == 0)
> all_symbols = 1;
> @@ -474,13 +552,36 @@ int main(int argc, char **argv)
> if ((*p == '"' && *(p+2) == '"') || (*p
> == '\'' && *(p+2) == '\''))
> p++;
> symbol_prefix_char = *p;
> - } else
> + } else if (strcmp(argv[i], "--sysv") == 0)
> + input_format = fmt_sysv;
> + else if (strcmp(argv[i], "--sort") == 0)
> + unsorted = true;
> + else if (strcmp(argv[i], "--warn-dup") == 0)
> + warn_dup = true;
> + else
> usage();
> }
> } else if (argc != 1)
> usage();
>
> read_map(stdin);
> +
> + if (warn_dup) {
> + qsort(table, table_cnt, sizeof(*table), compare_name);
> + for (i = 1; i < table_cnt; ++i)
> + if (strcmp(SYMBOL_NAME(table + i - 1),
> + SYMBOL_NAME(table + i)) == 0 &&
> + table[i - 1].addr != table[i].addr)
> + fprintf(stderr,
> + "Duplicate symbol '%s' (%llx !=
> %llx)\n",
> + SYMBOL_NAME(table + i),
> + table[i].addr, table[i -
> 1].addr);
> + unsorted = true;
> + }
> +
> + if (unsorted)
> + qsort(table, table_cnt, sizeof(*table), compare_value);
> +
> optimize_token_table();
> write_src();
>
>
>
next prev parent reply other threads:[~2015-10-21 8:43 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-20 10:31 [PATCH 00/10] disambiguate symbol names Jan Beulich
2015-10-20 10:38 ` [PATCH 01/10] symbols: prefix static symbols with their source file name Jan Beulich
2015-10-21 8:43 ` Ian Campbell [this message]
2015-10-21 9:14 ` Jan Beulich
2015-10-20 10:39 ` [PATCH 02/10] x86/mm: override stored file names for multiply built sources Jan Beulich
2015-10-20 10:43 ` George Dunlap
2015-10-20 12:43 ` Tim Deegan
2015-10-20 12:44 ` Andrew Cooper
2015-10-20 13:12 ` Jan Beulich
2015-10-20 13:21 ` Andrew Cooper
2015-10-20 10:40 ` [PATCH 03/10] x86: don't build platform hypercall helpers multiple times Jan Beulich
2015-10-20 12:48 ` Andrew Cooper
2015-10-20 10:41 ` [PATCH 04/10] x86/HVM: prefix both instances of enable_intr_window() Jan Beulich
2015-10-20 12:49 ` Andrew Cooper
2015-10-20 14:45 ` Aravind Gopalakrishnan
2015-10-21 3:01 ` Tian, Kevin
2015-10-20 10:41 ` [PATCH 05/10] x86/mm: build map_domain_gfn() just once Jan Beulich
2015-10-20 12:54 ` Andrew Cooper
2015-10-20 13:15 ` Jan Beulich
2015-10-20 10:42 ` [PATCH 06/10] x86/mm: only a single instance of gw_page_flags[] is needed Jan Beulich
2015-10-20 13:00 ` Andrew Cooper
2015-10-20 10:43 ` [PATCH 07/10] x86/shadow: only a single instance of fetch_type_names[] " Jan Beulich
2015-10-20 12:44 ` Tim Deegan
2015-10-20 10:44 ` [PATCH 08/10] x86/shadow: adjust sh_{make, destroy}_monitor_table() name tags Jan Beulich
2015-10-20 12:45 ` Tim Deegan
2015-10-20 10:45 ` [PATCH 09/10] x86/shadow: drop stray name tags from sh_{guest_get, map}_eff_l1e() Jan Beulich
2015-10-20 12:49 ` Tim Deegan
2015-10-20 10:45 ` [PATCH RFC 10/10] memory/compat: rename get_reserved_device_memory() Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1445416980.9563.41.camel@citrix.com \
--to=ian.campbell@citrix.com \
--cc=Ian.Jackson@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=julien.grall@citrix.com \
--cc=keir@xen.org \
--cc=stefano.stabellini@citrix.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.