syscall_emul.hh (13569:47a2291177a7) | syscall_emul.hh (13570:b6484720c6a9) |
---|---|
1/* 2 * Copyright (c) 2012-2013, 2015 ARM Limited 3 * Copyright (c) 2015 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 64 unchanged lines hidden (view full) --- 73/// This file defines objects used to emulate syscalls from the target 74/// application on the host machine. 75 76#ifdef __CYGWIN32__ 77#include <sys/fcntl.h> 78 79#endif 80#include <fcntl.h> | 1/* 2 * Copyright (c) 2012-2013, 2015 ARM Limited 3 * Copyright (c) 2015 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 64 unchanged lines hidden (view full) --- 73/// This file defines objects used to emulate syscalls from the target 74/// application on the host machine. 75 76#ifdef __CYGWIN32__ 77#include <sys/fcntl.h> 78 79#endif 80#include <fcntl.h> |
81#include <poll.h> |
|
81#include <sys/mman.h> 82#include <sys/socket.h> 83#include <sys/stat.h> 84#if (NO_STATFS == 0) 85#include <sys/statfs.h> 86#else 87#include <sys/mount.h> 88#endif 89#include <sys/time.h> | 82#include <sys/mman.h> 83#include <sys/socket.h> 84#include <sys/stat.h> 85#if (NO_STATFS == 0) 86#include <sys/statfs.h> 87#else 88#include <sys/mount.h> 89#endif 90#include <sys/time.h> |
91#include <sys/types.h> |
|
90#include <sys/uio.h> 91#include <unistd.h> 92 93#include <cerrno> 94#include <memory> 95#include <string> 96 97#include "arch/generic/tlb.hh" --- 59 unchanged lines hidden (view full) --- 157/// Target brk() handler: set brk address. 158SyscallReturn brkFunc(SyscallDesc *desc, int num, 159 Process *p, ThreadContext *tc); 160 161/// Target close() handler. 162SyscallReturn closeFunc(SyscallDesc *desc, int num, 163 Process *p, ThreadContext *tc); 164 | 92#include <sys/uio.h> 93#include <unistd.h> 94 95#include <cerrno> 96#include <memory> 97#include <string> 98 99#include "arch/generic/tlb.hh" --- 59 unchanged lines hidden (view full) --- 159/// Target brk() handler: set brk address. 160SyscallReturn brkFunc(SyscallDesc *desc, int num, 161 Process *p, ThreadContext *tc); 162 163/// Target close() handler. 164SyscallReturn closeFunc(SyscallDesc *desc, int num, 165 Process *p, ThreadContext *tc); 166 |
165// Target read() handler. 166SyscallReturn readFunc(SyscallDesc *desc, int num, 167 Process *p, ThreadContext *tc); 168 169/// Target write() handler. 170SyscallReturn writeFunc(SyscallDesc *desc, int num, 171 Process *p, ThreadContext *tc); 172 | |
173/// Target lseek() handler. 174SyscallReturn lseekFunc(SyscallDesc *desc, int num, 175 Process *p, ThreadContext *tc); 176 177/// Target _llseek() handler. 178SyscallReturn _llseekFunc(SyscallDesc *desc, int num, 179 Process *p, ThreadContext *tc); 180 --- 760 unchanged lines hidden (view full) --- 941 // do the chmod 942 int result = chmod(path.c_str(), hostMode); 943 if (result < 0) 944 return -errno; 945 946 return 0; 947} 948 | 167/// Target lseek() handler. 168SyscallReturn lseekFunc(SyscallDesc *desc, int num, 169 Process *p, ThreadContext *tc); 170 171/// Target _llseek() handler. 172SyscallReturn _llseekFunc(SyscallDesc *desc, int num, 173 Process *p, ThreadContext *tc); 174 --- 760 unchanged lines hidden (view full) --- 935 // do the chmod 936 int result = chmod(path.c_str(), hostMode); 937 if (result < 0) 938 return -errno; 939 940 return 0; 941} 942 |
943template <class OS> 944SyscallReturn 945pollFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 946{ 947 int index = 0; 948 Addr fdsPtr = p->getSyscallArg(tc, index); 949 int nfds = p->getSyscallArg(tc, index); 950 int tmout = p->getSyscallArg(tc, index); |
|
949 | 951 |
952 BufferArg fdsBuf(fdsPtr, sizeof(struct pollfd) * nfds); 953 fdsBuf.copyIn(tc->getMemProxy()); 954 955 /** 956 * Record the target file descriptors in a local variable. We need to 957 * replace them with host file descriptors but we need a temporary copy 958 * for later. Afterwards, replace each target file descriptor in the 959 * poll_fd array with its host_fd. 960 */ 961 int temp_tgt_fds[nfds]; 962 for (index = 0; index < nfds; index++) { 963 temp_tgt_fds[index] = ((struct pollfd *)fdsBuf.bufferPtr())[index].fd; 964 auto tgt_fd = temp_tgt_fds[index]; 965 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]); 966 if (!hbfdp) 967 return -EBADF; 968 auto host_fd = hbfdp->getSimFD(); 969 ((struct pollfd *)fdsBuf.bufferPtr())[index].fd = host_fd; 970 } 971 972 /** 973 * We cannot allow an infinite poll to occur or it will inevitably cause 974 * a deadlock in the gem5 simulator with clone. We must pass in tmout with 975 * a non-negative value, however it also makes no sense to poll on the 976 * underlying host for any other time than tmout a zero timeout. 977 */ 978 int status; 979 if (tmout < 0) { 980 status = poll((struct pollfd *)fdsBuf.bufferPtr(), nfds, 0); 981 if (status == 0) { 982 /** 983 * If blocking indefinitely, check the signal list to see if a 984 * signal would break the poll out of the retry cycle and try 985 * to return the signal interrupt instead. 986 */ 987 System *sysh = tc->getSystemPtr(); 988 std::list<BasicSignal>::iterator it; 989 for (it=sysh->signalList.begin(); it!=sysh->signalList.end(); it++) 990 if (it->receiver == p) 991 return -EINTR; 992 return SyscallReturn::retry(); 993 } 994 } else 995 status = poll((struct pollfd *)fdsBuf.bufferPtr(), nfds, 0); 996 997 if (status == -1) 998 return -errno; 999 1000 /** 1001 * Replace each host_fd in the returned poll_fd array with its original 1002 * target file descriptor. 1003 */ 1004 for (index = 0; index < nfds; index++) { 1005 auto tgt_fd = temp_tgt_fds[index]; 1006 ((struct pollfd *)fdsBuf.bufferPtr())[index].fd = tgt_fd; 1007 } 1008 1009 /** 1010 * Copy out the pollfd struct because the host may have updated fields 1011 * in the structure. 1012 */ 1013 fdsBuf.copyOut(tc->getMemProxy()); 1014 1015 return status; 1016} 1017 |
|
950/// Target fchmod() handler. 951template <class OS> 952SyscallReturn 953fchmodFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc) 954{ 955 int index = 0; 956 int tgt_fd = p->getSyscallArg(tc, index); 957 uint32_t mode = p->getSyscallArg(tc, index); --- 306 unchanged lines hidden (view full) --- 1264 if (result < 0) 1265 return -errno; 1266 1267 copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (sim_fd == 1)); 1268 1269 return 0; 1270} 1271 | 1018/// Target fchmod() handler. 1019template <class OS> 1020SyscallReturn 1021fchmodFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc) 1022{ 1023 int index = 0; 1024 int tgt_fd = p->getSyscallArg(tc, index); 1025 uint32_t mode = p->getSyscallArg(tc, index); --- 306 unchanged lines hidden (view full) --- 1332 if (result < 0) 1333 return -errno; 1334 1335 copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (sim_fd == 1)); 1336 1337 return 0; 1338} 1339 |
1272 | |
1273/// Target statfs() handler. 1274template <class OS> 1275SyscallReturn 1276statfsFunc(SyscallDesc *desc, int callnum, Process *process, 1277 ThreadContext *tc) 1278{ 1279#if NO_STATFS 1280 warn("Host OS cannot support calls to statfs. Ignoring syscall"); --- 872 unchanged lines hidden (view full) --- 2153 fds[0] = p->fds->allocFD(sfdp1); 2154 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1], domain, type, prot); 2155 fds[1] = p->fds->allocFD(sfdp2); 2156 svBuf.copyOut(tc->getMemProxy()); 2157 2158 return status; 2159} 2160 | 1340/// Target statfs() handler. 1341template <class OS> 1342SyscallReturn 1343statfsFunc(SyscallDesc *desc, int callnum, Process *process, 1344 ThreadContext *tc) 1345{ 1346#if NO_STATFS 1347 warn("Host OS cannot support calls to statfs. Ignoring syscall"); --- 872 unchanged lines hidden (view full) --- 2220 fds[0] = p->fds->allocFD(sfdp1); 2221 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1], domain, type, prot); 2222 fds[1] = p->fds->allocFD(sfdp2); 2223 svBuf.copyOut(tc->getMemProxy()); 2224 2225 return status; 2226} 2227 |
2228template <class OS> 2229SyscallReturn 2230selectFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc) 2231{ 2232 int retval; 2233 2234 int index = 0; 2235 int nfds_t = p->getSyscallArg(tc, index); 2236 Addr fds_read_ptr = p->getSyscallArg(tc, index); 2237 Addr fds_writ_ptr = p->getSyscallArg(tc, index); 2238 Addr fds_excp_ptr = p->getSyscallArg(tc, index); 2239 Addr time_val_ptr = p->getSyscallArg(tc, index); 2240 2241 TypedBufferArg<typename OS::fd_set> rd_t(fds_read_ptr); 2242 TypedBufferArg<typename OS::fd_set> wr_t(fds_writ_ptr); 2243 TypedBufferArg<typename OS::fd_set> ex_t(fds_excp_ptr); 2244 TypedBufferArg<typename OS::timeval> tp(time_val_ptr); 2245 2246 /** 2247 * Host fields. Notice that these use the definitions from the system 2248 * headers instead of the gem5 headers and libraries. If the host and 2249 * target have different header file definitions, this will not work. 2250 */ 2251 fd_set rd_h; 2252 FD_ZERO(&rd_h); 2253 fd_set wr_h; 2254 FD_ZERO(&wr_h); 2255 fd_set ex_h; 2256 FD_ZERO(&ex_h); 2257 2258 /** 2259 * Copy in the fd_set from the target. 2260 */ 2261 if (fds_read_ptr) 2262 rd_t.copyIn(tc->getMemProxy()); 2263 if (fds_writ_ptr) 2264 wr_t.copyIn(tc->getMemProxy()); 2265 if (fds_excp_ptr) 2266 ex_t.copyIn(tc->getMemProxy()); 2267 2268 /** 2269 * We need to translate the target file descriptor set into a host file 2270 * descriptor set. This involves both our internal process fd array 2271 * and the fd_set defined in Linux header files. The nfds field also 2272 * needs to be updated as it will be only target specific after 2273 * retrieving it from the target; the nfds value is expected to be the 2274 * highest file descriptor that needs to be checked, so we need to extend 2275 * it out for nfds_h when we do the update. 2276 */ 2277 int nfds_h = 0; 2278 std::map<int, int> trans_map; 2279 auto try_add_host_set = [&](fd_set *tgt_set_entry, 2280 fd_set *hst_set_entry, 2281 int iter) -> bool 2282 { 2283 /** 2284 * By this point, we know that we are looking at a valid file 2285 * descriptor set on the target. We need to check if the target file 2286 * descriptor value passed in as iter is part of the set. 2287 */ 2288 if (FD_ISSET(iter, tgt_set_entry)) { 2289 /** 2290 * We know that the target file descriptor belongs to the set, 2291 * but we do not yet know if the file descriptor is valid or 2292 * that we have a host mapping. Check that now. 2293 */ 2294 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[iter]); 2295 if (!hbfdp) 2296 return true; 2297 auto sim_fd = hbfdp->getSimFD(); 2298 2299 /** 2300 * Add the sim_fd to tgt_fd translation into trans_map for use 2301 * later when we need to zero the target fd_set structures and 2302 * then update them with hits returned from the host select call. 2303 */ 2304 trans_map[sim_fd] = iter; 2305 2306 /** 2307 * We know that the host file descriptor exists so now we check 2308 * if we need to update the max count for nfds_h before passing 2309 * the duplicated structure into the host. 2310 */ 2311 nfds_h = std::max(nfds_h - 1, sim_fd + 1); 2312 2313 /** 2314 * Add the host file descriptor to the set that we are going to 2315 * pass into the host. 2316 */ 2317 FD_SET(sim_fd, hst_set_entry); 2318 } 2319 return false; 2320 }; 2321 2322 for (int i = 0; i < nfds_t; i++) { 2323 if (fds_read_ptr) { 2324 bool ebadf = try_add_host_set((fd_set*)&*rd_t, &rd_h, i); 2325 if (ebadf) return -EBADF; 2326 } 2327 if (fds_writ_ptr) { 2328 bool ebadf = try_add_host_set((fd_set*)&*wr_t, &wr_h, i); 2329 if (ebadf) return -EBADF; 2330 } 2331 if (fds_excp_ptr) { 2332 bool ebadf = try_add_host_set((fd_set*)&*ex_t, &ex_h, i); 2333 if (ebadf) return -EBADF; 2334 } 2335 } 2336 2337 if (time_val_ptr) { 2338 /** 2339 * It might be possible to decrement the timeval based on some 2340 * derivation of wall clock determined from elapsed simulator ticks 2341 * but that seems like overkill. Rather, we just set the timeval with 2342 * zero timeout. (There is no reason to block during the simulation 2343 * as it only decreases simulator performance.) 2344 */ 2345 tp->tv_sec = 0; 2346 tp->tv_usec = 0; 2347 2348 retval = select(nfds_h, 2349 fds_read_ptr ? &rd_h : nullptr, 2350 fds_writ_ptr ? &wr_h : nullptr, 2351 fds_excp_ptr ? &ex_h : nullptr, 2352 (timeval*)&*tp); 2353 } else { 2354 /** 2355 * If the timeval pointer is null, setup a new timeval structure to 2356 * pass into the host select call. Unfortunately, we will need to 2357 * manually check the return value and throw a retry fault if the 2358 * return value is zero. Allowing the system call to block will 2359 * likely deadlock the event queue. 2360 */ 2361 struct timeval tv = { 0, 0 }; 2362 2363 retval = select(nfds_h, 2364 fds_read_ptr ? &rd_h : nullptr, 2365 fds_writ_ptr ? &wr_h : nullptr, 2366 fds_excp_ptr ? &ex_h : nullptr, 2367 &tv); 2368 2369 if (retval == 0) { 2370 /** 2371 * If blocking indefinitely, check the signal list to see if a 2372 * signal would break the poll out of the retry cycle and try to 2373 * return the signal interrupt instead. 2374 */ 2375 for (auto sig : tc->getSystemPtr()->signalList) 2376 if (sig.receiver == p) 2377 return -EINTR; 2378 return SyscallReturn::retry(); 2379 } 2380 } 2381 2382 if (retval == -1) 2383 return -errno; 2384 2385 FD_ZERO((fd_set*)&*rd_t); 2386 FD_ZERO((fd_set*)&*wr_t); 2387 FD_ZERO((fd_set*)&*ex_t); 2388 2389 /** 2390 * We need to translate the host file descriptor set into a target file 2391 * descriptor set. This involves both our internal process fd array 2392 * and the fd_set defined in header files. 2393 */ 2394 for (int i = 0; i < nfds_h; i++) { 2395 if (fds_read_ptr) { 2396 if (FD_ISSET(i, &rd_h)) 2397 FD_SET(trans_map[i], (fd_set*)&*rd_t); 2398 } 2399 2400 if (fds_writ_ptr) { 2401 if (FD_ISSET(i, &wr_h)) 2402 FD_SET(trans_map[i], (fd_set*)&*wr_t); 2403 } 2404 2405 if (fds_excp_ptr) { 2406 if (FD_ISSET(i, &ex_h)) 2407 FD_SET(trans_map[i], (fd_set*)&*ex_t); 2408 } 2409 } 2410 2411 if (fds_read_ptr) 2412 rd_t.copyOut(tc->getMemProxy()); 2413 if (fds_writ_ptr) 2414 wr_t.copyOut(tc->getMemProxy()); 2415 if (fds_excp_ptr) 2416 ex_t.copyOut(tc->getMemProxy()); 2417 if (time_val_ptr) 2418 tp.copyOut(tc->getMemProxy()); 2419 2420 return retval; 2421} 2422 2423template <class OS> 2424SyscallReturn 2425readFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 2426{ 2427 int index = 0; 2428 int tgt_fd = p->getSyscallArg(tc, index); 2429 Addr buf_ptr = p->getSyscallArg(tc, index); 2430 int nbytes = p->getSyscallArg(tc, index); 2431 2432 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]); 2433 if (!hbfdp) 2434 return -EBADF; 2435 int sim_fd = hbfdp->getSimFD(); 2436 2437 struct pollfd pfd; 2438 pfd.fd = sim_fd; 2439 pfd.events = POLLIN | POLLPRI; 2440 if ((poll(&pfd, 1, 0) == 0) 2441 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK)) 2442 return SyscallReturn::retry(); 2443 2444 BufferArg buf_arg(buf_ptr, nbytes); 2445 int bytes_read = read(sim_fd, buf_arg.bufferPtr(), nbytes); 2446 2447 if (bytes_read > 0) 2448 buf_arg.copyOut(tc->getMemProxy()); 2449 2450 return (bytes_read == -1) ? -errno : bytes_read; 2451} 2452 2453template <class OS> 2454SyscallReturn 2455writeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 2456{ 2457 int index = 0; 2458 int tgt_fd = p->getSyscallArg(tc, index); 2459 Addr buf_ptr = p->getSyscallArg(tc, index); 2460 int nbytes = p->getSyscallArg(tc, index); 2461 2462 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]); 2463 if (!hbfdp) 2464 return -EBADF; 2465 int sim_fd = hbfdp->getSimFD(); 2466 2467 BufferArg buf_arg(buf_ptr, nbytes); 2468 buf_arg.copyIn(tc->getMemProxy()); 2469 2470 struct pollfd pfd; 2471 pfd.fd = sim_fd; 2472 pfd.events = POLLOUT; 2473 2474 /** 2475 * We don't want to poll on /dev/random. The kernel will not enable the 2476 * file descriptor for writing unless the entropy in the system falls 2477 * below write_wakeup_threshold. This is not guaranteed to happen 2478 * depending on host settings. 2479 */ 2480 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(hbfdp); 2481 if (ffdp && (ffdp->getFileName() != "/dev/random")) { 2482 if (!poll(&pfd, 1, 0) && !(ffdp->getFlags() & OS::TGT_O_NONBLOCK)) 2483 return SyscallReturn::retry(); 2484 } 2485 2486 int bytes_written = write(sim_fd, buf_arg.bufferPtr(), nbytes); 2487 2488 if (bytes_written != -1) 2489 fsync(sim_fd); 2490 2491 return (bytes_written == -1) ? -errno : bytes_written; 2492} 2493 2494template <class OS> 2495SyscallReturn 2496wait4Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 2497{ 2498 int index = 0; 2499 pid_t pid = p->getSyscallArg(tc, index); 2500 Addr statPtr = p->getSyscallArg(tc, index); 2501 int options = p->getSyscallArg(tc, index); 2502 Addr rusagePtr = p->getSyscallArg(tc, index); 2503 2504 if (rusagePtr) 2505 DPRINTFR(SyscallVerbose, 2506 "%d: %s: syscall wait4: rusage pointer provided however " 2507 "functionality not supported. Ignoring rusage pointer.\n", 2508 curTick(), tc->getCpuPtr()->name()); 2509 2510 /** 2511 * Currently, wait4 is only implemented so that it will wait for children 2512 * exit conditions which are denoted by a SIGCHLD signals posted into the 2513 * system signal list. We return no additional information via any of the 2514 * parameters supplied to wait4. If nothing is found in the system signal 2515 * list, we will wait indefinitely for SIGCHLD to post by retrying the 2516 * call. 2517 */ 2518 System *sysh = tc->getSystemPtr(); 2519 std::list<BasicSignal>::iterator iter; 2520 for (iter=sysh->signalList.begin(); iter!=sysh->signalList.end(); iter++) { 2521 if (iter->receiver == p) { 2522 if (pid < -1) { 2523 if ((iter->sender->pgid() == -pid) 2524 && (iter->signalValue == OS::TGT_SIGCHLD)) 2525 goto success; 2526 } else if (pid == -1) { 2527 if (iter->signalValue == OS::TGT_SIGCHLD) 2528 goto success; 2529 } else if (pid == 0) { 2530 if ((iter->sender->pgid() == p->pgid()) 2531 && (iter->signalValue == OS::TGT_SIGCHLD)) 2532 goto success; 2533 } else { 2534 if ((iter->sender->pid() == pid) 2535 && (iter->signalValue == OS::TGT_SIGCHLD)) 2536 goto success; 2537 } 2538 } 2539 } 2540 2541 return (options & OS::TGT_WNOHANG) ? 0 : SyscallReturn::retry(); 2542 2543success: 2544 // Set status to EXITED for WIFEXITED evaluations. 2545 const int EXITED = 0; 2546 BufferArg statusBuf(statPtr, sizeof(int)); 2547 *(int *)statusBuf.bufferPtr() = EXITED; 2548 statusBuf.copyOut(tc->getMemProxy()); 2549 2550 // Return the child PID. 2551 pid_t retval = iter->sender->pid(); 2552 sysh->signalList.erase(iter); 2553 return retval; 2554} 2555 2556template <class OS> 2557SyscallReturn 2558acceptFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 2559{ 2560 struct sockaddr sa; 2561 socklen_t addrLen; 2562 int host_fd; 2563 int index = 0; 2564 int tgt_fd = p->getSyscallArg(tc, index); 2565 Addr addrPtr = p->getSyscallArg(tc, index); 2566 Addr lenPtr = p->getSyscallArg(tc, index); 2567 2568 BufferArg *lenBufPtr = nullptr; 2569 BufferArg *addrBufPtr = nullptr; 2570 2571 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]); 2572 if (!sfdp) 2573 return -EBADF; 2574 int sim_fd = sfdp->getSimFD(); 2575 2576 /** 2577 * We poll the socket file descriptor first to guarantee that we do not 2578 * block on our accept call. The socket can be opened without the 2579 * non-blocking flag (it blocks). This will cause deadlocks between 2580 * communicating processes. 2581 */ 2582 struct pollfd pfd; 2583 pfd.fd = sim_fd; 2584 pfd.events = POLLIN | POLLPRI; 2585 if ((poll(&pfd, 1, 0) == 0) 2586 && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK)) 2587 return SyscallReturn::retry(); 2588 2589 if (lenPtr) { 2590 lenBufPtr = new BufferArg(lenPtr, sizeof(socklen_t)); 2591 lenBufPtr->copyIn(tc->getMemProxy()); 2592 memcpy(&addrLen, (socklen_t *)lenBufPtr->bufferPtr(), 2593 sizeof(socklen_t)); 2594 } 2595 2596 if (addrPtr) { 2597 addrBufPtr = new BufferArg(addrPtr, sizeof(struct sockaddr)); 2598 addrBufPtr->copyIn(tc->getMemProxy()); 2599 memcpy(&sa, (struct sockaddr *)addrBufPtr->bufferPtr(), 2600 sizeof(struct sockaddr)); 2601 } 2602 2603 host_fd = accept(sim_fd, &sa, &addrLen); 2604 2605 if (host_fd == -1) 2606 return -errno; 2607 2608 if (addrPtr) { 2609 memcpy(addrBufPtr->bufferPtr(), &sa, sizeof(sa)); 2610 addrBufPtr->copyOut(tc->getMemProxy()); 2611 delete(addrBufPtr); 2612 } 2613 2614 if (lenPtr) { 2615 *(socklen_t *)lenBufPtr->bufferPtr() = addrLen; 2616 lenBufPtr->copyOut(tc->getMemProxy()); 2617 delete(lenBufPtr); 2618 } 2619 2620 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain, 2621 sfdp->_type, sfdp->_protocol); 2622 return p->fds->allocFD(afdp); 2623} 2624 |
|
2161#endif // __SIM_SYSCALL_EMUL_HH__ | 2625#endif // __SIM_SYSCALL_EMUL_HH__ |