Fix symbol lookup for mips64* targets
PATCH 1/1 Fix symbol lookup for mips64* targets
For 64 bit targets, lookup_symbol() compares a 64-bit target address with a 32 bit symbol address. This only works for addresses less than 2^32.
MIPS64 kernels use addresses larger than 0xffffffff80000000, so qemu.log never shows symbolic names.
My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Regards
Stefan
Fix symbol lookup for mips64* targets.
disas.c +5 -0
@@ -309,6 +309,11 @@struct syminfo *s;target_ulong addr; +#if defined(TARGET_MIPS64 ) +/* Adresses in syminfos are 32 bit values. */ + orig_addr &=0xffffffff ; +#endif +for (s = syminfos; s; s = s->next) { sym = s->disas_symtab;for (i =0 ; i < s->disas_num_syms; i++) {
Quoted 8 lines · Stefan Weil
For 64 bit targets,
lookup_symbol()compares a 64-bit target address
with a 32 bit symbol address. This only works for addresses less than 2^32.MIPS64 kernels use addresses larger than
0xffffffff80000000, so qemu.log never shows symbolic names.My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
This applies to all architectures, not just MIPS64, so it need not be conditional to TARGET_MIPS64.
Quoted 2 lines
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Yes. That would mean using elf_sym instead of Elf32_sym in places where symbols are used and removing the SZ==64 hacks in elf_ops.h.
PATCH 1/1 Improve symbol lookup (was: Re: [Qemu-devel] [PATCH] Fix symbol lookup for mips64* targets)
Quoted 5 lines · Blue Swirl
Quoted 4 lines · Stefan Weil
For 64 bit targets,
lookup_symbol()compares a 64-bit target address with a 32 bit symbol address. This only works for addresses less than 2^32.
Quoted 11 lines
Quoted 5 lines
MIPS64 kernels use addresses larger than
0xffffffff80000000, so qemu.log never shows symbolic names.My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
This applies to all architectures, not just MIPS64, so it need not be conditional to
TARGET_MIPS64.Quoted 2 lines
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Here is the better solution (at least I hope so).
Quoted 4 lines
Yes. That would mean using
elf_syminstead ofElf32_symin places where symbols are used and removing the SZ==64 hacks inelf_ops.h.
So I did. Here is a short summary of my new patch:
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded).
This also fixes the bug with mips elf64 symbols in current Qemu trunk.
* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to
11656 entries.
* In disas.c, the patch also fixes some warnings from old fashioned function prototypes.
In loader.c, two defines control some compile time options (could be removed in
production code):
#define CONFIG_BINARY_SYMBOL_SEARCH
#define CONFIG_REDUCE_SYMBOL_TABLE
I tested the new code using 32 bit and 64 bit linux mips kernels and Qemu logging (-d in_asm).
The speed improvement is extremely large - both because of the much smaller table and
the binary search.
Stefan
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded). This also fixes the bug with mips elf64 symbols in current Qemu trunk.
* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to 11656 entries.
* In disas.c, the patch also fixes some warnings from old fashioned function prototypes.
loader.c +2 -0
@@ -251,6 +251,8 @@return ptr; } +#define CONFIG_BINARY_SYMBOL_SEARCH +#define CONFIG_REDUCE_SYMBOL_TABLE #define ELF_CLASS ELFCLASS32#include "elf.h"
disas.c +12 -39
85 lines not on this page · raw message
disas.h +16 -4
@@ -10,12 +10,24 @@/* Look up symbol for debugging purpose. Returns "" if unknown. */ const char *lookup_symbol (target_ulong orig_addr); -/* Filled in by elfload.c. Simplistic, but will do for now. */ -extern struct syminfo { +struct syminfo ; +struct elf32_sym ; +struct elf64_sym ; + +typedef const char *(*lookup_symbol_t )(struct syminfo *s,target_ulong orig_addr); + +struct syminfo { +lookup_symbol_t lookup_symbol;unsigned int disas_num_syms; -void *disas_symtab; +union { +struct elf32_sym *elf32; +struct elf64_sym *elf64; + } disas_symtab;const char *disas_strtab;struct syminfo *next; -} *syminfos; +}; +/* Filled in by elfload.c. Simplistic, but will do for now. */ +extern struct syminfo *syminfos; +#endif /* _QEMU_DISAS_H */
elf_ops.h +88 -23
147 lines not on this page · raw message
Re: [Qemu-devel] [PATCH] Improve symbol lookup
Quoted 48 lines · Stefan Weil
Quoted 6 lines · Blue Swirl
Quoted 4 lines · Stefan Weil
For 64 bit targets,
lookup_symbol()compares a 64-bit target address with a 32 bit symbol address. This only works for addresses less than 2^32.Quoted 13 lines
Quoted 6 lines
MIPS64 kernels use addresses larger than
0xffffffff80000000, so qemu.log never shows symbolic names.My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
This applies to all architectures, not just MIPS64, so it need not be conditional to
TARGET_MIPS64.Quoted 3 lines
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Here is the better solution (at least I hope so).
Quoted 4 lines
Yes. That would mean using
elf_syminstead ofElf32_symin places where symbols are used and removing the SZ==64 hacks inelf_ops.h.So I did. Here is a short summary of my new patch:
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded).
This also fixes the bug with mips elf64 symbols in current Qemu trunk.* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to
11656 entries.* In
disas.c, the patch also fixes some warnings from old fashioned function prototypes.In
loader.c, two defines control some compile time options (could be removed in
production code):
#defineCONFIG_BINARY_SYMBOL_SEARCH
#defineCONFIG_REDUCE_SYMBOL_TABLE
Quoted 9 lines
I tested the new code using 32 bit and 64 bit linux mips kernels and Qemu logging (-d
in_asm).
The speed improvement is extremely large - both because of the much smaller table and
the binary search.Stefan
Please note:
The current patch only supports system emulation.
User emulation needs more fixes to compile again.
Stefan
Re: [Qemu-devel] [PATCH] Improve symbol lookup
Quoted 3 lines · Stefan Weil
The current patch only supports system emulation.
User emulation needs more fixes to compile again.
I will take a look at it this week-end unless someone beats me to it.
Laurent
Re: [Qemu-devel] [PATCH] Improve symbol lookup for system and user mode
In reply to Stefan WeilQuoted 29 lines
Quoted 27 lines · Stefan Weil
Here is a short summary of my new patch:
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded).
This also fixes the bug with mips elf64 symbols in current Qemu trunk.* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to 11656 entries.* In
disas.c, the patch also fixes some warnings from old fashioned function prototypes.In
loader.c, two defines control some compile time options (could be removed in
production code):
#defineCONFIG_BINARY_SYMBOL_SEARCH
#defineCONFIG_REDUCE_SYMBOL_TABLEI tested the new code using 32 bit and 64 bit linux mips kernels and Qemu logging (-d
in_asm).
The speed improvement is extremely large - both because of the much smaller table and
the binary search.
Quoted 10 lines
Quoted 2 lines
Stefan
Please note:
The current patch only supports system emulation.
User emulation needs more fixes to compile again.Stefan
Here is an updated patch which now supports binary symbol lookup for both system emulation and user emulation.
User emulation was tested using qemu-x86_64 and a simple application with symbol information.
The new patch no longer includes compile time options for the old linear symbol search.
I hope this new patch will be included in Qemu trunk.
Regards
Stefan
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded). This also fixes the bug with mips elf64 symbols in current Qemu trunk.
* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to 11656 entries.
* In disas.c, the patch also fixes some warnings from old fashioned function prototypes.
elfload.c +94 -44
@@ -984,80 +984,130 @@return ((abi_ulong ) interp_elf_ex->e_entry) + load_addr; } +static int symfind (const void *s0,const void *s1) +{ +struct elf_sym *key = (struct elf_sym *)s0; +struct elf_sym *sym = (struct elf_sym *)s1; +int result =0 ; +if (key->st_value < sym->st_value) { + result =-1 ; + }else if (key->st_value > sym->st_value + sym->st_size) { + result =1 ; + } +return result; +} + +static const char *lookup_symbolxx (struct syminfo *s,target_ulong orig_addr) +{ +#if ELF_CLASS ==ELFCLASS32 +struct elf_sym *syms = s->disas_symtab.elf32; +#else +struct elf_sym *syms = s->disas_symtab.elf64; +#endif + +// binary search +struct elf_sym key; +struct elf_sym *sym; + + key.st_value = orig_addr; + + sym =bsearch (&key, syms, s->disas_num_syms,sizeof (*syms), symfind); +if (sym !=0 ) { +return s->disas_strtab + sym->st_name; + } + +return "" ; +} + +static int symcmp (const void *s0,const void *s1) +{ +struct elf_sym *sym0 = (struct elf_sym *)s0; +struct elf_sym *sym1 = (struct elf_sym *)s1; +return (sym0->st_value < sym1->st_value) + ?-1 + : ((sym0->st_value > sym1->st_value) ?1 :0 ); +} +/* Best attempt to load symbols from this ELF object. */ static void load_symbols (struct elfhdr *hdr,int fd) { -unsigned int i; +unsigned int i, nsyms;struct elf_shdr sechdr, symtab, strtab;char *strings;struct syminfo *s; -#if (ELF_CLASS ==ELFCLASS64 ) -// Disas uses 32 bit symbols -struct elf32_sym *syms32 =NULL ; -struct elf_sym *sym; -#endif +struct elf_sym *syms;lseek (fd, hdr->e_shoff,SEEK_SET );for (i =0 ; i < hdr->e_shnum; i++) { -if (read (fd, &sechdr,sizeof (sechdr)) !=sizeof (sechdr)) -return ; +if (read (fd, &sechdr,sizeof (sechdr)) !=sizeof (sechdr)) +return ;#ifdef BSWAP_NEEDED -bswap_shdr (&sechdr); +bswap_shdr (&sechdr);#endif -if (sechdr.sh_type ==SHT_SYMTAB ) { - symtab = sechdr; -lseek (fd, hdr->e_shoff - +sizeof (sechdr) * sechdr.sh_link,SEEK_SET ); -if (read (fd, &strtab,sizeof (strtab)) - !=sizeof (strtab)) -return ; +if (sechdr.sh_type ==SHT_SYMTAB ) { + symtab = sechdr; +lseek (fd, hdr->e_shoff + +sizeof (sechdr) * sechdr.sh_link,SEEK_SET ); +if (read (fd, &strtab,sizeof (strtab)) + !=sizeof (strtab)) +return ;#ifdef BSWAP_NEEDED -bswap_shdr (&strtab); +bswap_shdr (&strtab);#endif - goto found; - } + goto found; + } }return ;/* Shouldn't happen... */ found:/* Now know where the strtab and symtab are. Snarf them. */ s =malloc (sizeof (*s)); - s->disas_symtab =malloc (symtab.sh_size); -#if (ELF_CLASS ==ELFCLASS64 ) - syms32 =malloc (symtab.sh_size /sizeof (struct elf_sym ) - *sizeof (struct elf32_sym )); -#endif + syms =malloc (symtab.sh_size); +if (!syms) +return ; s->disas_strtab = strings =malloc (strtab.sh_size); -if (!s->disas_symtab || !s->disas_strtab) -return ; +if (!s->disas_strtab) +return ;lseek (fd, symtab.sh_offset,SEEK_SET ); -if (read (fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size) -return ; +if (read (fd, syms, symtab.sh_size) != symtab.sh_size) +return ; -for (i =0 ; i < symtab.sh_size /sizeof (struct elf_sym ); i++) { + nsyms = symtab.sh_size /sizeof (struct elf_sym ); + +for (i =0 ; i < nsyms; i++) {#ifdef BSWAP_NEEDED -bswap_sym (s->disas_symtab +sizeof (struct elf_sym )*i); +bswap_sym (syms + i);#endif -#if (ELF_CLASS ==ELFCLASS64 ) - sym = s->disas_symtab +sizeof (struct elf_sym )*i; - syms32[i].st_name = sym->st_name; - syms32[i].st_info = sym->st_info; - syms32[i].st_other = sym->st_other; - syms32[i].st_shndx = sym->st_shndx; - syms32[i].st_value = sym->st_value &0xffffffff ; - syms32[i].st_size = sym->st_size &0xffffffff ; +// Throw away entries which we do not need. +while ((syms[i].st_shndx ==SHN_UNDEF || + syms[i].st_shndx >=SHN_LORESERVE || +ELF_ST_TYPE (syms[i].st_info) !=STT_FUNC ) && i < --nsyms) { + syms[i] = syms[nsyms]; +#ifdef BSWAP_NEEDED +bswap_sym (syms + i);#endif + } +#if defined(TARGET_ARM ) || defined (TARGET_MIPS ) +/* The bottom address bit marks a Thumb or MIPS16 symbol. */ + syms[i].st_value &= ~(target_ulong )1 ; +#endif } + syms =realloc (syms, nsyms *sizeof (*syms)); -#if (ELF_CLASS ==ELFCLASS64 ) -free (s->disas_symtab); - s->disas_symtab = syms32; -#endif +qsort (syms, nsyms,sizeof (*syms), symcmp); +lseek (fd, strtab.sh_offset,SEEK_SET );if (read (fd, strings, strtab.sh_size) != strtab.sh_size) -return ; - s->disas_num_syms = symtab.sh_size /sizeof (struct elf_sym ); +return ; + s->disas_num_syms = nsyms; +#if ELF_CLASS ==ELFCLASS32 + s->disas_symtab.elf32 = syms; + s->lookup_symbol = lookup_symbolxx; +#else + s->disas_symtab.elf64 = syms; + s->lookup_symbol = lookup_symbolxx; +#endif s->next = syminfos; syminfos = s; }
disas.c +12 -39
85 lines not on this page · raw message
disas.h +16 -4
@@ -10,12 +10,24 @@/* Look up symbol for debugging purpose. Returns "" if unknown. */ const char *lookup_symbol (target_ulong orig_addr); -/* Filled in by elfload.c. Simplistic, but will do for now. */ -extern struct syminfo { +struct syminfo ; +struct elf32_sym ; +struct elf64_sym ; + +typedef const char *(*lookup_symbol_t )(struct syminfo *s,target_ulong orig_addr); + +struct syminfo { +lookup_symbol_t lookup_symbol;unsigned int disas_num_syms; -void *disas_symtab; +union { +struct elf32_sym *elf32; +struct elf64_sym *elf64; + } disas_symtab;const char *disas_strtab;struct syminfo *next; -} *syminfos; +}; +/* Filled in by elfload.c. Simplistic, but will do for now. */ +extern struct syminfo *syminfos; +#endif /* _QEMU_DISAS_H */
elf_ops.h +60 -23
119 lines not on this page · raw message
Re: [Qemu-devel] [PATCH] Improve symbol lookup for system and user mode
Quoted 8 lines · Stefan Weil
Quoted 8 lines
Quoted 6 lines · Stefan Weil
Here is a short summary of my new patch:
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded).
This also fixes the bug with mips elf64 symbols in current Qemu trunk.
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to 11656 entries.* In
disas.c, the patch also fixes some warnings from old fashioned function prototypes.
This should be a separate patch.
Quoted 28 lines
Quoted 13 lines
Quoted 13 lines
In
loader.c, two defines control some compile time options (could be removed in
production code):
#defineCONFIG_BINARY_SYMBOL_SEARCH
#defineCONFIG_REDUCE_SYMBOL_TABLEI tested the new code using 32 bit and 64 bit linux mips kernels and Qemu logging (-d
in_asm).
The speed improvement is extremely large - both because of the much smaller table and
the binary search.Quoted 10 lines
Quoted 2 lines
Stefan
Please note:
The current patch only supports system emulation.
User emulation needs more fixes to compile again.Stefan
Here is an updated patch which now supports binary symbol lookup for both system emulation and user emulation.
Quoted 7 lines
User emulation was tested using qemu-x86_64 and a simple application with symbol information.
The new patch no longer includes compile time options for the old linear symbol search.
I hope this new patch will be included in Qemu trunk.
There are some white space only changes, these should be taken out.
For some reason, loading a bios with symbols on Sparc32 corrupts the bios but Sparc64 works. This happens also without your patch.
Re: [Qemu-devel] [PATCH] Improve symbol lookup (was: Re: [Qemu-devel] [PATCH] Fix symbol lookup for mips64* targets)
In reply to Stefan WeilQuoted 22 lines · Stefan Weil
So I did. Here is a short summary of my new patch:
* Use function pointers for symbol lookup (currently for elf32 and elf64, could be expanded).
This also fixes the bug with mips elf64 symbols in current Qemu trunk.* Use quicksort and binary search for symbol lookup.
* Remove unneeded entries from symbol table.
This reduced a typical table size (linux mips kernel) from 1764487 to
11656 entries.* In
disas.c, the patch also fixes some warnings from old fashioned function prototypes.In
loader.c, two defines control some compile time options (could be removed in
production code):
#defineCONFIG_BINARY_SYMBOL_SEARCH
#defineCONFIG_REDUCE_SYMBOL_TABLE
Quoted 5 lines
I tested the new code using 32 bit and 64 bit linux mips kernels and Qemu logging (-d
in_asm).
The speed improvement is extremely large - both because of the much smaller table and
the binary search.
Nice! Did you profile the time spent looking up symbols when running some big executable with a big symbol table?
Laurent
Quoted 25 lines · Stefan Weil
For 64 bit targets,
lookup_symbol()compares a 64-bit target address with a 32 bit symbol address. This only works for addresses less than 2^32.MIPS64 kernels use addresses larger than
0xffffffff80000000, so qemu.log never shows symbolic names.My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Regards
StefanFix symbol lookup for mips64* targets.
Signed-off-by Stefan Weil <[email protected]>Index:
disas.c
===================================================================
disas.c line 314
Quoted 6 lines
disas.c +3
-0@@ -309,6 +309,11 @@struct syminfo *s;target_ulong addr; +#if defined(TARGET_MIPS64 ) +/* Adresses in syminfos are 32 bit values. */ + orig_addr &=0xffffffff ;
This isn't true in general, not all MIPS64 kernels use the -msym32 optimization.
Thiemo
Quoted 41 lines · Thiemo Seufer
Quoted 27 lines · Stefan Weil
For 64 bit targets,
lookup_symbol()compares a 64-bit target address with a 32 bit symbol address. This only works for addresses less than 2^32.MIPS64 kernels use addresses larger than
0xffffffff80000000, so qemu.log never shows symbolic names.My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Regards
StefanFix symbol lookup for mips64* targets.
Signed-off-by Stefan Weil <[email protected]>Index:
disas.c
===================================================================disas.c line 315
Quoted 7 lines
disas.c +3
-0@@ -309,6 +309,11 @@struct syminfo *s;target_ulong addr; +#if defined(TARGET_MIPS64 ) +/* Adresses in syminfos are 32 bit values. */ + orig_addr &=0xffffffff ;This isn't true in general, not all MIPS64 kernels use the -msym32 optimization.
Quoted 1 line
Thiemo
Nor does my MIPS64 kernel: it uses 64 bit symbol addresses.
The current Qemu loads these addresses, reduces them to 32 bit and stores the reduced 32 bit addresses. So the 32 bit addresses are made by Qemu. They have nothing to do with kernel compile flags.
In lookup_symbol, Qemu compares real 64 bit addresses to the reduced 32 bit addresses which does not work for addresses larger than 2^32. x86_64 kernels have no problem because they have small addresses. MIPS64 kernels have a problem because they have large addresses. I don't know whether ppc64 and sparc64 work, maybe someone who has such kernels can do a "nm vmlinux".
My patch is only a workaround which reduces the real 64 bit addresses to 32 bit, too.
I suggest to apply it to Qemu trunk (because it is small and it improves the current situation) and to add a note to the TODO list:
- store symbol addresses in full size (important for 64 bit targets)
Stefan
On Fri, Oct 3, 2008 at 12:09 PM, Stefan Weil <[email protected]> wrote:
[...]
Quoted 2 lines
add a note to the TODO list:
- store symbol addresses in full size (important for 64 bit targets)
And while you're at it add a note saying using linked lists for that is killing performance :-)
I have a hash-table based implementation somewhere if someone wants to take a look.
Laurent
Quoted 7 lines · Laurent Desnogues
On Fri, Oct 3, 2008 at 12:09 PM, Stefan Weil <[email protected]> wrote:
[...]Quoted 2 lines
add a note to the TODO list:
- store symbol addresses in full size (important for 64 bit targets)
Quoted 5 lines
And while you're at it add a note saying using linked lists for that
is killing performance :-)I have a hash-table based implementation somewhere if someone wants to take a look.
That would be interesting, please send.
Quoted 51 lines · Stefan Weil
Quoted 41 lines · Thiemo Seufer
Quoted 27 lines · Stefan Weil
For 64 bit targets,
lookup_symbol()compares a 64-bit target address with a 32 bit symbol address. This only works for addresses less than 2^32.MIPS64 kernels use addresses larger than
0xffffffff80000000, so qemu.log never shows symbolic names.My patch is a workaround which works with Qemu's 32 bit address hack. Please apply it to Qemu trunk.
Maybe a better solution would use symbol addresses without shortening them to 32 bits.
Regards
StefanFix symbol lookup for mips64* targets.
Signed-off-by Stefan Weil <[email protected]>Index:
disas.c
===================================================================disas.c (Arbeitskopie) line 315
Quoted 7 lines
disas.c (Arbeitskopie) renamed from disas.c (Revision 5400) +3
-0@@ -309,6 +309,11 @@ struct syminfo *s; target_ulong addr; +#if defined(TARGET_MIPS64) + /* Adresses in syminfos are 32 bit values. */ + orig_addr &= 0xffffffff;This isn't true in general, not all MIPS64 kernels use the -msym32 optimization.
Quoted 1 line
Thiemo
Nor does my MIPS64 kernel: it uses 64 bit symbol addresses.
The current Qemu loads these addresses, reduces them to 32 bit and stores the reduced 32 bit addresses. So the 32 bit addresses are made by Qemu. They have nothing to do with kernel compile flags.
Quoted 6 lines
In
lookup_symbol, Qemu compares real 64 bit addresses to the reduced 32 bit addresses which does not work for addresses larger than 2^32.x86_64kernels have no problem because they have small addresses. MIPS64 kernels have a problem because they have large addresses. I don't know whether ppc64 and sparc64 work, maybe someone who has such kernels can do a "nm vmlinux".
Sparc64 kernel is located below 4G.
Quoted 6 lines
My patch is only a workaround which reduces the real 64 bit addresses to 32 bit, too.
I suggest to apply it to Qemu trunk (because it is small and it improves the current situation) and to add a note to the TODO list:
- store symbol addresses in full size (important for 64 bit targets)
We could be more ambitious and make the symbol size depend on target. It does not look too hard.