-> Bool;
/** Moves the section iterator to point to the next section. */
pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
- /** Returns the current section name. */
- pub fn LLVMGetSectionName(SI: SectionIteratorRef) -> *c_char;
/** Returns the current section size. */
pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
/** Returns the current section contents as a string buffer. */
pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
pub fn LLVMVersionMinor() -> c_int;
+
+ pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
+ data: *mut *c_char) -> c_int;
}
}
use std::cmp;
use std::io;
use std::os::consts::{macos, freebsd, linux, android, win32};
+use std::ptr;
use std::rc::Rc;
-use std::str;
use std::slice;
+use std::str;
use collections::{HashMap, HashSet};
use flate;
};
let si = mk_section_iter(of.llof);
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
- let name_buf = llvm::LLVMGetSectionName(si.llsi);
- let name = str::raw::from_c_str(name_buf);
+ let mut name_buf = ptr::null();
+ let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
+ let name = str::raw::from_buf_len(name_buf as *u8, name_len as uint);
debug!("get_metadata_section: name {}", name);
if read_meta_section_name(os) == name {
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
#include "rustllvm.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/ObjectFile.h"
//===----------------------------------------------------------------------===
//
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();
+}