Add SID cache and read-first derivation
This commit is contained in:
parent
4932fbd21c
commit
c4571c3bfb
|
|
@ -57,6 +57,7 @@ set(AMDUAT_UTIL_SRCS
|
|||
src/internal/varint.c
|
||||
src/internal/endian.c
|
||||
src/internal/hex.c
|
||||
src/internal/log.c
|
||||
)
|
||||
|
||||
set(AMDUAT_ASL_SRCS
|
||||
|
|
@ -105,6 +106,7 @@ set(AMDUAT_FORMAT_SRCS
|
|||
|
||||
set(AMDUAT_PEL_SRCS
|
||||
src/kernel/pel/core.c
|
||||
src/core/derivation_sid.c
|
||||
src/pel_stack/decode.c
|
||||
src/pel_stack/surf/surf.c
|
||||
src/pel_stack/program_dag/program_dag.c
|
||||
|
|
@ -144,6 +146,10 @@ set(AMDUAT_ASL_DERIVATION_INDEX_FS_SRCS
|
|||
src/adapters/asl_derivation_index_fs/asl_derivation_index_fs.c
|
||||
)
|
||||
|
||||
set(AMDUAT_ASL_MATERIALIZATION_CACHE_FS_SRCS
|
||||
src/adapters/asl_materialization_cache_fs/asl_materialization_cache_fs.c
|
||||
)
|
||||
|
||||
set(AMDUAT_TGK_STORE_MEM_SRCS
|
||||
src/adapters/tgk_store_mem/tgk_store_mem.c
|
||||
)
|
||||
|
|
@ -171,7 +177,7 @@ amduat_add_lib(format SRCS ${AMDUAT_FORMAT_SRCS})
|
|||
amduat_link(format amduat_asl amduat_enc amduat_util)
|
||||
|
||||
amduat_add_lib(pel SRCS ${AMDUAT_PEL_SRCS})
|
||||
amduat_link(pel amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
|
||||
amduat_link(pel amduat_asl_materialization_cache_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
|
||||
|
||||
amduat_add_lib(tgk SRCS ${AMDUAT_TGK_SRCS})
|
||||
amduat_link(tgk amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
|
||||
|
|
@ -191,6 +197,10 @@ amduat_add_lib(asl_derivation_index_fs SRCS ${AMDUAT_ASL_DERIVATION_INDEX_FS_SRC
|
|||
amduat_link(asl_derivation_index_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
|
||||
target_compile_definitions(amduat_asl_derivation_index_fs_obj PRIVATE _POSIX_C_SOURCE=200809L)
|
||||
|
||||
amduat_add_lib(asl_materialization_cache_fs SRCS ${AMDUAT_ASL_MATERIALIZATION_CACHE_FS_SRCS})
|
||||
amduat_link(asl_materialization_cache_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
|
||||
target_compile_definitions(amduat_asl_materialization_cache_fs_obj PRIVATE _POSIX_C_SOURCE=200809L)
|
||||
|
||||
amduat_add_lib(tgk_store_mem SRCS ${AMDUAT_TGK_STORE_MEM_SRCS})
|
||||
amduat_link(tgk_store_mem amduat_tgk amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
|
||||
|
||||
|
|
|
|||
40
include/amduat/asl/asl_materialization_cache_fs.h
Normal file
40
include/amduat/asl/asl_materialization_cache_fs.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef AMDUAT_ASL_MATERIALIZATION_CACHE_FS_H
|
||||
#define AMDUAT_ASL_MATERIALIZATION_CACHE_FS_H
|
||||
|
||||
#include "amduat/asl/core.h"
|
||||
#include "amduat/asl/store.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { AMDUAT_ASL_MATERIALIZATION_CACHE_FS_ROOT_MAX = 1024 };
|
||||
|
||||
typedef struct {
|
||||
char root_path[AMDUAT_ASL_MATERIALIZATION_CACHE_FS_ROOT_MAX];
|
||||
} amduat_asl_materialization_cache_fs_t;
|
||||
|
||||
bool amduat_asl_materialization_cache_fs_init(
|
||||
amduat_asl_materialization_cache_fs_t *cache,
|
||||
const char *root_path);
|
||||
|
||||
amduat_asl_store_error_t amduat_asl_materialization_cache_fs_get(
|
||||
amduat_asl_materialization_cache_fs_t *cache,
|
||||
amduat_octets_t sid,
|
||||
amduat_reference_t **out_refs,
|
||||
size_t *out_refs_len);
|
||||
|
||||
amduat_asl_store_error_t amduat_asl_materialization_cache_fs_put(
|
||||
amduat_asl_materialization_cache_fs_t *cache,
|
||||
amduat_octets_t sid,
|
||||
const amduat_reference_t *refs,
|
||||
size_t refs_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* AMDUAT_ASL_MATERIALIZATION_CACHE_FS_H */
|
||||
31
include/amduat/pel/derivation_sid.h
Normal file
31
include/amduat/pel/derivation_sid.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef AMDUAT_PEL_DERIVATION_SID_H
|
||||
#define AMDUAT_PEL_DERIVATION_SID_H
|
||||
|
||||
#include "amduat/asl/core.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
amduat_reference_t program_ref;
|
||||
const amduat_reference_t *input_refs;
|
||||
size_t input_refs_len;
|
||||
bool has_params_ref;
|
||||
amduat_reference_t params_ref;
|
||||
bool has_exec_profile;
|
||||
amduat_octets_t exec_profile;
|
||||
} amduat_pel_derivation_sid_input_t;
|
||||
|
||||
bool amduat_pel_derivation_sid_compute(
|
||||
const amduat_pel_derivation_sid_input_t *in,
|
||||
amduat_octets_t *out_sid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* AMDUAT_PEL_DERIVATION_SID_H */
|
||||
23
include/amduat/util/log.h
Normal file
23
include/amduat/util/log.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef AMDUAT_UTIL_LOG_H
|
||||
#define AMDUAT_UTIL_LOG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
AMDUAT_LOG_ERROR = 0,
|
||||
AMDUAT_LOG_WARN = 1,
|
||||
AMDUAT_LOG_INFO = 2,
|
||||
AMDUAT_LOG_DEBUG = 3
|
||||
} amduat_log_level_t;
|
||||
|
||||
void amduat_log(amduat_log_level_t level, const char *fmt, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* AMDUAT_UTIL_LOG_H */
|
||||
|
|
@ -0,0 +1,716 @@
|
|||
#include "amduat/asl/asl_materialization_cache_fs.h"
|
||||
|
||||
#include "amduat/enc/asl1_core_codec.h"
|
||||
#include "amduat/util/log.h"
|
||||
#include "amduat/util/hex.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum {
|
||||
AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN = 8,
|
||||
AMDUAT_ASL_MATERIALIZATION_VERSION = 1
|
||||
};
|
||||
|
||||
static const uint8_t k_amduat_asl_materialization_magic[
|
||||
AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN] = {'A', 'S', 'L', 'M',
|
||||
'A', 'T', '1', '\0'};
|
||||
|
||||
enum {
|
||||
AMDUAT_ASL_MATERIALIZATION_FLAG_TIMESTAMP = 1u << 0,
|
||||
AMDUAT_ASL_MATERIALIZATION_FLAG_PEL_VERSION = 1u << 1
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *data;
|
||||
size_t len;
|
||||
size_t offset;
|
||||
} amduat_asl_materialization_cursor_t;
|
||||
|
||||
static void amduat_asl_materialization_store_u32_le(uint8_t *out,
|
||||
uint32_t value) {
|
||||
out[0] = (uint8_t)(value & 0xffu);
|
||||
out[1] = (uint8_t)((value >> 8) & 0xffu);
|
||||
out[2] = (uint8_t)((value >> 16) & 0xffu);
|
||||
out[3] = (uint8_t)((value >> 24) & 0xffu);
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_read_u32_le(
|
||||
amduat_asl_materialization_cursor_t *cur,
|
||||
uint32_t *out) {
|
||||
const uint8_t *data;
|
||||
|
||||
if (cur->len - cur->offset < 4u) {
|
||||
return false;
|
||||
}
|
||||
data = cur->data + cur->offset;
|
||||
*out = (uint32_t)data[0] | ((uint32_t)data[1] << 8) |
|
||||
((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24);
|
||||
cur->offset += 4u;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_read_u64_le(
|
||||
amduat_asl_materialization_cursor_t *cur,
|
||||
uint64_t *out) {
|
||||
const uint8_t *data;
|
||||
|
||||
if (cur->len - cur->offset < 8u) {
|
||||
return false;
|
||||
}
|
||||
data = cur->data + cur->offset;
|
||||
*out = (uint64_t)data[0] | ((uint64_t)data[1] << 8) |
|
||||
((uint64_t)data[2] << 16) | ((uint64_t)data[3] << 24) |
|
||||
((uint64_t)data[4] << 32) | ((uint64_t)data[5] << 40) |
|
||||
((uint64_t)data[6] << 48) | ((uint64_t)data[7] << 56);
|
||||
cur->offset += 8u;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_read_u16_le(
|
||||
amduat_asl_materialization_cursor_t *cur,
|
||||
uint16_t *out) {
|
||||
const uint8_t *data;
|
||||
|
||||
if (cur->len - cur->offset < 2u) {
|
||||
return false;
|
||||
}
|
||||
data = cur->data + cur->offset;
|
||||
*out = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
|
||||
cur->offset += 2u;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_read_u8(
|
||||
amduat_asl_materialization_cursor_t *cur,
|
||||
uint8_t *out) {
|
||||
if (cur->len - cur->offset < 1u) {
|
||||
return false;
|
||||
}
|
||||
*out = cur->data[cur->offset++];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_join_path(const char *base,
|
||||
const char *segment,
|
||||
char **out_path) {
|
||||
size_t base_len;
|
||||
size_t segment_len;
|
||||
bool needs_sep;
|
||||
size_t total_len;
|
||||
char *buffer;
|
||||
size_t offset;
|
||||
|
||||
if (base == NULL || segment == NULL || out_path == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (base[0] == '\0' || segment[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
base_len = strlen(base);
|
||||
segment_len = strlen(segment);
|
||||
needs_sep = base[base_len - 1u] != '/';
|
||||
total_len = base_len + (needs_sep ? 1u : 0u) + segment_len + 1u;
|
||||
|
||||
buffer = (char *)malloc(total_len);
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = 0u;
|
||||
memcpy(buffer + offset, base, base_len);
|
||||
offset += base_len;
|
||||
if (needs_sep) {
|
||||
buffer[offset++] = '/';
|
||||
}
|
||||
memcpy(buffer + offset, segment, segment_len);
|
||||
offset += segment_len;
|
||||
buffer[offset] = '\0';
|
||||
|
||||
*out_path = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_ensure_directory(const char *path) {
|
||||
struct stat st;
|
||||
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
if (stat(path, &st) == 0) {
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
if (errno != ENOENT) {
|
||||
return false;
|
||||
}
|
||||
if (mkdir(path, 0755) != 0) {
|
||||
if (errno == EEXIST) {
|
||||
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_hex_byte(uint8_t value, char out[3]) {
|
||||
static const char k_hex[] = "0123456789abcdef";
|
||||
out[0] = k_hex[value >> 4u];
|
||||
out[1] = k_hex[value & 0x0fu];
|
||||
out[2] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *amduat_asl_materialization_parent_dir(const char *path) {
|
||||
const char *slash;
|
||||
size_t len;
|
||||
char *dir;
|
||||
|
||||
if (path == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
slash = strrchr(path, '/');
|
||||
if (slash == NULL || slash == path) {
|
||||
return NULL;
|
||||
}
|
||||
len = (size_t)(slash - path);
|
||||
dir = (char *)malloc(len + 1u);
|
||||
if (dir == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(dir, path, len);
|
||||
dir[len] = '\0';
|
||||
return dir;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_fsync_directory(const char *path) {
|
||||
int fd;
|
||||
int flags = O_RDONLY;
|
||||
|
||||
if (path == NULL) {
|
||||
return false;
|
||||
}
|
||||
#ifdef O_DIRECTORY
|
||||
flags |= O_DIRECTORY;
|
||||
#endif
|
||||
fd = open(path, flags);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
if (fsync(fd) != 0) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
return close(fd) == 0;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_build_sid_path(
|
||||
const char *root_path,
|
||||
amduat_octets_t sid,
|
||||
bool ensure_dirs,
|
||||
char **out_path) {
|
||||
char *index_path = NULL;
|
||||
char *materializations_path = NULL;
|
||||
char *by_sid_path = NULL;
|
||||
char *prefix_a_path = NULL;
|
||||
char *prefix_b_path = NULL;
|
||||
char *sid_hex = NULL;
|
||||
char prefix_a[3];
|
||||
char prefix_b[3];
|
||||
bool ok = false;
|
||||
|
||||
if (root_path == NULL || out_path == NULL) {
|
||||
return false;
|
||||
}
|
||||
*out_path = NULL;
|
||||
|
||||
if (sid.len < 2u || sid.data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!amduat_hex_encode_alloc(sid.data, sid.len, &sid_hex)) {
|
||||
return false;
|
||||
}
|
||||
amduat_asl_materialization_hex_byte(sid.data[0], prefix_a);
|
||||
amduat_asl_materialization_hex_byte(sid.data[1], prefix_b);
|
||||
|
||||
if (!amduat_asl_materialization_join_path(root_path, "index", &index_path)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!amduat_asl_materialization_join_path(index_path, "materializations",
|
||||
&materializations_path)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!amduat_asl_materialization_join_path(materializations_path, "by_sid",
|
||||
&by_sid_path)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!amduat_asl_materialization_join_path(by_sid_path, prefix_a,
|
||||
&prefix_a_path)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!amduat_asl_materialization_join_path(prefix_a_path, prefix_b,
|
||||
&prefix_b_path)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!amduat_asl_materialization_join_path(prefix_b_path, sid_hex,
|
||||
out_path)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ensure_dirs) {
|
||||
if (!amduat_asl_materialization_ensure_directory(index_path) ||
|
||||
!amduat_asl_materialization_ensure_directory(materializations_path) ||
|
||||
!amduat_asl_materialization_ensure_directory(by_sid_path) ||
|
||||
!amduat_asl_materialization_ensure_directory(prefix_a_path) ||
|
||||
!amduat_asl_materialization_ensure_directory(prefix_b_path)) {
|
||||
free(*out_path);
|
||||
*out_path = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ok = true;
|
||||
|
||||
cleanup:
|
||||
free(index_path);
|
||||
free(materializations_path);
|
||||
free(by_sid_path);
|
||||
free(prefix_a_path);
|
||||
free(prefix_b_path);
|
||||
free(sid_hex);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool amduat_asl_materialization_cache_fs_init(
|
||||
amduat_asl_materialization_cache_fs_t *cache,
|
||||
const char *root_path) {
|
||||
size_t len;
|
||||
|
||||
if (cache == NULL || root_path == NULL) {
|
||||
return false;
|
||||
}
|
||||
len = strlen(root_path);
|
||||
if (len == 0u || len >= AMDUAT_ASL_MATERIALIZATION_CACHE_FS_ROOT_MAX) {
|
||||
return false;
|
||||
}
|
||||
memcpy(cache->root_path, root_path, len);
|
||||
cache->root_path[len] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
static amduat_asl_store_error_t amduat_asl_materialization_decode_refs(
|
||||
amduat_asl_materialization_cursor_t *cur,
|
||||
uint32_t count,
|
||||
amduat_reference_t **out_refs,
|
||||
size_t *out_refs_len) {
|
||||
amduat_reference_t *refs;
|
||||
uint32_t i;
|
||||
|
||||
if (out_refs == NULL || out_refs_len == NULL) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
*out_refs = NULL;
|
||||
*out_refs_len = 0u;
|
||||
|
||||
if (count == 0u) {
|
||||
return AMDUAT_ASL_STORE_OK;
|
||||
}
|
||||
if (count > SIZE_MAX / sizeof(*refs)) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
|
||||
refs = (amduat_reference_t *)calloc(count, sizeof(*refs));
|
||||
if (refs == NULL) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
for (i = 0u; i < count; ++i) {
|
||||
uint32_t ref_len;
|
||||
amduat_octets_t ref_bytes;
|
||||
|
||||
if (!amduat_asl_materialization_read_u32_le(cur, &ref_len)) {
|
||||
goto decode_error;
|
||||
}
|
||||
if (ref_len < 2u || cur->len - cur->offset < ref_len) {
|
||||
goto decode_error;
|
||||
}
|
||||
ref_bytes = amduat_octets(cur->data + cur->offset, ref_len);
|
||||
if (!amduat_enc_asl1_core_decode_reference_v1(ref_bytes, &refs[i])) {
|
||||
goto decode_error;
|
||||
}
|
||||
cur->offset += ref_len;
|
||||
}
|
||||
|
||||
*out_refs = refs;
|
||||
*out_refs_len = count;
|
||||
return AMDUAT_ASL_STORE_OK;
|
||||
|
||||
decode_error:
|
||||
for (uint32_t j = 0u; j < i; ++j) {
|
||||
amduat_reference_free(&refs[j]);
|
||||
}
|
||||
free(refs);
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
|
||||
static void amduat_asl_materialization_refs_free(amduat_reference_t *refs,
|
||||
size_t refs_len) {
|
||||
size_t i;
|
||||
|
||||
if (refs == NULL) {
|
||||
return;
|
||||
}
|
||||
for (i = 0u; i < refs_len; ++i) {
|
||||
amduat_reference_free(&refs[i]);
|
||||
}
|
||||
free(refs);
|
||||
}
|
||||
|
||||
amduat_asl_store_error_t amduat_asl_materialization_cache_fs_get(
|
||||
amduat_asl_materialization_cache_fs_t *cache,
|
||||
amduat_octets_t sid,
|
||||
amduat_reference_t **out_refs,
|
||||
size_t *out_refs_len) {
|
||||
char *path = NULL;
|
||||
FILE *fp = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
long file_size;
|
||||
amduat_asl_materialization_cursor_t cur;
|
||||
uint8_t flags;
|
||||
uint32_t version;
|
||||
uint32_t sid_len;
|
||||
uint32_t output_count;
|
||||
amduat_asl_store_error_t err = AMDUAT_ASL_STORE_ERR_NOT_FOUND;
|
||||
|
||||
if (out_refs == NULL || out_refs_len == NULL) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
*out_refs = NULL;
|
||||
*out_refs_len = 0u;
|
||||
|
||||
if (cache == NULL || sid.len == 0u || sid.data == NULL) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
|
||||
if (!amduat_asl_materialization_build_sid_path(cache->root_path, sid, false,
|
||||
&path)) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL) {
|
||||
free(path);
|
||||
return errno == ENOENT ? AMDUAT_ASL_STORE_ERR_NOT_FOUND
|
||||
: AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||
fclose(fp);
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
file_size = ftell(fp);
|
||||
if (file_size < 0) {
|
||||
fclose(fp);
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_SET) != 0) {
|
||||
fclose(fp);
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
buffer = (uint8_t *)malloc((size_t)file_size);
|
||||
if (buffer == NULL) {
|
||||
fclose(fp);
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (fread(buffer, 1u, (size_t)file_size, fp) != (size_t)file_size) {
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
fclose(fp);
|
||||
free(path);
|
||||
|
||||
cur.data = buffer;
|
||||
cur.len = (size_t)file_size;
|
||||
cur.offset = 0u;
|
||||
|
||||
if (cur.len < AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN + 4u) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
if (memcmp(cur.data, k_amduat_asl_materialization_magic,
|
||||
AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN) != 0) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
cur.offset += AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN;
|
||||
if (!amduat_asl_materialization_read_u32_le(&cur, &version) ||
|
||||
version != AMDUAT_ASL_MATERIALIZATION_VERSION) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!amduat_asl_materialization_read_u32_le(&cur, &sid_len)) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
if (sid_len != sid.len || cur.len - cur.offset < sid_len) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
if (memcmp(cur.data + cur.offset, sid.data, sid.len) != 0) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
cur.offset += sid_len;
|
||||
if (!amduat_asl_materialization_read_u32_le(&cur, &output_count)) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
err = amduat_asl_materialization_decode_refs(&cur, output_count, out_refs,
|
||||
out_refs_len);
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!amduat_asl_materialization_read_u8(&cur, &flags)) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
if (flags & AMDUAT_ASL_MATERIALIZATION_FLAG_TIMESTAMP) {
|
||||
uint64_t ignored;
|
||||
if (!amduat_asl_materialization_read_u64_le(&cur, &ignored)) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (flags & AMDUAT_ASL_MATERIALIZATION_FLAG_PEL_VERSION) {
|
||||
uint16_t ignored;
|
||||
if (!amduat_asl_materialization_read_u16_le(&cur, &ignored)) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur.offset != cur.len) {
|
||||
err = AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
err = AMDUAT_ASL_STORE_OK;
|
||||
|
||||
cleanup:
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
amduat_asl_materialization_refs_free(*out_refs, *out_refs_len);
|
||||
*out_refs = NULL;
|
||||
*out_refs_len = 0u;
|
||||
}
|
||||
free(buffer);
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool amduat_asl_materialization_refs_equal(
|
||||
const amduat_reference_t *a,
|
||||
size_t a_len,
|
||||
const amduat_reference_t *b,
|
||||
size_t b_len) {
|
||||
size_t i;
|
||||
|
||||
if (a_len != b_len) {
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < a_len; ++i) {
|
||||
if (!amduat_reference_eq(a[i], b[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static amduat_asl_store_error_t amduat_asl_materialization_write_record(
|
||||
FILE *fp,
|
||||
amduat_octets_t sid,
|
||||
const amduat_reference_t *refs,
|
||||
size_t refs_len) {
|
||||
uint8_t header[AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN + 4u];
|
||||
uint8_t flags = 0u;
|
||||
uint32_t count_u32;
|
||||
size_t i;
|
||||
|
||||
if (sid.len > UINT32_MAX || refs_len > UINT32_MAX) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
|
||||
memcpy(header, k_amduat_asl_materialization_magic,
|
||||
AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN);
|
||||
amduat_asl_materialization_store_u32_le(
|
||||
header + AMDUAT_ASL_MATERIALIZATION_MAGIC_LEN,
|
||||
AMDUAT_ASL_MATERIALIZATION_VERSION);
|
||||
if (fwrite(header, 1u, sizeof(header), fp) != sizeof(header)) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
amduat_asl_materialization_store_u32_le(header, (uint32_t)sid.len);
|
||||
if (fwrite(header, 1u, 4u, fp) != 4u) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (sid.len != 0u &&
|
||||
fwrite(sid.data, 1u, sid.len, fp) != sid.len) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
count_u32 = (uint32_t)refs_len;
|
||||
amduat_asl_materialization_store_u32_le(header, count_u32);
|
||||
if (fwrite(header, 1u, 4u, fp) != 4u) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
for (i = 0u; i < refs_len; ++i) {
|
||||
amduat_octets_t ref_bytes = amduat_octets(NULL, 0u);
|
||||
uint8_t len_buf[4u];
|
||||
if (!amduat_enc_asl1_core_encode_reference_v1(refs[i], &ref_bytes)) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
amduat_asl_materialization_store_u32_le(len_buf,
|
||||
(uint32_t)ref_bytes.len);
|
||||
if (fwrite(len_buf, 1u, 4u, fp) != 4u ||
|
||||
(ref_bytes.len != 0u &&
|
||||
fwrite(ref_bytes.data, 1u, ref_bytes.len, fp) != ref_bytes.len)) {
|
||||
free((void *)ref_bytes.data);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
free((void *)ref_bytes.data);
|
||||
}
|
||||
|
||||
if (fwrite(&flags, 1u, 1u, fp) != 1u) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
return AMDUAT_ASL_STORE_OK;
|
||||
}
|
||||
|
||||
amduat_asl_store_error_t amduat_asl_materialization_cache_fs_put(
|
||||
amduat_asl_materialization_cache_fs_t *cache,
|
||||
amduat_octets_t sid,
|
||||
const amduat_reference_t *refs,
|
||||
size_t refs_len) {
|
||||
amduat_reference_t *existing_refs = NULL;
|
||||
size_t existing_len = 0u;
|
||||
amduat_asl_store_error_t err;
|
||||
char *path = NULL;
|
||||
char *tmp_path = NULL;
|
||||
FILE *fp = NULL;
|
||||
size_t tmp_len;
|
||||
|
||||
if (cache == NULL || sid.len == 0u || sid.data == NULL) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
if (refs_len != 0u && refs == NULL) {
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
|
||||
err = amduat_asl_materialization_cache_fs_get(cache, sid,
|
||||
&existing_refs, &existing_len);
|
||||
if (err == AMDUAT_ASL_STORE_OK) {
|
||||
bool same = amduat_asl_materialization_refs_equal(
|
||||
existing_refs, existing_len, refs, refs_len);
|
||||
amduat_asl_materialization_refs_free(existing_refs, existing_len);
|
||||
if (!same) {
|
||||
amduat_log(AMDUAT_LOG_ERROR,
|
||||
"materialization cache SID collision with mismatched outputs");
|
||||
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
||||
}
|
||||
return AMDUAT_ASL_STORE_OK;
|
||||
}
|
||||
if (err != AMDUAT_ASL_STORE_ERR_NOT_FOUND) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!amduat_asl_materialization_build_sid_path(cache->root_path, sid, true,
|
||||
&path)) {
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
tmp_len = strlen(path) + 5u;
|
||||
tmp_path = (char *)malloc(tmp_len);
|
||||
if (tmp_path == NULL) {
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
snprintf(tmp_path, tmp_len, "%s.tmp", path);
|
||||
|
||||
fp = fopen(tmp_path, "wb");
|
||||
if (fp == NULL) {
|
||||
free(tmp_path);
|
||||
free(path);
|
||||
return AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Crash consistency: write + fsync temp file, rename, then fsync parent
|
||||
* directory. Failure only affects cache persistence, not correctness.
|
||||
*/
|
||||
err = amduat_asl_materialization_write_record(fp, sid, refs, refs_len);
|
||||
if (fflush(fp) != 0) {
|
||||
err = AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (err == AMDUAT_ASL_STORE_OK && fsync(fileno(fp)) != 0) {
|
||||
err = AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (fclose(fp) != 0) {
|
||||
err = AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
fp = NULL;
|
||||
|
||||
if (err == AMDUAT_ASL_STORE_OK && rename(tmp_path, path) != 0) {
|
||||
err = AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
if (err == AMDUAT_ASL_STORE_OK) {
|
||||
char *parent_dir = amduat_asl_materialization_parent_dir(path);
|
||||
if (parent_dir != NULL) {
|
||||
if (!amduat_asl_materialization_fsync_directory(parent_dir)) {
|
||||
amduat_log(AMDUAT_LOG_WARN,
|
||||
"materialization cache fsync dir failed for %s",
|
||||
parent_dir);
|
||||
err = AMDUAT_ASL_STORE_ERR_IO;
|
||||
}
|
||||
free(parent_dir);
|
||||
}
|
||||
}
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
(void)remove(tmp_path);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (err == AMDUAT_ASL_STORE_OK) {
|
||||
amduat_reference_t *check_refs = NULL;
|
||||
size_t check_len = 0u;
|
||||
amduat_asl_store_error_t check_err =
|
||||
amduat_asl_materialization_cache_fs_get(cache, sid, &check_refs,
|
||||
&check_len);
|
||||
assert(check_err == AMDUAT_ASL_STORE_OK);
|
||||
assert(amduat_asl_materialization_refs_equal(
|
||||
check_refs, check_len, refs, refs_len));
|
||||
amduat_asl_materialization_refs_free(check_refs, check_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(tmp_path);
|
||||
free(path);
|
||||
return err;
|
||||
}
|
||||
163
src/core/derivation_sid.c
Normal file
163
src/core/derivation_sid.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#include "amduat/pel/derivation_sid.h"
|
||||
|
||||
#include "amduat/enc/asl1_core_codec.h"
|
||||
#include "amduat/hash/asl1.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool amduat_derivation_sid_check_ref(amduat_reference_t ref) {
|
||||
const amduat_hash_asl1_desc_t *desc;
|
||||
size_t digest_len;
|
||||
|
||||
if (ref.digest.len != 0 && ref.digest.data == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (amduat_hash_asl1_is_reserved(ref.hash_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
desc = amduat_hash_asl1_desc_lookup(ref.hash_id);
|
||||
digest_len = ref.digest.len;
|
||||
if (desc != NULL && desc->digest_len != 0) {
|
||||
assert(desc->digest_len == digest_len);
|
||||
if (desc->digest_len != digest_len) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool amduat_pel_derivation_sid_compute(
|
||||
const amduat_pel_derivation_sid_input_t *in,
|
||||
amduat_octets_t *out_sid) {
|
||||
amduat_hash_asl1_stream_t stream;
|
||||
uint8_t marker;
|
||||
size_t i;
|
||||
|
||||
if (out_sid == NULL) {
|
||||
return false;
|
||||
}
|
||||
out_sid->data = NULL;
|
||||
out_sid->len = 0;
|
||||
|
||||
if (in == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (in->input_refs_len != 0 && in->input_refs == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (in->has_params_ref && !amduat_derivation_sid_check_ref(in->params_ref)) {
|
||||
return false;
|
||||
}
|
||||
if (!amduat_derivation_sid_check_ref(in->program_ref)) {
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < in->input_refs_len; ++i) {
|
||||
if (!amduat_derivation_sid_check_ref(in->input_refs[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!amduat_hash_asl1_stream_init(AMDUAT_HASH_ASL1_ID_SHA256, &stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
amduat_octets_t ref_bytes = amduat_octets(NULL, 0u);
|
||||
bool ok;
|
||||
|
||||
/* ReferenceBytes are self-delimiting because hash_id implies digest_len. */
|
||||
ok = amduat_enc_asl1_core_encode_reference_v1(in->program_ref, &ref_bytes);
|
||||
if (!ok ||
|
||||
!amduat_hash_asl1_stream_update(&stream, ref_bytes.data,
|
||||
ref_bytes.len)) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
free((void *)ref_bytes.data);
|
||||
return false;
|
||||
}
|
||||
free((void *)ref_bytes.data);
|
||||
}
|
||||
|
||||
for (i = 0; i < in->input_refs_len; ++i) {
|
||||
amduat_octets_t ref_bytes = amduat_octets(NULL, 0u);
|
||||
bool ok = amduat_enc_asl1_core_encode_reference_v1(in->input_refs[i],
|
||||
&ref_bytes);
|
||||
if (!ok ||
|
||||
!amduat_hash_asl1_stream_update(&stream, ref_bytes.data,
|
||||
ref_bytes.len)) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
free((void *)ref_bytes.data);
|
||||
return false;
|
||||
}
|
||||
free((void *)ref_bytes.data);
|
||||
}
|
||||
|
||||
marker = in->has_params_ref ? 0x01u : 0x00u;
|
||||
if (!amduat_hash_asl1_stream_update(&stream, &marker, 1u)) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
if (in->has_params_ref) {
|
||||
amduat_octets_t ref_bytes = amduat_octets(NULL, 0u);
|
||||
bool ok = amduat_enc_asl1_core_encode_reference_v1(in->params_ref,
|
||||
&ref_bytes);
|
||||
if (!ok ||
|
||||
!amduat_hash_asl1_stream_update(&stream, ref_bytes.data,
|
||||
ref_bytes.len)) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
free((void *)ref_bytes.data);
|
||||
return false;
|
||||
}
|
||||
free((void *)ref_bytes.data);
|
||||
}
|
||||
|
||||
/* ExecProfile is currently absent; presence must be explicitly marked. */
|
||||
marker = in->has_exec_profile ? 0x01u : 0x00u;
|
||||
if (!amduat_hash_asl1_stream_update(&stream, &marker, 1u)) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
if (in->has_exec_profile) {
|
||||
if (in->exec_profile.len != 0 && in->exec_profile.data == NULL) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
if (!amduat_hash_asl1_stream_update(&stream, in->exec_profile.data,
|
||||
in->exec_profile.len)) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const amduat_hash_asl1_desc_t *desc =
|
||||
amduat_hash_asl1_desc_lookup(AMDUAT_HASH_ASL1_ID_SHA256);
|
||||
uint8_t *digest;
|
||||
size_t digest_len;
|
||||
|
||||
if (desc == NULL || desc->digest_len == 0u) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
digest_len = desc->digest_len;
|
||||
digest = (uint8_t *)malloc(digest_len);
|
||||
if (digest == NULL) {
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
if (!amduat_hash_asl1_stream_final(&stream, digest, digest_len)) {
|
||||
free(digest);
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
return false;
|
||||
}
|
||||
amduat_hash_asl1_stream_destroy(&stream);
|
||||
*out_sid = amduat_octets(digest, digest_len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
41
src/internal/log.c
Normal file
41
src/internal/log.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "amduat/util/log.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *amduat_log_level_label(amduat_log_level_t level) {
|
||||
switch (level) {
|
||||
case AMDUAT_LOG_ERROR:
|
||||
return "ERROR";
|
||||
case AMDUAT_LOG_WARN:
|
||||
return "WARN";
|
||||
case AMDUAT_LOG_INFO:
|
||||
return "INFO";
|
||||
case AMDUAT_LOG_DEBUG:
|
||||
return "DEBUG";
|
||||
default:
|
||||
return "LOG";
|
||||
}
|
||||
}
|
||||
|
||||
static bool amduat_log_debug_enabled(void) {
|
||||
#ifdef AMDUAT_LOG_ENABLE_DEBUG
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void amduat_log(amduat_log_level_t level, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
if (level == AMDUAT_LOG_DEBUG && !amduat_log_debug_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: ", amduat_log_level_label(level));
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
#include "amduat/pel/surf.h"
|
||||
|
||||
#include "amduat/asl/asl_materialization_cache_fs.h"
|
||||
#include "amduat/asl/asl_store_fs.h"
|
||||
#include "amduat/enc/pel1_result.h"
|
||||
#include "amduat/enc/pel_program_dag.h"
|
||||
#include "amduat/enc/pel_trace_dag.h"
|
||||
#include "amduat/pel/derivation_sid.h"
|
||||
#include "amduat/util/log.h"
|
||||
#include "pel_program_dag_internal.h"
|
||||
#include "amduat/pel/program_dag_desc.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -217,6 +222,37 @@ static void amduat_trace_nodes_free(amduat_pel_node_trace_dag_t *nodes,
|
|||
free(nodes);
|
||||
}
|
||||
|
||||
static const char k_materialized_hit_op_name[] = "materialized_hit";
|
||||
|
||||
static bool amduat_pel_surf_store_fs_ctx(
|
||||
const amduat_asl_store_t *store,
|
||||
amduat_asl_store_fs_t **out_fs) {
|
||||
amduat_asl_store_ops_t fs_ops;
|
||||
|
||||
if (out_fs == NULL) {
|
||||
return false;
|
||||
}
|
||||
*out_fs = NULL;
|
||||
if (store == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fs_ops = amduat_asl_store_fs_ops();
|
||||
if (store->ops.put != fs_ops.put ||
|
||||
store->ops.get != fs_ops.get ||
|
||||
store->ops.put_indexed != fs_ops.put_indexed ||
|
||||
store->ops.get_indexed != fs_ops.get_indexed ||
|
||||
store->ops.tombstone != fs_ops.tombstone ||
|
||||
store->ops.tombstone_lift != fs_ops.tombstone_lift ||
|
||||
store->ops.log_scan != fs_ops.log_scan ||
|
||||
store->ops.current_state != fs_ops.current_state ||
|
||||
store->ops.validate_config != fs_ops.validate_config) {
|
||||
return false;
|
||||
}
|
||||
*out_fs = (amduat_asl_store_fs_t *)store->ctx;
|
||||
return *out_fs != NULL;
|
||||
}
|
||||
|
||||
static bool amduat_store_trace(
|
||||
amduat_asl_store_t *store,
|
||||
amduat_reference_t scheme_ref,
|
||||
|
|
@ -230,6 +266,7 @@ static bool amduat_store_trace(
|
|||
const amduat_pel_execution_result_value_t *core_result,
|
||||
const amduat_pel_program_t *program,
|
||||
const amduat_pel_program_dag_trace_t *trace_eval,
|
||||
bool materialized_hit,
|
||||
amduat_reference_t *out_trace_ref) {
|
||||
amduat_pel_trace_dag_value_t trace;
|
||||
amduat_pel_node_trace_dag_t *node_traces;
|
||||
|
|
@ -311,6 +348,29 @@ static bool amduat_store_trace(
|
|||
}
|
||||
}
|
||||
|
||||
if (materialized_hit) {
|
||||
amduat_pel_node_trace_dag_t *next;
|
||||
|
||||
/* Emit a synthetic trace entry to mark a materialization cache hit. */
|
||||
next = (amduat_pel_node_trace_dag_t *)realloc(
|
||||
node_traces, (node_count + 1u) * sizeof(*node_traces));
|
||||
if (next == NULL) {
|
||||
amduat_trace_nodes_free(node_traces, node_count);
|
||||
return false;
|
||||
}
|
||||
node_traces = next;
|
||||
memset(&node_traces[node_count], 0, sizeof(*node_traces));
|
||||
/* UINT32_MAX is a reserved sentinel; decoders treat node_id as opaque. */
|
||||
node_traces[node_count].node_id = UINT32_MAX;
|
||||
node_traces[node_count].op_name = amduat_octets(
|
||||
(const uint8_t *)k_materialized_hit_op_name,
|
||||
sizeof(k_materialized_hit_op_name) - 1u);
|
||||
node_traces[node_count].op_version = 1u;
|
||||
node_traces[node_count].status = AMDUAT_PEL_NODE_TRACE_SKIPPED;
|
||||
node_traces[node_count].status_code = 0u;
|
||||
node_count += 1u;
|
||||
}
|
||||
|
||||
memset(&trace, 0, sizeof(trace));
|
||||
trace.pel1_version = 1;
|
||||
trace.scheme_ref = scheme_ref;
|
||||
|
|
@ -367,6 +427,8 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
size_t outputs_len;
|
||||
amduat_reference_t *output_refs;
|
||||
size_t output_refs_len;
|
||||
amduat_asl_materialization_cache_fs_t mat_cache;
|
||||
amduat_octets_t sid;
|
||||
amduat_reference_t trace_ref;
|
||||
amduat_reference_t exec_result_ref;
|
||||
size_t i;
|
||||
|
|
@ -375,6 +437,10 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
bool exec_invoked = false;
|
||||
bool trace_ok = false;
|
||||
bool has_exec_result_ref = false;
|
||||
bool mat_cache_ready = false;
|
||||
bool materialized_hit = false;
|
||||
bool cache_miss_due_missing = false;
|
||||
bool executed = false;
|
||||
|
||||
if (store == NULL || out_output_refs == NULL ||
|
||||
out_output_refs_len == NULL || out_result_ref == NULL) {
|
||||
|
|
@ -392,6 +458,7 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
trace_ref.digest = amduat_octets(NULL, 0);
|
||||
exec_result_ref.hash_id = 0;
|
||||
exec_result_ref.digest = amduat_octets(NULL, 0);
|
||||
sid = amduat_octets(NULL, 0);
|
||||
|
||||
if (!amduat_reference_eq(scheme_ref,
|
||||
amduat_pel_program_dag_scheme_ref())) {
|
||||
|
|
@ -490,6 +557,75 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
has_params_artifact = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache safety assumptions:
|
||||
* - PEL DAG execution is deterministic for ProgramRef + Inputs + Params.
|
||||
* - ExecProfile is currently absent and encoded as a marker only.
|
||||
* - The store is single-tenant; SID collisions are treated as integrity errors.
|
||||
* - This code path assumes amduat_asl_store_fs_t as the backing store.
|
||||
*/
|
||||
{
|
||||
amduat_pel_derivation_sid_input_t sid_input;
|
||||
|
||||
memset(&sid_input, 0, sizeof(sid_input));
|
||||
sid_input.program_ref = program_ref;
|
||||
sid_input.input_refs = input_refs;
|
||||
sid_input.input_refs_len = input_refs_len;
|
||||
sid_input.has_params_ref = has_params_ref;
|
||||
if (has_params_ref) {
|
||||
sid_input.params_ref = params_ref;
|
||||
}
|
||||
sid_input.has_exec_profile = false;
|
||||
sid_input.exec_profile = amduat_octets(NULL, 0u);
|
||||
|
||||
if (amduat_pel_derivation_sid_compute(&sid_input, &sid)) {
|
||||
amduat_asl_store_fs_t *fs = NULL;
|
||||
if (amduat_pel_surf_store_fs_ctx(store, &fs) &&
|
||||
amduat_asl_materialization_cache_fs_init(&mat_cache,
|
||||
fs->root_path)) {
|
||||
mat_cache_ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mat_cache_ready) {
|
||||
amduat_reference_t *cached_refs = NULL;
|
||||
size_t cached_len = 0;
|
||||
amduat_asl_store_error_t cache_err;
|
||||
|
||||
cache_err = amduat_asl_materialization_cache_fs_get(&mat_cache, sid,
|
||||
&cached_refs,
|
||||
&cached_len);
|
||||
if (cache_err == AMDUAT_ASL_STORE_OK) {
|
||||
bool cache_valid = true;
|
||||
for (i = 0; i < cached_len; ++i) {
|
||||
amduat_artifact_t cached_artifact;
|
||||
if (amduat_asl_store_get(store, cached_refs[i],
|
||||
&cached_artifact) !=
|
||||
AMDUAT_ASL_STORE_OK) {
|
||||
cache_valid = false;
|
||||
break;
|
||||
}
|
||||
amduat_artifact_free(&cached_artifact);
|
||||
}
|
||||
if (cache_valid) {
|
||||
output_refs = cached_refs;
|
||||
output_refs_len = cached_len;
|
||||
materialized_hit = true;
|
||||
exec_invoked = true;
|
||||
amduat_init_core_result(&core_result, scheme_ref,
|
||||
AMDUAT_PEL_EXEC_STATUS_OK,
|
||||
AMDUAT_PEL_EXEC_ERROR_NONE, 0);
|
||||
outputs = NULL;
|
||||
outputs_len = 0;
|
||||
amduat_artifact_free(&program_artifact);
|
||||
goto cache_hit;
|
||||
}
|
||||
cache_miss_due_missing = true;
|
||||
amduat_pel_surf_free_refs(cached_refs, cached_len);
|
||||
}
|
||||
}
|
||||
|
||||
exec_invoked = true;
|
||||
outputs = NULL;
|
||||
outputs_len = 0;
|
||||
|
|
@ -570,6 +706,7 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
|
||||
return false;
|
||||
}
|
||||
executed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -593,6 +730,27 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
}
|
||||
}
|
||||
|
||||
if (mat_cache_ready) {
|
||||
(void)amduat_asl_materialization_cache_fs_put(&mat_cache, sid,
|
||||
output_refs, output_refs_len);
|
||||
}
|
||||
|
||||
cache_hit:
|
||||
#ifndef NDEBUG
|
||||
if (cache_miss_due_missing) {
|
||||
assert(!materialized_hit);
|
||||
}
|
||||
#endif
|
||||
if (materialized_hit) {
|
||||
amduat_log(AMDUAT_LOG_DEBUG, "pel surf: materialization hit");
|
||||
} else if (executed) {
|
||||
if (cache_miss_due_missing) {
|
||||
amduat_log(AMDUAT_LOG_DEBUG,
|
||||
"pel surf: executed (cache miss: missing outputs)");
|
||||
} else {
|
||||
amduat_log(AMDUAT_LOG_DEBUG, "pel surf: executed");
|
||||
}
|
||||
}
|
||||
trace_ok = false;
|
||||
if (exec_invoked) {
|
||||
if (!amduat_store_surface_result(
|
||||
|
|
@ -607,7 +765,9 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
has_params_ref, params_ref, has_exec_result_ref, exec_result_ref,
|
||||
&core_result,
|
||||
program_decoded ? &program : NULL,
|
||||
program_decoded ? &trace_eval : NULL, &trace_ref);
|
||||
program_decoded ? &trace_eval : NULL,
|
||||
materialized_hit,
|
||||
&trace_ref);
|
||||
if (!trace_ok) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -637,6 +797,7 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
|
|||
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
|
||||
amduat_pel_execution_result_free(&core_result);
|
||||
amduat_pel_surf_free_ref(&exec_result_ref);
|
||||
amduat_octets_free(&sid);
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
|
|
@ -655,5 +816,6 @@ cleanup:
|
|||
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
|
||||
amduat_pel_execution_result_free(&core_result);
|
||||
amduat_pel_surf_free_ref(&exec_result_ref);
|
||||
amduat_octets_free(&sid);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "amduat/asl/artifact_io.h"
|
||||
#include "amduat/asl/asl_derivation_index_fs.h"
|
||||
#include "amduat/asl/asl_materialization_cache_fs.h"
|
||||
#include "amduat/asl/asl_store_fs.h"
|
||||
#include "amduat/asl/asl_store_fs_meta.h"
|
||||
#include "amduat/asl/io.h"
|
||||
|
|
@ -18,11 +19,13 @@
|
|||
#include "amduat/format/pel.h"
|
||||
#include "amduat/format/ref.h"
|
||||
#include "amduat/pel/decode.h"
|
||||
#include "amduat/pel/derivation_sid.h"
|
||||
#include "amduat/pel/opreg_kernel.h"
|
||||
#include "amduat/pel/opreg_kernel_params.h"
|
||||
#include "amduat/pel/program_dag_desc.h"
|
||||
#include "amduat/pel/run.h"
|
||||
#include "amduat/pel/surf.h"
|
||||
#include "amduat/util/hex.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
|
@ -66,6 +69,7 @@ static void amduat_pel_cli_print_usage(FILE *stream) {
|
|||
" trace Trace DAG tools (decode, from-result).\n"
|
||||
" result Surface result tools (decode).\n"
|
||||
" op Kernel op registry tools.\n"
|
||||
" matcache Materialization cache tools (get, sid).\n"
|
||||
" scheme Scheme refs, type tags, profile IDs.\n"
|
||||
" help Show help for a command.\n"
|
||||
"\n"
|
||||
|
|
@ -135,6 +139,11 @@ static void amduat_pel_cli_print_usage(FILE *stream) {
|
|||
" amduat-pel scheme show [--format text|json] [--ref-format hex|bytes]\n"
|
||||
" amduat-pel scheme dag-ref [--format hex|bytes]\n"
|
||||
"\n"
|
||||
"matcache:\n"
|
||||
" amduat-pel matcache get --sid HEX [--verify]\n"
|
||||
" amduat-pel matcache sid --program-ref REF --input-ref REF...\n"
|
||||
" [--params-ref REF]\n"
|
||||
"\n"
|
||||
"defaults:\n"
|
||||
" --root .amduat-asl\n"
|
||||
" --ref-format hex\n"
|
||||
|
|
@ -355,20 +364,43 @@ static bool amduat_pel_cli_index_derivations(
|
|||
return false;
|
||||
}
|
||||
|
||||
for (i = 0u; i < output_refs_len; ++i) {
|
||||
amduat_asl_derivation_record_t record;
|
||||
{
|
||||
amduat_pel_derivation_sid_input_t sid_input;
|
||||
amduat_octets_t sid = amduat_octets(NULL, 0u);
|
||||
amduat_asl_store_error_t err;
|
||||
|
||||
if (!amduat_octets_clone(output_refs[i].digest, &sid)) {
|
||||
memset(&sid_input, 0, sizeof(sid_input));
|
||||
sid_input.program_ref = program_ref;
|
||||
sid_input.input_refs = input_refs;
|
||||
sid_input.input_refs_len = input_refs_len;
|
||||
sid_input.has_params_ref = has_params_ref;
|
||||
if (has_params_ref) {
|
||||
sid_input.params_ref = params_ref;
|
||||
}
|
||||
sid_input.has_exec_profile = false;
|
||||
sid_input.exec_profile = amduat_octets(NULL, 0u);
|
||||
|
||||
if (!amduat_pel_derivation_sid_compute(&sid_input, &sid)) {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "error: failed to allocate derivation sid\n");
|
||||
fprintf(stderr, "error: failed to compute derivation sid\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0u; i < output_refs_len; ++i) {
|
||||
amduat_asl_derivation_record_t record;
|
||||
amduat_asl_store_error_t err;
|
||||
amduat_octets_t record_sid = amduat_octets(NULL, 0u);
|
||||
|
||||
if (!amduat_octets_clone(sid, &record_sid)) {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "error: failed to clone derivation sid\n");
|
||||
}
|
||||
amduat_octets_free(&sid);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&record, 0, sizeof(record));
|
||||
record.sid = sid;
|
||||
record.sid = record_sid;
|
||||
record.program_ref = program_ref;
|
||||
record.output_index = (uint32_t)i;
|
||||
record.input_refs = (amduat_reference_t *)input_refs;
|
||||
|
|
@ -388,10 +420,14 @@ static bool amduat_pel_cli_index_derivations(
|
|||
if (!quiet) {
|
||||
fprintf(stderr, "error: derivation index add failed: %d\n", err);
|
||||
}
|
||||
amduat_octets_free(&sid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
amduat_octets_free(&sid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2723,6 +2759,257 @@ static int amduat_pel_cli_cmd_scheme(
|
|||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
|
||||
static int amduat_pel_cli_cmd_matcache_get(
|
||||
int argc,
|
||||
char **argv,
|
||||
const amduat_pel_cli_global_opts_t *global) {
|
||||
const char *sid_hex = NULL;
|
||||
bool verify = false;
|
||||
uint8_t *sid_bytes = NULL;
|
||||
size_t sid_len = 0u;
|
||||
amduat_asl_materialization_cache_fs_t cache;
|
||||
amduat_reference_t *refs = NULL;
|
||||
size_t refs_len = 0u;
|
||||
int i;
|
||||
|
||||
if (global == NULL) {
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--sid") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "error: --sid requires a value\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
sid_hex = argv[++i];
|
||||
} else if (strcmp(argv[i], "--verify") == 0) {
|
||||
verify = true;
|
||||
} else if (strcmp(argv[i], "--help") == 0 ||
|
||||
strcmp(argv[i], "-h") == 0) {
|
||||
amduat_pel_cli_print_usage(stdout);
|
||||
return AMDUAT_PEL_CLI_EXIT_OK;
|
||||
} else {
|
||||
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (sid_hex == NULL) {
|
||||
fprintf(stderr, "error: --sid is required\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
if (!amduat_hex_decode_alloc(sid_hex, &sid_bytes, &sid_len)) {
|
||||
fprintf(stderr, "error: invalid SID hex\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
if (!amduat_asl_materialization_cache_fs_init(&cache, global->root)) {
|
||||
free(sid_bytes);
|
||||
fprintf(stderr, "error: failed to init materialization cache\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_CONFIG;
|
||||
}
|
||||
|
||||
{
|
||||
amduat_octets_t sid = amduat_octets(sid_bytes, sid_len);
|
||||
amduat_asl_store_error_t err =
|
||||
amduat_asl_materialization_cache_fs_get(&cache, sid, &refs, &refs_len);
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
free(sid_bytes);
|
||||
return amduat_pel_cli_map_store_error(err);
|
||||
}
|
||||
|
||||
{
|
||||
char *sid_norm = NULL;
|
||||
if (amduat_hex_encode_alloc(sid_bytes, sid_len, &sid_norm)) {
|
||||
printf("sid=%s\n", sid_norm);
|
||||
free(sid_norm);
|
||||
}
|
||||
}
|
||||
printf("outputs=%zu\n", refs_len);
|
||||
for (size_t j = 0u; j < refs_len; ++j) {
|
||||
fputs("output_ref=", stdout);
|
||||
if (!amduat_format_ref_write_text(stdout, refs[j],
|
||||
global->ref_format)) {
|
||||
fprintf(stderr, "error: failed to format output ref\n");
|
||||
amduat_pel_cli_free_refs(refs, refs_len);
|
||||
free(sid_bytes);
|
||||
return AMDUAT_PEL_CLI_EXIT_CODEC;
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
err = amduat_asl_materialization_cache_fs_put(&cache, sid, refs,
|
||||
refs_len);
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
fprintf(stderr, "error: cache verify failed: %s\n",
|
||||
amduat_pel_cli_store_error_str(err));
|
||||
amduat_pel_cli_free_refs(refs, refs_len);
|
||||
free(sid_bytes);
|
||||
return amduat_pel_cli_map_store_error(err);
|
||||
}
|
||||
printf("verify=ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
amduat_pel_cli_free_refs(refs, refs_len);
|
||||
free(sid_bytes);
|
||||
return AMDUAT_PEL_CLI_EXIT_OK;
|
||||
}
|
||||
|
||||
static int amduat_pel_cli_cmd_matcache_sid(
|
||||
int argc,
|
||||
char **argv,
|
||||
const amduat_pel_cli_global_opts_t *global) {
|
||||
const char *program_ref_text = NULL;
|
||||
const char *params_ref_text = NULL;
|
||||
amduat_reference_t program_ref;
|
||||
amduat_reference_t params_ref;
|
||||
amduat_reference_t *input_refs = NULL;
|
||||
size_t input_refs_len = 0u;
|
||||
bool has_params_ref = false;
|
||||
bool stdin_used = false;
|
||||
int i;
|
||||
|
||||
if (global == NULL) {
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--program-ref") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "error: --program-ref requires a value\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
program_ref_text = argv[++i];
|
||||
} else if (strcmp(argv[i], "--input-ref") == 0) {
|
||||
amduat_reference_t ref;
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "error: --input-ref requires a value\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
if (!amduat_pel_cli_ref_from_text(argv[++i], global->ref_format,
|
||||
&stdin_used, &ref)) {
|
||||
fprintf(stderr, "error: invalid input ref\n");
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
if (!amduat_pel_cli_append_ref(&input_refs, &input_refs_len, ref)) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
amduat_pel_cli_free_reference(&ref);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_IO;
|
||||
}
|
||||
} else if (strcmp(argv[i], "--params-ref") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "error: --params-ref requires a value\n");
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
params_ref_text = argv[++i];
|
||||
has_params_ref = true;
|
||||
} else if (strcmp(argv[i], "--help") == 0 ||
|
||||
strcmp(argv[i], "-h") == 0) {
|
||||
amduat_pel_cli_print_usage(stdout);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_OK;
|
||||
} else {
|
||||
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (program_ref_text == NULL || input_refs_len == 0u) {
|
||||
fprintf(stderr, "error: --program-ref and --input-ref are required\n");
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
|
||||
if (!amduat_pel_cli_ref_from_text(program_ref_text, global->ref_format,
|
||||
&stdin_used, &program_ref)) {
|
||||
fprintf(stderr, "error: invalid program ref\n");
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
|
||||
if (has_params_ref) {
|
||||
if (!amduat_pel_cli_ref_from_text(params_ref_text, global->ref_format,
|
||||
&stdin_used, ¶ms_ref)) {
|
||||
fprintf(stderr, "error: invalid params ref\n");
|
||||
amduat_pel_cli_free_reference(&program_ref);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
amduat_pel_derivation_sid_input_t sid_input;
|
||||
amduat_octets_t sid = amduat_octets(NULL, 0u);
|
||||
char *sid_hex = NULL;
|
||||
|
||||
memset(&sid_input, 0, sizeof(sid_input));
|
||||
sid_input.program_ref = program_ref;
|
||||
sid_input.input_refs = input_refs;
|
||||
sid_input.input_refs_len = input_refs_len;
|
||||
sid_input.has_params_ref = has_params_ref;
|
||||
if (has_params_ref) {
|
||||
sid_input.params_ref = params_ref;
|
||||
}
|
||||
sid_input.has_exec_profile = false;
|
||||
sid_input.exec_profile = amduat_octets(NULL, 0u);
|
||||
|
||||
if (!amduat_pel_derivation_sid_compute(&sid_input, &sid)) {
|
||||
fprintf(stderr, "error: failed to compute sid\n");
|
||||
if (has_params_ref) {
|
||||
amduat_pel_cli_free_reference(¶ms_ref);
|
||||
}
|
||||
amduat_pel_cli_free_reference(&program_ref);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_CODEC;
|
||||
}
|
||||
|
||||
if (!amduat_hex_encode_alloc(sid.data, sid.len, &sid_hex)) {
|
||||
fprintf(stderr, "error: failed to encode sid\n");
|
||||
amduat_octets_free(&sid);
|
||||
if (has_params_ref) {
|
||||
amduat_pel_cli_free_reference(¶ms_ref);
|
||||
}
|
||||
amduat_pel_cli_free_reference(&program_ref);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_CODEC;
|
||||
}
|
||||
printf("%s\n", sid_hex);
|
||||
free(sid_hex);
|
||||
amduat_octets_free(&sid);
|
||||
}
|
||||
|
||||
if (has_params_ref) {
|
||||
amduat_pel_cli_free_reference(¶ms_ref);
|
||||
}
|
||||
amduat_pel_cli_free_reference(&program_ref);
|
||||
amduat_pel_cli_free_refs(input_refs, input_refs_len);
|
||||
return AMDUAT_PEL_CLI_EXIT_OK;
|
||||
}
|
||||
|
||||
static int amduat_pel_cli_cmd_matcache(
|
||||
int argc,
|
||||
char **argv,
|
||||
const amduat_pel_cli_global_opts_t *global) {
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "error: matcache requires a subcommand\n");
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
if (strcmp(argv[0], "get") == 0) {
|
||||
return amduat_pel_cli_cmd_matcache_get(argc - 1, argv + 1, global);
|
||||
}
|
||||
if (strcmp(argv[0], "sid") == 0) {
|
||||
return amduat_pel_cli_cmd_matcache_sid(argc - 1, argv + 1, global);
|
||||
}
|
||||
fprintf(stderr, "error: unknown matcache subcommand: %s\n", argv[0]);
|
||||
return AMDUAT_PEL_CLI_EXIT_USAGE;
|
||||
}
|
||||
|
||||
static int amduat_pel_cli_cmd_help(int argc, char **argv) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
|
@ -2810,6 +3097,9 @@ int main(int argc, char **argv) {
|
|||
if (strcmp(command, "op") == 0) {
|
||||
return amduat_pel_cli_cmd_op(argc - i, argv + i, &global);
|
||||
}
|
||||
if (strcmp(command, "matcache") == 0) {
|
||||
return amduat_pel_cli_cmd_matcache(argc - i, argv + i, &global);
|
||||
}
|
||||
if (strcmp(command, "scheme") == 0) {
|
||||
return amduat_pel_cli_cmd_scheme(argc - i, argv + i, &global);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue