Skip to content

Commit

Permalink
HostInterface: Don't pass host::info pointer across hostfxr/hostpolicy.
Browse files Browse the repository at this point in the history
Host::info* is not POD, so pass the bundle-header offset instead.
The deps-json and runtime-config json locations are recomputed in hostpolicy.
Since hostpolicy needs to re-map the bundle, recomputing these locations is not expensive than passing them through the interface.
This also keeps the host_interface cleaner.
  • Loading branch information
swaroop-sridhar committed Apr 7, 2020
1 parent 3268b29 commit 7d2c74e
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 64 deletions.
4 changes: 1 addition & 3 deletions src/installer/corehost/cli/bundle/header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ header_t header_t::read(reader_t& reader)
header_t header(fixed_header->num_embedded_files);

// bundle_id is a component of the extraction path
size_t bundle_id_size = reader.read_path_string(header.m_bundle_id);
reader.read_path_string(header.m_bundle_id);

const header_fixed_v2_t *v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
header.m_v2_header = *v2_header;

header.m_header_size = sizeof(header_fixed_t) + bundle_id_size + sizeof(header_fixed_v2_t);

return header;
}
4 changes: 0 additions & 4 deletions src/installer/corehost/cli/bundle/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ namespace bundle
: m_num_embedded_files(num_embedded_files)
, m_bundle_id()
, m_v2_header()
, m_header_size(0)
{
}

Expand All @@ -89,16 +88,13 @@ namespace bundle
const location_t& runtimeconfig_json_location() const { return m_v2_header.runtimeconfig_json_location; }
bool is_netcoreapp3_compat_mode() const { return m_v2_header.is_netcoreapp3_compat_mode(); }

size_t size() const { return m_header_size; }

static const uint32_t major_version = 2;
static const uint32_t minor_version = 0;

private:
int32_t m_num_embedded_files;
pal::string_t m_bundle_id;
header_fixed_v2_t m_v2_header;
size_t m_header_size;
};
}
#endif // __HEADER_H__
43 changes: 23 additions & 20 deletions src/installer/corehost/cli/bundle/info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ using namespace bundle;
// Global single-file bundle information, if any
const info_t* info_t::the_app = nullptr;

info_t::info_t(const pal::char_t* bundle_path,
const pal::char_t* app_path,
int64_t header_offset)
: m_bundle_path(bundle_path)
, m_bundle_size(0)
, m_header_offset(header_offset)
{
m_base_path = get_directory(m_bundle_path);

// Single-file bundles currently only support deps/runtime config json files
// named based on the app.dll. Any other name for these configuration files
// mentioned via the command line are assumed to be actual files on disk.
//
// Supporting custom names for these config files is straightforward (with associated changes in bundler and SDK).
// There is no known use-case for it yet, and the facility is TBD.

m_deps_json = config_t(get_deps_from_app_binary(m_base_path, app_path));
m_runtimeconfig_json = config_t(get_runtime_config_path(m_base_path, get_filename_without_ext(app_path)));
}

StatusCode info_t::process_bundle(const pal::char_t* bundle_path, const pal::char_t* app_path, int64_t header_offset)
{
if (header_offset == 0)
Expand All @@ -19,16 +39,14 @@ StatusCode info_t::process_bundle(const pal::char_t* bundle_path, const pal::cha
return StatusCode::Success;
}

static info_t info(bundle_path, header_offset);
static info_t info(bundle_path, app_path, header_offset);
StatusCode status = info.process_header();

if (status != StatusCode::Success)
{
return status;
}

info.init_config(app_path);

trace::info(_X("Single-File bundle details:"));
trace::info(_X("DepsJson Offset:[%lx] Size[%lx]"), info.m_header.deps_json_location().offset, info.m_header.deps_json_location().size);
trace::info(_X("RuntimeConfigJson Offset:[%lx] Size[%lx]"), info.m_header.runtimeconfig_json_location().offset, info.m_header.runtimeconfig_json_location().size);
Expand All @@ -48,6 +66,8 @@ StatusCode info_t::process_header()
reader_t reader(addr, m_bundle_size, m_header_offset);

m_header = header_t::read(reader);
m_deps_json.set_location(&m_header.deps_json_location());
m_runtimeconfig_json.set_location(&m_header.runtimeconfig_json_location());

unmap_bundle(addr);

Expand All @@ -59,23 +79,6 @@ StatusCode info_t::process_header()
}
}

void info_t::init_config(const pal::string_t& app_path)
{
// Single-file bundles currently only support deps/runtime config json files
// named based on the app.dll. Any other name for these configuration files
// mentioned via the command line are assumed to be actual files on disk.
//
// Supporting custom names for these config files is straightforward (with associated changes in bundler and SDK).
// There is no known use-case for it yet, and the facility is TBD.

m_base_path = get_directory(m_bundle_path);
pal::string_t deps_json_name = get_deps_from_app_binary(m_base_path, app_path);
pal::string_t runtimeconfig_json_name = get_runtime_config_path(m_base_path, get_filename_without_ext(app_path));

m_deps_json = config_t(deps_json_name, &m_header.deps_json_location());
m_runtimeconfig_json = config_t(runtimeconfig_json_name, &m_header.runtimeconfig_json_location());
}

int8_t* info_t::config_t::map(const pal::string_t& path, const location_t* &location)
{
assert(is_single_file_bundle());
Expand Down
30 changes: 10 additions & 20 deletions src/installer/corehost/cli/bundle/info.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace bundle
m_location = config.m_location;
}

config_t(const pal::string_t& path, const location_t *location)
config_t(const pal::string_t& path, const location_t *location=nullptr)
{
m_path = path;
m_location = location;
Expand All @@ -45,6 +45,11 @@ namespace bundle
(the_app->m_deps_json.matches(path) || the_app->m_runtimeconfig_json.matches(path));
}

void set_location(const location_t* location)
{
m_location = location;
}

static int8_t* map(const pal::string_t& path, const location_t* &location);
static void unmap(const int8_t* addr, const location_t* location);

Expand All @@ -58,29 +63,15 @@ namespace bundle

bool is_netcoreapp3_compat_mode() const { return m_header.is_netcoreapp3_compat_mode(); }
const pal::string_t& base_path() const { return m_base_path; }
int64_t header_offset() const { return m_header_offset; }

// Global single-file info object
static const info_t* the_app;

protected:
info_t(const pal::char_t* bundle_path_value,
int64_t header_offset_value)
: m_bundle_path(bundle_path_value)
, m_bundle_size(0)
, m_header_offset(header_offset_value)
, m_deps_json()
, m_runtimeconfig_json() {}

info_t(const info_t* info)
{
m_bundle_path = info->m_bundle_path;
m_base_path = info->m_base_path;
m_bundle_size = info->m_bundle_size;
m_header_offset = info->m_header_offset;
m_header = info->m_header;
m_deps_json = info->m_deps_json;
m_runtimeconfig_json = info->m_runtimeconfig_json;
}
info_t(const pal::char_t* bundle_path,
const pal::char_t* app_path,
int64_t header_offset);

const int8_t* map_bundle();
void unmap_bundle(const int8_t* addr) const;
Expand All @@ -94,7 +85,6 @@ namespace bundle
config_t m_runtimeconfig_json;

private:
void init_config(const pal::string_t& app_path);
StatusCode process_header();
};
}
Expand Down
9 changes: 7 additions & 2 deletions src/installer/corehost/cli/bundle/runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ StatusCode runner_t::extract()
{
const int8_t* addr = map_bundle();

// Set the Reader offset to read post the bundle header
reader_t reader(addr, m_bundle_size, m_header_offset + m_header.size());
// Set the Reader at header_offset
reader_t reader(addr, m_bundle_size, m_header_offset);

// Read the bundle header
m_header = header_t::read(reader);
m_deps_json.set_location(&m_header.deps_json_location());
m_runtimeconfig_json.set_location(&m_header.runtimeconfig_json_location());

// Read the bundle manifest
m_manifest = manifest_t::read(reader, m_header.num_embedded_files());
Expand Down
10 changes: 4 additions & 6 deletions src/installer/corehost/cli/bundle/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@ namespace bundle
class runner_t : public info_t
{
public:
runner_t(const pal::char_t* bundle_path_value,
int64_t header_offset_value)
: info_t(bundle_path_value, header_offset_value) {}

runner_t(const bundle::info_t* info)
: info_t(info) {}
runner_t(const pal::char_t* bundle_path,
const pal::char_t *app_path,
int64_t header_offset)
: info_t(bundle_path, app_path, header_offset) {}

const pal::string_t& extraction_path() const { return m_extraction_path; }

Expand Down
2 changes: 1 addition & 1 deletion src/installer/corehost/cli/fxr/corehost_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ const host_interface_t& corehost_init_t::get_host_init_data()
hi.host_info_dotnet_root = m_host_info_dotnet_root.c_str();
hi.host_info_app_path = m_host_info_app_path.c_str();

hi.app_bundle = bundle::info_t::the_app;
hi.single_file_bundle_header_offset = bundle::info_t::is_single_file_bundle() ? bundle::info_t::the_app->header_offset() : 0;

return hi;
}
Expand Down
1 change: 0 additions & 1 deletion src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <utils.h>

#include "json_parser.h"
#include "bundle/info.h"

namespace
{
Expand Down
4 changes: 2 additions & 2 deletions src/installer/corehost/cli/host_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct host_interface_t
const pal::char_t* host_info_host_path;
const pal::char_t* host_info_dotnet_root;
const pal::char_t* host_info_app_path;
const bundle::info_t *app_bundle;
size_t single_file_bundle_header_offset;
// !! WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING
// !! 1. Only append to this structure to maintain compat.
// !! 2. Any nested structs should not use compiler specific padding (pack with _HOST_INTERFACE_PACK)
Expand Down Expand Up @@ -93,7 +93,7 @@ static_assert(offsetof(host_interface_t, host_command) == 26 * sizeof(size_t), "
static_assert(offsetof(host_interface_t, host_info_host_path) == 27 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(offsetof(host_interface_t, host_info_dotnet_root) == 28 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(offsetof(host_interface_t, host_info_app_path) == 29 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(offsetof(host_interface_t, app_bundle) == 30 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(offsetof(host_interface_t, single_file_bundle_header_offset) == 30 * sizeof(size_t), "Struct offset breaks backwards compatibility");
static_assert(sizeof(host_interface_t) == 31 * sizeof(size_t), "Did you add static asserts for the newly added fields?");

#define HOST_INTERFACE_LAYOUT_VERSION_HI 0x16041101 // YYMMDD:nn always increases when layout breaks compat.
Expand Down
2 changes: 1 addition & 1 deletion src/installer/corehost/cli/hostpolicy/args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool set_root_from_app(const pal::string_t& managed_application_path,

if (pal::realpath(&args.managed_application))
{
args.app_root = get_directory(managed_application_path);
args.app_root = get_directory(args.managed_application);
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/installer/corehost/cli/hostpolicy/hostpolicy_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ bool hostpolicy_init_t::init(host_interface_t* input, hostpolicy_init_t* init)
// For the backwards compat case, this will be later initialized with argv[0]
}

if (input->version_lo >= offsetof(host_interface_t, app_bundle) + sizeof(input->app_bundle))
if (input->version_lo >= offsetof(host_interface_t, single_file_bundle_header_offset) + sizeof(input->single_file_bundle_header_offset))
{
if (input->app_bundle != nullptr)
if (input->single_file_bundle_header_offset != 0)
{
static bundle::runner_t bundle_runner(input->app_bundle);
static bundle::runner_t bundle_runner(input->host_info_host_path, input->host_info_app_path, input->single_file_bundle_header_offset);
bundle::info_t::the_app = &bundle_runner;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ SHARED_API int HOSTPOLICY_CALLTYPE corehost_load(host_interface_t* init)
std::cout << "mock host_info_host_path:" << tostr(init->host_info_host_path).data() << std::endl;
std::cout << "mock host_info_dotnet_root:" << tostr(init->host_info_dotnet_root).data() << std::endl;
std::cout << "mock host_info_app_path:" << tostr(init->host_info_app_path).data() << std::endl;
std::cout << "mock app_bundle:" << std::hex << init->app_bundle << std::endl;
std::cout << "mock single_file_bundle_header_offset:" << std::hex << init->single_file_bundle_header_offset << std::endl;

if (init->fx_names.len == 0)
{
Expand Down

0 comments on commit 7d2c74e

Please sign in to comment.