diff options
| -rw-r--r-- | src/librustc/lib/llvm.rs | 5 | ||||
| -rw-r--r-- | src/librustc/metadata/loader.rs | 8 | ||||
| -rw-r--r-- | src/rustllvm/RustWrapper.cpp | 25 |
3 files changed, 33 insertions, 5 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index a733d2672e8..9cfe064ad98 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1438,8 +1438,6 @@ pub mod llvm { -> 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. */ @@ -1784,6 +1782,9 @@ pub mod llvm { pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef); pub fn LLVMVersionMinor() -> c_int; + + pub fn LLVMRustGetSectionName(SI: SectionIteratorRef, + data: *mut *c_char) -> c_int; } } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 8a3d6567c77..4dd892fd703 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -29,9 +29,10 @@ use std::cast; 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; @@ -439,8 +440,9 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~st }; 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); 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(); +} |
