// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/zbi/zbi.h>
#include <stdbool.h>
#include <string.h>

// At most, a ZBI container can be the header + 32 bytes of length.
#define MAX_CONTAINER_SIZE (sizeof(zbi_header_t) + 0xFFFFFFFFull)

struct check_state {
  zbi_header_t** err;
  bool seen_bootfs;
};

static bool is_zbi_container(const zbi_header_t* hdr) {
  return (hdr->type == ZBI_TYPE_CONTAINER) && (hdr->magic == ZBI_ITEM_MAGIC) &&
         (hdr->extra == ZBI_CONTAINER_MAGIC);
}

zbi_result_t zbi_init(void* buffer, const size_t length) {
  if (!buffer) {
    return ZBI_RESULT_ERROR;
  }

  if (length < sizeof(zbi_header_t)) {
    return ZBI_RESULT_TOO_BIG;
  }

  if ((uintptr_t)buffer % ZBI_ALIGNMENT != 0) {
    return ZBI_RESULT_BAD_ALIGNMENT;
  }

  zbi_header_t* hdr = (zbi_header_t*)buffer;
  hdr->type = ZBI_TYPE_CONTAINER;
  hdr->length = 0;
  hdr->extra = ZBI_CONTAINER_MAGIC;
  hdr->flags = ZBI_FLAG_VERSION;
  hdr->reserved0 = 0;
  hdr->reserved1 = 0;
  hdr->magic = ZBI_ITEM_MAGIC;
  hdr->crc32 = ZBI_ITEM_NO_CRC32;

  return ZBI_RESULT_OK;
}

static zbi_result_t for_each_check_entry(zbi_header_t* hdr, void* payload, void* cookie) {
  struct check_state* const state = cookie;

  zbi_result_t result = ZBI_RESULT_OK;

  if (hdr->magic != ZBI_ITEM_MAGIC) {
    result = ZBI_RESULT_BAD_MAGIC;
  } else if ((hdr->flags & ZBI_FLAG_VERSION) == 0) {
    result = ZBI_RESULT_BAD_VERSION;
  } else if ((hdr->flags & ZBI_FLAG_CRC32) == 0 && hdr->crc32 != ZBI_ITEM_NO_CRC32) {
    result = ZBI_RESULT_BAD_CRC;
  }

  // If we found a problem, try to report it back up to the caller.
  if (state->err != NULL && result != ZBI_RESULT_OK) {
    *state->err = hdr;
  }

  if (hdr->type == ZBI_TYPE_STORAGE_BOOTFS) {
    state->seen_bootfs = true;
  }

  return result;
}

static zbi_result_t zbi_check_internal(const void* base, uint32_t check_complete,
                                       zbi_header_t** err) {
  if (!base) {
    return ZBI_RESULT_ERROR;
  }

  zbi_result_t res = ZBI_RESULT_OK;
  const zbi_header_t* header = base;

  if (header->type != ZBI_TYPE_CONTAINER) {
    res = ZBI_RESULT_BAD_TYPE;
  } else if (header->extra != ZBI_CONTAINER_MAGIC || header->magic != ZBI_ITEM_MAGIC) {
    res = ZBI_RESULT_BAD_MAGIC;
  } else if ((header->flags & ZBI_FLAG_VERSION) == 0) {
    res = ZBI_RESULT_BAD_VERSION;
  } else if ((header->flags & ZBI_FLAG_CRC32) == 0 && header->crc32 != ZBI_ITEM_NO_CRC32) {
    res = ZBI_RESULT_BAD_CRC;
  }

  // Something was wrong with the container.  Don't even attempt to process
  // the rest of the image.  Return diagnostic information back to the caller
  // if they requested it.
  if (res != ZBI_RESULT_OK) {
    if (err) {
      *err = (zbi_header_t*)header;
    }
    return res;
  }

  struct check_state state = {.err = err};
  res = zbi_for_each(base, for_each_check_entry, &state);

  if (res == ZBI_RESULT_OK && check_complete != 0) {
    if (header->length == 0) {
      res = ZBI_RESULT_ERR_TRUNCATED;
    } else if (header[1].type != check_complete) {
      res = ZBI_RESULT_INCOMPLETE_KERNEL;
      if (err) {
        *err = (zbi_header_t*)(header + 1);
      }
    } else if (!state.seen_bootfs) {
      res = ZBI_RESULT_INCOMPLETE_BOOTFS;
      if (err) {
        *err = (zbi_header_t*)header;
      }
    }
  }

  if (err && res == ZBI_RESULT_ERR_TRUNCATED) {
    // A truncated image perhaps indicates a problem with the container?
    *err = (zbi_header_t*)header;
  }

  return res;
}

zbi_result_t zbi_check(const void* base, zbi_header_t** err) {
  return zbi_check_internal(base, 0, err);
}

zbi_result_t zbi_check_complete(const void* base, zbi_header_t** err) {
  return zbi_check_internal(base,
#ifdef __aarch64__
                            ZBI_TYPE_KERNEL_ARM64,
#elif defined(__x86_64__) || defined(__i386__)
                            ZBI_TYPE_KERNEL_X64,
#else
#error "what architecture?"
#endif
                            err);
}

zbi_result_t zbi_for_each(const void* base, const zbi_foreach_cb_t callback, void* cookie) {
  if (!base || !callback) {
    return ZBI_RESULT_ERROR;
  }

  zbi_header_t* header = (zbi_header_t*)(base);

  // Skip container header.
  const uint32_t totalSize = (uint32_t)sizeof(zbi_header_t) + header->length;
  uint32_t offset = sizeof(zbi_header_t);
  while (offset < totalSize) {
    zbi_header_t* entryHeader = (zbi_header_t*)(base + offset);

    zbi_result_t result = callback(entryHeader, entryHeader + 1, cookie);

    if (result != ZBI_RESULT_OK) {
      return result;
    }

    if ((offset + entryHeader->length + sizeof(zbi_header_t)) > totalSize) {
      return ZBI_RESULT_ERR_TRUNCATED;
    }

    offset = ZBI_ALIGN(offset + entryHeader->length + sizeof(zbi_header_t));
  }

  return ZBI_RESULT_OK;
}

zbi_result_t zbi_create_entry_with_payload(void* base, const size_t capacity, uint32_t type,
                                           uint32_t extra, uint32_t flags, const void* payload,
                                           size_t payload_length) {
  if (!base || !payload) {
    return ZBI_RESULT_ERROR;
  }

  uint8_t* new_section;
  zbi_result_t result =
      zbi_create_entry(base, capacity, type, extra, flags, payload_length, (void**)&new_section);

  if (result != ZBI_RESULT_OK) {
    return result;
  }

  // Copy in the payload.
  memcpy(new_section, payload, payload_length);
  return ZBI_RESULT_OK;
}

zbi_result_t zbi_create_entry(void* base, size_t capacity, uint32_t type, uint32_t extra,
                              uint32_t flags, size_t payload_length, void** payload) {
  if (!base) {
    return ZBI_RESULT_ERROR;
  }

  // We don't support CRC computation (yet?)
  if (flags & ZBI_FLAG_CRC32) {
    return ZBI_RESULT_ERROR;
  }

  if (payload_length > 0xFFFFFFFFU) {
    return ZBI_RESULT_TOO_BIG;
  }

  zbi_header_t* hdr = (zbi_header_t*)base;

  // Find the payload entry point and make sure we have enough room.
  void* next_payload = NULL;
  uint32_t max_payload_length = 0;
  zbi_result_t result =
      zbi_get_next_entry_payload(base, capacity, &next_payload, &max_payload_length);
  if (result != ZBI_RESULT_OK) {
    return result;
  }

  if (max_payload_length < payload_length) {
    return ZBI_RESULT_TOO_BIG;
  }

  // Fill in the new section header.
  zbi_header_t* new_header = (void*)((uint8_t*)(hdr + 1) + hdr->length);
  *new_header = (zbi_header_t){
      .type = type,
      .length = (uint32_t)payload_length,
      .extra = extra,
      .flags = flags | ZBI_FLAG_VERSION,
      .magic = ZBI_ITEM_MAGIC,
      .crc32 = ZBI_ITEM_NO_CRC32,
  };

  // Tell the caller where to fill in the payload. They may not need this if
  // the payload has already been loaded or the length is 0.
  if (payload) {
    *payload = next_payload;
  }

  // Update the container header, always keeping the length aligned.
  hdr->length += sizeof(*new_header) + new_header->length;
  if (hdr->length % ZBI_ALIGNMENT != 0) {
    // It was already verified that the capacity can fit the aligned length.
    uint32_t aligned_length = ZBI_ALIGN(hdr->length);
    memset((uint8_t*)(hdr + 1) + hdr->length, 0, aligned_length - hdr->length);
    hdr->length = aligned_length;
  }

  return ZBI_RESULT_OK;
}

zbi_result_t zbi_get_next_entry_payload(void* base, size_t capacity, void** payload,
                                        uint32_t* max_payload_length) {
  if (!base || !payload || !max_payload_length) {
    return ZBI_RESULT_ERROR;
  }

  zbi_header_t* hdr = (zbi_header_t*)base;

  // Make sure we were actually passed a bootdata container.
  if (!is_zbi_container(hdr)) {
    return ZBI_RESULT_BAD_TYPE;
  }

  // Determine the maximum payload size available.
  // It's OK if the caller has more capacity available than the ZBI can actually
  // take, e.g. a bootloader may just supply whatever leftover memory it has.
  // Just truncate to the max ZBI size and ignore any extra capacity.
  if (capacity > MAX_CONTAINER_SIZE) {
    capacity = MAX_CONTAINER_SIZE;
  }
  if (capacity < sizeof(*hdr) || capacity - sizeof(*hdr) < hdr->length) {
    return ZBI_RESULT_TOO_BIG;
  }
  const uint32_t available = (capacity - sizeof(*hdr) - hdr->length) & ~(ZBI_ALIGNMENT - 1);
  if (available < sizeof(*hdr)) {
    return ZBI_RESULT_TOO_BIG;
  }

  // The next payload starts after the current container + the next header.
  *payload = (uint8_t*)(hdr + 2) + hdr->length;
  *max_payload_length = available - sizeof(*hdr);
  return ZBI_RESULT_OK;
}

zbi_result_t zbi_extend(void* dst_buffer, size_t capacity, const void* src_buffer) {
  if (!dst_buffer || !src_buffer) {
    return ZBI_RESULT_ERROR;
  }

  zbi_header_t* dst = (zbi_header_t*)dst_buffer;
  zbi_header_t* src = (zbi_header_t*)src_buffer;

  // Extend only works against two zbi containers, if you want to append a zbi
  // section to the end of a container, use zbi_append_section instead.
  if (!is_zbi_container(dst) || !is_zbi_container(src)) {
    return ZBI_RESULT_BAD_TYPE;
  }

  // Make sure there's enough space in the destination buffer to contain the
  // source.
  const uint32_t dst_size = ZBI_ALIGN(dst->length + sizeof(*dst));

  // This captures the situation where there's not even enough space to have
  // padding between this section and the next.
  if (dst_size > capacity) {
    return ZBI_RESULT_TOO_BIG;
  }

  // This makes sure that there's enough space to perform the copy after
  const size_t remaining_buffer = capacity - dst_size;
  if (remaining_buffer < src->length) {
    return ZBI_RESULT_TOO_BIG;
  }

  // Okay everything looks good, let's do the copy.
  memcpy(dst_buffer + dst_size, src_buffer + sizeof(*src), src->length);

  // And patch up the length on the destination buffer's header.
  dst->length += src->length;

  return ZBI_RESULT_OK;
}
