Module Name: src
Committed By: yamt
Date: Fri Feb 3 05:06:08 UTC 2012
Modified Files:
src/usr.bin/tpfmt: sym.c
Log Message:
make the result stable.
releng@ ok
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/tpfmt/sym.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/tpfmt/sym.c
diff -u src/usr.bin/tpfmt/sym.c:1.3 src/usr.bin/tpfmt/sym.c:1.4
--- src/usr.bin/tpfmt/sym.c:1.3 Sat Nov 26 05:04:09 2011
+++ src/usr.bin/tpfmt/sym.c Fri Feb 3 05:06:08 2012
@@ -1,7 +1,7 @@
-/* $NetBSD: sym.c,v 1.3 2011/11/26 05:04:09 yamt Exp $ */
+/* $NetBSD: sym.c,v 1.4 2012/02/03 05:06:08 yamt Exp $ */
/*-
- * Copyright (c) 2010 YAMAMOTO Takashi,
+ * Copyright (c) 2010,2011,2012 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: sym.c,v 1.3 2011/11/26 05:04:09 yamt Exp $");
+__RCSID("$NetBSD: sym.c,v 1.4 2012/02/03 05:06:08 yamt Exp $");
#endif /* not lint */
#include <assert.h>
@@ -63,7 +63,16 @@ compare_value(const void *p1, const void
} else if (s1->value < s2->value) {
return 1;
}
- return 0;
+ /*
+ * to produce a stable result, it's better not to return 0
+ * even for __strong_alias.
+ */
+ if (s1->size > s2->size) {
+ return -1;
+ } else if (s1->size < s2->size) {
+ return 1;
+ }
+ return strcmp(s1->name, s2->name);
}
void
@@ -140,8 +149,8 @@ ksymlookup(uint64_t value, uint64_t *off
size_t i;
/*
- * find the smallest i for which syms[i]->value <= value.
- * syms[] is ordered with value in the descending order.
+ * try to find the smallest i for which syms[i]->value <= value.
+ * syms[] is ordered by syms[]->value in the descending order.
*/
hi = nsyms - 1;
@@ -150,16 +159,21 @@ ksymlookup(uint64_t value, uint64_t *off
const size_t mid = (lo + hi) / 2;
const struct sym *sym = syms[mid];
+ assert(syms[lo]->value >= sym->value);
+ assert(sym->value >= syms[hi]->value);
if (sym->value <= value) {
hi = mid;
continue;
}
lo = mid + 1;
}
+ assert(lo == nsyms - 1 || syms[lo]->value <= value);
+ assert(lo == 0 || syms[lo - 1]->value > value);
for (i = lo; i < nsyms; i++) {
const struct sym *sym = syms[i];
- if (sym->value <= value) {
+ if (sym->value <= value &&
+ (sym->size == 0 || value - sym->value <= sym->size )) {
*offset = value - sym->value;
return sym->name;
}