22#include "common/io/io.h"
33#include "util/unused.h"
44#include "util/mallocHelper.h"
5+ #include "util/debug.h"
56
67bool 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