The attributes of a symbol include the alignment, visibility, and kind.
+Tools working with object files on Darwin (e.g. lipo) may need to know properties like the CPU type:
+
+.. code-block:: c
+
+ lto_module_get_macho_cputype(lto_module_t mod, unsigned int *out_cputype, unsigned int *out_cpusubtype)
+
``lto_code_gen_t``
------------------
* @{
*/
-#define LTO_API_VERSION 26
+#define LTO_API_VERSION 27
/**
* \since prior to LTO_API_VERSION=3
lto_module_get_linkeropts(lto_module_t mod);
/**
+ * If targeting mach-o on darwin, this function gets the CPU type and subtype
+ * that will end up being encoded in the mach-o header. These are the values
+ * that can be found in mach/machine.h.
+ *
+ * \p out_cputype and \p out_cpusubtype must be non-NULL.
+ *
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since LTO_API_VERSION=27
+ */
+extern lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
+ unsigned int *out_cputype,
+ unsigned int *out_cpusubtype);
+
+/**
* Diagnostic severity.
*
* \since LTO_API_VERSION=7
static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
+ Expected<uint32_t> getMachOCPUType() const;
+
+ Expected<uint32_t> getMachOCPUSubType() const;
+
private:
/// Parse metadata from the module
// FIXME: it only parses "llvm.linker.options" metadata at the moment
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
*size = S.size();
return S.data();
}
+
+Expected<uint32_t> LTOModule::getMachOCPUType() const {
+ return MachO::getCPUType(Triple(Mod->getTargetTriple()));
+}
+
+Expected<uint32_t> LTOModule::getMachOCPUSubType() const {
+ return MachO::getCPUSubType(Triple(Mod->getTargetTriple()));
+}
--- /dev/null
+; RUN: rm -rf %t && mkdir -p %t
+; RUN: llvm-as -o %t/1.bc %s
+; RUN: llvm-lto -print-macho-cpu-only %t/1.bc | FileCheck %s
+
+target triple = "x86_64-apple-darwin"
+; CHECK: 1.bc:
+; CHECK-NEXT: cputype: 16777223
+; CHECK-NEXT: cpusubtype: 3
; RUN: not llvm-lto --list-dependent-libraries-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIBS
; CHECK-LIBS: llvm-lto: {{.*}}/Inputs/empty.bc: Could not read LTO input file: The file was not recognized as a valid object file
+; RUN: not llvm-lto --print-macho-cpu-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO
+; CHECK-MACHO: llvm-lto: error: The file was not recognized as a valid object file
+
; RUN: not llvm-lto --thinlto %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-THIN
; CHECK-THIN: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': file too small to contain bitcode header
"check-for-objc", cl::init(false),
cl::desc("Only check if the module has objective-C defined in it"));
+static cl::opt<bool> PrintMachOCPUOnly(
+ "print-macho-cpu-only", cl::init(false),
+ cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"));
+
namespace {
struct ModuleInfo {
}
}
+static void printMachOCPUOnly() {
+ LLVMContext Context;
+ Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
+ true);
+ TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+ for (auto &Filename : InputFilenames) {
+ ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
+ LTOModule::createFromFile(Context, Filename, Options);
+ if (!ModuleOrErr)
+ error(ModuleOrErr, "llvm-lto: ");
+
+ Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType();
+ Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType();
+ if (!CPUType)
+ error("Error while printing mach-o cputype: " +
+ toString(CPUType.takeError()));
+ if (!CPUSubType)
+ error("Error while printing mach-o cpusubtype: " +
+ toString(CPUSubType.takeError()));
+ outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n",
+ Filename.c_str(), *CPUType, *CPUSubType);
+ }
+}
+
/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
return 0;
}
+ if (PrintMachOCPUOnly) {
+ printMachOCPUOnly();
+ return 0;
+ }
+
if (ThinLTOMode.getNumOccurrences()) {
if (ThinLTOMode.getNumOccurrences() > 1)
report_fatal_error("You can't specify more than one -thinlto-action");
return unwrap(mod)->getLinkerOpts().data();
}
+lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
+ unsigned int *out_cputype,
+ unsigned int *out_cpusubtype) {
+ LTOModule *M = unwrap(mod);
+ Expected<uint32_t> CPUType = M->getMachOCPUType();
+ if (!CPUType) {
+ sLastErrorString = toString(CPUType.takeError());
+ return true;
+ }
+ *out_cputype = *CPUType;
+
+ Expected<uint32_t> CPUSubType = M->getMachOCPUSubType();
+ if (!CPUSubType) {
+ sLastErrorString = toString(CPUSubType.takeError());
+ return true;
+ }
+ *out_cpusubtype = *CPUSubType;
+
+ return false;
+}
+
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
lto_diagnostic_handler_t diag_handler,
void *ctxt) {
lto_module_create_in_local_context
lto_module_create_in_codegen_context
lto_module_get_linkeropts
+lto_module_get_macho_cputype
lto_module_get_num_symbols
lto_module_get_symbol_attribute
lto_module_get_symbol_name