llvm: update ffi bindings for split dwarf

This commit modifies the FFI bindings to LLVM required for Split DWARF
support in rustc. In particular:

- `addPassesToEmitFile`'s wrapper, `LLVMRustWriteOutputFile` now takes
  a `DwoPath` `const char*`. When disabled, `nullptr` should be provided
  which will preserve existing behaviour. When enabled, the path to the
  `.dwo` file should be provided.
- `createCompileUnit`'s wrapper, `LLVMRustDIBuilderCreateCompileUnit`
  now has two additional arguments, for the `DWOId` and to enable
  `SplitDebugInlining`. `DWOId` should always be zero.
- `createTargetMachine`'s wrapper, `LLVMRustCreateTargetMachine` has an
  additional argument which should be provided the path to the `.dwo`
  when enabled.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-09-23 16:25:20 +01:00
parent ddbc6176de
commit 341aa97adb
No known key found for this signature in database
GPG Key ID: 2592E76C87381FD9
5 changed files with 41 additions and 7 deletions

View File

@ -53,7 +53,14 @@ pub fn write_output_file(
) -> Result<(), FatalError> {
unsafe {
let output_c = path_to_c_string(output);
let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
let result = llvm::LLVMRustWriteOutputFile(
target,
pm,
m,
output_c.as_ptr(),
std::ptr::null(),
file_type,
);
result.into_result().map_err(|()| {
let msg = format!("could not write output to {}", output.display());
llvm_err(handler, &msg)
@ -164,6 +171,7 @@ pub fn target_machine_factory(
!sess.opts.debugging_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section);
Arc::new(move || {
let split_dwarf_file = std::ptr::null();
let tm = unsafe {
llvm::LLVMRustCreateTargetMachine(
triple.as_ptr(),
@ -182,6 +190,7 @@ pub fn target_machine_factory(
emit_stack_size_section,
relax_elf_relocations,
use_init_array,
split_dwarf_file,
)
};

View File

@ -1039,6 +1039,8 @@ pub fn compile_unit_metadata(
split_name.as_ptr().cast(),
split_name.len(),
kind,
0,
true,
);
if tcx.sess.opts.debugging_opts.profile {

View File

@ -1830,6 +1830,8 @@ extern "C" {
SplitName: *const c_char,
SplitNameLen: size_t,
kind: DebugEmissionKind,
DWOId: u64,
SplitDebugInlining: bool,
) -> &'a DIDescriptor;
pub fn LLVMRustDIBuilderCreateFile(
@ -2151,6 +2153,7 @@ extern "C" {
EmitStackSizeSection: bool,
RelaxELFRelocations: bool,
UseInitArray: bool,
SplitDwarfFile: *const c_char,
) -> Option<&'static mut TargetMachine>;
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
pub fn LLVMRustAddBuilderLibraryInfo(
@ -2179,6 +2182,7 @@ extern "C" {
PM: &PassManager<'a>,
M: &'a Module,
Output: *const c_char,
DwoOutput: *const c_char,
FileType: FileType,
) -> LLVMRustResult;
pub fn LLVMRustOptimizeWithNewPassManager(

View File

@ -450,7 +450,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
bool AsmComments,
bool EmitStackSizeSection,
bool RelaxELFRelocations,
bool UseInitArray) {
bool UseInitArray,
const char *SplitDwarfFile) {
auto OptLevel = fromRust(RustOptLevel);
auto RM = fromRust(RustReloc);
@ -476,6 +477,9 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.MCOptions.AsmVerbose = AsmComments;
Options.MCOptions.PreserveAsmComments = AsmComments;
Options.MCOptions.ABIName = ABIStr;
if (SplitDwarfFile) {
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
}
Options.RelaxELFRelocations = RelaxELFRelocations;
Options.UseInitArray = UseInitArray;
@ -610,7 +614,7 @@ static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
extern "C" LLVMRustResult
LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
LLVMModuleRef M, const char *Path,
LLVMModuleRef M, const char *Path, const char *DwoPath,
LLVMRustFileType RustFileType) {
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
auto FileType = fromRust(RustFileType);
@ -626,8 +630,22 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
}
buffer_ostream BOS(OS);
unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
PM->run(*unwrap(M));
if (DwoPath) {
raw_fd_ostream DOS(DwoPath, EC, sys::fs::F_None);
EC.clear();
if (EC)
ErrorInfo = EC.message();
if (ErrorInfo != "") {
LLVMRustSetLastError(ErrorInfo.c_str());
return LLVMRustResult::Failure;
}
buffer_ostream DBOS(DOS);
unwrap(Target)->addPassesToEmitFile(*PM, BOS, &DBOS, FileType, false);
PM->run(*unwrap(M));
} else {
unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
PM->run(*unwrap(M));
}
// Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
// stream (OS), so the only real safe place to delete this is here? Don't we

View File

@ -690,13 +690,14 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
const char *Producer, size_t ProducerLen, bool isOptimized,
const char *Flags, unsigned RuntimeVer,
const char *SplitName, size_t SplitNameLen,
LLVMRustDebugEmissionKind Kind) {
LLVMRustDebugEmissionKind Kind,
uint64_t DWOId, bool SplitDebugInlining) {
auto *File = unwrapDI<DIFile>(FileRef);
return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
isOptimized, Flags, RuntimeVer,
StringRef(SplitName, SplitNameLen),
fromRust(Kind)));
fromRust(Kind), DWOId, SplitDebugInlining));
}
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(