Skip to content

Commit 0952d79

Browse files
committed
Smbios: add verbose debug logs
1 parent a3f50f3 commit 0952d79

File tree

1 file changed

+169
-26
lines changed

1 file changed

+169
-26
lines changed

src/util/smbiosHelper.c

Lines changed: 169 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "common/io/io.h"
33
#include "util/unused.h"
44
#include "util/mallocHelper.h"
5+
#include "util/debug.h"
56

67
bool ffIsSmbiosValueSet(FFstrbuf* value)
78
{
@@ -138,151 +139,265 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
138139

139140
if (buffer.chars == NULL)
140141
{
142+
FF_DEBUG("Initializing SMBIOS buffer");
141143
ffStrbufInit(&buffer);
142144
#if !__HAIKU__ && !__OpenBSD__
143145
#ifdef __linux__
146+
FF_DEBUG("Using Linux implementation - trying /sys/firmware/dmi/tables/DMI");
144147
if (!ffAppendFileBuffer("/sys/firmware/dmi/tables/DMI", &buffer))
145148
#endif
146149
{
147150
#if !defined(__sun) && !defined(__NetBSD__)
151+
FF_DEBUG("Using memory-mapped implementation");
148152
FF_STRBUF_AUTO_DESTROY strEntryAddress = ffStrbufCreate();
149153
#ifdef __FreeBSD__
150-
if (!ffSettingsGetFreeBSDKenv("hint.smbios.0.mem", &strEntryAddress))
154+
FF_DEBUG("Using FreeBSD kenv implementation");
155+
if (!ffSettingsGetFreeBSDKenv("hint.smbios.0.mem", &strEntryAddress)) {
156+
FF_DEBUG("Failed to get SMBIOS address from FreeBSD kenv");
151157
return NULL;
158+
}
159+
FF_DEBUG("Got SMBIOS address from kenv: %s", strEntryAddress.chars);
152160
#elif defined(__linux__)
153161
{
162+
FF_DEBUG("Using Linux EFI systab implementation");
154163
FF_STRBUF_AUTO_DESTROY systab = ffStrbufCreate();
155-
if (!ffAppendFileBuffer("/sys/firmware/efi/systab", &systab))
164+
if (!ffAppendFileBuffer("/sys/firmware/efi/systab", &systab)) {
165+
FF_DEBUG("Failed to read /sys/firmware/efi/systab");
156166
return NULL;
167+
}
157168
if (!ffParsePropLines(systab.chars, "SMBIOS3=", &strEntryAddress) &&
158-
!ffParsePropLines(systab.chars, "SMBIOS=", &strEntryAddress))
169+
!ffParsePropLines(systab.chars, "SMBIOS=", &strEntryAddress)) {
170+
FF_DEBUG("Failed to find SMBIOS entry in systab");
159171
return NULL;
172+
}
173+
FF_DEBUG("Found SMBIOS entry in systab: %s", strEntryAddress.chars);
160174
}
161175
#endif
162176

163177
loff_t entryAddress = (loff_t) strtol(strEntryAddress.chars, NULL, 16);
164-
if (entryAddress == 0) return NULL;
178+
if (entryAddress == 0) {
179+
FF_DEBUG("Invalid SMBIOS entry address: 0");
180+
return NULL;
181+
}
182+
FF_DEBUG("Parsed SMBIOS entry address: 0x%lx", (unsigned long)entryAddress);
165183

166184
FF_AUTO_CLOSE_FD int fd = open("/dev/mem", O_RDONLY);
167-
if (fd < 0) return NULL;
185+
if (fd < 0) {
186+
FF_DEBUG("Failed to open /dev/mem: %s", strerror(errno));
187+
return NULL;
188+
}
189+
FF_DEBUG("/dev/mem opened successfully with fd=%d", fd);
168190

169191
FFSmbiosEntryPoint entryPoint;
192+
FF_DEBUG("Attempting to read %zu bytes from physical address 0x%lx",
193+
sizeof(entryPoint), (unsigned long)entryAddress);
170194
if (pread(fd, &entryPoint, sizeof(entryPoint), entryAddress) < 0x10)
171195
{
196+
FF_DEBUG("pread failed, trying mmap");
172197
// `pread /dev/mem` returns EFAULT in FreeBSD
173198
// https://stackoverflow.com/questions/69372330/how-to-read-dev-mem-using-read
174199
void* p = mmap(NULL, sizeof(entryPoint), PROT_READ, MAP_SHARED, fd, entryAddress);
175-
if (p == MAP_FAILED) return NULL;
200+
if (p == MAP_FAILED) {
201+
FF_DEBUG("mmap failed: %s", strerror(errno));
202+
return NULL;
203+
}
176204
memcpy(&entryPoint, p, sizeof(entryPoint));
177205
munmap(p, sizeof(entryPoint));
206+
FF_DEBUG("Successfully read entry point data via mmap");
207+
} else {
208+
FF_DEBUG("Successfully read entry point data via pread");
178209
}
179210
#else
211+
// Sun or NetBSD
212+
FF_DEBUG("Using %s specific implementation",
213+
#ifdef __NetBSD__
214+
"NetBSD"
215+
#else
216+
"SunOS"
217+
#endif
218+
);
219+
180220
FF_AUTO_CLOSE_FD int fd = open("/dev/smbios", O_RDONLY);
181-
if (fd < 0) return NULL;
221+
if (fd < 0) {
222+
FF_DEBUG("Failed to open /dev/smbios: %s", strerror(errno));
223+
return NULL;
224+
}
225+
FF_DEBUG("/dev/smbios opened successfully with fd=%d", fd);
182226

183227
FFSmbiosEntryPoint entryPoint;
184228
#ifdef __NetBSD__
185229
off_t addr = (off_t) ffSysctlGetInt64("machdep.smbios", 0);
186-
if (addr == 0) return NULL;
187-
if (pread(fd, &entryPoint, sizeof(entryPoint), addr) < 1) return NULL;
230+
if (addr == 0) {
231+
FF_DEBUG("Failed to get SMBIOS address from sysctl");
232+
return NULL;
233+
}
234+
FF_DEBUG("Got SMBIOS address from sysctl: 0x%lx", (unsigned long)addr);
235+
236+
if (pread(fd, &entryPoint, sizeof(entryPoint), addr) < 1) {
237+
FF_DEBUG("Failed to read SMBIOS entry point: %s", strerror(errno));
238+
return NULL;
239+
}
240+
FF_DEBUG("Successfully read SMBIOS entry point");
188241
#else
189-
if (ffReadFDData(fd, sizeof(entryPoint), &entryPoint) < 1) return NULL;
242+
FF_DEBUG("Reading SMBIOS entry point from /dev/smbios");
243+
if (ffReadFDData(fd, sizeof(entryPoint), &entryPoint) < 1) {
244+
FF_DEBUG("Failed to read SMBIOS entry point: %s", strerror(errno));
245+
return NULL;
246+
}
247+
FF_DEBUG("Successfully read SMBIOS entry point");
190248
#endif
191249
#endif
192250

193251
uint32_t tableLength = 0;
194252
loff_t tableAddress = 0;
195253
if (memcmp(entryPoint.Smbios20.AnchorString, "_SM_", sizeof(entryPoint.Smbios20.AnchorString)) == 0)
196254
{
197-
if (entryPoint.Smbios20.EntryPointLength != sizeof(entryPoint.Smbios20))
255+
FF_DEBUG("Found SMBIOS 2.0 entry point");
256+
if (entryPoint.Smbios20.EntryPointLength != sizeof(entryPoint.Smbios20)) {
257+
FF_DEBUG("Invalid SMBIOS 2.0 entry point length: %u (expected %zu)",
258+
entryPoint.Smbios20.EntryPointLength, sizeof(entryPoint.Smbios20));
198259
return NULL;
260+
}
199261
tableLength = entryPoint.Smbios20.StructureTableLength;
200262
tableAddress = (loff_t) entryPoint.Smbios20.StructureTableAddress;
263+
FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u",
264+
tableLength, (unsigned long)tableAddress,
265+
entryPoint.Smbios20.SmbiosMajorVersion, entryPoint.Smbios20.SmbiosMinorVersion);
201266
}
202267
else if (memcmp(entryPoint.Smbios30.AnchorString, "_SM3_", sizeof(entryPoint.Smbios30.AnchorString)) == 0)
203268
{
204-
if (entryPoint.Smbios30.EntryPointLength != sizeof(entryPoint.Smbios30))
269+
FF_DEBUG("Found SMBIOS 3.0 entry point");
270+
if (entryPoint.Smbios30.EntryPointLength != sizeof(entryPoint.Smbios30)) {
271+
FF_DEBUG("Invalid SMBIOS 3.0 entry point length: %u (expected %zu)",
272+
entryPoint.Smbios30.EntryPointLength, sizeof(entryPoint.Smbios30));
205273
return NULL;
274+
}
206275
tableLength = entryPoint.Smbios30.StructureTableMaximumSize;
207276
tableAddress = (loff_t) entryPoint.Smbios30.StructureTableAddress;
277+
FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u",
278+
tableLength, (unsigned long)tableAddress,
279+
entryPoint.Smbios30.SmbiosMajorVersion, entryPoint.Smbios30.SmbiosMinorVersion, entryPoint.Smbios30.SmbiosDocrev);
208280
}
209-
else
281+
else {
282+
FF_DEBUG("Unknown SMBIOS entry point format");
210283
return NULL;
284+
}
211285

212286
ffStrbufEnsureFixedLengthFree(&buffer, tableLength);
287+
FF_DEBUG("Attempting to read SMBIOS table data: %u bytes at 0x%lx", tableLength, (unsigned long)tableAddress);
213288
if (pread(fd, buffer.chars, tableLength, tableAddress) == (ssize_t) tableLength)
214289
{
215290
buffer.length = tableLength;
216291
buffer.chars[buffer.length] = '\0';
292+
FF_DEBUG("Successfully read SMBIOS table data: %u bytes", tableLength);
217293
}
218294
else
219295
{
296+
FF_DEBUG("pread failed, trying mmap");
220297
// entryPoint.StructureTableAddress must be page aligned.
221298
// Unaligned physical memory access results in all kinds of crashes.
222299
void* p = mmap(NULL, tableLength, PROT_READ, MAP_SHARED, fd, tableAddress);
223300
if (p == MAP_FAILED)
224301
{
302+
FF_DEBUG("mmap failed: %s", strerror(errno));
225303
ffStrbufDestroy(&buffer); // free buffer and reset state
226304
return NULL;
227305
}
228306
ffStrbufSetNS(&buffer, tableLength, (char*) p);
229307
munmap(p, tableLength);
308+
FF_DEBUG("Successfully read SMBIOS table data via mmap: %u bytes", tableLength);
230309
}
231310
}
232311
#else
233312
{
313+
FF_DEBUG("Using %s implementation",
314+
#if __HAIKU__
315+
"Haiku"
316+
#else
317+
"OpenBSD"
318+
#endif
319+
);
320+
234321
uint32_t tableLength = 0;
235322
off_t tableAddress = 0;
236323
FF_AUTO_CLOSE_FD int fd = open(
237324
#if __HAIKU__
238325
"/dev/misc/mem"
239326
#else
240-
"/dev/mem"
327+
"/dev/mem" // kern.securelevel must be -1
241328
#endif
242329
, O_RDONLY);
243-
if (fd < 0)
330+
if (fd < 0) {
331+
FF_DEBUG("Failed to open memory device: %s", strerror(errno));
244332
return NULL;
333+
}
334+
FF_DEBUG("Memory device opened successfully with fd=%d", fd);
245335

246336
// Works on legacy BIOS only
247337
// See: https://wiki.osdev.org/System_Management_BIOS#UEFI_systems
248338
FF_AUTO_FREE uint8_t* smBiosBase = malloc(0x10000);
249-
if (pread(fd, smBiosBase, 0x10000, 0xF0000) != 0x10000)
339+
if (pread(fd, smBiosBase, 0x10000, 0xF0000) != 0x10000) {
340+
FF_DEBUG("Failed to read SMBIOS memory region: %s", strerror(errno));
250341
return NULL;
342+
}
343+
FF_DEBUG("Successfully read 0x10000 bytes from physical address 0xF0000");
251344

252345
for (off_t offset = 0; offset <= 0xffe0; offset += 0x10)
253346
{
254347
FFSmbiosEntryPoint* p = (void*)(smBiosBase + offset);
255348
if (memcmp(p, "_SM3_", sizeof(p->Smbios30.AnchorString)) == 0)
256349
{
257-
if (p->Smbios30.EntryPointLength != sizeof(p->Smbios30))
350+
FF_DEBUG("Found SMBIOS 3.0 entry point at offset 0x%lx", (unsigned long)offset);
351+
if (p->Smbios30.EntryPointLength != sizeof(p->Smbios30)) {
352+
FF_DEBUG("Invalid SMBIOS 3.0 entry point length: %u (expected %zu)",
353+
p->Smbios30.EntryPointLength, sizeof(p->Smbios30));
258354
return NULL;
355+
}
259356
tableLength = p->Smbios30.StructureTableMaximumSize;
260357
tableAddress = (off_t) p->Smbios30.StructureTableAddress;
358+
FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u",
359+
tableLength, (unsigned long)tableAddress,
360+
p->Smbios30.SmbiosMajorVersion, p->Smbios30.SmbiosMinorVersion, p->Smbios30.SmbiosDocrev);
261361
break;
262362
}
263363
else if (memcmp(p, "_SM_", sizeof(p->Smbios20.AnchorString)) == 0)
264364
{
265-
if (p->Smbios20.EntryPointLength != sizeof(p->Smbios20))
365+
FF_DEBUG("Found SMBIOS 2.0 entry point at offset 0x%lx", (unsigned long)offset);
366+
if (p->Smbios20.EntryPointLength != sizeof(p->Smbios20)) {
367+
FF_DEBUG("Invalid SMBIOS 2.0 entry point length: %u (expected %zu)",
368+
p->Smbios20.EntryPointLength, sizeof(p->Smbios20));
266369
return NULL;
370+
}
267371
tableLength = p->Smbios20.StructureTableLength;
268372
tableAddress = (off_t) p->Smbios20.StructureTableAddress;
373+
FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u",
374+
tableLength, (unsigned long)tableAddress,
375+
p->Smbios20.SmbiosMajorVersion, p->Smbios20.SmbiosMinorVersion);
269376
break;
270377
}
271378
}
272-
if (tableLength == 0)
379+
if (tableLength == 0) {
380+
FF_DEBUG("No valid SMBIOS entry point found in memory region");
273381
return NULL;
382+
}
274383

275384
ffStrbufEnsureFixedLengthFree(&buffer, tableLength);
385+
FF_DEBUG("Attempting to read SMBIOS table data: %u bytes at 0x%lx", tableLength, (unsigned long)tableAddress);
276386
if (pread(fd, buffer.chars, tableLength, tableAddress) == tableLength)
277387
{
278388
buffer.length = tableLength;
279389
buffer.chars[buffer.length] = '\0';
390+
FF_DEBUG("Successfully read SMBIOS table data: %u bytes", tableLength);
280391
}
281-
else
392+
else {
393+
FF_DEBUG("Failed to read SMBIOS table data: %s", strerror(errno));
282394
return NULL;
395+
}
283396
}
284397
#endif
285398

399+
FF_DEBUG("Parsing SMBIOS table structures");
400+
int structureCount = 0;
286401
for (
287402
const FFSmbiosHeader* header = (const FFSmbiosHeader*) buffer.chars;
288403
(const uint8_t*) header < (const uint8_t*) buffer.chars + buffer.length;
@@ -291,16 +406,25 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
291406
{
292407
if (header->Type < FF_SMBIOS_TYPE_END_OF_TABLE)
293408
{
294-
if (!table[header->Type])
409+
if (!table[header->Type]) {
295410
table[header->Type] = header;
411+
FF_DEBUG("Found SMBIOS structure type %u, handle 0x%04X, length %u",
412+
header->Type, header->Handle, header->Length);
413+
structureCount++;
414+
}
296415
}
297-
else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE)
416+
else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE) {
417+
FF_DEBUG("Reached end-of-table marker");
298418
break;
419+
}
299420
}
421+
FF_DEBUG("Parsed %d SMBIOS structures", structureCount);
300422
}
301423

302-
if (buffer.length == 0)
424+
if (buffer.length == 0) {
425+
FF_DEBUG("No valid SMBIOS data available");
303426
return NULL;
427+
}
304428

305429
return &table;
306430
}
@@ -326,16 +450,28 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
326450

327451
if (!buffer)
328452
{
453+
FF_DEBUG("Initializing Windows SMBIOS buffer");
329454
const DWORD signature = 'RSMB';
455+
FF_DEBUG("Querying system firmware table size with signature 'RSMB'");
330456
uint32_t bufSize = GetSystemFirmwareTable(signature, 0, NULL, 0);
331-
if (bufSize <= sizeof(FFRawSmbiosData))
457+
if (bufSize <= sizeof(FFRawSmbiosData)) {
458+
FF_DEBUG("Invalid firmware table size: %u (must be > %zu)",
459+
bufSize, sizeof(FFRawSmbiosData));
332460
return NULL;
461+
}
462+
FF_DEBUG("Firmware table size: %u bytes", bufSize);
333463

334464
buffer = (FFRawSmbiosData*) malloc(bufSize);
335465
assert(buffer);
466+
FF_DEBUG("Allocated buffer for SMBIOS data");
467+
336468
FF_MAYBE_UNUSED uint32_t resultSize = GetSystemFirmwareTable(signature, 0, buffer, bufSize);
337469
assert(resultSize == bufSize);
470+
FF_DEBUG("Successfully retrieved SMBIOS data: version %u.%u, length %u bytes",
471+
buffer->SMBIOSMajorVersion, buffer->SMBIOSMinorVersion, buffer->Length);
338472

473+
FF_DEBUG("Parsing SMBIOS table structures");
474+
int structureCount = 0;
339475
for (
340476
const FFSmbiosHeader* header = (const FFSmbiosHeader*) buffer->SMBIOSTableData;
341477
(const uint8_t*) header < buffer->SMBIOSTableData + buffer->Length;
@@ -344,12 +480,19 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
344480
{
345481
if (header->Type < FF_SMBIOS_TYPE_END_OF_TABLE)
346482
{
347-
if (!table[header->Type])
483+
if (!table[header->Type]) {
348484
table[header->Type] = header;
485+
FF_DEBUG("Found SMBIOS structure type %u, handle 0x%04X, length %u",
486+
header->Type, header->Handle, header->Length);
487+
structureCount++;
488+
}
349489
}
350-
else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE)
490+
else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE) {
491+
FF_DEBUG("Reached end-of-table marker");
351492
break;
493+
}
352494
}
495+
FF_DEBUG("Parsed %d SMBIOS structures", structureCount);
353496
}
354497

355498
return &table;

0 commit comments

Comments
 (0)