Common (Endian): adds new header

This commit is contained in:
李通洲
2026-09-01 00:20:40 +08:00
parent b0ba084b5e
commit 8ea4468eec
9 changed files with 87 additions and 57 deletions
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
#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
+3 -6
View File
@@ -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];
+17 -16
View File
@@ -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,
+8 -12
View File
@@ -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:
+2 -1
View File
@@ -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);
+2 -1
View File
@@ -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";
+8 -5
View File
@@ -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) {
+9 -1
View File
@@ -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");
@@ -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;
}
}
}