forked from OSchip/llvm-project
[LTO][Legacy] Add new API to query Mach-O CPU (sub)type
Tools working with object files on Darwin (e.g. lipo) may need to know properties like the CPU type and subtype of a bitcode file. The logic of converting a triple to a Mach-O CPU_(SUB_)TYPE should be provided by LLVM instead of relying on tools to re-implement it. Differential Revision: https://reviews.llvm.org/D75067
This commit is contained in:
parent
67c1615440
commit
e551b737c3
|
@ -249,6 +249,12 @@ symbols and getting the name and attributes of each symbol via:
|
||||||
|
|
||||||
The attributes of a symbol include the alignment, visibility, and kind.
|
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``
|
``lto_code_gen_t``
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ typedef bool lto_bool_t;
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LTO_API_VERSION 26
|
#define LTO_API_VERSION 27
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \since prior to LTO_API_VERSION=3
|
* \since prior to LTO_API_VERSION=3
|
||||||
|
@ -297,6 +297,21 @@ lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
|
||||||
extern const char*
|
extern const char*
|
||||||
lto_module_get_linkeropts(lto_module_t mod);
|
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.
|
* Diagnostic severity.
|
||||||
*
|
*
|
||||||
|
|
|
@ -165,6 +165,10 @@ public:
|
||||||
|
|
||||||
static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
|
static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
|
||||||
|
|
||||||
|
Expected<uint32_t> getMachOCPUType() const;
|
||||||
|
|
||||||
|
Expected<uint32_t> getMachOCPUSubType() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Parse metadata from the module
|
/// Parse metadata from the module
|
||||||
// FIXME: it only parses "llvm.linker.options" metadata at the moment
|
// FIXME: it only parses "llvm.linker.options" metadata at the moment
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "llvm/MC/MCSymbol.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/MC/SubtargetFeature.h"
|
#include "llvm/MC/SubtargetFeature.h"
|
||||||
#include "llvm/Object/IRObjectFile.h"
|
#include "llvm/Object/IRObjectFile.h"
|
||||||
|
#include "llvm/Object/MachO.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
#include "llvm/Support/Host.h"
|
#include "llvm/Support/Host.h"
|
||||||
|
@ -676,3 +677,11 @@ const char *LTOModule::getDependentLibrary(lto::InputFile *input, size_t index,
|
||||||
*size = S.size();
|
*size = S.size();
|
||||||
return S.data();
|
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()));
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
; 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
|
|
@ -7,5 +7,8 @@
|
||||||
; RUN: not llvm-lto --list-dependent-libraries-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIBS
|
; 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
|
; 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
|
; 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-THIN: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': file too small to contain bitcode header
|
||||||
|
|
|
@ -223,6 +223,10 @@ static cl::opt<bool> CheckHasObjC(
|
||||||
"check-for-objc", cl::init(false),
|
"check-for-objc", cl::init(false),
|
||||||
cl::desc("Only check if the module has objective-C defined in it"));
|
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 {
|
namespace {
|
||||||
|
|
||||||
struct ModuleInfo {
|
struct ModuleInfo {
|
||||||
|
@ -404,6 +408,30 @@ static void listDependentLibraries() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
/// Create a combined index file from the input IR files and write it.
|
||||||
///
|
///
|
||||||
/// This is meant to enable testing of ThinLTO combined index generation,
|
/// This is meant to enable testing of ThinLTO combined index generation,
|
||||||
|
@ -905,6 +933,11 @@ int main(int argc, char **argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PrintMachOCPUOnly) {
|
||||||
|
printMachOCPUOnly();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ThinLTOMode.getNumOccurrences()) {
|
if (ThinLTOMode.getNumOccurrences()) {
|
||||||
if (ThinLTOMode.getNumOccurrences() > 1)
|
if (ThinLTOMode.getNumOccurrences() > 1)
|
||||||
report_fatal_error("You can't specify more than one -thinlto-action");
|
report_fatal_error("You can't specify more than one -thinlto-action");
|
||||||
|
|
|
@ -327,6 +327,27 @@ const char* lto_module_get_linkeropts(lto_module_t mod) {
|
||||||
return unwrap(mod)->getLinkerOpts().data();
|
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,
|
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
|
||||||
lto_diagnostic_handler_t diag_handler,
|
lto_diagnostic_handler_t diag_handler,
|
||||||
void *ctxt) {
|
void *ctxt) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ lto_module_create_from_memory_with_path
|
||||||
lto_module_create_in_local_context
|
lto_module_create_in_local_context
|
||||||
lto_module_create_in_codegen_context
|
lto_module_create_in_codegen_context
|
||||||
lto_module_get_linkeropts
|
lto_module_get_linkeropts
|
||||||
|
lto_module_get_macho_cputype
|
||||||
lto_module_get_num_symbols
|
lto_module_get_num_symbols
|
||||||
lto_module_get_symbol_attribute
|
lto_module_get_symbol_attribute
|
||||||
lto_module_get_symbol_name
|
lto_module_get_symbol_name
|
||||||
|
|
Loading…
Reference in New Issue