From add4bd0a714df20856501bd7f528abd3529e751c Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Thu, 22 Aug 2024 19:49:13 +0100 Subject: [PATCH] [v1.06][ARM] Fix issue with NULL characters --- src/arm/soc.c | 48 +++++++++++++++++++++++++++++++++++++---------- src/common/udev.c | 5 ++--- src/common/udev.h | 2 +- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/arm/soc.c b/src/arm/soc.c index 2a7dd51..e6ad017 100644 --- a/src/arm/soc.c +++ b/src/arm/soc.c @@ -895,34 +895,62 @@ struct system_on_chip* guess_soc_from_uarch(struct system_on_chip* soc, struct c return soc; } -bool match_dt(struct system_on_chip* soc, char* dt, char* expected_name, char* soc_name, SOC soc_model, int32_t process) { - if (strstr(dt, expected_name) == NULL) { - return false; +// Return the dt string without the NULL characters. +char* get_dt_str(char* dt, int filelen) { + char* dt_without_null = (char *) malloc(sizeof(char) * filelen); + memcpy(dt_without_null, dt, filelen); + + for (int i=0; i < filelen-1; i++) { + if (dt_without_null[i] == '\0') + dt_without_null[i] = ','; } - else { + return dt_without_null; +} + +bool match_dt(struct system_on_chip* soc, char* dt, int filelen, char* expected_name, char* soc_name, SOC soc_model, int32_t process) { + // The /proc/device-tree/compatible file (passed by dt) uses NULL + // to separate the strings, so we need to make an special case here + // and iterate over the NULL characters, thus iterating over each + // individual compatible strings. + + if (strstr(dt, expected_name) != NULL) { fill_soc(soc, soc_name, soc_model, process); return true; } + + char *compatible = dt; + char *end_of_dt = dt + filelen; + + while ((compatible = strchr(compatible, '\0')) != end_of_dt) { + compatible++; + if (strstr(compatible, expected_name) != NULL) { + fill_soc(soc, soc_name, soc_model, process); + return true; + } + } + + return false; } #define DT_START if (false) {} -#define DT_EQ(dt, soc, expected_name, soc_name, soc_model, process) \ - else if (match_dt(soc, dt, expected_name, soc_name, soc_model, process)) return soc; -#define DT_END else { printWarn("guess_soc_from_devtree: No match found"); return soc; } +#define DT_EQ(dt, filelen, soc, expected_name, soc_name, soc_model, process) \ + else if (match_dt(soc, dt, filelen, expected_name, soc_name, soc_model, process)) return soc; +#define DT_END(dt, filelen) else { printWarn("guess_soc_from_devtree: No match found for '%s'", get_dt_str(dt, filelen)); return soc; } // TODO: Move this to doc // The number of fields seems non-standard, so for now it seems wiser // to just get the entire string with all fields and just look for the // substring. struct system_on_chip* guess_soc_from_devtree(struct system_on_chip* soc) { - char* dt = get_devtree_compatible(); + int len; + char* dt = get_devtree_compatible(&len); if (dt == NULL) { return soc; } DT_START - DT_EQ(dt, soc, "t6000apple", "M1 Pro", SOC_APPLE_M1_PRO, 5) - DT_END + DT_EQ(dt, len, soc, "apple,t6000", "M1 Pro", SOC_APPLE_M1_PRO, 5) + DT_END(dt, len) } struct system_on_chip* guess_soc_from_pci(struct system_on_chip* soc, struct cpuInfo* cpu) { diff --git a/src/common/udev.c b/src/common/udev.c index 069c605..d7eb1f3 100644 --- a/src/common/udev.c +++ b/src/common/udev.c @@ -353,11 +353,10 @@ bool is_devtree_compatible(char* str) { return true; } -char* get_devtree_compatible(void) { - int filelen; +char* get_devtree_compatible(int *filelen) { char* buf; - if ((buf = read_file(_PATH_DEVTREE, &filelen)) == NULL) { + if ((buf = read_file(_PATH_DEVTREE, filelen)) == NULL) { printWarn("read_file: %s: %s", _PATH_DEVTREE, strerror(errno)); } diff --git a/src/common/udev.h b/src/common/udev.h index 4cb6825..92ff1d1 100644 --- a/src/common/udev.h +++ b/src/common/udev.h @@ -43,6 +43,6 @@ int get_num_sockets_package_cpus(struct topology* topo); int get_ncores_from_cpuinfo(void); char* get_field_from_cpuinfo(char* CPUINFO_FIELD); bool is_devtree_compatible(char* str); -char* get_devtree_compatible(void); +char* get_devtree_compatible(int *filelen); #endif