summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-07-30 20:55:20 +0200
committerRichard Braun <rbraun@sceen.net>2018-07-30 20:55:20 +0200
commit83080805408a89367d9778107df6732ca04a2915 (patch)
tree773fb06706829088e10d8235253a71379ee67b41
parent096f0ea4c29feb19d2747f8b1eda3526952d6b0c (diff)
kern/symbol: work around clang aggressive optimization behavior
-rw-r--r--kern/symbol.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/kern/symbol.c b/kern/symbol.c
index 30df091e..7d0fb30a 100644
--- a/kern/symbol.c
+++ b/kern/symbol.c
@@ -21,17 +21,26 @@
#include <kern/macros.h>
#include <kern/symbol.h>
-const size_t symbol_table_size __weak;
-const struct symbol *symbol_table_ptr __weak;
+/*
+ * XXX Clang doesn't consider that weak symbols may change at link time
+ * by default, which turns the lookup into a no-op when optimizations
+ * are enabled. Make these variables volatile to work around this issue.
+ */
+const volatile size_t symbol_table_size __weak;
+const struct symbol * volatile symbol_table_ptr __weak;
const struct symbol *
symbol_lookup(uintptr_t addr)
{
- const struct symbol *symbol;
+ const struct symbol *table, *symbol;
uintptr_t start, end;
+ size_t size;
+
+ table = symbol_table_ptr;
+ size = symbol_table_size;
- for (size_t i = 0; i < symbol_table_size; i++) {
- symbol = &symbol_table_ptr[i];
+ for (size_t i = 0; i < size; i++) {
+ symbol = &table[i];
if (!symbol->name || (symbol->size == 0)) {
continue;