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

View File

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

View File

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

View File

@ -450,7 +450,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
bool AsmComments, bool AsmComments,
bool EmitStackSizeSection, bool EmitStackSizeSection,
bool RelaxELFRelocations, bool RelaxELFRelocations,
bool UseInitArray) { bool UseInitArray,
const char *SplitDwarfFile) {
auto OptLevel = fromRust(RustOptLevel); auto OptLevel = fromRust(RustOptLevel);
auto RM = fromRust(RustReloc); auto RM = fromRust(RustReloc);
@ -476,6 +477,9 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.MCOptions.AsmVerbose = AsmComments; Options.MCOptions.AsmVerbose = AsmComments;
Options.MCOptions.PreserveAsmComments = AsmComments; Options.MCOptions.PreserveAsmComments = AsmComments;
Options.MCOptions.ABIName = ABIStr; Options.MCOptions.ABIName = ABIStr;
if (SplitDwarfFile) {
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
}
Options.RelaxELFRelocations = RelaxELFRelocations; Options.RelaxELFRelocations = RelaxELFRelocations;
Options.UseInitArray = UseInitArray; Options.UseInitArray = UseInitArray;
@ -610,7 +614,7 @@ static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
extern "C" LLVMRustResult extern "C" LLVMRustResult
LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR, LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
LLVMModuleRef M, const char *Path, LLVMModuleRef M, const char *Path, const char *DwoPath,
LLVMRustFileType RustFileType) { LLVMRustFileType RustFileType) {
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR); llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
auto FileType = fromRust(RustFileType); auto FileType = fromRust(RustFileType);
@ -626,8 +630,22 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
} }
buffer_ostream BOS(OS); buffer_ostream BOS(OS);
unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false); if (DwoPath) {
PM->run(*unwrap(M)); 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 // 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 // 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 *Producer, size_t ProducerLen, bool isOptimized,
const char *Flags, unsigned RuntimeVer, const char *Flags, unsigned RuntimeVer,
const char *SplitName, size_t SplitNameLen, const char *SplitName, size_t SplitNameLen,
LLVMRustDebugEmissionKind Kind) { LLVMRustDebugEmissionKind Kind,
uint64_t DWOId, bool SplitDebugInlining) {
auto *File = unwrapDI<DIFile>(FileRef); auto *File = unwrapDI<DIFile>(FileRef);
return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen), return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
isOptimized, Flags, RuntimeVer, isOptimized, Flags, RuntimeVer,
StringRef(SplitName, SplitNameLen), StringRef(SplitName, SplitNameLen),
fromRust(Kind))); fromRust(Kind), DWOId, SplitDebugInlining));
} }
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile( extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(