From f74260c55232ffeeb0e4318894b0c2a2f00993a7 Mon Sep 17 00:00:00 2001 From: Tiberiu Bucur Date: Tue, 20 Aug 2024 14:56:22 +0100 Subject: [PATCH] arch, sim-se: Fix off_t size mismatch bug Some system calls were using incorrect sizing for offset parametres, which was causing the ABI to pass wrong values due to size mismatches. One such syscall is lseek, which in the Arm syscall table was incorrectly marked as llseek, which does not exist in aarch64 Linux. In addition, the off_t alias for general Linux was changed from an unsigned to a signed type, to accurately reflect the behaviour in the real-life Linux operating system. Change-Id: Iada4b66a8933466c162ba9ec901dbdae73c73a18 Reviewed-by: Giacomo Travaglini --- src/arch/arm/linux/se_workload.cc | 6 +++--- src/arch/mips/linux/linux.hh | 12 +++++++++++ src/arch/mips/linux/se_workload.cc | 13 +++++++++++- src/arch/power/linux/se_workload.cc | 13 +++++++++++- src/arch/riscv/linux/se_workload.cc | 19 +++++++++++++---- src/arch/sparc/linux/linux.hh | 15 ++++++++++++++ src/arch/sparc/linux/syscalls.cc | 15 ++++++++++++-- src/arch/x86/linux/linux.hh | 5 +++-- src/arch/x86/linux/syscall_tbl32.cc | 13 +++++++++++- src/arch/x86/linux/syscall_tbl64.cc | 13 +++++++++++- src/kern/linux/linux.hh | 4 ++-- src/sim/syscall_emul.cc | 32 +++++++++++++---------------- src/sim/syscall_emul.hh | 32 +++++++++++++++++++++-------- 13 files changed, 149 insertions(+), 43 deletions(-) diff --git a/src/arch/arm/linux/se_workload.cc b/src/arch/arm/linux/se_workload.cc index 83d6788c91..ef9c9136dc 100644 --- a/src/arch/arm/linux/se_workload.cc +++ b/src/arch/arm/linux/se_workload.cc @@ -163,7 +163,7 @@ class SyscallTable32 : public SyscallDescTable { base + 14, "mknod", mknodFunc }, { base + 15, "chmod", chmodFunc }, { base + 16, "lchown", chownFunc }, - { base + 19, "lseek", lseekFunc }, + { base + 19, "lseek", lseekFunc }, { base + 20, "getpid", getpidFunc }, { base + 21, "mount" }, { base + 22, "umount" }, @@ -567,7 +567,7 @@ class SyscallTable64 : public SyscallDescTable #else { base + 61, "getdents64" }, #endif - { base + 62, "llseek", lseekFunc }, + { base + 62, "lseek", lseekFunc }, { base + 63, "read", readFunc }, { base + 64, "write", writeFunc }, { base + 65, "readv" }, @@ -817,7 +817,7 @@ class SyscallTable64 : public SyscallDescTable { base + 1054, "newfstatat" }, { base + 1055, "fstatfs" }, { base + 1056, "statfs" }, - { base + 1057, "lseek", lseekFunc }, + { base + 1057, "lseek", lseekFunc }, { base + 1058, "mmap", mmapFunc }, { base + 1059, "alarm" }, { base + 1060, "getpgrp" }, diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index 2dab558750..393cceaedd 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -192,6 +203,7 @@ class MipsLinux : public Linux, public OpenFlagTable uint32_t mem_unit; /* Memory unit size in bytes */ }; + typedef int32_t off_t; }; } // namespace gem5 diff --git a/src/arch/mips/linux/se_workload.cc b/src/arch/mips/linux/se_workload.cc index 0f5cd788e2..0cb59d2f26 100644 --- a/src/arch/mips/linux/se_workload.cc +++ b/src/arch/mips/linux/se_workload.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright 2005 The Regents of The University of Michigan * Copyright 2007 MIPS Technologies, Inc. * Copyright 2020 Google Inc. @@ -177,7 +188,7 @@ SyscallDescTable EmuLinux::syscallDescs = { { 4016, "lchown", chownFunc }, { 4017, "break", brkFunc }, { 4018, "unused#18" }, - { 4019, "lseek", lseekFunc }, + { 4019, "lseek", lseekFunc }, { 4020, "getpid", getpidFunc }, { 4021, "mount" }, { 4022, "umount" }, diff --git a/src/arch/power/linux/se_workload.cc b/src/arch/power/linux/se_workload.cc index c376b5f723..5304de8a15 100644 --- a/src/arch/power/linux/se_workload.cc +++ b/src/arch/power/linux/se_workload.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright 2003-2005 The Regents of The University of Michigan * Copyright 2007-2008 The Florida State University * Copyright 2009 The University of Edinburgh @@ -126,7 +137,7 @@ SyscallDescTable EmuLinux::syscallDescs = { { 16, "lchown", chownFunc }, { 17, "break", brkFunc }, //??? { 18, "unused#18" }, //??? - { 19, "lseek", lseekFunc }, + { 19, "lseek", lseekFunc }, { 20, "getpid", getpidFunc }, { 21, "mount" }, { 22, "umount" }, diff --git a/src/arch/riscv/linux/se_workload.cc b/src/arch/riscv/linux/se_workload.cc index 952fe7140f..acd7d7c094 100644 --- a/src/arch/riscv/linux/se_workload.cc +++ b/src/arch/riscv/linux/se_workload.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright 2005 The Regents of The University of Michigan * Copyright 2007 MIPS Technologies, Inc. * Copyright 2016 The University of Virginia @@ -190,7 +201,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { #else { 61, "getdents64" }, #endif - { 62, "lseek", lseekFunc }, + { 62, "lseek", lseekFunc }, { 63, "read", readFunc }, { 64, "write", writeFunc }, { 66, "writev", writevFunc }, @@ -432,7 +443,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { { 1054, "newfstatat", newfstatatFunc }, { 1055, "fstatfs", fstatfsFunc }, { 1056, "statfs", statfsFunc }, - { 1057, "lseek", lseekFunc }, + { 1057, "lseek", lseekFunc }, { 1058, "mmap", mmapFunc }, { 1059, "alarm" }, { 1060, "getpgrp", getpgrpFunc }, @@ -529,7 +540,7 @@ SyscallDescTable EmuLinux::syscallDescs32 = { #else { 61, "getdents64" }, #endif - { 62, "lseek", lseekFunc }, + { 62, "lseek", lseekFunc }, { 63, "read", readFunc }, { 64, "write", writeFunc }, { 66, "writev", writevFunc }, @@ -771,7 +782,7 @@ SyscallDescTable EmuLinux::syscallDescs32 = { { 1054, "newfstatat", newfstatatFunc }, { 1055, "fstatfs", fstatfsFunc }, { 1056, "statfs", statfsFunc }, - { 1057, "lseek", lseekFunc }, + { 1057, "lseek", lseekFunc }, { 1058, "mmap", mmapFunc }, { 1059, "alarm" }, { 1060, "getpgrp", getpgrpFunc }, diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index 5913ddb737..eae4651e99 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * @@ -242,6 +253,8 @@ class SparcLinux : public Linux, public OpenFlagTable ptc->setReg(SparcISA::SyscallPseudoReturnReg, (RegVal)0); ctc->setReg(SparcISA::SyscallPseudoReturnReg, 1); } + + typedef int64_t off_t; }; class Sparc32Linux : public SparcLinux @@ -288,6 +301,8 @@ class Sparc32Linux : public SparcLinux uint32_t mem_unit; /* Memory unit size in bytes */ }; + typedef int32_t off_t; + /// Resource constants for getrlimit() (overide some generics). static const unsigned TGT_RLIMIT_NPROC = 7; static const unsigned TGT_RLIMIT_NOFILE = 6; diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 093fc9ccd3..1b5be17fca 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * @@ -104,7 +115,7 @@ SyscallDescTable EmuLinux::syscall32Descs = { { 16, "lchown" }, // 32 bit { 17, "brk", brkFunc }, { 18, "perfctr" }, // 32 bit - { 19, "lseek", lseekFunc }, // 32 bit + { 19, "lseek", lseekFunc }, // 32 bit { 20, "getpid", getpidFunc }, { 21, "capget" }, { 22, "capset" }, @@ -407,7 +418,7 @@ SyscallDescTable EmuLinux::syscallDescs = { { 16, "lchown" }, { 17, "brk", brkFunc }, { 18, "perfctr" }, - { 19, "lseek", lseekFunc }, + { 19, "lseek", lseekFunc }, { 20, "getpid", getpidFunc }, { 21, "capget" }, { 22, "capset" }, diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index 2b2031cc3c..caebbe8247 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Arm Limited * Copyright (c) 2007 The Hewlett-Packard Development Company * All rights reserved. * @@ -240,7 +241,7 @@ class X86Linux64 : public X86Linux, public OpenFlagTable //@{ /// Basic X86_64 Linux types typedef uint64_t size_t; - typedef uint64_t off_t; + typedef int64_t off_t; typedef int64_t time_t; typedef int64_t clock_t; //@} @@ -387,7 +388,7 @@ class X86Linux32 : public X86Linux, public OpenFlagTable //@{ /// Basic X86 Linux types typedef uint32_t size_t; - typedef uint32_t off_t; + typedef int32_t off_t; typedef int32_t time_t; typedef int32_t clock_t; //@} diff --git a/src/arch/x86/linux/syscall_tbl32.cc b/src/arch/x86/linux/syscall_tbl32.cc index 2de334cee3..02f12f1014 100644 --- a/src/arch/x86/linux/syscall_tbl32.cc +++ b/src/arch/x86/linux/syscall_tbl32.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright 2020 Google Inc. * * Redistribution and use in source and binary forms, with or without @@ -58,7 +69,7 @@ SyscallDescTable EmuLinux::syscallDescs32 = { { 16, "lchown" }, { 17, "break" }, { 18, "oldstat" }, - { 19, "lseek" }, + { 19, "lseek", lseekFunc }, { 20, "getpid", getpidFunc }, { 21, "mount" }, { 22, "umount" }, diff --git a/src/arch/x86/linux/syscall_tbl64.cc b/src/arch/x86/linux/syscall_tbl64.cc index 1b3dfaf020..c8bd28ced1 100644 --- a/src/arch/x86/linux/syscall_tbl64.cc +++ b/src/arch/x86/linux/syscall_tbl64.cc @@ -1,4 +1,15 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright 2020 Google Inc. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +58,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { { 5, "fstat", fstat64Func }, { 6, "lstat", lstat64Func }, { 7, "poll", pollFunc }, - { 8, "lseek", lseekFunc }, + { 8, "lseek", lseekFunc }, { 9, "mmap", mmapFunc }, { 10, "mprotect", ignoreFunc }, { 11, "munmap", munmapFunc }, diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 5b7a20ff4a..9d1d5392de 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Arm Limited + * Copyright (c) 2021, 2024 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -66,7 +66,7 @@ class Linux : public OperatingSystem //@{ /// Basic Linux types. typedef uint64_t size_t; - typedef uint64_t off_t; + typedef int64_t off_t; typedef int64_t time_t; typedef int64_t clock_t; typedef uint32_t uid_t; diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 9794a4835e..28fe4798ae 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2024 Arm Limited + * + * The license below extends only to copyright in the software and + * shall not be construed as granting a license to any other + * intellectual property including but not limited to intellectual + * property relating to a hardware implementation of the + * functionality of the software licensed hereunder. You may use the + * software subject to the license terms below provided that you + * ensure that this notice is replicated unmodified and in its + * entirety in all distributions of the software, modified or + * unmodified, in source code or in binary form. + * * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * @@ -292,26 +304,10 @@ closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd) return p->fds->closeFDEntry(tgt_fd); } -SyscallReturn -lseekFunc(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, uint64_t offs, int whence) -{ - auto p = tc->getProcessPtr(); - - auto ffdp = std::dynamic_pointer_cast((*p->fds)[tgt_fd]); - if (!ffdp) - return -EBADF; - int sim_fd = ffdp->getSimFD(); - - off_t result = lseek(sim_fd, offs, whence); - - return (result == (off_t)-1) ? -errno : result; -} - SyscallReturn _llseekFunc(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, uint64_t offset_high, uint32_t offset_low, + int tgt_fd, uint32_t offset_high, uint32_t offset_low, VPtr<> result_ptr, int whence) { auto p = tc->getProcessPtr(); @@ -321,7 +317,7 @@ _llseekFunc(SyscallDesc *desc, ThreadContext *tc, return -EBADF; int sim_fd = ffdp->getSimFD(); - uint64_t offset = (offset_high << 32) | offset_low; + uint64_t offset = ((uint64_t) offset_high << 32) | offset_low; uint64_t result = lseek(sim_fd, offset, whence); result = htog(result, tc->getSystemPtr()->getGuestByteOrder()); diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 4c822d14a1..37d4a598eb 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, 2015, 2019-2021, 2023 Arm Limited + * Copyright (c) 2012-2013, 2015, 2019-2021, 2023-2024 Arm Limited * Copyright (c) 2015 Advanced Micro Devices, Inc. * All rights reserved * @@ -160,13 +160,9 @@ SyscallReturn brkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> new_brk); /// Target close() handler. SyscallReturn closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd); -/// Target lseek() handler. -SyscallReturn lseekFunc(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, uint64_t offs, int whence); - /// Target _llseek() handler. SyscallReturn _llseekFunc(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, uint64_t offset_high, + int tgt_fd, uint32_t offset_high, uint32_t offset_low, VPtr<> result_ptr, int whence); /// Target shutdown() handler. @@ -976,6 +972,24 @@ openFunc(SyscallDesc *desc, ThreadContext *tc, desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_flags, mode); } +/// Target lseek() handler +template +SyscallReturn +lseekFunc(SyscallDesc *desc, ThreadContext *tc, + int tgt_fd, typename OS::off_t offs, int whence) +{ + auto p = tc->getProcessPtr(); + + auto ffdp = std::dynamic_pointer_cast((*p->fds)[tgt_fd]); + if (!ffdp) + return -EBADF; + int sim_fd = ffdp->getSimFD(); + + off_t result = lseek(sim_fd, offs, whence); + + return (result == (off_t)-1) ? -errno : result; +} + /// Target unlinkat() handler. template SyscallReturn @@ -2092,7 +2106,8 @@ mmapFunc(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn pread64Func(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, VPtr<> bufPtr, int nbytes, int offset) + int tgt_fd, VPtr<> bufPtr, int nbytes, + typename OS::off_t offset) { auto p = tc->getProcessPtr(); @@ -2113,7 +2128,8 @@ pread64Func(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn pwrite64Func(SyscallDesc *desc, ThreadContext *tc, - int tgt_fd, VPtr<> bufPtr, int nbytes, int offset) + int tgt_fd, VPtr<> bufPtr, int nbytes, + typename OS::off_t offset) { auto p = tc->getProcessPtr();