blob: bee468bf572c09f3b292008fbf6732176c844a0a [file] [log] [blame]
// Copyright 2019 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Loads a VM module from the provided file and outputs the requested
// information.
//
// $ iree-dump-module [--output=...] module.vmfb
// --output=metadata: module metadata and size breakdown.
// --output=flatbuffer-binary: module flatbuffer in binary format.
// --output=flatbuffer-json: module flatbuffer in JSON format.
#include <ctype.h>
#include <stdio.h>
#include "iree/base/api.h"
#include "iree/base/internal/file_io.h"
#include "iree/base/internal/flags.h"
#include "iree/vm/bytecode/archive.h"
#include "iree/vm/bytecode/module.h"
// NOTE: include order matters:
#include "iree/base/internal/flatcc/parsing.h"
#include "iree/schemas/bytecode_module_def_json_printer.h"
#include "iree/schemas/bytecode_module_def_reader.h"
#include "iree/schemas/bytecode_module_def_verifier.h"
//===----------------------------------------------------------------------===//
// IO utilities
//===----------------------------------------------------------------------===//
#if defined(IREE_PLATFORM_WINDOWS)
#include <fcntl.h>
#include <io.h>
#define IREE_SET_BINARY_MODE(handle) _setmode(_fileno(handle), O_BINARY)
#else
#define IREE_SET_BINARY_MODE(handle) ((void)0)
#endif // IREE_PLATFORM_WINDOWS
static void iree_tooling_print_indent(int indent) {
fprintf(stdout, "%*s", indent, "");
}
static void iree_tooling_printf_section_header(const char* format, ...) {
fprintf(stdout,
"//"
"===-----------------------------------------------------------------"
"---------------------------------------------===//\n");
fprintf(stdout, "// ");
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fprintf(stdout, "\n");
fprintf(stdout,
"//"
"===-----------------------------------------------------------------"
"---------------------------------------------===//\n");
}
//===----------------------------------------------------------------------===//
// --output=metadata
//===----------------------------------------------------------------------===//
static size_t iree_tooling_print_feature_bits(iree_vm_FeatureBits_enum_t bits) {
size_t length = 0;
if (bits & iree_vm_FeatureBits_EXT_F32) {
if (length) fprintf(stdout, " | ");
fprintf(stdout, "EXT_F32");
length += strlen("EXT_F32");
bits = bits & ~iree_vm_FeatureBits_EXT_F32;
}
if (bits & iree_vm_FeatureBits_EXT_F64) {
if (length) fprintf(stdout, " | ");
fprintf(stdout, "EXT_F64");
length += strlen("EXT_F64");
bits = bits & ~iree_vm_FeatureBits_EXT_F64;
}
if (bits) {
if (length) fprintf(stdout, " | ");
fprintf(stdout, "%08X", bits);
length += 8;
}
return length;
}
static void iree_tooling_print_attr_def(iree_vm_AttrDef_table_t attr_def) {
fprintf(stdout, "%s: %s", iree_vm_AttrDef_key(attr_def),
iree_vm_AttrDef_value(attr_def));
}
static void iree_tooling_print_attr_defs(iree_vm_AttrDef_vec_t attr_defs,
int indent) {
for (size_t i = 0; i < iree_vm_AttrDef_vec_len(attr_defs); ++i) {
iree_tooling_print_indent(indent);
iree_tooling_print_attr_def(iree_vm_AttrDef_vec_at(attr_defs, i));
fprintf(stdout, "\n");
}
}
static void iree_tooling_print_type_def(iree_vm_TypeDef_table_t type_def) {
fprintf(stdout, "%s", iree_vm_TypeDef_full_name(type_def));
}
static void iree_tooling_print_type_defs(iree_vm_TypeDef_vec_t type_defs,
int indent) {
for (size_t i = 0; i < iree_vm_TypeDef_vec_len(type_defs); ++i) {
iree_tooling_print_indent(indent);
fprintf(stdout, "[%3zu] ", i);
iree_tooling_print_type_def(iree_vm_TypeDef_vec_at(type_defs, i));
fprintf(stdout, "\n");
}
}
static void iree_tooling_print_module_dependency_def(
iree_vm_ModuleDependencyDef_table_t dependency_def) {
fprintf(stdout, "%s, version >= %d, ",
iree_vm_ModuleDependencyDef_name(dependency_def),
iree_vm_ModuleDependencyDef_minimum_version(dependency_def));
if (iree_vm_ModuleDependencyDef_flags(dependency_def) &
iree_vm_ModuleDependencyFlagBits_OPTIONAL) {
fprintf(stdout, "optional");
} else {
fprintf(stdout, "required");
}
}
static void iree_tooling_print_module_dependency_defs(
iree_vm_ModuleDependencyDef_vec_t dependency_defs, int indent) {
for (size_t i = 0; i < iree_vm_ModuleDependencyDef_vec_len(dependency_defs);
++i) {
iree_tooling_print_indent(indent);
iree_tooling_print_module_dependency_def(
iree_vm_ModuleDependencyDef_vec_at(dependency_defs, i));
fprintf(stdout, "\n");
}
}
static iree_status_t iree_tooling_print_cconv_fragment(
iree_string_view_t cconv_fragment) {
for (iree_host_size_t i = 0; i < cconv_fragment.size; ++i) {
if (i > 0) fprintf(stdout, ", ");
switch (cconv_fragment.data[i]) {
case IREE_VM_CCONV_TYPE_VOID:
break;
case IREE_VM_CCONV_TYPE_I32:
fprintf(stdout, "i32");
break;
case IREE_VM_CCONV_TYPE_F32:
fprintf(stdout, "f32");
break;
case IREE_VM_CCONV_TYPE_I64:
fprintf(stdout, "i64");
break;
case IREE_VM_CCONV_TYPE_F64:
fprintf(stdout, "f64");
break;
case IREE_VM_CCONV_TYPE_REF:
fprintf(stdout, "!vm.ref<?>");
break;
case IREE_VM_CCONV_TYPE_SPAN_START: {
iree_host_size_t end_pos = iree_string_view_find_char(
cconv_fragment, IREE_VM_CCONV_TYPE_SPAN_END, i + 1);
if (end_pos == IREE_STRING_VIEW_NPOS) {
return iree_make_status(IREE_STATUS_FAILED_PRECONDITION,
"unterminated cconv span");
}
fprintf(stdout, "tuple<");
IREE_RETURN_IF_ERROR(iree_tooling_print_cconv_fragment(
iree_string_view_substr(cconv_fragment, i + 1, end_pos - i - 1)));
fprintf(stdout, ">...");
i = end_pos; // +1 from the for-loop
} break;
default:
return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
"unsupported cconv type '%c'",
cconv_fragment.data[i]);
}
}
return iree_ok_status();
}
static void iree_tooling_print_function_cconv(flatbuffers_string_t cconv) {
iree_vm_function_signature_t signature = {
.calling_convention = iree_make_cstring_view(cconv),
};
iree_string_view_t arguments, results;
IREE_CHECK_OK(iree_vm_function_call_get_cconv_fragments(
&signature, &arguments, &results));
fprintf(stdout, "(");
IREE_CHECK_OK(iree_tooling_print_cconv_fragment(arguments));
fprintf(stdout, ") -> (");
IREE_CHECK_OK(iree_tooling_print_cconv_fragment(results));
fprintf(stdout, ")");
}
static void iree_tooling_print_imported_function_def(
iree_vm_ImportFunctionDef_table_t function_def, int indent) {
if (iree_vm_ImportFunctionDef_flags(function_def) &
iree_vm_ImportFlagBits_OPTIONAL) {
fprintf(stdout, "?");
}
fprintf(stdout, "%s", iree_vm_ImportFunctionDef_full_name(function_def));
iree_vm_FunctionSignatureDef_table_t signature_def =
iree_vm_ImportFunctionDef_signature(function_def);
if (iree_vm_FunctionSignatureDef_calling_convention_is_present(
signature_def)) {
iree_tooling_print_function_cconv(
iree_vm_FunctionSignatureDef_calling_convention(signature_def));
}
fprintf(stdout, "\n");
if (iree_vm_FunctionSignatureDef_attrs_is_present(signature_def)) {
iree_tooling_print_attr_defs(
iree_vm_FunctionSignatureDef_attrs(signature_def), indent);
}
}
static void iree_tooling_print_imported_function_defs(
iree_vm_ImportFunctionDef_vec_t function_defs, int indent) {
for (size_t i = 0; i < iree_vm_ImportFunctionDef_vec_len(function_defs);
++i) {
iree_tooling_print_indent(indent);
fprintf(stdout, "[%3zu] ", i);
iree_tooling_print_imported_function_def(
iree_vm_ImportFunctionDef_vec_at(function_defs, i), indent + 6);
}
}
static void iree_tooling_print_exported_function_def(
iree_vm_ExportFunctionDef_table_t function_def,
iree_vm_FunctionSignatureDef_vec_t function_signature_defs) {
fprintf(stdout, "%s", iree_vm_ExportFunctionDef_local_name(function_def));
iree_vm_FunctionSignatureDef_table_t signature_def =
iree_vm_FunctionSignatureDef_vec_at(
function_signature_defs,
iree_vm_ExportFunctionDef_internal_ordinal(function_def));
if (iree_vm_FunctionSignatureDef_calling_convention_is_present(
signature_def)) {
iree_tooling_print_function_cconv(
iree_vm_FunctionSignatureDef_calling_convention(signature_def));
}
fprintf(stdout, "\n");
if (iree_vm_FunctionSignatureDef_attrs_is_present(signature_def)) {
iree_tooling_print_attr_defs(
iree_vm_FunctionSignatureDef_attrs(signature_def), 8);
}
}
static void iree_tooling_print_exported_function_defs(
iree_vm_ExportFunctionDef_vec_t function_defs,
iree_vm_FunctionSignatureDef_vec_t function_signature_defs, int indent) {
for (size_t i = 0; i < iree_vm_ExportFunctionDef_vec_len(function_defs);
++i) {
iree_tooling_print_indent(indent);
fprintf(stdout, "[%3zu] ", i);
iree_tooling_print_exported_function_def(
iree_vm_ExportFunctionDef_vec_at(function_defs, i),
function_signature_defs);
}
}
static size_t iree_tooling_calculate_external_rodata_size(
iree_vm_RodataSegmentDef_vec_t segment_defs) {
size_t total_size = 0;
for (size_t i = 0; i < iree_vm_RodataSegmentDef_vec_len(segment_defs); ++i) {
iree_vm_RodataSegmentDef_table_t segment_def =
iree_vm_RodataSegmentDef_vec_at(segment_defs, i);
if (!iree_vm_RodataSegmentDef_embedded_data_is_present(segment_def)) {
total_size += iree_vm_RodataSegmentDef_external_data_length(segment_def);
}
}
return total_size;
}
// Returns true if |data| is likely a string. The string may not have a NUL
// terminator and the length is returned in |out_length|. Note that string
// tables may have NUL terminators and this will only return the first string.
static bool iree_tooling_data_is_string(flatbuffers_uint8_vec_t data,
size_t* out_length) {
*out_length = 0;
size_t length = flatbuffers_uint8_vec_scan(data, 0);
if (length == flatbuffers_not_found) {
length = flatbuffers_uint8_vec_len(data);
}
for (size_t i = 0; i < length; ++i) {
char c = flatbuffers_uint8_vec_at(data, i);
if (!isprint(c)) return false;
}
*out_length = length;
return true;
}
static void iree_tooling_print_rodata_segment_defs(
iree_vm_RodataSegmentDef_vec_t segment_defs, int indent) {
for (size_t i = 0; i < iree_vm_RodataSegmentDef_vec_len(segment_defs); ++i) {
iree_tooling_print_indent(indent);
iree_vm_RodataSegmentDef_table_t segment_def =
iree_vm_RodataSegmentDef_vec_at(segment_defs, i);
fprintf(stdout, ".rodata[%3zu] ", i);
switch (iree_vm_RodataSegmentDef_compression_type_type(segment_def)) {
case iree_vm_CompressionTypeDef_UncompressedDataDef:
fprintf(stdout, "uncompressed ");
break;
default:
break;
}
if (iree_vm_RodataSegmentDef_embedded_data_is_present(segment_def)) {
flatbuffers_uint8_vec_t data =
iree_vm_RodataSegmentDef_embedded_data(segment_def);
fprintf(stdout, "embedded %8zu bytes", flatbuffers_uint8_vec_len(data));
size_t string_length = 0;
if (iree_tooling_data_is_string(data, &string_length)) {
static const size_t MAX_LENGTH = 32;
fprintf(stdout, " `%.*s`", (int)iree_min(MAX_LENGTH, string_length),
(const char*)data);
if (string_length >= MAX_LENGTH) fprintf(stdout, "...");
}
} else {
fprintf(stdout,
"external %8" PRIu64 " bytes (offset %" PRIu64 " / %" PRIX64
"h to %" PRIX64 "h)",
iree_vm_RodataSegmentDef_external_data_length(segment_def),
iree_vm_RodataSegmentDef_external_data_offset(segment_def),
iree_vm_RodataSegmentDef_external_data_offset(segment_def),
iree_vm_RodataSegmentDef_external_data_offset(segment_def) +
iree_vm_RodataSegmentDef_external_data_length(segment_def));
}
fprintf(stdout, "\n");
}
}
static void iree_tooling_print_rwdata_segment_defs(
iree_vm_RwdataSegmentDef_vec_t segment_defs, int indent) {
for (size_t i = 0; i < iree_vm_RwdataSegmentDef_vec_len(segment_defs); ++i) {
iree_tooling_print_indent(indent);
iree_vm_RwdataSegmentDef_table_t segment_def =
iree_vm_RwdataSegmentDef_vec_at(segment_defs, i);
fprintf(stdout, ".rwdata[%3zu] %d bytes\n", i,
iree_vm_RwdataSegmentDef_byte_size(segment_def));
}
}
static void iree_tooling_print_function_descriptors(
iree_vm_FunctionDescriptor_vec_t descriptors,
iree_vm_ExportFunctionDef_vec_t export_defs) {
fprintf(stdout,
" # | Offset | Length | Blocks | i32 # | ref # | Requirements | "
"Aliases\n");
fprintf(stdout,
"----+----------+----------+--------+-------+-------+--------------+-"
"----------------------------------------------------\n");
for (size_t i = 0; i < iree_vm_FunctionDescriptor_vec_len(descriptors); ++i) {
iree_vm_FunctionDescriptor_struct_t descriptor =
iree_vm_FunctionDescriptor_vec_at(descriptors, i);
fprintf(stdout, "%3zu | %08X | %8d | %6d | %5d | %5d | ", i,
iree_vm_FunctionDescriptor_bytecode_offset(descriptor),
iree_vm_FunctionDescriptor_bytecode_length(descriptor),
iree_vm_FunctionDescriptor_block_count(descriptor),
iree_vm_FunctionDescriptor_i32_register_count(descriptor),
iree_vm_FunctionDescriptor_ref_register_count(descriptor));
size_t pos = iree_tooling_print_feature_bits(
iree_vm_FunctionDescriptor_requirements(descriptor));
if (pos < 12) iree_tooling_print_indent(12 - pos);
fprintf(stdout, " | ");
bool any_aliases = false;
for (size_t j = 0; j < iree_vm_ExportFunctionDef_vec_len(export_defs);
++j) {
iree_vm_ExportFunctionDef_table_t export_def =
iree_vm_ExportFunctionDef_vec_at(export_defs, j);
if (iree_vm_ExportFunctionDef_internal_ordinal(export_def) == i) {
if (any_aliases) fprintf(stdout, ", ");
fprintf(stdout, "%s", iree_vm_ExportFunctionDef_local_name(export_def));
any_aliases = true;
}
}
fprintf(stdout, "\n");
}
}
static iree_status_t iree_tooling_dump_module_metadata(
iree_const_byte_span_t flatbuffer_contents,
iree_const_byte_span_t rodata_contents) {
iree_vm_BytecodeModuleDef_table_t module_def =
iree_vm_BytecodeModuleDef_as_root(flatbuffer_contents.data);
iree_tooling_printf_section_header(
"@%s : version %d", iree_vm_BytecodeModuleDef_name(module_def),
iree_vm_BytecodeModuleDef_version(module_def));
fprintf(stdout, "\n");
if (iree_vm_BytecodeModuleDef_requirements_is_present(module_def)) {
fprintf(stdout, "Requirements: ");
iree_tooling_print_feature_bits(
iree_vm_BytecodeModuleDef_requirements(module_def));
fprintf(stdout, "\n\n");
}
if (iree_vm_BytecodeModuleDef_attrs_is_present(module_def)) {
fprintf(stdout, "Attributes:\n");
iree_tooling_print_attr_defs(iree_vm_BytecodeModuleDef_attrs(module_def),
2);
fprintf(stdout, "\n");
}
if (iree_vm_BytecodeModuleDef_types_is_present(module_def)) {
fprintf(stdout, "Required Types:\n");
iree_tooling_print_type_defs(iree_vm_BytecodeModuleDef_types(module_def),
2);
fprintf(stdout, "\n");
}
if (iree_vm_BytecodeModuleDef_dependencies_is_present(module_def)) {
fprintf(stdout, "Module Dependencies:\n");
iree_tooling_print_module_dependency_defs(
iree_vm_BytecodeModuleDef_dependencies(module_def), 2);
fprintf(stdout, "\n");
}
if (iree_vm_BytecodeModuleDef_imported_functions_is_present(module_def)) {
fprintf(stdout, "Imported Functions:\n");
iree_tooling_print_imported_function_defs(
iree_vm_BytecodeModuleDef_imported_functions(module_def), 2);
fprintf(stdout, "\n");
}
if (iree_vm_BytecodeModuleDef_exported_functions_is_present(module_def)) {
fprintf(stdout, "Exported Functions:\n");
iree_tooling_print_exported_function_defs(
iree_vm_BytecodeModuleDef_exported_functions(module_def),
iree_vm_BytecodeModuleDef_function_signatures(module_def), 2);
fprintf(stdout, "\n");
}
iree_tooling_printf_section_header("Sections");
fprintf(stdout, "\n");
if (iree_vm_BytecodeModuleDef_module_state_is_present(module_def)) {
iree_vm_ModuleStateDef_table_t module_state_def =
iree_vm_BytecodeModuleDef_module_state(module_def);
fprintf(stdout, "Module State:\n");
fprintf(stdout, " %d bytes, %d refs, ~%zu bytes total\n",
iree_vm_ModuleStateDef_global_bytes_capacity(module_state_def),
iree_vm_ModuleStateDef_global_ref_count(module_state_def),
iree_vm_ModuleStateDef_global_bytes_capacity(module_state_def) +
sizeof(iree_vm_ref_t) *
iree_vm_ModuleStateDef_global_ref_count(module_state_def));
fprintf(stdout, "\n");
}
fprintf(stdout, "FlatBuffer: %" PRIhsz " bytes\n",
flatbuffer_contents.data_length);
if (iree_vm_BytecodeModuleDef_bytecode_data_is_present(module_def)) {
flatbuffers_uint8_vec_t bytecode_data =
iree_vm_BytecodeModuleDef_bytecode_data(module_def);
fprintf(stdout, " Bytecode: %zu bytes\n",
flatbuffers_uint8_vec_len(bytecode_data));
}
if (iree_vm_BytecodeModuleDef_rodata_segments_is_present(module_def)) {
iree_tooling_print_rodata_segment_defs(
iree_vm_BytecodeModuleDef_rodata_segments(module_def), 2);
}
if (iree_vm_BytecodeModuleDef_rwdata_segments_is_present(module_def)) {
iree_tooling_print_rwdata_segment_defs(
iree_vm_BytecodeModuleDef_rwdata_segments(module_def), 2);
}
fprintf(stdout, "\n");
size_t external_size = iree_tooling_calculate_external_rodata_size(
iree_vm_BytecodeModuleDef_rodata_segments(module_def));
if (external_size > 0) {
fprintf(stdout, "External .rodata: ~%zu bytes\n\n", external_size);
}
iree_tooling_printf_section_header(
"Bytecode : version %d", iree_vm_BytecodeModuleDef_version(module_def));
fprintf(stdout, "\n");
if (iree_vm_BytecodeModuleDef_function_descriptors_is_present(module_def)) {
iree_tooling_print_function_descriptors(
iree_vm_BytecodeModuleDef_function_descriptors(module_def),
iree_vm_BytecodeModuleDef_exported_functions(module_def));
}
fprintf(stdout, "\n");
if (iree_vm_BytecodeModuleDef_debug_database_is_present(module_def)) {
iree_tooling_printf_section_header("Debug Information");
iree_vm_DebugDatabaseDef_table_t database_def =
iree_vm_BytecodeModuleDef_debug_database(module_def);
fprintf(stdout,
"// NOTE: debug databases are large and should be stripped in "
"deployed artifacts.\n");
fprintf(stdout, "\n");
// TODO(benvanik): some kind of informative output; for now just counts to
// indicate how much is present (would be nice to calculate full sizing).
fprintf(stdout, "Locations: %zu\n",
flatbuffers_generic_vec_len(
iree_vm_DebugDatabaseDef_location_table(database_def)));
fprintf(stdout, "\n");
}
return iree_ok_status();
}
//===----------------------------------------------------------------------===//
// --output=flatbuffer-binary
//===----------------------------------------------------------------------===//
static iree_status_t iree_tooling_dump_module_flatbuffer_binary(
iree_const_byte_span_t flatbuffer_contents) {
IREE_SET_BINARY_MODE(stdout); // ensure binary output mode
fwrite(flatbuffer_contents.data, 1, flatbuffer_contents.data_length, stdout);
return iree_ok_status();
}
//===----------------------------------------------------------------------===//
// --output=flatbuffer-json
//===----------------------------------------------------------------------===//
IREE_FLAG(bool, flatbuffer_pretty, false, "Pretty print flatbuffer JSON.");
static iree_status_t iree_tooling_dump_module_flatbuffer_json(
iree_const_byte_span_t flatbuffer_contents) {
flatcc_json_printer_t printer;
flatcc_json_printer_init(&printer, NULL);
if (FLAG_flatbuffer_pretty) {
flatcc_json_printer_set_flags(&printer, flatcc_json_printer_f_pretty);
}
flatcc_json_printer_set_skip_default(&printer, true);
bytecode_module_def_print_json(&printer,
(const char*)flatbuffer_contents.data,
flatbuffer_contents.data_length);
flatcc_json_printer_flush(&printer);
flatcc_json_printer_clear(&printer);
return iree_ok_status();
}
//===----------------------------------------------------------------------===//
// main
//===----------------------------------------------------------------------===//
IREE_FLAG(string, output, "metadata",
"Output mode:\n"
" 'metadata': module metadata and size breakdown.\n"
" 'flatbuffer-binary': module flatbuffer in binary format.\n"
" 'flatbuffer-json': module flatbuffer in JSON format.\n");
int main(int argc, char** argv) {
IREE_TRACE_APP_ENTER();
iree_allocator_t host_allocator = iree_allocator_system();
int exit_code = EXIT_SUCCESS;
// Parse command line flags.
iree_flags_set_usage("iree-dump-module",
"Dumps IREE VM module details to stdout.\n"
"$ iree-dump-module [--output=...] module.vmfb\n");
iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_DEFAULT, &argc, &argv);
if (argc < 2) {
fprintf(stderr, "Syntax: iree-dump-module [--output=...] module.vmfb\n");
IREE_TRACE_APP_EXIT(EXIT_FAILURE);
return EXIT_FAILURE;
}
iree_file_contents_t* file_contents = NULL;
iree_status_t status = iree_file_read_contents(
argv[1], IREE_FILE_READ_FLAG_DEFAULT, host_allocator, &file_contents);
iree_const_byte_span_t flatbuffer_contents = iree_const_byte_span_empty();
iree_const_byte_span_t rodata_contents = iree_const_byte_span_empty();
if (iree_status_is_ok(status)) {
iree_host_size_t rodata_offset = 0;
status = iree_vm_bytecode_archive_parse_header(
file_contents->const_buffer, &flatbuffer_contents, &rodata_offset);
rodata_contents = iree_make_const_byte_span(
file_contents->const_buffer.data + rodata_offset,
file_contents->const_buffer.data_length - rodata_offset);
}
if (iree_status_is_ok(status)) {
int verify_ret = iree_vm_BytecodeModuleDef_verify_as_root(
flatbuffer_contents.data, flatbuffer_contents.data_length);
if (verify_ret != flatcc_verify_ok) {
status = iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
"FlatBuffer verification failed: %s",
flatcc_verify_error_string(verify_ret));
}
}
if (iree_status_is_ok(status)) {
if (strcmp(FLAG_output, "metadata") == 0) {
status = iree_tooling_dump_module_metadata(flatbuffer_contents,
rodata_contents);
} else if (strcmp(FLAG_output, "flatbuffer-binary") == 0) {
status = iree_tooling_dump_module_flatbuffer_binary(flatbuffer_contents);
} else if (strcmp(FLAG_output, "flatbuffer-json") == 0) {
status = iree_tooling_dump_module_flatbuffer_json(flatbuffer_contents);
} else {
status = iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
"unrecognized --output= flag value '%s'",
FLAG_output);
}
}
iree_file_contents_free(file_contents);
fflush(stdout);
if (!iree_status_is_ok(status)) {
iree_status_fprint(stderr, status);
iree_status_free(status);
exit_code = EXIT_FAILURE;
}
fflush(stderr);
IREE_TRACE_APP_EXIT(exit_code);
return exit_code;
}