Files
mesa/src/intel/common/intel_debug_identifier.c
Matt Turner b3a14d7b91 intel: Avoid unaligned pointer access
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>
2024-11-14 01:05:02 +00:00

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;
}