@@ -1413,17 +1413,45 @@ class Statx64(ctypes.Structure):
14131413
14141414 _pack_ = 4
14151415
1416+ # Big-endian counterparts of the statx structs. The kernel statx layout is the
1417+ # same on every architecture, so the big-endian variants reuse the little-endian
1418+ # field lists verbatim and only change the ctypes base class (and the nested
1419+ # timestamp type, which must itself be big-endian). Without these, statx() byte-
1420+ # swaps every field on a big-endian guest (e.g. MIPS/MIPS64 EB), so stx_mode
1421+ # loses its S_IFDIR bit and tools like `ls` treat directories as plain files.
1422+ class StatxTimestamp32EB (ctypes .BigEndianStructure ):
1423+ _fields_ = StatxTimestamp32 ._fields_
1424+
1425+ class StatxTimestamp64EB (ctypes .BigEndianStructure ):
1426+ _fields_ = StatxTimestamp64 ._fields_
1427+
1428+ def _statx_fields_eb (fields ):
1429+ swap = {StatxTimestamp32 : StatxTimestamp32EB , StatxTimestamp64 : StatxTimestamp64EB }
1430+ return [(name , swap .get (ftype , ftype )) for (name , ftype ) in fields ]
1431+
1432+ class Statx32EB (ctypes .BigEndianStructure ):
1433+ _fields_ = _statx_fields_eb (Statx32 ._fields_ )
1434+ _pack_ = 8
1435+
1436+ class Statx64EB (ctypes .BigEndianStructure ):
1437+ _fields_ = _statx_fields_eb (Statx64 ._fields_ )
1438+ _pack_ = 4
1439+
14161440# int statx(int dirfd, const char *restrict pathname, int flags,
14171441# unsigned int mask, struct statx *restrict statxbuf);
14181442def ql_syscall_statx (ql : Qiling , dirfd : int , path : int , flags : int , mask : int , buf_ptr : int ):
1443+ is_eb = ql .arch .endian == QL_ENDIAN .EB
1444+
14191445 def statx_convert_timestamp (tv_sec , tv_nsec ):
14201446 tv_sec = struct .unpack ('i' , struct .pack ('f' , tv_sec ))[0 ]
14211447 tv_nsec = struct .unpack ('i' , struct .pack ('f' , tv_nsec ))[0 ]
14221448
14231449 if ql .arch .bits == 32 :
1424- return StatxTimestamp32 ( tv_sec = tv_sec , tv_nsec = tv_nsec )
1450+ Timestamp = StatxTimestamp32EB if is_eb else StatxTimestamp32
14251451 else :
1426- return StatxTimestamp64 (tv_sec = tv_sec , tv_nsec = tv_nsec )
1452+ Timestamp = StatxTimestamp64EB if is_eb else StatxTimestamp64
1453+
1454+ return Timestamp (tv_sec = tv_sec , tv_nsec = tv_nsec )
14271455
14281456
14291457 def major (dev ):
@@ -1438,9 +1466,9 @@ def minor(dev):
14381466 st = Stat (real_path , fd )
14391467
14401468 if ql .arch .bits == 32 :
1441- Statx = Statx32
1469+ Statx = Statx32EB if is_eb else Statx32
14421470 else :
1443- Statx = Statx64
1471+ Statx = Statx64EB if is_eb else Statx64
14441472
14451473 stx = Statx (
14461474 stx_mask = 0x07ff , # STATX_BASIC_STATS
0 commit comments