util: Add build_id for macOS

Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38420>
This commit is contained in:
Aitor Camacho 2025-11-13 20:25:50 +09:00 committed by Marge Bot
parent a77e09eaeb
commit 38fe7b7352
2 changed files with 59 additions and 3 deletions

View file

@ -25,12 +25,19 @@
#if HAVE_BUILD_ID
#include <dlfcn.h>
#include <link.h>
#include <stddef.h>
#include <string.h>
#include "macros.h"
#if DETECT_OS_APPLE
#include <mach-o/loader.h>
struct build_id_note {
const struct uuid_command uuid_cmd;
};
#else
#include <link.h>
#ifndef NT_GNU_BUILD_ID
#define NT_GNU_BUILD_ID 3
#endif
@ -45,6 +52,7 @@ struct build_id_note {
char name[4]; /* Note name for build-id is "GNU\0" */
uint8_t build_id[0];
};
#endif /* DETECT_OS_APPLE */
struct callback_data {
/* Base address of shared object, taken from Dl_info::dli_fbase */
@ -53,6 +61,38 @@ struct callback_data {
struct build_id_note *note;
};
#if DETECT_OS_APPLE
static int
build_id_find_uuid_command(void *data_)
{
struct callback_data *data = data_;
const struct mach_header *header =
(const struct mach_header *)data->dli_fbase;
const struct load_command *cmd = NULL;
/* Headers' sizes differ based on architecture */
if (header->magic == MH_MAGIC_64 || header->magic == MH_CIGAM_64) {
cmd =
(const struct load_command *)((const struct mach_header_64 *)header +
1);
} else if (header->magic == MH_MAGIC || header->magic == MH_CIGAM) {
cmd = (const struct load_command *)(header + 1);
} else {
return 0;
}
uint32_t ncmds = header->ncmds;
for (uint32_t i = 0; i < ncmds; i++) {
if (cmd->cmd == LC_UUID) {
data->note = (struct build_id_note *)cmd;
return 1;
}
cmd = (const struct load_command *)((const char *)cmd + cmd->cmdsize);
}
return 0;
}
#else
static int
build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_)
{
@ -99,6 +139,7 @@ build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_)
return 0;
}
#endif /* DETECT_OS_APPLE */
const struct build_id_note *
build_id_find_nhdr_for_addr(const void *addr)
@ -116,8 +157,13 @@ build_id_find_nhdr_for_addr(const void *addr)
.note = NULL,
};
#if DETECT_OS_APPLE
if (!build_id_find_uuid_command(&data))
return NULL;
#else
if (!dl_iterate_phdr(build_id_find_nhdr_callback, &data))
return NULL;
#endif /* DETECT_OS_APPLE */
return data.note;
}
@ -125,13 +171,21 @@ build_id_find_nhdr_for_addr(const void *addr)
unsigned
build_id_length(const struct build_id_note *note)
{
#if DETECT_OS_APPLE
return sizeof(note->uuid_cmd.uuid);
#else
return note->nhdr.n_descsz;
#endif /* DETECT_OS_APPLE */
}
const uint8_t *
build_id_data(const struct build_id_note *note)
{
#if DETECT_OS_APPLE
return note->uuid_cmd.uuid;
#else
return note->build_id;
#endif /* DETECT_OS_APPLE */
}
#endif

View file

@ -24,11 +24,13 @@
#ifndef BUILD_ID_H
#define BUILD_ID_H
#if defined(HAVE_DL_ITERATE_PHDR)
#include "detect_os.h"
#if defined(HAVE_DL_ITERATE_PHDR) || DETECT_OS_APPLE
#define HAVE_BUILD_ID 1
#else
#define HAVE_BUILD_ID 0
#endif /* defined(HAVE_DL_ITERATE_PHDR) */
#endif /* defined(HAVE_DL_ITERATE_PHDR) || DETECT_OS_APPLE */
#ifdef __cplusplus
extern "C" {