|
From: <sv...@va...> - 2009-04-29 05:08:25
|
Author: njn
Date: 2009-04-29 06:08:15 +0100 (Wed, 29 Apr 2009)
New Revision: 9677
Log:
Add some extra symbol comparisons, based on those from the DARWIN branch.
Modified:
trunk/coregrind/m_debuginfo/storage.c
Modified: trunk/coregrind/m_debuginfo/storage.c
===================================================================
--- trunk/coregrind/m_debuginfo/storage.c 2009-04-29 04:55:36 UTC (rev 9676)
+++ trunk/coregrind/m_debuginfo/storage.c 2009-04-29 05:08:15 UTC (rev 9677)
@@ -1018,15 +1018,27 @@
}
-/* Two symbols have the same address. Which name do we prefer?
+/* Two symbols have the same address. Which name do we prefer? In order:
- The general rule is to prefer the shorter symbol name. If the
- symbol contains a '@', which means it is versioned, then the length
- up to the '@' is used for length comparison purposes (so
- "foo@GLIBC_2.4.2" is considered shorter than "foobar"), but if two
- symbols have the same length, the one with the version string is
- preferred. If all else fails, use alphabetical ordering.
+ - Prefer "PMPI_<foo>" over "MPI_<foo>".
+ - Else, prefer a non-NULL name over a NULL one.
+
+ - Else, prefer a non-whitespace name over an all-whitespace name.
+
+ - Else, prefer the shorter symbol name. If the symbol contains a
+ version symbol ('@' on Linux, other platforms may differ), which means it
+ is versioned, then the length up to the version symbol is used for length
+ comparison purposes (so "foo@GLIBC_2.4.2" is considered shorter than
+ "foobar").
+
+ - Else, if two symbols have the same length, prefer a versioned symbol over
+ a non-versioned symbol.
+
+ - Else, use alphabetical ordering.
+
+ - Otherwise, they must be the same; use the symbol with the lower address.
+
Very occasionally this goes wrong (eg. 'memcmp' and 'bcmp' are
aliases in glibc, we choose the 'bcmp' symbol because it's shorter,
so we can misdescribe memcmp() as bcmp()). This is hard to avoid.
@@ -1046,9 +1058,15 @@
vlena = VG_(strlen)(a->name);
vlenb = VG_(strlen)(b->name);
- vpa = VG_(strchr)(a->name, '@');
- vpb = VG_(strchr)(b->name, '@');
+#if defined(VGO_linux) || defined(VGO_aix5)
+# define VERSION_CHAR '@'
+#else
+# error Unknown OS
+#endif
+ vpa = VG_(strchr)(a->name, VERSION_CHAR);
+ vpb = VG_(strchr)(b->name, VERSION_CHAR);
+
if (vpa)
vlena = vpa - a->name;
if (vpb)
@@ -1066,6 +1084,42 @@
preferA = True; goto out;
}
+ /* Prefer non-empty name. */
+ if (vlena && !vlenb) {
+ preferA = True; goto out;
+ }
+ if (vlenb && !vlena) {
+ preferB = True; goto out;
+ }
+
+ /* Prefer non-whitespace name. */
+ {
+ Bool blankA = True;
+ Bool blankB = True;
+ Char *s;
+ s = a->name;
+ while (*s) {
+ if (!VG_(isspace)(*s++)) {
+ blankA = False;
+ break;
+ }
+ }
+ s = b->name;
+ while (*s) {
+ if (!VG_(isspace)(*s++)) {
+ blankB = False;
+ break;
+ }
+ }
+
+ if (!blankA && blankB) {
+ preferA = True; goto out;
+ }
+ if (!blankB && blankA) {
+ preferB = True; goto out;
+ }
+ }
+
/* Select the shortest unversioned name */
if (vlena < vlenb) {
preferA = True; goto out;
@@ -1091,8 +1145,9 @@
if (cmp > 0) {
preferB = True; goto out;
}
- /* If we get here, they are the same (?!). That's very odd. In
- this case we could choose either (arbitrarily), but might as
+ /* If we get here, they are the same name. */
+
+ /* In this case we could choose either (arbitrarily), but might as
well choose the one with the lowest DiSym* address, so as to try
and make the comparison mechanism more stable (a la sorting
parlance). Also, skip the diagnostic printing in this case. */
|