Recent

Author Topic: FreeBSD 13/14: RTL dirent record mismatch (64-bit inodes) causes empty directory  (Read 207 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 3946
    • StrumPract is the musicians best friend
I have identified a critical ABI mismatch in the Free Pascal RTL for FreeBSD versions 13, 14 and 15.
When running applications on FreeBSD 14, directory listings (via FindFirst/FindNext or fpGetDirentries) return empty results because the RTL still uses the legacy 32-bit dirent structure.
In FreeBSD 13+, the dirent structure was updated for 64-bit inodes (ino64):d_fileno (inode) is now 64-bit.
An 8-byte d_off (directory offset) field was added.d_namlen is now 16-bit.
Because FPC uses its own record definitions rather than the system's dirent.h, the data returned by the kernel is misaligned in Pascal applications.

Request:Could the RTL be updated to detect the FreeBSD version and use the correct structure? Since there is no built-in FPC_FREEBSD_OSVERSION define, perhaps the RTL should be using a version check similar to how C headers use __FreeBSD_version.

I have verified that manually patching the record to the following layout fixes the issue in mselibc.pas of MSEgui:

Code: Pascal  [Select][+][-]
  1. type
  2.   dirent = record
  3.     d_fileno: cuint64;
  4.     d_off: clonglong;
  5.     d_reclen: cuint16;
  6.     d_type: cuint8;
  7.     d_pad0: cuint8;
  8.     d_namlen: cuint16;
  9.     d_pad1: cuint16;
  10.     d_name: array[0..255] of char;
  11.   end;
  12.  
« Last Edit: May 08, 2026, 02:02:08 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12901
  • FPC developer.
Please file a bug, so that it is not forgotten. When I'm done merging I'll look at it, if nobody else did.

It can be updated since anything before FreeBSD 14 is EOL. I didn't even plan on generate FreeBSD 13 binaries for next release.


Fred vS

  • Hero Member
  • *****
  • Posts: 3946
    • StrumPract is the musicians best friend
Please file a bug, so that it is not forgotten. When I'm done merging I'll look at it, if nobody else did.

OK, done: https://gitlab.com/freepascal.org/fpc/source/-/work_items/41759
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3946
    • StrumPract is the musicians best friend
Sorry for the noise, it was a problem (fixed) only with MSEgui.

By the way  I would be very happy to learn how fpc knows which version of FreeBSD is being used during compilation and therefore switches between the different definitions of the record dirent.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12901
  • FPC developer.
Sorry for the noise, it was a problem (fixed) only with MSEgui.

By the way  I would be very happy to learn how fpc knows which version of FreeBSD is being used during compilation and therefore switches between the different definitions of the record dirent.

The one in bsd/ostypes.inc under $ifdef freebsd, line 254.   If there are version defined needed in the RTL to compile for major versions, just freebsd major version (FREEBSD13, FREEBSD14 etc) is used. But that is in the tree, not for end user usage.  Also, the IDENT is adjusted in rtl/freebsd/x86_64/prt0.as and cprt0.as   (now at    ".long   1500068" by default). This is baked into the ELF binary, and tells the FreeBSD program loader which set of libraries to connect it to. (COMPAT versions, or Linux ones if need be).

Fred vS

  • Hero Member
  • *****
  • Posts: 3946
    • StrumPract is the musicians best friend
Sorry for the noise, it was a problem (fixed) only with MSEgui.

By the way  I would be very happy to learn how fpc knows which version of FreeBSD is being used during compilation and therefore switches between the different definitions of the record dirent.

The one in bsd/ostypes.inc under $ifdef freebsd, line 254.   If there are version defined needed in the RTL to compile for major versions, just freebsd major version (FREEBSD13, FREEBSD14 etc) is used. But that is in the tree, not for end user usage.  Also, the IDENT is adjusted in rtl/freebsd/x86_64/prt0.as and cprt0.as   (now at    ".long   1500068" by default). This is baked into the ELF binary, and tells the FreeBSD program loader which set of libraries to connect it to. (COMPAT versions, or Linux ones if need be).

Many thanks, Marcov, for your insights.

So, if I understand correctly, the latest versions of fpc target FreeBSD 13+, and if I want to target older versions of FreeBSD 12-, I need to recompile the RTL itself with OPT="-dFREEBSD12". Is that correct?
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018