Avoids the sanitizer error:
```
../src/intel/common/intel_debug_identifier.c:122:15: runtime error: member access within misaligned address 0x7f5ca8b32051 for type 'struct intel_debug_block_base', which requires 4 byte alignment
0x7f5ca8b32051: note: pointer points here
66 30 29 00 03 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 08 00 00 00 00 00 00 00
^
```
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32098>
143 lines
3.6 KiB
C
143 lines
3.6 KiB
C
/**
|
|
* \file intel_debug_identifier.c
|
|
*
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "git_sha1.h"
|
|
|
|
#include "common/intel_debug_identifier.h"
|
|
#include "dev/intel_debug.h"
|
|
#include "util/macros.h"
|
|
#include "util/u_math.h"
|
|
|
|
static uint64_t debug_identifier[4] = {
|
|
0xffeeddccbbaa9988,
|
|
0x7766554433221100,
|
|
0xffeeddccbbaa9988,
|
|
0x7766554433221100,
|
|
};
|
|
|
|
void *
|
|
intel_debug_identifier(void)
|
|
{
|
|
return debug_identifier;
|
|
}
|
|
|
|
uint32_t
|
|
intel_debug_identifier_size(void)
|
|
{
|
|
return sizeof(debug_identifier);
|
|
}
|
|
|
|
uint32_t
|
|
intel_debug_write_identifiers(void *_output,
|
|
uint32_t output_size,
|
|
const char *driver_name)
|
|
{
|
|
void *output = _output, *output_end = _output + output_size;
|
|
|
|
assert(output_size > intel_debug_identifier_size());
|
|
|
|
memcpy(output, intel_debug_identifier(), intel_debug_identifier_size());
|
|
output += intel_debug_identifier_size();
|
|
|
|
for (uint32_t id = INTEL_DEBUG_BLOCK_TYPE_DRIVER; id < INTEL_DEBUG_BLOCK_TYPE_MAX; id++) {
|
|
switch (id) {
|
|
case INTEL_DEBUG_BLOCK_TYPE_DRIVER: {
|
|
struct intel_debug_block_driver driver_desc = {
|
|
.base = {
|
|
.type = id,
|
|
},
|
|
};
|
|
int len = snprintf(output + sizeof(driver_desc),
|
|
output_end - (output + sizeof(driver_desc)),
|
|
"%s " PACKAGE_VERSION " build " MESA_GIT_SHA1,
|
|
driver_name);
|
|
driver_desc.base.length = sizeof(driver_desc) + len + 1;
|
|
memcpy(output, &driver_desc, sizeof(driver_desc));
|
|
output += driver_desc.base.length;
|
|
break;
|
|
}
|
|
|
|
case INTEL_DEBUG_BLOCK_TYPE_FRAME: {
|
|
struct intel_debug_block_frame frame_desc = {
|
|
.base = {
|
|
.type = INTEL_DEBUG_BLOCK_TYPE_FRAME,
|
|
.length = sizeof(frame_desc),
|
|
},
|
|
};
|
|
memcpy(output, &frame_desc, sizeof(frame_desc));
|
|
output += sizeof(frame_desc);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
unreachable("Missing identifier write");
|
|
}
|
|
|
|
assert(output < output_end);
|
|
}
|
|
|
|
struct intel_debug_block_base end = {
|
|
.type = INTEL_DEBUG_BLOCK_TYPE_END,
|
|
.length = sizeof(end),
|
|
};
|
|
memcpy(output, &end, sizeof(end));
|
|
output += sizeof(end);
|
|
|
|
assert(output < output_end);
|
|
|
|
/* Add at least a full aligned uint64_t of zero padding at the end
|
|
* to make the identifiers easier to spot.
|
|
*/
|
|
const unsigned unpadded_len = output - _output;
|
|
const unsigned padding = align(unpadded_len + 8, 8) - unpadded_len;
|
|
memset(output, 0, padding);
|
|
output += padding;
|
|
|
|
assert(output < output_end);
|
|
|
|
/* Return the how many bytes where written, so that the rest of the buffer
|
|
* can be used for other things.
|
|
*/
|
|
return output - _output;
|
|
}
|
|
|
|
void *
|
|
intel_debug_get_identifier_block(void *_buffer,
|
|
uint32_t buffer_size,
|
|
enum intel_debug_block_type type)
|
|
{
|
|
void *buffer = _buffer + intel_debug_identifier_size(),
|
|
*end_buffer = _buffer + buffer_size;
|
|
|
|
while (buffer < end_buffer) {
|
|
struct intel_debug_block_base item;
|
|
memcpy(&item, buffer, sizeof(item));
|
|
|
|
if (item.type == type)
|
|
return buffer;
|
|
if (item.type == INTEL_DEBUG_BLOCK_TYPE_END)
|
|
return NULL;
|
|
|
|
buffer += item.length;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Check if in valid frame range for batch dumping
|
|
*/
|
|
bool
|
|
intel_debug_batch_in_range(uint64_t frame_id)
|
|
{
|
|
return frame_id >= intel_debug_batch_frame_start &&
|
|
frame_id < intel_debug_batch_frame_stop;
|
|
}
|