aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-05-14 12:23:33 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-05-14 12:34:24 +0100
commit9bcbfee5f3e7d69b59c985404b3e4e0788f4a607 (patch)
tree4ab3ce185bf03a191ad4241fc72a3c957066fa1d /gcc/rust/backend
parent5d7fbc4a78897f8f561bdd78b4d3bbc15f4b351f (diff)
downloadgcc-9bcbfee5f3e7d69b59c985404b3e4e0788f4a607.zip
gcc-9bcbfee5f3e7d69b59c985404b3e4e0788f4a607.tar.gz
gcc-9bcbfee5f3e7d69b59c985404b3e4e0788f4a607.tar.bz2
Add FNV-128 hash for legacy symbol mangling
Rustc uses a SIP128 hash for the legacy symbol mangling but an FNV hash is simpler to implement this is a port of the implementation from golang stdlib hash package. The fingerprint for the hash is simple the function signiture for now. Rustc takes into account options such as -Cmetadata to generate uniqueness. We still need to implement an SIP128 and the V0 symbol mangling but this will do in the interim. Addresses: #305 Fixes: #428
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-context.h5
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h4
-rw-r--r--gcc/rust/backend/rust-compile-item.h4
-rw-r--r--gcc/rust/backend/rust-compile.cc35
4 files changed, 36 insertions, 12 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 45fb6c2..5df0d89 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -283,9 +283,12 @@ public:
return pop;
}
- std::string mangle_item (const std::string &name) const;
+ // this needs to support Legacy and V0 see github #429 or #305
+ std::string mangle_item (const TyTy::BaseType *ty,
+ const std::string &name) const;
std::string mangle_impl_item (const TyTy::BaseType *self,
+ const TyTy::BaseType *ty,
const std::string &name) const;
private:
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index b071d94..a5ca13b 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -125,7 +125,7 @@ public:
std::string fn_identifier
= self->get_name () + "_" + function.get_function_name ();
std::string asm_name
- = ctx->mangle_impl_item (self, function.get_function_name ());
+ = ctx->mangle_impl_item (self, fntype, function.get_function_name ());
Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
@@ -310,7 +310,7 @@ public:
std::string fn_identifier
= self->get_name () + "_" + method.get_method_name ();
std::string asm_name
- = ctx->mangle_impl_item (self, method.get_method_name ());
+ = ctx->mangle_impl_item (self, fntype, method.get_method_name ());
Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index c3dc279..e3b6d0f 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -53,7 +53,7 @@ public:
Bexpression *value = CompileExpr::Compile (var.get_expr (), ctx);
std::string name = var.get_identifier ();
- std::string asm_name = ctx->mangle_item (name);
+ std::string asm_name = ctx->mangle_item (resolved_type, name);
bool is_external = false;
bool is_hidden = false;
@@ -154,7 +154,7 @@ public:
// we don't mangle the main fn since we haven't implemented the main shim
// yet
if (!is_main_fn)
- asm_name = ctx->mangle_item (ir_symbol_name);
+ asm_name = ctx->mangle_item (fntype, ir_symbol_name);
Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 9dd3b57..480afc8b 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -20,6 +20,7 @@
#include "rust-compile-item.h"
#include "rust-compile-expr.h"
#include "rust-compile-struct-field-expr.h"
+#include "fnv-hash.h"
namespace Rust {
namespace Compile {
@@ -427,10 +428,23 @@ mangle_name (const std::string &name)
return std::to_string (name.size ()) + name;
}
+// rustc uses a sip128 hash for legacy mangling, but an fnv 128 was quicker to
+// implement for now
static std::string
-dummy_hash ()
+legacy_hash (const std::string &fingerprint)
{
- return "h0123456789abcdef";
+ Hash::FNV128 hasher;
+ hasher.write ((const unsigned char *) fingerprint.c_str (),
+ fingerprint.size ());
+
+ uint64_t hi, lo;
+ hasher.sum (&hi, &lo);
+
+ char hex[16 + 1];
+ memset (hex, 0, sizeof hex);
+ snprintf (hex, sizeof hex, "%08lx%08lx", lo, hi);
+
+ return "h" + std::string (hex, sizeof (hex) - 1);
}
static std::string
@@ -464,21 +478,28 @@ mangle_self (const TyTy::BaseType *self)
}
std::string
-Context::mangle_item (const std::string &name) const
+Context::mangle_item (const TyTy::BaseType *ty, const std::string &name) const
{
const std::string &crate_name = mappings->get_current_crate_name ();
+
+ const std::string hash = legacy_hash (ty->as_string ());
+ const std::string hash_sig = mangle_name (hash);
+
return kMangledSymbolPrefix + mangle_name (crate_name) + mangle_name (name)
- + mangle_name (dummy_hash ()) + kMangledSymbolDelim;
+ + hash_sig + kMangledSymbolDelim;
}
std::string
-Context::mangle_impl_item (const TyTy::BaseType *self,
+Context::mangle_impl_item (const TyTy::BaseType *self, const TyTy::BaseType *ty,
const std::string &name) const
{
const std::string &crate_name = mappings->get_current_crate_name ();
+
+ const std::string hash = legacy_hash (ty->as_string ());
+ const std::string hash_sig = mangle_name (hash);
+
return kMangledSymbolPrefix + mangle_name (crate_name) + mangle_self (self)
- + mangle_name (name) + mangle_name (dummy_hash ())
- + kMangledSymbolDelim;
+ + mangle_name (name) + hash_sig + kMangledSymbolDelim;
}
} // namespace Compile