about summary refs log tree commit diff
path: root/src/rustllvm/RustWrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
-rw-r--r--src/rustllvm/RustWrapper.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 4755c7873fc..5a00a8034e6 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -10,6 +10,7 @@
 
 #include "rustllvm.h"
 #include "llvm/Object/Archive.h"
+#include "llvm/Object/ObjectFile.h"
 
 //===----------------------------------------------------------------------===
 //
@@ -679,3 +680,27 @@ extern "C" int
 LLVMVersionMinor() {
     return LLVM_VERSION_MINOR;
 }
+
+// Note that the two following functions look quite similar to the
+// LLVMGetSectionName function. Sadly, it appears that this function only
+// returns a char* pointer, which isn't guaranteed to be null-terminated. The
+// function provided by LLVM doesn't return the length, so we've created our own
+// function which returns the length as well as the data pointer.
+//
+// For an example of this not returning a null terminated string, see
+// lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
+// branches explicitly creates a StringRef without a null terminator, and then
+// that's returned.
+
+inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
+    return reinterpret_cast<section_iterator*>(SI);
+}
+
+extern "C" int
+LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
+    StringRef ret;
+    if (error_code ec = (*unwrap(SI))->getName(ret))
+      report_fatal_error(ec.message());
+    *ptr = ret.data();
+    return ret.size();
+}