aboutsummaryrefslogtreecommitdiff
path: root/hw/acpi/bios-linker-loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/acpi/bios-linker-loader.c')
-rw-r--r--hw/acpi/bios-linker-loader.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c
index b67da68e5f..3fb54dcf03 100644
--- a/hw/acpi/bios-linker-loader.c
+++ b/hw/acpi/bios-linker-loader.c
@@ -238,37 +238,38 @@ void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file_name,
}
/*
- * bios_linker_loader_add_pointer: ask guest to add address of source file
- * into destination file at the specified pointer.
+ * bios_linker_loader_add_pointer: ask guest to patch address in
+ * destination file with a pointer to source file
*
* @linker: linker object instance
* @dest_file: destination file that must be changed
+ * @dst_patched_offset: location within destination file blob to be patched
+ * with the pointer to @src_file+@src_offset (i.e. source
+ * blob allocated in guest memory + @src_offset), in bytes
+ * @dst_patched_offset_size: size of the pointer to be patched
+ * at @dst_patched_offset in @dest_file blob, in bytes
* @src_file: source file who's address must be taken
- * @pointer: location of the pointer to be patched within destination file blob
- * @pointer_size: size of pointer to be patched, in bytes
- *
- * Notes:
- * - @pointer_size bytes must have been pushed into blob associated with
- * @dest_file and reside at address @pointer.
- * - Guest address is added to initial value at @pointer
- * into copy of @dest_file in Guest memory.
- * e.g. to get start of src_file in guest memory, put 0x0 there
- * to get address of a field at offset 0x10 in src_file, put 0x10 there
- * - Both @dest_file and @src_file must be
- * loaded into Guest memory using bios_linker_loader_alloc
+ * @src_offset: location within source file blob to which
+ * @dest_file+@dst_patched_offset will point to after
+ * firmware's executed ADD_POINTER command
*/
void bios_linker_loader_add_pointer(BIOSLinker *linker,
const char *dest_file,
+ uint32_t dst_patched_offset,
+ uint8_t dst_patched_size,
const char *src_file,
- void *pointer,
- uint8_t pointer_size)
+ uint32_t src_offset)
{
+ uint64_t le_src_offset;
BiosLinkerLoaderEntry entry;
- const BiosLinkerFileEntry *file = bios_linker_find_file(linker, dest_file);
- ptrdiff_t offset = (gchar *)pointer - file->blob->data;
+ const BiosLinkerFileEntry *dst_file =
+ bios_linker_find_file(linker, dest_file);
+ const BiosLinkerFileEntry *source_file =
+ bios_linker_find_file(linker, src_file);
- assert(offset >= 0);
- assert(offset + pointer_size <= file->blob->len);
+ assert(dst_patched_offset < dst_file->blob->len);
+ assert(dst_patched_offset + dst_patched_size <= dst_file->blob->len);
+ assert(src_offset < source_file->blob->len);
memset(&entry, 0, sizeof entry);
strncpy(entry.pointer.dest_file, dest_file,
@@ -276,10 +277,14 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker,
strncpy(entry.pointer.src_file, src_file,
sizeof entry.pointer.src_file - 1);
entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);
- entry.pointer.offset = cpu_to_le32(offset);
- entry.pointer.size = pointer_size;
- assert(pointer_size == 1 || pointer_size == 2 ||
- pointer_size == 4 || pointer_size == 8);
+ entry.pointer.offset = cpu_to_le32(dst_patched_offset);
+ entry.pointer.size = dst_patched_size;
+ assert(dst_patched_size == 1 || dst_patched_size == 2 ||
+ dst_patched_size == 4 || dst_patched_size == 8);
+
+ le_src_offset = cpu_to_le64(src_offset);
+ memcpy(dst_file->blob->data + dst_patched_offset,
+ &le_src_offset, dst_patched_size);
g_array_append_vals(linker->cmd_blob, &entry, sizeof entry);
}