From f3a8fedf0a70e28ef8a71ce58790419a3ab0996b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 10 Oct 2025 10:50:20 +0800 Subject: [PATCH] CPU (Linux): improves SoC name detection from device tree Fixes #1997 --- src/detection/cpu/cpu_linux.c | 47 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 4f8c65538..18a6ae01f 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -621,19 +621,46 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu) if (cpu->name.length > 0) return; - // device-vendor,device-model\0soc-vendor,soc-model\0 - char content[256]; + // [x-vendor,x-model\0]*N + char content[512]; ssize_t length = ffReadFileData("/proc/device-tree/compatible", ARRAY_SIZE(content), content); - if (length <= 2) return; + if (length < 4) return; // v,m\0 - // get the second NUL terminated string if it exists - char* vendor = memchr(content, '\0', (size_t) length) + 1; - if (!vendor || vendor - content >= length) vendor = content; + if (content[length - 1] != '\0') return; // must end with \0 - char* model = strchr(vendor, ','); - if (!model) return; - *model = '\0'; - ++model; + --length; + + char* vendor = NULL; + char* model = NULL; + + for (char* p; length > 0; length = p ? (ssize_t) (p - content) - 1 : 0) + { + p = memrchr(content, '\0', (size_t) length); + + vendor = p /* first entry */ ? p + 1 : content; + + size_t partLen = (size_t) (length - (vendor - content)); + if (partLen < 3) continue; + + char* comma = memchr(vendor, ',', partLen); + if (!comma) continue; + + size_t vendorLen = (size_t) (comma - vendor); + if (vendorLen == 0) continue; + + model = comma + 1; + size_t modelLen = (size_t) (partLen - (size_t) (model - vendor)); + if (modelLen == 0) continue; + + if ((modelLen >= strlen("-platform") && ffStrEndsWith(model, "-platform")) || + (modelLen >= strlen("-soc") && ffStrEndsWith(model, "-soc"))) + continue; + + *comma = '\0'; + break; + } + + if (!length) return; if (false) {} #if __aarch64__