From 8ea4468eec60fb43dcb12a61afcc229e6103b2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 1 Sep 2026 00:20:40 +0800 Subject: [PATCH] Common (Endian): adds new header --- src/common/endian.h | 17 +++++++++ src/common/impl/base64.c | 9 ++--- src/common/impl/smbios.c | 33 ++++++++--------- src/detection/battery/battery_windows.c | 20 +++++------ src/detection/chassis/chassis_linux.c | 3 +- src/detection/cpu/cpu_windows.c | 3 +- src/detection/cpucache/cpucache_shared.c | 13 ++++--- src/detection/host/host_windows.c | 10 +++++- .../physicalmemory/physicalmemory_linux.c | 36 +++++++++++-------- 9 files changed, 87 insertions(+), 57 deletions(-) create mode 100644 src/common/endian.h diff --git a/src/common/endian.h b/src/common/endian.h new file mode 100644 index 000000000..2410911ee --- /dev/null +++ b/src/common/endian.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#if __BIG_ENDIAN__ + #define FF_READ_LE(x) _Generic((x), \ + uint16_t: __builtin_bswap16(x), \ + uint32_t: __builtin_bswap32(x), \ + uint64_t: __builtin_bswap64(x)) + #define FF_READ_BE(x) (x) +#else + #define FF_READ_LE(x) (x) + #define FF_READ_BE(x) _Generic((x), \ + uint16_t: __builtin_bswap16(x), \ + uint32_t: __builtin_bswap32(x), \ + uint64_t: __builtin_bswap64(x)) +#endif diff --git a/src/common/impl/base64.c b/src/common/impl/base64.c index fa987c303..3d743691b 100644 --- a/src/common/impl/base64.c +++ b/src/common/impl/base64.c @@ -1,4 +1,5 @@ #include "common/base64.h" +#include "common/endian.h" // https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145 void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char* output) { @@ -7,12 +8,8 @@ void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char* const char* ends = str + (size - size % 3); while (str != ends) { uint32_t n = *(uint32_t*) str; - #if !__BIG_ENDIAN__ - // The 3 input bytes must be laid out big-endian (str[0] in the most - // significant position). On little-endian hosts swap; on big-endian - // hosts the word is already in the right order. - n = __builtin_bswap32(n); - #endif + // The 3 input bytes must be laid out big-endian (str[0] in the most significant position). + n = FF_READ_BE(n); *out++ = chars[(n >> 26) & 63]; *out++ = chars[(n >> 20) & 63]; *out++ = chars[(n >> 14) & 63]; diff --git a/src/common/impl/smbios.c b/src/common/impl/smbios.c index fc7df14b3..9a54003bc 100644 --- a/src/common/impl/smbios.c +++ b/src/common/impl/smbios.c @@ -1,3 +1,4 @@ +#include "common/endian.h" #include "common/smbios.h" #include "common/io.h" #include "common/mallocHelper.h" @@ -81,9 +82,9 @@ static bool parseSmbiosTable(const uint8_t* data, uint32_t length) { break; } - if (header->Handle >= 0xFF00) { + if (FF_READ_LE(header->Handle) >= 0xFF00) { FF_DEBUG("Invalid SMBIOS structure handle 0x%04x at offset 0x%lx", - header->Handle, + FF_READ_LE(header->Handle), (unsigned long) ((const uint8_t*) header - data)); break; } @@ -103,25 +104,25 @@ static bool parseSmbiosTable(const uint8_t* data, uint32_t length) { smbiosTable[header->Type] = header; FF_DEBUG("Found SMBIOS structure type %u, handle 0x%04X, length %u", header->Type, - header->Handle, + FF_READ_LE(header->Handle), header->Length); structureCount++; } else { FF_DEBUG("Duplicate SMBIOS structure type %u, handle 0x%04X, length %u", header->Type, - header->Handle, + FF_READ_LE(header->Handle), header->Length); } } else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE) { FF_DEBUG("Reached SMBIOS end of type %u, handle 0x%04X, length %u", header->Type, - header->Handle, + FF_READ_LE(header->Handle), header->Length); break; } else { FF_DEBUG("Found custom SMBIOS structure type %u, handle 0x%04X, length %u; ignoring", header->Type, - header->Handle, + FF_READ_LE(header->Handle), header->Length); } } @@ -308,8 +309,8 @@ static bool fillTableBufferFallback(FFstrbuf* buffer) { sizeof(p->Smbios30)); return false; } - tableLength = p->Smbios30.StructureTableMaximumSize; - tableAddress = (off_t) p->Smbios30.StructureTableAddress; + tableLength = FF_READ_LE(p->Smbios30.StructureTableMaximumSize); + tableAddress = (off_t) FF_READ_LE(p->Smbios30.StructureTableAddress); FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u", tableLength, (unsigned long) tableAddress, @@ -325,8 +326,8 @@ static bool fillTableBufferFallback(FFstrbuf* buffer) { sizeof(p->Smbios20)); return false; } - tableLength = p->Smbios20.StructureTableLength; - tableAddress = (off_t) p->Smbios20.StructureTableAddress; + tableLength = FF_READ_LE(p->Smbios20.StructureTableLength); + tableAddress = (off_t) FF_READ_LE(p->Smbios20.StructureTableAddress); FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u", tableLength, (unsigned long) tableAddress, @@ -369,9 +370,9 @@ static bool detectSmbiosTableLength(const uint8_t* data, uint32_t bufferLength, return false; } - if (header->Handle >= 0xFF00) { + if (FF_READ_LE(header->Handle) >= 0xFF00) { FF_DEBUG("Invalid SMBIOS structure handle 0x%04x at offset 0x%lx", - header->Handle, + FF_READ_LE(header->Handle), (unsigned long) (p - data)); return false; } @@ -614,8 +615,8 @@ static bool fillTableBufferPlatform(FFstrbuf* buffer) { sizeof(entryPoint.Smbios20)); return false; } - tableLength = entryPoint.Smbios20.StructureTableLength; - tableAddress = (off_t) entryPoint.Smbios20.StructureTableAddress; + tableLength = FF_READ_LE(entryPoint.Smbios20.StructureTableLength); + tableAddress = (off_t) FF_READ_LE(entryPoint.Smbios20.StructureTableAddress); FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u", tableLength, (unsigned long) tableAddress, @@ -629,8 +630,8 @@ static bool fillTableBufferPlatform(FFstrbuf* buffer) { sizeof(entryPoint.Smbios30)); return false; } - tableLength = entryPoint.Smbios30.StructureTableMaximumSize; - tableAddress = (off_t) entryPoint.Smbios30.StructureTableAddress; + tableLength = FF_READ_LE(entryPoint.Smbios30.StructureTableMaximumSize); + tableAddress = (off_t) FF_READ_LE(entryPoint.Smbios30.StructureTableAddress); FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u", tableLength, (unsigned long) tableAddress, diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index 720d5cbd3..cbede5d1e 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -1,6 +1,7 @@ #define INITGUID #include "battery.h" +#include "common/endian.h" #include "common/debug.h" #include "common/mallocHelper.h" @@ -127,29 +128,24 @@ static void detectStaticData(FFlist* entries, FFlist* results) { FFBatteryWmiEntry* entry = getBatteryEntry(entries, results, data->Tag); FF_DEBUG("chemistry: %.4s", (const char*) &data->Chemistry); -#if __BIG_ENDIAN__ - #define htobe32(x) (x) // Should not happen on Windows, but just in case -#else - #define htobe32(x) __builtin_bswap32(x) -#endif switch (data->Chemistry) { - case htobe32('PbAc'): + case FF_READ_BE((uint32_t) 'PbAc'): ffStrbufSetStatic(&entry->result->technology, "Lead Acid"); break; - case htobe32('LION'): - case htobe32('Li-I'): + case FF_READ_BE((uint32_t) 'LION'): + case FF_READ_BE((uint32_t) 'Li-I'): ffStrbufSetStatic(&entry->result->technology, "Lithium Ion"); break; - case htobe32('NiCd'): + case FF_READ_BE((uint32_t) 'NiCd'): ffStrbufSetStatic(&entry->result->technology, "Nickel Cadmium"); break; - case htobe32('NiMH'): + case FF_READ_BE((uint32_t) 'NiMH'): ffStrbufSetStatic(&entry->result->technology, "Nickel Metal Hydride"); break; - case htobe32('NiZn'): + case FF_READ_BE((uint32_t) 'NiZn'): ffStrbufSetStatic(&entry->result->technology, "Nickel Zinc"); break; - case htobe32('RAM\0'): + case FF_READ_BE((uint32_t) 'RAM\0'): ffStrbufSetStatic(&entry->result->technology, "Rechargeable Alkaline-Manganese"); break; default: diff --git a/src/detection/chassis/chassis_linux.c b/src/detection/chassis/chassis_linux.c index 686fc67be..e23f73463 100644 --- a/src/detection/chassis/chassis_linux.c +++ b/src/detection/chassis/chassis_linux.c @@ -1,4 +1,5 @@ #include "chassis.h" +#include "common/endian.h" #include "common/io.h" #include "common/smbios.h" @@ -21,7 +22,7 @@ const char* ffDetectChassis(FFChassisResult* result) { uint32_t chassisType = 0; if (ffReadFileData("/sys/firmware/devicetree/base/smbios/smbios/chassis/chassis-type", sizeof(chassisType), &chassisType)) // big endian { - chassisType = __builtin_bswap32(chassisType); + chassisType = FF_READ_BE(chassisType); const char* typeStr = ffChassisTypeToString(chassisType); if (typeStr) { ffStrbufSetStatic(&result->type, typeStr); diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index 82b656e4f..8975775d0 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -1,4 +1,5 @@ #include "cpu.h" +#include "common/endian.h" #include "common/windows/registry.h" #include "common/windows/nt.h" #include "common/mallocHelper.h" @@ -205,7 +206,7 @@ static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu) { } } - uint32_t speed = data->MaxSpeed; + uint32_t speed = FF_READ_LE(data->MaxSpeed); // Sometimes SMBIOS reports invalid value. We assume that max speed is small than 2x of base if (speed < cpu->frequencyBase || speed > cpu->frequencyBase * 2) { return "Possible invalid CPU max speed in SMBIOS data. See #800"; diff --git a/src/detection/cpucache/cpucache_shared.c b/src/detection/cpucache/cpucache_shared.c index 58419a963..f8888313a 100644 --- a/src/detection/cpucache/cpucache_shared.c +++ b/src/detection/cpucache/cpucache_shared.c @@ -1,4 +1,5 @@ #include "cpucache.h" +#include "common/endian.h" #include "common/smbios.h" #include "common/strutil.h" @@ -43,24 +44,26 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result) { continue; } - bool enabled = !!(data->CacheConfiguration & (1 << 7)); + uint16_t cacheConfiguration = FF_READ_LE(data->CacheConfiguration); + uint16_t installedSize = FF_READ_LE(data->InstalledSize); + bool enabled = !!(cacheConfiguration & (1 << 7)); if (!enabled) { continue; } - uint32_t size = data->InstalledSize; + uint32_t size = installedSize; if (size == 0) { continue; } - if (data->InstalledSize != 0xFFFF) { + if (installedSize != 0xFFFF) { size *= (size >> 15 ? 64 : 1) * 1024u; } else if (data->Header.Length > offsetof(FFSmbiosCacheInfo, InstalledCacheSize2)) { - size = data->InstalledCacheSize2; + size = FF_READ_LE(data->InstalledCacheSize2); size *= (size >> 31 ? 64 : 1) * 1024u; } - uint32_t level = (data->CacheConfiguration & 0b111u) + 1; + uint32_t level = (cacheConfiguration & 0b111u) + 1; FFCPUCacheType type; switch (data->SystemCacheType) { diff --git a/src/detection/host/host_windows.c b/src/detection/host/host_windows.c index 13bf56e88..a39a3041e 100644 --- a/src/detection/host/host_windows.c +++ b/src/detection/host/host_windows.c @@ -1,4 +1,5 @@ #include "host.h" +#include "common/endian.h" #include "common/smbios.h" typedef struct [[gnu::packed]] FFSmbiosSystemInfo { @@ -52,7 +53,14 @@ const char* ffDetectHost(FFHostResult* host) { static_assert(offsetof(FFSmbiosSystemInfo, UUID) == 0x08, "FFSmbiosSystemInfo.UUID offset is wrong"); if (data->Header.Length > offsetof(FFSmbiosSystemInfo, UUID)) { - ffStrbufSetF(&host->uuid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", data->UUID.TimeLow, data->UUID.TimeMid, data->UUID.TimeHighAndVersion, data->UUID.ClockSeqHiAndReserved, data->UUID.ClockSeqLow, data->UUID.Node[0], data->UUID.Node[1], data->UUID.Node[2], data->UUID.Node[3], data->UUID.Node[4], data->UUID.Node[5]); + ffStrbufSetF(&host->uuid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + FF_READ_LE(data->UUID.TimeLow), + FF_READ_LE(data->UUID.TimeMid), + FF_READ_LE(data->UUID.TimeHighAndVersion), + data->UUID.ClockSeqHiAndReserved, + data->UUID.ClockSeqLow, + data->UUID.Node[0], data->UUID.Node[1], data->UUID.Node[2], + data->UUID.Node[3], data->UUID.Node[4], data->UUID.Node[5]); } static_assert(offsetof(FFSmbiosSystemInfo, SKUNumber) == 0x19, "FFSmbiosSystemInfo.SKUNumber offset is wrong"); diff --git a/src/detection/physicalmemory/physicalmemory_linux.c b/src/detection/physicalmemory/physicalmemory_linux.c index fe248be0c..c3e3fae96 100644 --- a/src/detection/physicalmemory/physicalmemory_linux.c +++ b/src/detection/physicalmemory/physicalmemory_linux.c @@ -1,4 +1,5 @@ #include "physicalmemory.h" +#include "common/endian.h" #include "common/smbios.h" // 7.18 @@ -82,7 +83,8 @@ const char* ffDetectPhysicalMemory(FFPhysicalMemoryOptions* options, FFlist* res } const char* strings = (const char*) data + data->Header.Length; - bool installed = data->Size != 0; + uint16_t size = FF_READ_LE(data->Size); + bool installed = size != 0; if (!installed && !options->showEmptySlots) { continue; @@ -101,19 +103,21 @@ const char* ffDetectPhysicalMemory(FFPhysicalMemoryOptions* options, FFlist* res device->installed = installed; device->ecc = false; - if (installed && data->TotalWidth != 0xFFFF && data->DataWidth != 0xFFFF) { - device->ecc = data->TotalWidth > data->DataWidth; + uint16_t totalWidth = FF_READ_LE(data->TotalWidth); + uint16_t dataWidth = FF_READ_LE(data->DataWidth); + if (installed && totalWidth != 0xFFFF && dataWidth != 0xFFFF) { + device->ecc = totalWidth > dataWidth; } - if (installed && data->Size != 0xFFFF) { - if (data->Size == 0x7FFF) { - device->size = (data->ExtendedSize & ~(1ULL << 31)) * 1024ULL * 1024ULL; - } else if (data->Size & (1 << 15)) { + if (installed && size != 0xFFFF) { + if (size == 0x7FFF) { + device->size = (FF_READ_LE(data->ExtendedSize) & ~(1ULL << 31)) * 1024ULL * 1024ULL; + } else if (size & (1 << 15)) { // in kB - device->size = (data->Size & ~(1ULL << 15)) * 1024ULL; + device->size = (size & ~(1ULL << 15)) * 1024ULL; } else { // in MB - device->size = data->Size * 1024ULL * 1024ULL; + device->size = size * 1024ULL * 1024ULL; } } @@ -206,8 +210,9 @@ const char* ffDetectPhysicalMemory(FFPhysicalMemoryOptions* options, FFlist* res if (installed && data->Header.Length > offsetof(FFSmbiosMemoryDevice, Speed)) // 2.3+ { - if (data->Speed) { - device->maxSpeed = data->Speed == 0xFFFF ? data->ExtendedSpeed : data->Speed; + uint16_t speed = FF_READ_LE(data->Speed); + if (speed) { + device->maxSpeed = speed == 0xFFFF ? FF_READ_LE(data->ExtendedSpeed) : speed; } ffStrbufSetStatic(&device->vendor, ffSmbiosLocateString(strings, data->Manufacturer)); @@ -223,10 +228,11 @@ const char* ffDetectPhysicalMemory(FFPhysicalMemoryOptions* options, FFlist* res if (installed && data->Header.Length > offsetof(FFSmbiosMemoryDevice, ConfiguredMemorySpeed)) // 2.7+ { - if (data->ConfiguredMemorySpeed) { - device->runningSpeed = data->ConfiguredMemorySpeed == 0xFFFF - ? data->ExtendedConfiguredSpeed - : data->ConfiguredMemorySpeed; + uint16_t configuredSpeed = FF_READ_LE(data->ConfiguredMemorySpeed); + if (configuredSpeed) { + device->runningSpeed = configuredSpeed == 0xFFFF + ? FF_READ_LE(data->ExtendedConfiguredSpeed) + : configuredSpeed; } } }