commit 29d4f61e6ad1d0f20332b87aec4777c85b1559d1 Author: Kamil Rytarowski Date: Thu Dec 5 01:35:54 2019 +0100 fix diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index 883be33024dc..d66d07d039c9 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,1106 +1,1106 @@ # $NetBSD: GENERIC,v 1.547 2019/11/20 09:37:45 hikaru Exp $ # # GENERIC machine description file # # This machine description file is used to generate the default NetBSD # kernel. The generic kernel does not include all options, subsystems # and device drivers, but should be useful for most applications. # # The machine description file can be customised for your specific # machine to reduce the kernel size and improve its performance. # # For further information on compiling NetBSD kernels, see the config(8) # man page. # # For further information on hardware support for this architecture, see # the intro(4) man page. For further information about kernel options # for this architecture, see the options(4) man page. For an explanation # of each device driver in this file see the section 4 man page for the # device. include "arch/amd64/conf/std.amd64" options INCLUDE_CONFIG_FILE # embed config file in kernel binary #ident "GENERIC-$Revision: 1.547 $" maxusers 64 # estimated number of users # delay between "rebooting ..." message and hardware reset, in milliseconds #options CPURESET_DELAY=2000 # This option allows you to force a serial console at the specified # I/O address. see console(4) for details. #options CONSDEVNAME="\"com\"",CONADDR=0x2f8,CONSPEED=57600 # you don't want the option below ON iff you are using the # serial console option of the new boot strap code. #options CONS_OVERRIDE # Always use above! independent of boot info # The following options override the memory sizes passed in from the boot # block. Use them *only* if the boot block is unable to determine the correct # values. Note that the BIOS may *correctly* report less than 640k of base # memory if the extended BIOS data area is located at the top of base memory # (as is the case on most recent systems). #options REALBASEMEM=639 # size of base memory (in KB) #options REALEXTMEM=15360 # size of extended memory (in KB) # The following options limit the overall size of physical memory # and/or the maximum address used by the system. # Contrary to REALBASEMEM and REALEXTMEM, they still use the BIOS memory map # and can deal with holes in the memory layout. #options PHYSMEM_MAX_SIZE=64 # max size of physical memory (in MB) #options PHYSMEM_MAX_ADDR=2048 # don't use memory above this (in MB) # Standard system options options INSECURE # disable kernel security levels - X needs this options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT options NTP # NTP phase/frequency locked loop options KTRACE # system call tracing via ktrace(1) options CPU_UCODE # cpu ucode loading support # Note: SysV IPC parameters could be changed dynamically, see sysctl(8). options SYSVMSG # System V-like message queues options SYSVSEM # System V-like semaphores options SYSVSHM # System V-like memory sharing options MODULAR # new style module(7) framework options MODULAR_DEFAULT_AUTOLOAD options USERCONF # userconf(4) support #options PIPE_SOCKETPAIR # smaller, but slower pipe(2) options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel # CPU-related options #options USER_LDT # User-settable LDT, used by Wine options SVS # Separate Virtual Space makeoptions SPECTRE_V2_GCC_MITIGATION=1 # GCC Spectre variant 2 # migitation options SPECTRE_V2_GCC_MITIGATION # CPU features acpicpu* at cpu? # ACPI CPU (including frequency scaling) coretemp* at cpu? # Intel on-die thermal sensor est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI) hyperv0 at cpu0 # Microsoft Hyper-V #odcm0 at cpu0 # On-demand clock modulation powernow0 at cpu0 # AMD PowerNow! and Cool'n'Quiet (non-ACPI) vmt0 at cpu0 # VMware Tools # Alternate buffer queue strategies for better responsiveness under high # disk I/O load. #options BUFQ_READPRIO options BUFQ_PRIOCSCAN # Diagnostic/debugging support options options DIAGNOSTIC # inexpensive kernel consistency checks # XXX to be commented out on release branch #options DEBUG # expensive debugging checks/support #options LOCKDEBUG # expensive locking checks/support # # Because gcc omits the frame pointer for any -O level, the line below # is needed to make backtraces in DDB work. # -makeoptions COPTS="-O2 -fno-omit-frame-pointer" +makeoptions COPTS="-O0 -g -fno-omit-frame-pointer -fno-inline" options DDB # in-kernel debugger #options DDB_COMMANDONENTER="bt" # execute command when ddb is entered #options DDB_ONPANIC=1 # see also sysctl(7): `ddb.onpanic' options DDB_HISTORY_SIZE=512 # enable history editing in DDB #options KGDB # remote debugger #options KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600 makeoptions DEBUG="-g" # compile full symbol table for CTF #options KUBSAN # Kernel Undefined Behavior Sanitizer (kUBSan) #options UBSAN_ALWAYS_FATAL # (optional) Panic on all kUBSan reports #options SYSCALL_STATS # per syscall counts #options SYSCALL_TIMES # per syscall times #options SYSCALL_TIMES_HASCOUNTER # use 'broken' rdtsc (soekris) options KDTRACE_HOOKS # kernel DTrace hooks # Kernel Address Sanitizer (kASan). You need to disable SVS to use it. # The quarantine is optional and can help KASAN find more use-after-frees. # Use KASAN_PANIC if you want panics instead of warnings. #makeoptions KASAN=1 # mandatory #options KASAN # mandatory #no options SVS # mandatory #options POOL_QUARANTINE # optional #options KASAN_PANIC # optional # Kernel Concurrency Sanitizer (kCSan). #makeoptions KCSAN=1 # mandatory #options KCSAN # mandatory #options KCSAN_PANIC # optional # Kernel Memory Sanitizer (kMSan). You need to disable SVS and kernel modules # to use it. The quarantine is optional and can help KMSAN find uninitialized # memory in pool caches. Note that KMSAN requires at least 4GB of RAM. #makeoptions KMSAN=1 # mandatory #options KMSAN # mandatory #no options SVS # mandatory #no options MODULAR # mandatory #no options MODULAR_DEFAULT_AUTOLOAD # mandatory #options POOL_QUARANTINE # optional #options KMSAN_PANIC # optional # Kernel Info Leak Detector. #makeoptions KLEAK=1 #options KLEAK # Kernel Code Coverage Driver. #makeoptions KCOV=1 #options KCOV # Compatibility options # x86_64 never shipped with a.out binaries; the two options below are # only relevant to 32-bit i386 binaries #options EXEC_AOUT # required by binaries from before 1.5 #options COMPAT_NOMID # NetBSD 0.8, 386BSD, and BSDI # NetBSD backward compatibility. Support goes from COMPAT_15 up until # the latest release. Note that really old compat (< COMPAT_16) is only # useful for 32-bit i386 binaries. include "conf/compat_netbsd15.config" #options COMPAT_386BSD_MBRPART # recognize old partition ID options COMPAT_OSSAUDIO options COMPAT_NETBSD32 options COMPAT_LINUX options COMPAT_LINUX32 # req. COMPAT_LINUX and COMPAT_NETBSD32 options EXEC_ELF32 # Wedge support options DKWEDGE_AUTODISCOVER # Automatically add dk(4) instances options DKWEDGE_METHOD_GPT # Supports GPT partitions as wedges #options DKWEDGE_METHOD_BSDLABEL # Support disklabel entries as wedges #options DKWEDGE_METHOD_MBR # Support MBR partitions as wedges options DKWEDGE_METHOD_APPLE # Support Apple partitions as wedges #options DKWEDGE_METHOD_RDB # Support RDB partitions as wedges # File systems include "conf/filesystems.config" # File system options # ffs options QUOTA # legacy UFS quotas options QUOTA2 # new, in-filesystem UFS quotas options FFS_EI # FFS Endian Independent support options WAPBL # File system journaling support # Note that UFS_DIRHASH is suspected of causing kernel memory corruption. # It is not recommended for general use. #options UFS_DIRHASH # UFS Large Directory Hashing - Experimental #options FFS_NO_SNAPSHOT # No FFS snapshot support options UFS_EXTATTR # Extended attribute support for UFS1 # ext2fs #options EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and # immutable) behave as system flags. # other options DISKLABEL_EI # disklabel Endian Independent support options NFSSERVER # Network File System server # Networking options #options GATEWAY # packet forwarding options INET # IP + ICMP + TCP + UDP options INET6 # IPV6 options IPSEC # IP security #options IPSEC_DEBUG # debug for IP security #options MPLS # MultiProtocol Label Switching (needs mpls) #options MROUTING # IP multicast routing #options PIM # Protocol Independent Multicast options NETATALK # AppleTalk networking protocols #options CAN # Controller Area Network protocol options PPP_BSDCOMP # BSD-Compress compression support for PPP options PPP_DEFLATE # Deflate compression support for PPP options PPP_FILTER # Active filter support for PPP (requires bpf) #options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG #options TCP_SIGNATURE # Enable RFC-2385 TCP md5 signatures #options ALTQ # Manipulate network interfaces' output queues #options ALTQ_BLUE # Stochastic Fair Blue #options ALTQ_CBQ # Class-Based Queueing #options ALTQ_CDNR # Diffserv Traffic Conditioner #options ALTQ_FIFOQ # First-In First-Out Queue #options ALTQ_FLOWVALVE # RED/flow-valve (red-penalty-box) #options ALTQ_HFSC # Hierarchical Fair Service Curve #options ALTQ_LOCALQ # Local queueing discipline #options ALTQ_PRIQ # Priority Queueing #options ALTQ_RED # Random Early Detection #options ALTQ_RIO # RED with IN/OUT #options ALTQ_WFQ # Weighted Fair Queueing # These options enable verbose messages for several subsystems. # Warning, these may compile large string tables into the kernel! #options ACPIVERBOSE # verbose ACPI configuration messages #options MIIVERBOSE # verbose PHY autoconfig messages #options PCIVERBOSE # verbose PCI device autoconfig messages #options PCI_CONFIG_DUMP # verbosely dump PCI config space #options PCMCIAVERBOSE # verbose PCMCIA configuration messages options SCSIVERBOSE # human readable SCSI error messages #options USBVERBOSE # verbose USB device autoconfig messages #options HDAUDIOVERBOSE # verbose HDAUDIO driver messages options NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM # # wscons options # # builtin terminal emulations options WSEMUL_VT100 # VT100 / VT220 emulation #options WSEMUL_SUN # sun terminal emulation #options WSEMUL_DEFAULT="\"vt100\"" # NB: default is "sun" if enabled # different kernel output - see dev/wscons/wsdisplayvar.h options WS_KERNEL_FG=WSCOL_GREEN #options WS_KERNEL_BG=WSCOL_BLACK # compatibility to other console drivers options WSDISPLAY_COMPAT_PCVT # emulate some ioctls options WSDISPLAY_COMPAT_SYSCONS # emulate some ioctls options WSDISPLAY_COMPAT_USL # wsconscfg VT handling options WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes # don't attach pckbd as the console if no PS/2 keyboard is found options PCKBD_CNATTACH_MAY_FAIL # see dev/pckbport/wskbdmap_mfii.c for implemented layouts #options PCKBD_LAYOUT="(KB_DE | KB_NODEAD)" # allocate a number of virtual screens at autoconfiguration time #options WSDISPLAY_DEFAULTSCREENS=4 # use a large software cursor that doesn't blink options PCDISPLAY_SOFTCURSOR # modify the screen type of the console; defaults to "80x25" #options VGA_CONSOLE_SCREENTYPE="\"80x24\"" # work around a hardware bug that loaded fonts don't work; found on ATI cards #options VGA_CONSOLE_ATI_BROKEN_FONTSEL # console scrolling support. options WSDISPLAY_SCROLLSUPPORT # enable VGA raster mode capable of displaying multilingual text on console #options VGA_RASTERCONSOLE # enable splash screen support; requires genfb or radeonfb #options SPLASHSCREEN # Kernel root file system and dump configuration. config netbsd root on ? type ? #config netbsd root on sd0a type ffs #config netbsd root on ? type nfs # # Device configuration # #IPMI support ipmi0 at mainbus? ipmi_acpi* at acpi? ipmi0 at ipmi_acpi? # ACPI will be used if present. If not it will fall back to MPBIOS acpi0 at mainbus0 options ACPI_SCANPCI # find PCI roots using ACPI options MPBIOS # configure CPUs and APICs using MPBIOS options MPBIOS_SCANPCI # MPBIOS configures PCI roots #options PCI_INTR_FIXUP # PCI interrupt routing via ACPI #options PCI_BUS_FIXUP # fixup PCI bus numbering #options PCI_ADDR_FIXUP # fixup PCI I/O addresses #options ACPI_ACTIVATE_DEV # If set, activate inactive devices options VGA_POST # in-kernel support for VGA POST # ACPI devices acpiacad* at acpi? # ACPI AC Adapter acpibat* at acpi? # ACPI Battery acpibut* at acpi? # ACPI Button acpidalb* at acpi? # Direct Application Launch Button acpiec* at acpi? # ACPI Embedded Controller (late) acpiecdt* at acpi? # ACPI Embedded Controller (early) acpifan* at acpi? # ACPI Fan acpilid* at acpi? # ACPI Lid Switch #acpipmtr* at acpi? # ACPI Power Meter (experimental) #acpismbus* at acpi? # ACPI SMBus CMI (experimental) acpitz* at acpi? # ACPI Thermal Zone acpivga* at acpi? # ACPI Display Adapter acpiout* at acpivga? # ACPI Display Output Device acpiwdrt* at acpi? # ACPI Watchdog Resource Table acpiwmi* at acpi? # ACPI WMI Mapper # Mainboard devices aibs* at acpi? # ASUSTeK AI Booster hardware monitor asus* at acpi? # ASUS hotkeys attimer* at acpi? # AT Timer #com* at acpi? # Serial communications interface #fdc* at acpi? # Floppy disk controller fujbp* at acpi? # Fujitsu Brightness & Pointer fujhk* at acpi? # Fujitsu Hotkeys #hpacel* at acpi? # HP 3D DriveGuard accelerometer #hpqlb* at acpi? # HP Quick Launch Buttons hpet* at acpihpetbus? # High Precision Event Timer (table) hpet* at acpinodebus? # High Precision Event Timer (device) joy* at acpi? # Joystick/Game port #lpt* at acpi? # Parallel port mpu* at acpi? # Roland MPU-401 MIDI UART pckbc* at acpi? # PC keyboard controller pcppi* at acpi? # AT-style speaker sound qemufwcfg* at acpi? # QEMU Firmware Configuration device sdhc* at acpi? # SD Host Controller sony* at acpi? # Sony Notebook Controller spic* at acpi? # Sony Programmable I/O Controller wsmouse* at spic? # mouse thinkpad* at acpi? # IBM/Lenovo Thinkpad hotkeys #tpm* at acpi? # ACPI TPM (Experimental) ug* at acpi? # Abit uGuru Hardware monitor valz* at acpi? # Toshiba Dynabook hotkeys wb* at acpi? # Winbond W83L518D SD/MMC reader sdmmc* at wb? # SD/MMC bus wmidell* at acpiwmibus? # Dell WMI mappings wmieeepc* at acpiwmibus? # Asus Eee PC WMI mappings wmihp* at acpiwmibus? # HP WMI mappings wmimsi* at acpiwmibus? # MSI WMI mappings # Basic Bus Support # PCI bus support pci* at mainbus? bus ? pci* at pchb? bus ? pci* at ppb? bus ? # PCI bridges pchb* at pci? dev ? function ? # PCI-Host bridges options AGP_X86 pcib* at pci? dev ? function ? # PCI-ISA bridges ppb* at pci? dev ? function ? # PCI-PCI bridges # XXX 'puc's aren't really bridges, but there's no better place for them here puc* at pci? dev ? function ? # PCI "universal" comm. cards amdpcib* at pci? dev ? function ? # AMD 8111 PCI-ISA w/ HPET hpet* at amdpcib? pwdog* at pci? dev ? function ? # QUANCOM PWDOG1 ichlpcib* at pci? dev ? function ? # Intel ICH PCI-LPC w/ timecounter, # watchdog, gpio, Speedstep and HPET fwhrng* at ichlpcib? # Intel 82802 FWH Random Number Generator #hpet* at ichlpcib? tco* at ichlpcib? # TCO watch dog timer aapic* at pci? dev ? function ? # AMD 8131 IO apic agp* at pchb? # ISA bus support isa0 at mainbus? isa0 at pcib? #isa0 at amdpcib? isa0 at ichlpcib? # CardBus bridge support cbb* at pci? dev ? function ? cardslot* at cbb? # CardBus bus support cardbus* at cardslot? pcmcia* at cardslot? # Console Devices # wscons pckbc0 at isa? # pc keyboard controller pckbd* at pckbc? # PC keyboard pms* at pckbc? # PS/2 mouse for wsmouse #options PMS_DISABLE_POWERHOOK # Disable PS/2 reset on resume options PMS_SYNAPTICS_TOUCHPAD # Enable support for Synaptics Touchpads options PMS_ELANTECH_TOUCHPAD # Enable support for Elantech Touchpads options PMS_ALPS_TOUCHPAD # Enable support for Alps Touchpads vga* at pci? dev ? function ? genfb* at pci? dev ? function ? options VCONS_DRAW_INTR wsdisplay* at vga? console ? wsdisplay* at wsemuldisplaydev? wskbd* at pckbd? console ? wsmouse* at pms? mux 0 wsmouse* at wsmousedev? attimer0 at isa? pcppi0 at isa? sysbeep0 at pcppi? # DRI legacy drivers #i915drm* at drm? # Intel i915, i945 DRM driver #mach64drm* at drm? # mach64 (3D Rage Pro, Rage) DRM driver #mgadrm* at drm? # Matrox G[24]00, G[45]50 DRM driver #r128drm* at drm? # ATI Rage 128 DRM driver #radeondrm* at drm? # ATI Radeon DRM driver #savagedrm* at drm? # S3 Savage DRM driver #sisdrm* at drm? # SiS DRM driver #tdfxdrm* at drm? # 3dfx (voodoo) DRM driver # DRMKMS drivers i915drmkms* at pci? dev ? function ? intelfb* at intelfbbus? radeon* at pci? dev ? function ? radeondrmkmsfb* at radeonfbbus? #amdgpu* at pci? dev ? function ? #amdgpufb* at amdgpufbbus? nouveau* at pci? dev ? function ? nouveaufb* at nouveaufbbus? # DRMUMS drivers #viadrmums* at drm? # Cryptographic Devices # PCI cryptographic devices hifn* at pci? dev ? function ? # Hifn 7755/7811/795x #qat* at pci? dev ? function ? # Intel QuickAssist ubsec* at pci? dev ? function ? # Broadcom 5501/5601/580x/582x # Trusted Platform Module tpm* at isa? iomem 0xfed40000 irq 7 # Serial Devices # PCI serial interfaces com* at puc? port ? # 16x50s on "universal" comm boards cy* at pci? dev ? function ? # Cyclades Cyclom-Y serial boards cz* at pci? dev ? function ? # Cyclades-Z multi-port serial boards # PCMCIA serial interfaces com* at pcmcia? function ? # Modems and serial cards pcmcom* at pcmcia? function ? # PCMCIA multi-port serial cards com* at pcmcom? slave ? # ...and the slave devices # CardBus serial interfaces com* at cardbus? function ? # Modems and serial cards # ISA serial interfaces #options COM_HAYESP # adds Hayes ESP serial board support com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports com1 at isa? port 0x2f8 irq 3 # Parallel Printer Interfaces # PCI parallel printer interfaces lpt* at puc? port ? # || ports on "universal" comm boards # ISA parallel printer interfaces lpt0 at isa? port 0x378 irq 7 # standard PC parallel ports lpt1 at isa? port 0x278 # Hardware monitors amdnb_misc* at pci? # AMD NB Misc Configuration amdtemp* at amdnb_misc? # AMD CPU Temperature sensors amdsmn* at pci? # AMD SMN Configuration amdzentemp* at amdsmnbus? # AMD Ryzen Family 17h CPU temp sensors # Winbond LPC Super I/O #wbsio* at isa? port 0x2e #wbsio* at isa? port 0x4e # IBM Hawk Integrated Systems Management Processor #ibmhawk0 at iic? addr 0x37 # LM7[89] and compatible hardware monitors # Use flags to select temp sensor type (see lm(4) man page for details) #lm0 at isa? port 0x290 flags 0x0 # other common ports: 0x280, 0x310 #lm* at wbsio? # SMSC LPC47B397 hardware monitor functions #smsc0 at isa? port 0x02e # SMSC LPC47M192 hardware monitor #smscmon* at iic? addr 0x2c #smscmon* at iic? addr 0x2d # (alternate address) # AMD 768 and 8111 power/ACPI controllers amdpm* at pci? dev ? function ? # RNG and SMBus 1.0 interface #iic* at amdpm? # sensors below are on this bus # NVIDIA nForce2/3/4 SMBus controller nfsmbc* at pci? dev ? function ? nfsmb* at nfsmbc? iic* at nfsmb? # Intel PIIX4 power management controllers piixpm* at pci? dev ? function ? # PIIX4 compatible PM controller iic* at piixpm? # SMBus on PIIX4 # Intel ICH SMBus controller ichsmb* at pci? dev ? function ? iic* at ichsmb? # Intel S1200,C2000 (non-pch) SMBus controller ismt* at pci? dev ? function ? iic* at ismt? # I2C controller as found in some Intel PCH devices. dwiic* at pci? # I2C controller iic* at dwiic? # Thermal monitor and fan controller #dbcool* at iic? addr 0x2C # Unknown other motherboard(s) #dbcool* at iic? addr 0x2D # Tyan S2881 #dbcool* at iic? addr 0x2E # Tyan S2882-D # IBM Thinkpad Active Protection System #aps0 at isa? port 0x1600 # Fintek Super I/O with hardware monitor #finsio0 at isa? port 0x4e # iTE IT87xxF Super I/O with watchdog and sensors support #itesio0 at isa? port 0x2e # Abit uGuru Hardware system monitor #ug0 at isa? port 0xe0 # Serial Presence Detect capable memory modules #spdmem* at iic? addr 0x50 #spdmem* at iic? addr 0x51 #spdmem* at iic? addr 0x52 #spdmem* at iic? addr 0x53 #spdmem* at iic? addr 0x54 #spdmem* at iic? addr 0x55 #spdmem* at iic? addr 0x56 #spdmem* at iic? addr 0x57 #sdtemp* at iic? addr 0x18 #sdtemp* at iic? addr 0x19 #sdtemp* at iic? addr 0x1a #sdtemp* at iic? addr 0x1b #sdtemp* at iic? addr 0x1c #sdtemp* at iic? addr 0x1d #sdtemp* at iic? addr 0x1e #sdtemp* at iic? addr 0x1f # I2C HID devices ihidev* at iic? # I2C Mice ims* at ihidev? reportid ? wsmouse* at ims? mux 0 # I2O devices iop* at pci? dev ? function ? # I/O processor iopsp* at iop? tid ? # SCSI/FC-AL ports ld* at iop? tid ? # block devices # XXX dpti.c wants a processor type that is not assigned for x86-64 #dpti* at iop? tid 0 # DPT/Adaptec control interface # GPIO devices gpio* at gpiobus? # 1- Wire support #gpioow* at gpio? offset ? mask ? # 1-wire bitbanging via gpio gpioow* at gpio? onewire* at gpioow? # 1-Wire devices owtemp* at onewire? # Temperature sensors # I2C support #gpioiic* at gpio? #iic* at gpioiic? # Keylock support #gpiolock* at gpio? # Pulsing GPIO pins in software #gpiopwm* at gpio? # Soekris 6501 GPIO/LED driver (provides gpiobus, needs gpio) #soekrisgpio0 at isa? port 0x680 # Nuvoton NCT5104D SuperIO providing GPIO nct0 at isa? port ? # SCSI Controllers and Devices # PCI SCSI controllers adv* at pci? dev ? function ? # AdvanSys 1200[A,B], 9xx[U,UA] SCSI adw* at pci? dev ? function ? # AdvanSys 9x0UW[D], 3940U[2,3]W SCSI ahc* at pci? dev ? function ? # Adaptec [23]94x, aic78x0 SCSI ahd* at pci? dev ? function ? # Adaptec aic790x SCSI bha* at pci? dev ? function ? # BusLogic 9xx SCSI dpt* at pci? dev ? function ? # DPT SmartCache/SmartRAID iha* at pci? dev ? function ? # Initio INIC-940/950 SCSI isp* at pci? dev ? function ? # Qlogic ISP [12]0x0 SCSI/FibreChannel mfi* at pci? dev ? function ? # LSI MegaRAID SAS mfii* at pci? dev ? function ? # LSI MegaRAID SAS (Fusion and newer) mly* at pci? dev ? function ? # Mylex AcceleRAID and eXtremeRAID mpt* at pci? dev ? function ? # LSILogic 9x9 and 53c1030 (Fusion-MPT) mpii* at pci? dev ? function ? # LSI Logic Fusion-MPT II njs* at pci? dev ? function ? # Workbit NinjaSCSI-32 pcscp* at pci? dev ? function ? # AMD 53c974 PCscsi-PCI SCSI siop* at pci? dev ? function ? # Symbios 53c8xx SCSI esiop* at pci? dev ? function ? # Symbios 53c875 and newer SCSI #options SIOP_SYMLED # drive the act. LED in software trm* at pci? dev ? function ? # Tekram DC-395U/UW/F, DC-315/U SCSI # PCMCIA SCSI controllers aic* at pcmcia? function ? # Adaptec APA-1460 SCSI esp* at pcmcia? function ? # Qlogic ESP406/FAS408 SCSI spc* at pcmcia? function ? # Fujitsu MB87030/MB89352 SCSI # CardBus SCSI cards adv* at cardbus? function ? # AdvanSys 1200[A,B], 9xx[U,UA] SCSI ahc* at cardbus? function ? # Adaptec ADP-1480 njs* at cardbus? function ? # Workbit NinjaSCSI-32 # SCSI bus support scsibus* at scsi? # SCSI devices sd* at scsibus? target ? lun ? # SCSI disk drives st* at scsibus? target ? lun ? # SCSI tape drives cd* at scsibus? target ? lun ? # SCSI CD-ROM drives ch* at scsibus? target ? lun ? # SCSI autochangers ses* at scsibus? target ? lun ? # SCSI Enclosure Services devices ss* at scsibus? target ? lun ? # SCSI scanners uk* at scsibus? target ? lun ? # SCSI unknown # RAID controllers and devices aac* at pci? dev ? function ? # Adaptec AAC family amr* at pci? dev ? function ? # AMI/LSI Logic MegaRAID arcmsr* at pci? dev ? function ? # Areca SATA RAID controllers cac* at pci? dev ? function ? # Compaq PCI array controllers ciss* at pci? dev ? function ? # HP Smart Array controllers icp* at pci? dev ? function ? # ICP-Vortex GDT & Intel RAID mlx* at pci? dev ? function ? # Mylex DAC960 & DEC SWXCR family twe* at pci? dev ? function ? # 3ware Escalade RAID controllers twa* at pci? dev ? function ? # 3ware Escalade 9xxx RAID controllers ld* at aac? unit ? ld* at amr? unit ? ld* at cac? unit ? ld* at icp? unit ? ld* at twe? unit ? ld* at twa? unit ? ld* at mlx? unit ? icpsp* at icp? unit ? # SCSI pass-through # IDE and related devices # PCI IDE controllers - see pciide(4) for supported hardware. # The 0x0001 flag force the driver to use DMA, even if the driver doesn't know # how to set up DMA modes for this chip. This may work, or may cause # a machine hang with some controllers. pciide* at pci? dev ? function ? flags 0x0000 # GENERIC pciide driver acardide* at pci? dev ? function ? # Acard IDE controllers aceride* at pci? dev ? function ? # Acer Lab IDE controllers ahcisata* at pci? dev ? function ? # AHCI SATA controllers artsata* at pci? dev ? function ? # Intel i31244 SATA controller cmdide* at pci? dev ? function ? # CMD tech IDE controllers cypide* at pci? dev ? function ? # Cypress IDE controllers hptide* at pci? dev ? function ? # Triones/HighPoint IDE controllers iteide* at pci? dev ? function ? # IT Express IDE controllers ixpide* at pci? dev ? function ? # ATI IXP IDE controllers jmide* at pci? dev ? function ? # JMicron PCI-e PATA/SATA controllers ahcisata* at jmide? mvsata* at pci? dev ? function ? # Marvell Hercules-I/II optiide* at pci? dev ? function ? # Opti IDE controllers piixide* at pci? dev ? function ? # Intel IDE controllers pdcide* at pci? dev ? function ? # Promise IDE controllers pdcsata* at pci? dev ? function ? # Promise SATA150 controllers satalink* at pci? dev ? function ? # SiI SATALink controllers siisata* at pci? dev ? function ? # SiI SteelVine controllers siside* at pci? dev ? function ? # SiS IDE controllers slide* at pci? dev ? function ? # Symphony Labs IDE controllers svwsata* at pci? dev ? function ? # ServerWorks SATA controllers toshide* at pci? dev ? function ? # TOSHIBA PICCOLO controllers viaide* at pci? dev ? function ? # VIA/AMD/Nvidia IDE controllers # PCMCIA IDE controllers wdc* at pcmcia? function ? # CardBus IDE controllers njata* at cardbus? function ? flags 0x01 # Workbit NinjaATA-32 siisata* at cardbus? function ? # SiI SteelVine controllers # ISA ST506, ESDI, and IDE controllers # Use flags 0x01 if you want to try to use 32bits data I/O (the driver will # fall back to 16bits I/O if 32bits I/O are not functional). # Some controllers pass the initial 32bit test, but will fail later. wdc0 at isa? port 0x1f0 irq 14 flags 0x00 wdc1 at isa? port 0x170 irq 15 flags 0x00 # ATA (IDE) bus support atabus* at ata? options ATADEBUG # IDE drives # Flags are used only with controllers that support DMA operations # and mode settings (e.g. some pciide controllers) # The lowest order four bits (rightmost digit) of the flags define the PIO # mode to use, the next set of four bits the DMA mode and the third set the # UltraDMA mode. For each set of four bits, the 3 lower bits define the mode # to use, and the last bit must be 1 for this setting to be used. # For DMA and UDMA, 0xf (1111) means 'disable'. # 0x0fac means 'use PIO mode 4, DMA mode 2, disable UltraDMA'. # (0xc=1100, 0xa=1010, 0xf=1111) # 0x0000 means "use whatever the drive claims to support". wd* at atabus? drive ? flags 0x0000 # ATAPI bus support atapibus* at atapi? # ATA RAID configuration support, as found on some Promise controllers. pseudo-device ataraid ld* at ataraid? vendtype ? unit ? # ATAPI devices # flags have the same meaning as for IDE drives. cd* at atapibus? drive ? flags 0x0000 # ATAPI CD-ROM drives sd* at atapibus? drive ? flags 0x0000 # ATAPI disk drives st* at atapibus? drive ? flags 0x0000 # ATAPI tape drives uk* at atapibus? drive ? flags 0x0000 # ATAPI unknown # NVM Express controllers and devices nvme* at pci? dev ? function ? ld* at nvme? nsid ? # Miscellaneous mass storage devices # ISA floppy fdc0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy controllers #fdc1 at isa? port 0x370 irq ? drq ? fd* at fdc? drive ? # the drives themselves # some machines need you to do this instead of fd* #fd0 at fdc0 drive 0 # Network Interfaces # PCI network interfaces age* at pci? dev ? function ? # Attansic/Atheros L1 Gigabit Ethernet alc* at pci? dev ? function ? # Attansic/Atheros L1C/L2C Ethernet ale* at pci? dev ? function ? # Attansic/Atheros L1E Ethernet an* at pci? dev ? function ? # Aironet PC4500/PC4800 (802.11) ath* at pci? dev ? function ? # Atheros 5210/5211/5212 802.11 athn* at pci? dev ? function ? # Atheros AR9k (802.11a/g/n) atw* at pci? dev ? function ? # ADMtek ADM8211 (802.11) bce* at pci? dev ? function ? # Broadcom 440x 10/100 Ethernet bge* at pci? dev ? function ? # Broadcom 570x gigabit Ethernet bnx* at pci? dev ? function ? # Broadcom NetXtremeII gigabit Ethernet bwi* at pci? dev ? function ? # Broadcom BCM43xx wireless bwfm* at pci? dev ? function ? # Broadcom FullMAC dge* at pci? dev ? function ? # Intel 82597 10GbE LR ena* at pci? dev ? function ? # Amazon.com Elastic Network Adapter ep* at pci? dev ? function ? # 3Com 3c59x epic* at pci? dev ? function ? # SMC EPIC/100 Ethernet esh* at pci? dev ? function ? # Essential HIPPI card et* at pci? dev ? function ? # Agere/LSI ET1310/ET1301 Gigabit ex* at pci? dev ? function ? # 3Com 90x[BC] fpa* at pci? dev ? function ? # DEC DEFPA FDDI fxp* at pci? dev ? function ? # Intel EtherExpress PRO 10+/100B gem* at pci? dev ? function ? # Apple GMAC and Sun ERI gigabit enet gsip* at pci? dev ? function ? # NS83820 Gigabit Ethernet ipw* at pci? dev ? function ? # Intel PRO/Wireless 2100 iwi* at pci? dev ? function ? # Intel PRO/Wireless 2200BG iwm* at pci? dev ? function ? # Intel Centrino 7260 iwn* at pci? dev ? function ? # Intel PRO/Wireless 4965AGN ixg* at pci? dev ? function ? # Intel 8259x 10 gigabit ixv* at pci? dev ? function ? # Intel 8259x 10G virtual function jme* at pci? dev ? function ? # JMicron JMC2[56]0 ethernet hme* at pci? dev ? function ? # Sun Microelectronics STP2002-STQ le* at pci? dev ? function ? # PCnet-PCI Ethernet lii* at pci? dev ? function ? # Atheros L2 Fast-Ethernet malo* at pci? dev ? function ? # Marvell Libertas Wireless mcx* at pci? dev ? function ? # Mellanox 5th generation Ethernet mskc* at pci? dev ? function ? # Marvell Yukon 2 Gigabit Ethernet msk* at mskc? # Marvell Yukon 2 Gigabit Ethernet mtd* at pci? dev ? function ? # Myson MTD803 3-in-1 Ethernet ne* at pci? dev ? function ? # NE2000-compatible Ethernet nfe* at pci? dev ? function ? # NVIDIA nForce Ethernet ntwoc* at pci? dev ? function ? # Riscom/N2 PCI Sync Serial pcn* at pci? dev ? function ? # AMD PCnet-PCI Ethernet ral* at pci? dev ? function ? # Ralink Technology RT25x0 802.11a/b/g re* at pci? dev ? function ? # Realtek 8139C+/8169/8169S/8110S rtk* at pci? dev ? function ? # Realtek 8129/8139 rtw* at pci? dev ? function ? # Realtek 8180L (802.11) rtwn* at pci? dev ? function ? # Realtek 8188CE/8192CE 802.11b/g/n sf* at pci? dev ? function ? # Adaptec AIC-6915 Ethernet sip* at pci? dev ? function ? # SiS 900/DP83815 Ethernet skc* at pci? dev ? function ? # SysKonnect SK9821 Gigabit Ethernet sk* at skc? # SysKonnect SK9821 Gigabit Ethernet ste* at pci? dev ? function ? # Sundance ST-201 Ethernet stge* at pci? dev ? function ? # Sundance/Tamarack TC9021 Gigabit ti* at pci? dev ? function ? # Alteon ACEnic gigabit Ethernet tl* at pci? dev ? function ? # ThunderLAN-based Ethernet tlp* at pci? dev ? function ? # DECchip 21x4x and clones txp* at pci? dev ? function ? # 3com 3cr990 vge* at pci? dev ? function ? # VIATech VT612X Gigabit Ethernet vmx* at pci? dev ? function ? # VMware VMXNET3 vr* at pci? dev ? function ? # VIA Rhine Fast Ethernet wi* at pci? dev ? function ? # Intersil Prism Mini-PCI (802.11b) wm* at pci? dev ? function ? # Intel 82543/82544 gigabit wpi* at pci? dev ? function ? # Intel PRO/Wireless 3945ABG xge* at pci? dev ? function ? # Neterion (S2io) Xframe-I 10GbE # PCMCIA network interfaces an* at pcmcia? function ? # Aironet PC4500/PC4800 (802.11) awi* at pcmcia? function ? # BayStack 650/660 (802.11FH/DS) cnw* at pcmcia? function ? # Xircom/Netwave AirSurfer cs* at pcmcia? function ? # CS89xx Ethernet ep* at pcmcia? function ? # 3Com 3c589 and 3c562 Ethernet malo* at pcmcia? function ? # Marvell Libertas mbe* at pcmcia? function ? # MB8696x based Ethernet ne* at pcmcia? function ? # NE2000-compatible Ethernet ray* at pcmcia? function ? # Raytheon Raylink (802.11) sm* at pcmcia? function ? # Megahertz Ethernet # tr at pcmcia has problems with Cardbus bridges #tr* at pcmcia? function ? # TROPIC based Token-Ring wi* at pcmcia? function ? # Lucent/Intersil WaveLan IEEE (802.11) xirc* at pcmcia? function ? # Xircom CreditCard Ethernet com* at xirc? xi* at xirc? mhzc* at pcmcia? function ? # Megahertz Ethernet/Modem combo cards com* at mhzc? sm* at mhzc? # CardBus network cards ath* at cardbus? function ? # Atheros 5210/5211/5212 802.11 athn* at cardbus? function ? # Atheros AR9k (802.11a/g/n) - UNTESTED atw* at cardbus? function ? # ADMtek ADM8211 (802.11) ex* at cardbus? function ? # 3Com 3C575TX fxp* at cardbus? function ? # Intel i8255x malo* at cardbus? function ? # Marvell Libertas Wireless ral* at cardbus? function ? # Ralink Technology RT25x0 802.11a/b/g re* at cardbus? function ? # Realtek 8139C+/8169/8169S/8110S rtk* at cardbus? function ? # Realtek 8129/8139 rtw* at cardbus? function ? # Realtek 8180L (802.11) tlp* at cardbus? function ? # DECchip 21143 # MII/PHY support acphy* at mii? phy ? # DAltima AC101 and AMD Am79c874 PHYs amhphy* at mii? phy ? # AMD 79c901 Ethernet PHYs atphy* at mii? phy ? # Attansic/Atheros PHYs bmtphy* at mii? phy ? # Broadcom BCM5201 and BCM5202 PHYs brgphy* at mii? phy ? # Broadcom BCM5400-family PHYs ciphy* at mii? phy ? # Cicada CS8201 Gig-E PHYs dmphy* at mii? phy ? # Davicom DM9101 PHYs etphy* at mii? phy ? # Agere/LSI ET1011 TruePHY Gig-E PHYs exphy* at mii? phy ? # 3Com internal PHYs gentbi* at mii? phy ? # Generic Ten-Bit 1000BASE-[CLS]X PHYs glxtphy* at mii? phy ? # Level One LXT-1000 PHYs gphyter* at mii? phy ? # NS83861 Gig-E PHY icsphy* at mii? phy ? # Integrated Circuit Systems ICS189x igphy* at mii? phy ? # Intel IGP01E1000 ihphy* at mii? phy ? # Intel 82577 PHYs ikphy* at mii? phy ? # Intel 82563 PHYs inphy* at mii? phy ? # Intel 82555 PHYs iophy* at mii? phy ? # Intel 82553 PHYs ipgphy* at mii? phy ? # IC PLUS IP1000A/IP1001 PHYs jmphy* at mii? phy ? # Jmicron JMP202/211 PHYs lxtphy* at mii? phy ? # Level One LXT-970 PHYs makphy* at mii? phy ? # Marvell Semiconductor 88E1000 PHYs nsphy* at mii? phy ? # NS83840 PHYs nsphyter* at mii? phy ? # NS83843 PHYs pnaphy* at mii? phy ? # generic HomePNA PHYs qsphy* at mii? phy ? # Quality Semiconductor QS6612 PHYs rgephy* at mii? phy ? # Realtek 8169S/8110 internal PHYs rlphy* at mii? phy ? # Realtek 8139/8201L PHYs smscphy* at mii? phy ? # SMSC LAN87xx PHYs sqphy* at mii? phy ? # Seeq 80220/80221/80223 PHYs tlphy* at mii? phy ? # ThunderLAN PHYs tqphy* at mii? phy ? # TDK Semiconductor PHYs ukphy* at mii? phy ? # generic unknown PHYs urlphy* at mii? phy ? # Realtek RTL8150L internal PHYs # USB Controller and Devices # Virtual USB controller #pseudo-device vhci # PCI USB controllers xhci* at pci? dev ? function ? # eXtensible Host Controller ehci* at pci? dev ? function ? # Enhanced Host Controller ohci* at pci? dev ? function ? # Open Host Controller uhci* at pci? dev ? function ? # Universal Host Controller (Intel) # CardBus USB controllers ehci* at cardbus? function ? # Enhanced Host Controller ohci* at cardbus? function ? # Open Host Controller uhci* at cardbus? function ? # Universal Host Controller (Intel) # ISA USB controllers #slhci0 at isa? port 0x300 irq 5 # ScanLogic SL811HS # PCMCIA USB controllers slhci* at pcmcia? function ? # ScanLogic SL811HS # USB bus support #usb* at vhci? usb* at xhci? usb* at ehci? usb* at ohci? usb* at uhci? usb* at slhci? include "dev/usb/usbdevices.config" # PCI IEEE1394 controllers fwohci* at pci? dev ? function ? # IEEE1394 Open Host Controller # CardBus IEEE1394 controllers fwohci* at cardbus? function ? # IEEE1394 Open Host Controller ieee1394if* at fwohci? fwip* at ieee1394if? # IP over IEEE1394 sbp* at ieee1394if? euihi ? euilo ? # Audio Devices # PCI audio devices auacer* at pci? dev ? function ? # ALi M5455 integrated AC'97 Audio auich* at pci? dev ? function ? # Intel/AMD/nVidia AC'97 Audio auixp* at pci? dev ? function ? # ATI IXP AC'97 Audio autri* at pci? dev ? function ? # Trident 4DWAVE based AC'97 Audio auvia* at pci? dev ? function ? # VIA AC'97 audio #azalia* at pci? dev ? function ? # High Definition Audio clcs* at pci? dev ? function ? # Cirrus Logic CS4280 clct* at pci? dev ? function ? # Cirrus Logic CS4281 cmpci* at pci? dev ? function ? # C-Media CMI8338/8738 eap* at pci? dev ? function ? # Ensoniq AudioPCI emuxki* at pci? dev ? function ? # Creative SBLive! and PCI512 esa* at pci? dev ? function ? # ESS Allegro-1 / Maestro-3 PCI Audio esm* at pci? dev ? function ? # ESS Maestro-1/2/2e PCI Audio Accelerator eso* at pci? dev ? function ? # ESS Solo-1 PCI AudioDrive fms* at pci? dev ? function ? # Forte Media FM801 neo* at pci? dev ? function ? # NeoMagic 256 AC'97 Audio sv* at pci? dev ? function ? # S3 SonicVibes yds* at pci? dev ? function ? # Yamaha DS-1 PCI Audio # OPL[23] FM synthesizers #opl0 at isa? port 0x388 # use only if not attached to sound card opl* at cmpci? flags 1 opl* at eso? opl* at fms? opl* at sv? # High Definition Audio hdaudio* at pci? dev ? function ? # High Definition Audio hdafg* at hdaudiobus? # Audio support audio* at audiobus? # The spkr driver provides a simple tone interface to the built in speaker. spkr* at pcppi? # PC speaker spkr* at audio? # PC speaker (synthesized) #wsbell* at spkr? # Bell for wscons display (module by default) # MPU 401 UARTs #mpu* at isa? port 0x330 irq 9 # MPU401 or compatible card mpu* at cmpci? mpu* at eso? mpu* at yds? # MIDI support midi* at midibus? midi* at pcppi? # MIDI interface to the PC speaker # FM-Radio devices # PCI radio devices #gtp* at pci? dev ? function ? # Guillemot Maxi Radio FM 2000 Radio Card # Radio support #radio* at gtp? # Video capture devices coram* at pci? dev ? function ? # Conexant CX23885 PCI-E TV cxdtv* at pci? dev ? function ? # Conexant CX2388[0-3] PCI TV video* at videobus? # Analog capture interface dtv* at dtvbus? # Digital capture interface # TV cards # Brooktree 848/849/878/879 based TV cards bktr* at pci? dev ? function ? radio* at bktr? # Bluetooth Controller and Device support # Bluetooth PCMCIA Controllers bt3c* at pcmcia? function ? # 3Com 3CRWB6096-A btbc* at pcmcia? function ? # AnyCom BlueCard LSE041/039/139 # Bluetooth SDIO Controllers sbt* at sdmmc? # Bluetooth USB Controllers ubt* at uhub? port ? aubtfwl* at uhub? port ? # Bluetooth Device Hub bthub* at bcsp? bthub* at bt3c? bthub* at btbc? bthub* at btuart? bthub* at sbt? bthub* at ubt? # Bluetooth HID support bthidev* at bthub? # Bluetooth Mouse btms* at bthidev? reportid ? wsmouse* at btms? mux 0 # Bluetooth Keyboard btkbd* at bthidev? reportid ? wskbd* at btkbd? console ? mux 1 # Bluetooth Apple Magic Mouse btmagic* at bthub? wsmouse* at btmagic? mux 0 # Bluetooth Audio support btsco* at bthub? # SD/MMC/SDIO Controller and Device support # SD/MMC controller sdhc* at pci? # SD Host Controller rtsx* at pci? # Realtek RTS5209/RTS5229 Card Reader sdhc* at cardbus? # SD Host Controller sdmmc* at sdhc? # SD/MMC bus sdmmc* at rtsx? # SD/MMC bus ld* at sdmmc? # Middle Digital, Inc. PCI-Weasel serial console board control # devices (watchdog timer, etc.) weasel* at pci? # Virtio devices virtio* at pci? dev ? function ? # Virtio PCI device viomb* at virtio? # Virtio memory balloon device ld* at virtio? # Virtio disk device vioif* at virtio? # Virtio network device viornd* at virtio? # Virtio entropy device vioscsi* at virtio? # Virtio SCSI device #vio9p* at virtio? # Virtio 9P device # Hyper-V devices vmbus* at acpi? # Hyper-V VMBus genfb* at vmbus? # Hyper-V Synthetic Video Framebuffer hvkbd* at vmbus? # Hyper-V Synthetic Keyboard wskbd* at hvkbd? console ? mux 1 hvn* at vmbus? # Hyper-V NetVSC hvs* at vmbus? # Hyper-V StorVSC hvheartbeat* at vmbus? # Hyper-V Heartbeat Service hvshutdown* at vmbus? # Hyper-V Guest Shutdown Service hvtimesync* at vmbus? # Hyper-V Time Synchronization Service #hvkvp* at vmbus? # Hyper-V Data Exchange Service diff --git a/sys/compat/netbsd32/netbsd32_ptrace.c b/sys/compat/netbsd32/netbsd32_ptrace.c index 1741b852051c..cb3a202157b5 100644 --- a/sys/compat/netbsd32/netbsd32_ptrace.c +++ b/sys/compat/netbsd32/netbsd32_ptrace.c @@ -1,295 +1,321 @@ /* $NetBSD: netbsd32_ptrace.c,v 1.7 2019/06/04 16:29:53 mgorny Exp $ */ /* * Copyright (c) 2016 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Nick Hudson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: netbsd32_ptrace.c,v 1.7 2019/06/04 16:29:53 mgorny Exp $"); #if defined(_KERNEL_OPT) #include "opt_ptrace.h" #include "opt_compat_netbsd.h" #endif #include #include #include #include #include #include #include #include #ifndef PTRACE_TRANSLATE_REQUEST32 #define PTRACE_TRANSLATE_REQUEST32(x) x #endif /* * PTRACE methods */ static int netbsd32_copyin_piod(struct ptrace_io_desc *piod, const void *addr, size_t len) { struct netbsd32_ptrace_io_desc piod32; if (len != 0 && sizeof(piod32) != len) return EINVAL; int error = copyin(addr, &piod32, sizeof(piod32)); if (error) return error; piod->piod_op = piod32.piod_op; piod->piod_offs = NETBSD32PTR64(piod32.piod_offs); piod->piod_addr = NETBSD32PTR64(piod32.piod_addr); piod->piod_len = (size_t)piod32.piod_len; return 0; } static int netbsd32_copyout_piod(const struct ptrace_io_desc *piod, void *addr, size_t len) { struct netbsd32_ptrace_io_desc piod32; if (len != 0 && sizeof(piod32) != len) return EINVAL; piod32.piod_op = piod->piod_op; NETBSD32PTR32(piod32.piod_offs, piod->piod_offs); NETBSD32PTR32(piod32.piod_addr, piod->piod_addr); piod32.piod_len = (netbsd32_size_t)piod->piod_len; return copyout(&piod32, addr, sizeof(piod32)); } static int netbsd32_copyin_siginfo(struct ptrace_siginfo *psi, const void *addr, size_t len) { struct netbsd32_ptrace_siginfo psi32; if (sizeof(psi32) != len) return EINVAL; int error = copyin(addr, &psi32, sizeof(psi32)); if (error) return error; psi->psi_lwpid = psi32.psi_lwpid; netbsd32_si32_to_si(&psi->psi_siginfo, &psi32.psi_siginfo); return 0; } static int netbsd32_copyout_siginfo(const struct ptrace_siginfo *psi, void *addr, size_t len) { struct netbsd32_ptrace_siginfo psi32; if (sizeof(psi32) != len) return EINVAL; psi32.psi_lwpid = psi->psi_lwpid; netbsd32_si_to_si32(&psi32.psi_siginfo, &psi->psi_siginfo); return copyout(&psi32, addr, sizeof(psi32)); } +static int +netbsd32_copyin_thread_area(void *private, void *addr) +{ + void *private64; + netbsd32_pointer_t private32; + + int error = copyin(addr, &private32, sizeof(private32)); + if (error) + return error; + + private64 = NETBSD32PTR64(private32); + memcpy(private, &private64, sizeof(private)); + return 0; +} + +static int +netbsd32_copyout_thread_area(const void *private, void *addr) +{ + netbsd32_pointer_t private32; + + NETBSD32PTR32(private32, private); + return copyout(&private32, addr, sizeof(private)); +} + static int netbsd32_doregs(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, struct uio *uio) { #if defined(PT_GETREGS) || defined(PT_SETREGS) process_reg32 r32; int error; char *kv; int kl; if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) return EINVAL; kl = sizeof(r32); kv = (char *)&r32; kv += uio->uio_offset; kl -= uio->uio_offset; if ((size_t)kl > uio->uio_resid) kl = uio->uio_resid; error = process_read_regs32(l, &r32); if (error == 0) error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (l->l_stat != LSSTOP) error = EBUSY; else error = process_write_regs32(l, &r32); } uio->uio_offset = 0; return error; #else return EINVAL; #endif } static int netbsd32_dofpregs(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, struct uio *uio) { #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) process_fpreg32 r32; int error; char *kv; size_t kl; KASSERT(l->l_proc->p_flag & PK_32); if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) return EINVAL; kl = sizeof(r32); kv = (char *)&r32; kv += uio->uio_offset; kl -= uio->uio_offset; if (kl > uio->uio_resid) kl = uio->uio_resid; error = process_read_fpregs32(l, &r32, &kl); if (error == 0) error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (l->l_stat != LSSTOP) error = EBUSY; else error = process_write_fpregs32(l, &r32, kl); } uio->uio_offset = 0; return error; #else return EINVAL; #endif } static int netbsd32_dodbregs(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, struct uio *uio) { #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS) process_dbreg32 r32; int error; char *kv; size_t kl; KASSERT(l->l_proc->p_flag & PK_32); if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) return EINVAL; kl = sizeof(r32); kv = (char *)&r32; kv += uio->uio_offset; kl -= uio->uio_offset; if (kl > uio->uio_resid) kl = uio->uio_resid; error = process_read_dbregs32(l, &r32, &kl); if (error == 0) error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (l->l_stat != LSSTOP) error = EBUSY; else error = process_write_dbregs32(l, &r32, kl); } uio->uio_offset = 0; return error; #else return EINVAL; #endif } static struct ptrace_methods netbsd32_ptm = { .ptm_copyin_piod = netbsd32_copyin_piod, .ptm_copyout_piod = netbsd32_copyout_piod, .ptm_copyin_siginfo = netbsd32_copyin_siginfo, .ptm_copyout_siginfo = netbsd32_copyout_siginfo, + .ptm_copyin_thread_area = netbsd32_copyin_thread_area, + .ptm_copyout_thread_area = netbsd32_copyout_thread_area, .ptm_doregs = netbsd32_doregs, .ptm_dofpregs = netbsd32_dofpregs, .ptm_dodbregs = netbsd32_dodbregs }; int netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, register_t *retval) { int req; /* { syscallarg(int) req; syscallarg(pid_t) pid; syscallarg(netbsd32_voidp *) addr; syscallarg(int) data; } */ req = PTRACE_TRANSLATE_REQUEST32(SCARG(uap, req)); if (req == -1) return EOPNOTSUPP; return do_ptrace(&netbsd32_ptm, l, req, SCARG(uap, pid), SCARG_P32(uap, addr), SCARG(uap, data), retval); } static const struct syscall_package compat_ptrace_syscalls[] = { { NETBSD32_SYS_netbsd32_ptrace, 0, (sy_call_t *)netbsd32_ptrace }, { 0, 0, NULL }, }; #define DEPS "compat_netbsd32,ptrace_common" MODULE(MODULE_CLASS_EXEC, compat_netbsd32_ptrace, DEPS); static int compat_netbsd32_ptrace_modcmd(modcmd_t cmd, void *arg) { int error; switch (cmd) { case MODULE_CMD_INIT: error = syscall_establish(&emul_netbsd32, compat_ptrace_syscalls); break; case MODULE_CMD_FINI: error = syscall_disestablish(&emul_netbsd32, compat_ptrace_syscalls); break; default: error = ENOTTY; break; } return error; } diff --git a/sys/kern/sys_ptrace.c b/sys/kern/sys_ptrace.c index 8515b6f4cd14..c1e9ede0759b 100644 --- a/sys/kern/sys_ptrace.c +++ b/sys/kern/sys_ptrace.c @@ -1,241 +1,257 @@ /* $NetBSD: sys_ptrace.c,v 1.5 2017/12/17 20:59:27 christos Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Andrew Doran. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 */ /*- * Copyright (c) 1993 Jan-Simon Pendry. * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 */ /* * References: * (1) Bach's "The Design of the UNIX Operating System", * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, * (3) the "4.4BSD Programmer's Reference Manual" published * by USENIX and O'Reilly & Associates. * The 4.4BSD PRM does a reasonably good job of documenting what the various * ptrace() requests should actually do, and its text is quoted several times * in this file. */ #include __KERNEL_RCSID(0, "$NetBSD: sys_ptrace.c,v 1.5 2017/12/17 20:59:27 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_ptrace.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * PTRACE methods */ static int ptrace_copyin_piod(struct ptrace_io_desc *piod, const void *addr, size_t len) { if (len != 0 && sizeof(*piod) != len) return EINVAL; return copyin(addr, piod, sizeof(*piod)); } static int ptrace_copyout_piod(const struct ptrace_io_desc *piod, void *addr, size_t len) { if (len != 0 && sizeof(*piod) != len) return EINVAL; return copyout(piod, addr, sizeof(*piod)); } static int ptrace_copyin_siginfo(struct ptrace_siginfo *psi, const void *addr, size_t len) { if (sizeof(*psi) != len) return EINVAL; return copyin(addr, psi, sizeof(*psi)); } static int ptrace_copyout_siginfo(const struct ptrace_siginfo *psi, void *addr, size_t len) { if (sizeof(*psi) != len) return EINVAL; return copyout(psi, addr, sizeof(*psi)); } +static int +ptrace_copyin_thread_area(void *private, void *addr) +{ + + return copyin(addr, private, sizeof(private)); +} + +static int +ptrace_copyout_thread_area(const void *private, void *addr) +{ + + return copyout(private, addr, sizeof(private)); +} + static struct ptrace_methods native_ptm = { .ptm_copyin_piod = ptrace_copyin_piod, .ptm_copyout_piod = ptrace_copyout_piod, .ptm_copyin_siginfo = ptrace_copyin_siginfo, .ptm_copyout_siginfo = ptrace_copyout_siginfo, + .ptm_copyin_thread_area = ptrace_copyin_thread_area, + .ptm_copyout_thread_area = ptrace_copyout_thread_area, .ptm_doregs = process_doregs, .ptm_dofpregs = process_dofpregs, .ptm_dodbregs = process_dodbregs, }; static const struct syscall_package ptrace_syscalls[] = { { SYS_ptrace, 0, (sy_call_t *)sys_ptrace }, { 0, 0, NULL }, }; /* * Process debugging system call. */ int sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval) { /* { syscallarg(int) req; syscallarg(pid_t) pid; syscallarg(void *) addr; syscallarg(int) data; } */ return do_ptrace(&native_ptm, l, SCARG(uap, req), SCARG(uap, pid), SCARG(uap, addr), SCARG(uap, data), retval); } #define DEPS "ptrace_common" MODULE(MODULE_CLASS_EXEC, ptrace, DEPS); static int ptrace_modcmd(modcmd_t cmd, void *arg) { int error; switch (cmd) { case MODULE_CMD_INIT: error = syscall_establish(&emul_netbsd, ptrace_syscalls); break; case MODULE_CMD_FINI: error = syscall_disestablish(&emul_netbsd, ptrace_syscalls); break; default: error = ENOTTY; break; } return error; } diff --git a/sys/kern/sys_ptrace_common.c b/sys/kern/sys_ptrace_common.c index d5d83bba51a1..2fdd61b8efed 100644 --- a/sys/kern/sys_ptrace_common.c +++ b/sys/kern/sys_ptrace_common.c @@ -1,1683 +1,1737 @@ /* $NetBSD: sys_ptrace_common.c,v 1.73 2019/11/22 05:01:44 rin Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Andrew Doran. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 */ /*- * Copyright (c) 1993 Jan-Simon Pendry. * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 */ /* * References: * (1) Bach's "The Design of the UNIX Operating System", * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, * (3) the "4.4BSD Programmer's Reference Manual" published * by USENIX and O'Reilly & Associates. * The 4.4BSD PRM does a reasonably good job of documenting what the various * ptrace() requests should actually do, and its text is quoted several times * in this file. */ #include __KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.73 2019/11/22 05:01:44 rin Exp $"); #ifdef _KERNEL_OPT #include "opt_ptrace.h" #include "opt_ktrace.h" #include "opt_pax.h" #include "opt_compat_netbsd32.h" #endif #if defined(__HAVE_COMPAT_NETBSD32) && !defined(COMPAT_NETBSD32) \ && !defined(_RUMPKERNEL) #define COMPAT_NETBSD32 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PTRACE # ifdef PTRACE_DEBUG # define DPRINTF(a) uprintf a # else # define DPRINTF(a) # endif static kauth_listener_t ptrace_listener; static int process_auxv_offset(struct proc *, struct uio *); extern int user_va0_disable; #if 0 static int ptrace_cbref; static kmutex_t ptrace_mtx; static kcondvar_t ptrace_cv; #endif #ifdef PT_GETREGS # define case_PT_GETREGS case PT_GETREGS: #else # define case_PT_GETREGS #endif #ifdef PT_SETREGS # define case_PT_SETREGS case PT_SETREGS: #else # define case_PT_SETREGS #endif #ifdef PT_GETFPREGS # define case_PT_GETFPREGS case PT_GETFPREGS: #else # define case_PT_GETFPREGS #endif #ifdef PT_SETFPREGS # define case_PT_SETFPREGS case PT_SETFPREGS: #else # define case_PT_SETFPREGS #endif #ifdef PT_GETDBREGS # define case_PT_GETDBREGS case PT_GETDBREGS: #else # define case_PT_GETDBREGS #endif #ifdef PT_SETDBREGS # define case_PT_SETDBREGS case PT_SETDBREGS: #else # define case_PT_SETDBREGS #endif #if defined(PT_SETREGS) || defined(PT_GETREGS) || \ defined(PT_SETFPREGS) || defined(PT_GETFPREGS) || \ defined(PT_SETDBREGS) || defined(PT_GETDBREGS) # define PT_REGISTERS #endif static int ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) { struct proc *p; int result; #ifdef PT_SETDBREGS extern int user_set_dbregs; #endif result = KAUTH_RESULT_DEFER; p = arg0; #if 0 mutex_enter(&ptrace_mtx); ptrace_cbref++; mutex_exit(&ptrace_mtx); #endif if (action != KAUTH_PROCESS_PTRACE) goto out; switch ((u_long)arg1) { #ifdef PT_SETDBREGS case_PT_SETDBREGS if (kauth_cred_getuid(cred) != 0 && user_set_dbregs == 0) { result = KAUTH_RESULT_DENY; break; } #endif /* FALLTHROUGH */ case PT_TRACE_ME: case PT_ATTACH: case PT_WRITE_I: case PT_WRITE_D: case PT_READ_I: case PT_READ_D: case PT_IO: case_PT_GETREGS case_PT_SETREGS case_PT_GETFPREGS case_PT_SETFPREGS case_PT_GETDBREGS case PT_SET_EVENT_MASK: case PT_GET_EVENT_MASK: case PT_GET_PROCESS_STATE: case PT_SET_SIGINFO: case PT_GET_SIGINFO: + case PT_SET_THREAD_AREA: + case PT_GET_THREAD_AREA: #ifdef __HAVE_PTRACE_MACHDEP PTRACE_MACHDEP_REQUEST_CASES #endif if (kauth_cred_getuid(cred) != kauth_cred_getuid(p->p_cred) || ISSET(p->p_flag, PK_SUGID)) { break; } result = KAUTH_RESULT_ALLOW; break; #ifdef PT_STEP case PT_STEP: case PT_SETSTEP: case PT_CLEARSTEP: #endif case PT_CONTINUE: case PT_KILL: case PT_DETACH: case PT_LWPINFO: case PT_SYSCALL: case PT_SYSCALLEMU: case PT_DUMPCORE: case PT_RESUME: case PT_SUSPEND: case PT_STOP: result = KAUTH_RESULT_ALLOW; break; default: break; } out: #if 0 mutex_enter(&ptrace_mtx); if (--ptrace_cbref == 0) cv_broadcast(&ptrace_cv); mutex_exit(&ptrace_mtx); #endif return result; } int ptrace_init(void) { #if 0 mutex_init(&ptrace_mtx, MUTEX_DEFAULT, IPL_NONE); cv_init(&ptrace_cv, "ptracecb"); ptrace_cbref = 0; #endif ptrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, ptrace_listener_cb, NULL); return 0; } int ptrace_fini(void) { kauth_unlisten_scope(ptrace_listener); #if 0 /* Make sure no-one is executing our kauth listener */ mutex_enter(&ptrace_mtx); while (ptrace_cbref != 0) cv_wait(&ptrace_cv, &ptrace_mtx); mutex_exit(&ptrace_mtx); mutex_destroy(&ptrace_mtx); cv_destroy(&ptrace_cv); #endif return 0; } static struct proc * ptrace_find(struct lwp *l, int req, pid_t pid) { struct proc *t; /* "A foolish consistency..." XXX */ if (req == PT_TRACE_ME) { t = l->l_proc; mutex_enter(t->p_lock); return t; } /* Find the process we're supposed to be operating on. */ t = proc_find(pid); if (t == NULL) return NULL; /* XXX-elad */ mutex_enter(t->p_lock); int error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); if (error) { mutex_exit(t->p_lock); return NULL; } return t; } static int ptrace_allowed(struct lwp *l, int req, struct proc *t, struct proc *p, bool *locked) { *locked = false; /* * Grab a reference on the process to prevent it from execing or * exiting. */ if (!rw_tryenter(&t->p_reflock, RW_READER)) return EBUSY; *locked = true; /* Make sure we can operate on it. */ switch (req) { case PT_TRACE_ME: /* * You can't say to the parent of a process to start tracing if: * (1) the parent is initproc, */ if (p->p_pptr == initproc) return EPERM; /* * (2) the process is initproc, or */ if (p == initproc) return EPERM; /* * (3) the child is already traced. */ if (ISSET(p->p_slflag, PSL_TRACED)) return EBUSY; return 0; case PT_ATTACH: /* * You can't attach to a process if: * (1) it's the process that's doing the attaching, */ if (t == p) return EINVAL; /* * (2) it's a system process, */ if (t->p_flag & PK_SYSTEM) return EPERM; /* * (3) the tracer is initproc, */ if (p == initproc) return EPERM; /* * (4) it's already being traced, */ if (ISSET(t->p_slflag, PSL_TRACED)) return EBUSY; /* * (5) it's a vfork(2)ed parent of the current process, or */ if (ISSET(p->p_lflag, PL_PPWAIT) && p->p_pptr == t) return EPERM; /* * (6) the tracer is chrooted, and its root directory is * not at or above the root directory of the tracee */ mutex_exit(t->p_lock); /* XXXSMP */ int tmp = proc_isunder(t, l); mutex_enter(t->p_lock); /* XXXSMP */ if (!tmp) return EPERM; return 0; case PT_READ_I: case PT_READ_D: case PT_WRITE_I: case PT_WRITE_D: case PT_IO: case PT_SET_SIGINFO: case PT_GET_SIGINFO: case_PT_GETREGS case_PT_SETREGS case_PT_GETFPREGS case_PT_SETFPREGS case_PT_GETDBREGS case_PT_SETDBREGS + case PT_SET_THREAD_AREA: + case PT_GET_THREAD_AREA: #ifdef __HAVE_PTRACE_MACHDEP PTRACE_MACHDEP_REQUEST_CASES #endif /* * You can't read/write the memory or registers of a process * if the tracer is chrooted, and its root directory is not at * or above the root directory of the tracee. */ mutex_exit(t->p_lock); /* XXXSMP */ tmp = proc_isunder(t, l); mutex_enter(t->p_lock); /* XXXSMP */ if (!tmp) return EPERM; /*FALLTHROUGH*/ case PT_CONTINUE: case PT_KILL: case PT_DETACH: case PT_LWPINFO: case PT_SYSCALL: case PT_SYSCALLEMU: case PT_DUMPCORE: #ifdef PT_STEP case PT_STEP: case PT_SETSTEP: case PT_CLEARSTEP: #endif case PT_SET_EVENT_MASK: case PT_GET_EVENT_MASK: case PT_GET_PROCESS_STATE: case PT_RESUME: case PT_SUSPEND: case PT_STOP: /* * You can't do what you want to the process if: * (1) It's not being traced at all, */ if (!ISSET(t->p_slflag, PSL_TRACED)) return EPERM; /* * (2) it's not being traced by _you_, or */ if (t->p_pptr != p) { DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid, p->p_pid)); return EBUSY; } /* * (3) it's not currently stopped. * * As an exception allow PT_KILL and PT_STOP here. */ if (req != PT_KILL && req != PT_STOP && (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */)) { DPRINTF(("stat %d flag %d\n", t->p_stat, !t->p_waited)); return EBUSY; } return 0; default: /* It was not a legal request. */ return EINVAL; } } static int ptrace_needs_hold(int req) { switch (req) { #ifdef PT_STEP case PT_STEP: #endif case PT_CONTINUE: case PT_DETACH: case PT_KILL: case PT_SYSCALL: case PT_SYSCALLEMU: case PT_ATTACH: case PT_TRACE_ME: case PT_GET_SIGINFO: case PT_SET_SIGINFO: case PT_STOP: return 1; default: return 0; } } static int ptrace_update_lwp(struct proc *t, struct lwp **lt, lwpid_t lid) { if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1) return 0; mutex_enter(t->p_lock); lwp_delref2(*lt); *lt = lwp_find(t, lid); if (*lt == NULL) { mutex_exit(t->p_lock); return ESRCH; } if ((*lt)->l_flag & LW_SYSTEM) { mutex_exit(t->p_lock); *lt = NULL; return EINVAL; } lwp_addref(*lt); mutex_exit(t->p_lock); return 0; } static int ptrace_get_siginfo(struct proc *t, struct ptrace_methods *ptm, void *addr, size_t data) { struct ptrace_siginfo psi; memset(&psi, 0, sizeof(psi)); psi.psi_siginfo._info = t->p_sigctx.ps_info; psi.psi_lwpid = t->p_sigctx.ps_lwp; DPRINTF(("%s: lwp=%d signal=%d\n", __func__, psi.psi_lwpid, psi.psi_siginfo.si_signo)); return ptm->ptm_copyout_siginfo(&psi, addr, data); } static int ptrace_set_siginfo(struct proc *t, struct lwp **lt, struct ptrace_methods *ptm, void *addr, size_t data) { struct ptrace_siginfo psi; int error = ptm->ptm_copyin_siginfo(&psi, addr, data); if (error) return error; /* Check that the data is a valid signal number or zero. */ if (psi.psi_siginfo.si_signo < 0 || psi.psi_siginfo.si_signo >= NSIG) return EINVAL; t->p_sigctx.ps_faked = true; t->p_sigctx.ps_info = psi.psi_siginfo._info; t->p_sigctx.ps_lwp = psi.psi_lwpid; DPRINTF(("%s: lwp=%d signal=%d\n", __func__, psi.psi_lwpid, psi.psi_siginfo.si_signo)); return 0; } +static int +ptrace_get_thread_area(struct proc *t, struct lwp **lt, + struct ptrace_methods *ptm, void *addr, size_t data) +{ + void *private; + int error; + + if ((error = ptrace_update_lwp(t, lt, data)) != 0) + return error; + + private = &(*lt)->l_private; + + error = ptm->ptm_copyout_thread_area(private, addr); + if (error) + return error; + + DPRINTF(("%s: addr=%p lwp=%d\n", __func__, addr, data)); + return 0; +} + +static int +ptrace_set_thread_area(struct proc *t, struct lwp **lt, + struct ptrace_methods *ptm, void *addr, int data) +{ + void *private; + int error; + + if ((error = ptrace_update_lwp(t, lt, data)) != 0) + return error; + + error = ptm->ptm_copyin_thread_area(&private, addr); + if (error) + return error; + + error = lwp_setprivate(*lt, private); + if (error) + return error; + + DPRINTF(("%s: addr=%p lwp=%d\n", __func__, addr, data)); + return 0; +} + static int ptrace_get_event_mask(struct proc *t, void *addr, size_t data) { struct ptrace_event pe; if (data != sizeof(pe)) { DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(pe))); return EINVAL; } memset(&pe, 0, sizeof(pe)); pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? PTRACE_FORK : 0; pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ? PTRACE_VFORK : 0; pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ? PTRACE_VFORK_DONE : 0; pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_CREATE) ? PTRACE_LWP_CREATE : 0; pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_EXIT) ? PTRACE_LWP_EXIT : 0; pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEPOSIX_SPAWN) ? PTRACE_POSIX_SPAWN : 0; DPRINTF(("%s: lwp=%d event=%#x\n", __func__, t->p_sigctx.ps_lwp, pe.pe_set_event)); return copyout(&pe, addr, sizeof(pe)); } static int ptrace_set_event_mask(struct proc *t, void *addr, size_t data) { struct ptrace_event pe; int error; if (data != sizeof(pe)) { DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(pe))); return EINVAL; } if ((error = copyin(addr, &pe, sizeof(pe))) != 0) return error; DPRINTF(("%s: lwp=%d event=%#x\n", __func__, t->p_sigctx.ps_lwp, pe.pe_set_event)); if (pe.pe_set_event & PTRACE_FORK) SET(t->p_slflag, PSL_TRACEFORK); else CLR(t->p_slflag, PSL_TRACEFORK); if (pe.pe_set_event & PTRACE_VFORK) SET(t->p_slflag, PSL_TRACEVFORK); else CLR(t->p_slflag, PSL_TRACEVFORK); if (pe.pe_set_event & PTRACE_VFORK_DONE) SET(t->p_slflag, PSL_TRACEVFORK_DONE); else CLR(t->p_slflag, PSL_TRACEVFORK_DONE); if (pe.pe_set_event & PTRACE_LWP_CREATE) SET(t->p_slflag, PSL_TRACELWP_CREATE); else CLR(t->p_slflag, PSL_TRACELWP_CREATE); if (pe.pe_set_event & PTRACE_LWP_EXIT) SET(t->p_slflag, PSL_TRACELWP_EXIT); else CLR(t->p_slflag, PSL_TRACELWP_EXIT); if (pe.pe_set_event & PTRACE_POSIX_SPAWN) SET(t->p_slflag, PSL_TRACEPOSIX_SPAWN); else CLR(t->p_slflag, PSL_TRACEPOSIX_SPAWN); return 0; } static int ptrace_get_process_state(struct proc *t, void *addr, size_t data) { struct _ksiginfo *si; struct ptrace_state ps; if (data != sizeof(ps)) { DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(ps))); return EINVAL; } if (t->p_sigctx.ps_info._signo != SIGTRAP || (t->p_sigctx.ps_info._code != TRAP_CHLD && t->p_sigctx.ps_info._code != TRAP_LWP)) { memset(&ps, 0, sizeof(ps)); } else { si = &t->p_sigctx.ps_info; KASSERT(si->_reason._ptrace_state._pe_report_event > 0); KASSERT(si->_reason._ptrace_state._option._pe_other_pid > 0); ps.pe_report_event = si->_reason._ptrace_state._pe_report_event; CTASSERT(sizeof(ps.pe_other_pid) == sizeof(ps.pe_lwp)); ps.pe_other_pid = si->_reason._ptrace_state._option._pe_other_pid; } DPRINTF(("%s: lwp=%d event=%#x pid=%d lwp=%d\n", __func__, t->p_sigctx.ps_lwp, ps.pe_report_event, ps.pe_other_pid, ps.pe_lwp)); return copyout(&ps, addr, sizeof(ps)); } static int ptrace_lwpinfo(struct proc *t, struct lwp **lt, void *addr, size_t data) { struct ptrace_lwpinfo pl; if (data != sizeof(pl)) { DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(pl))); return EINVAL; } int error = copyin(addr, &pl, sizeof(pl)); if (error) return error; lwpid_t tmp = pl.pl_lwpid; lwp_delref(*lt); mutex_enter(t->p_lock); if (tmp == 0) *lt = lwp_find_first(t); else { *lt = lwp_find(t, tmp); if (*lt == NULL) { mutex_exit(t->p_lock); return ESRCH; } *lt = LIST_NEXT(*lt, l_sibling); } while (*lt != NULL && !lwp_alive(*lt)) *lt = LIST_NEXT(*lt, l_sibling); pl.pl_lwpid = 0; pl.pl_event = 0; if (*lt) { lwp_addref(*lt); pl.pl_lwpid = (*lt)->l_lid; if ((*lt)->l_flag & LW_WSUSPEND) pl.pl_event = PL_EVENT_SUSPENDED; /* * If we match the lwp, or it was sent to every lwp, * we set PL_EVENT_SIGNAL. * XXX: ps_lwp == 0 means everyone and noone, so * check ps_signo too. */ else if ((*lt)->l_lid == t->p_sigctx.ps_lwp || (t->p_sigctx.ps_lwp == 0 && t->p_sigctx.ps_info._signo)) { DPRINTF(("%s: lwp=%d siglwp=%d signo %d\n", __func__, pl.pl_lwpid, t->p_sigctx.ps_lwp, t->p_sigctx.ps_info._signo)); pl.pl_event = PL_EVENT_SIGNAL; } } mutex_exit(t->p_lock); DPRINTF(("%s: lwp=%d event=%#x\n", __func__, pl.pl_lwpid, pl.pl_event)); return copyout(&pl, addr, sizeof(pl)); } static int ptrace_startstop(struct proc *t, struct lwp **lt, int rq, void *addr, size_t data) { int error; if ((error = ptrace_update_lwp(t, lt, data)) != 0) return error; DPRINTF(("%s: lwp=%d request=%d\n", __func__, (*lt)->l_lid, rq)); lwp_lock(*lt); if (rq == PT_SUSPEND) (*lt)->l_flag |= LW_DBGSUSPEND; else { (*lt)->l_flag &= ~LW_DBGSUSPEND; if ((*lt)->l_flag != LSSUSPENDED) (*lt)->l_stat = LSSTOP; } lwp_unlock(*lt); return 0; } #ifdef PT_REGISTERS static int ptrace_uio_dir(int req) { switch (req) { case_PT_GETREGS case_PT_GETFPREGS case_PT_GETDBREGS return UIO_READ; case_PT_SETREGS case_PT_SETFPREGS case_PT_SETDBREGS return UIO_WRITE; default: return -1; } } static int ptrace_regs(struct lwp *l, struct lwp **lt, int rq, struct ptrace_methods *ptm, void *addr, size_t data) { int error; struct proc *p, *t; struct vmspace *vm; p = l->l_proc; /* tracer */ t = (*lt)->l_proc; /* traced */ if ((error = ptrace_update_lwp(t, lt, data)) != 0) return error; int dir = ptrace_uio_dir(rq); size_t size; int (*func)(struct lwp *, struct lwp *, struct uio *); DPRINTF(("%s: lwp=%d request=%d\n", __func__, l->l_lid, rq)); switch (rq) { #if defined(PT_SETREGS) || defined(PT_GETREGS) case_PT_GETREGS case_PT_SETREGS if (!process_validregs(*lt)) return EINVAL; size = PROC_REGSZ(p); func = ptm->ptm_doregs; break; #endif #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) case_PT_GETFPREGS case_PT_SETFPREGS if (!process_validfpregs(*lt)) return EINVAL; size = PROC_FPREGSZ(p); func = ptm->ptm_dofpregs; break; #endif #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) case_PT_GETDBREGS case_PT_SETDBREGS if (!process_validdbregs(*lt)) return EINVAL; size = PROC_DBREGSZ(p); func = ptm->ptm_dodbregs; break; #endif default: return EINVAL; } error = proc_vmspace_getref(l->l_proc, &vm); if (error) return error; struct uio uio; struct iovec iov; iov.iov_base = addr; iov.iov_len = size; uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = 0; uio.uio_resid = iov.iov_len; uio.uio_rw = dir; uio.uio_vmspace = vm; error = (*func)(l, *lt, &uio); uvmspace_free(vm); return error; } #endif static int ptrace_sendsig(struct lwp *l, int req, struct proc *t, struct lwp *lt, int signo, int resume_all) { ksiginfo_t ksi; /* Finally, deliver the requested signal (or none). */ if (t->p_stat == SSTOP) { /* * Unstop the process. If it needs to take a * signal, make all efforts to ensure that at * an LWP runs to see it. */ t->p_xsig = signo; /* * signo > 0 check prevents a potential panic, as * sigismember(&...,0) is invalid check and signo * can be equal to 0 as a special case of no-signal. */ if (signo > 0 && sigismember(&stopsigmask, signo)) { t->p_waited = 0; child_psignal(t, 0); } else if (resume_all) proc_unstop(t); else lwp_unstop(lt); return 0; } KASSERT(req == PT_KILL || req == PT_STOP || req == PT_ATTACH); KSI_INIT(&ksi); ksi.ksi_signo = signo; ksi.ksi_code = SI_USER; ksi.ksi_pid = l->l_proc->p_pid; ksi.ksi_uid = kauth_cred_geteuid(l->l_cred); t->p_sigctx.ps_faked = false; DPRINTF(("%s: pid=%d.%d signal=%d resume_all=%d\n", __func__, t->p_pid, lt->l_lid, signo, resume_all)); return kpsignal2(t, &ksi); } static int ptrace_dumpcore(struct lwp *lt, char *path, size_t len) { int error; if (path != NULL) { if (len >= MAXPATHLEN) return EINVAL; char *src = path; path = kmem_alloc(len + 1, KM_SLEEP); error = copyin(src, path, len); if (error) goto out; path[len] = '\0'; } DPRINTF(("%s: lwp=%d\n", __func__, lt->l_lid)); MODULE_HOOK_CALL(coredump_hook, (lt, path), 0, error); out: if (path) kmem_free(path, len + 1); return error; } static int ptrace_doio(struct lwp *l, struct proc *t, struct lwp *lt, struct ptrace_io_desc *piod, void *addr, bool sysspace) { struct uio uio; struct iovec iov; int error, tmp; error = 0; iov.iov_base = piod->piod_addr; iov.iov_len = piod->piod_len; uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = (off_t)(unsigned long)piod->piod_offs; uio.uio_resid = piod->piod_len; DPRINTF(("%s: lwp=%d request=%d\n", __func__, l->l_lid, piod->piod_op)); switch (piod->piod_op) { case PIOD_READ_D: case PIOD_READ_I: uio.uio_rw = UIO_READ; break; case PIOD_WRITE_D: case PIOD_WRITE_I: /* * Can't write to a RAS */ if (ras_lookup(t, addr) != (void *)-1) { return EACCES; } uio.uio_rw = UIO_WRITE; break; case PIOD_READ_AUXV: uio.uio_rw = UIO_READ; tmp = t->p_execsw->es_arglen; if (uio.uio_offset > tmp) return EIO; if (uio.uio_resid > tmp - uio.uio_offset) uio.uio_resid = tmp - uio.uio_offset; piod->piod_len = iov.iov_len = uio.uio_resid; error = process_auxv_offset(t, &uio); break; default: error = EINVAL; break; } if (error) return error; if (sysspace) { uio.uio_vmspace = vmspace_kernel(); } else { error = proc_vmspace_getref(l->l_proc, &uio.uio_vmspace); if (error) return error; } error = process_domem(l, lt, &uio); if (!sysspace) uvmspace_free(uio.uio_vmspace); if (error) return error; piod->piod_len -= uio.uio_resid; return 0; } int do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid, void *addr, int data, register_t *retval) { struct proc *p = l->l_proc; struct lwp *lt = NULL; struct lwp *lt2; struct proc *t; /* target process */ struct ptrace_io_desc piod; int error, write, tmp, pheld; int signo = 0; int resume_all; bool locked; error = 0; /* * If attaching or detaching, we need to get a write hold on the * proclist lock so that we can re-parent the target process. */ mutex_enter(proc_lock); t = ptrace_find(l, req, pid); if (t == NULL) { mutex_exit(proc_lock); return ESRCH; } pheld = 1; if ((error = ptrace_allowed(l, req, t, p, &locked)) != 0) goto out; if ((error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req), NULL, NULL)) != 0) goto out; if ((lt = lwp_find_first(t)) == NULL) { error = ESRCH; goto out; } /* Do single-step fixup if needed. */ FIX_SSTEP(t); KASSERT(lt != NULL); lwp_addref(lt); /* * Which locks do we need held? XXX Ugly. */ if ((pheld = ptrace_needs_hold(req)) == 0) { mutex_exit(t->p_lock); mutex_exit(proc_lock); } /* Now do the operation. */ write = 0; *retval = 0; tmp = 0; resume_all = 1; switch (req) { case PT_TRACE_ME: /* Just set the trace flag. */ SET(t->p_slflag, PSL_TRACED); t->p_opptr = t->p_pptr; break; /* * The I and D separate address space has been inherited from PDP-11. * The 16-bit UNIX started with a single address space per program, * but was extended to two 16-bit (2 x 64kb) address spaces. * * We no longer maintain this feature in maintained architectures, but * we keep the API for backward compatiblity. Currently the I and D * operations are exactly the same and not distinguished in debuggers. */ case PT_WRITE_I: case PT_WRITE_D: write = 1; tmp = data; /* FALLTHROUGH */ case PT_READ_I: case PT_READ_D: piod.piod_addr = &tmp; piod.piod_len = sizeof(tmp); piod.piod_offs = addr; piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D; if ((error = ptrace_doio(l, t, lt, &piod, addr, true)) != 0) break; /* * For legacy reasons we treat here two results as success: * - incomplete transfer piod.piod_len < sizeof(tmp) * - no transfer piod.piod_len == 0 * * This means that there is no way to determine whether * transfer operation was performed in PT_WRITE and PT_READ * calls. */ if (!write) *retval = tmp; break; case PT_IO: if ((error = ptm->ptm_copyin_piod(&piod, addr, data)) != 0) break; if (piod.piod_len < 1) { error = EINVAL; break; } if ((error = ptrace_doio(l, t, lt, &piod, addr, false)) != 0) break; /* * For legacy reasons we treat here two results as success: * - incomplete transfer piod.piod_len < sizeof(tmp) * - no transfer piod.piod_len == 0 */ error = ptm->ptm_copyout_piod(&piod, addr, data); break; case PT_DUMPCORE: error = ptrace_dumpcore(lt, addr, data); break; #ifdef PT_STEP case PT_STEP: /* * From the 4.4BSD PRM: * "Execution continues as in request PT_CONTINUE; however * as soon as possible after execution of at least one * instruction, execution stops again. [ ... ]" */ #endif case PT_CONTINUE: case PT_SYSCALL: case PT_DETACH: if (req == PT_SYSCALL) { if (!ISSET(t->p_slflag, PSL_SYSCALL)) { SET(t->p_slflag, PSL_SYSCALL); #ifdef __HAVE_SYSCALL_INTERN (*t->p_emul->e_syscall_intern)(t); #endif } } else { if (ISSET(t->p_slflag, PSL_SYSCALL)) { CLR(t->p_slflag, PSL_SYSCALL); #ifdef __HAVE_SYSCALL_INTERN (*t->p_emul->e_syscall_intern)(t); #endif } } t->p_trace_enabled = trace_is_enabled(t); /* * Pick up the LWPID, if supplied. There are two cases: * data < 0 : step or continue single thread, lwp = -data * data > 0 in PT_STEP : step this thread, continue others * For operations other than PT_STEP, data > 0 means * data is the signo to deliver to the process. */ tmp = data; if (tmp >= 0) { #ifdef PT_STEP if (req == PT_STEP) signo = 0; else #endif { signo = tmp; tmp = 0; /* don't search for LWP */ } } else if (tmp == INT_MIN) { error = ESRCH; break; } else { tmp = -tmp; } if (tmp > 0) { if (req == PT_DETACH) { error = EINVAL; break; } lwp_delref2 (lt); lt = lwp_find(t, tmp); if (lt == NULL) { error = ESRCH; break; } lwp_addref(lt); resume_all = 0; signo = 0; } /* * From the 4.4BSD PRM: * "The data argument is taken as a signal number and the * child's execution continues at location addr as if it * incurred that signal. Normally the signal number will * be either 0 to indicate that the signal that caused the * stop should be ignored, or that value fetched out of * the process's image indicating which signal caused * the stop. If addr is (int *)1 then execution continues * from where it stopped." */ /* Check that the data is a valid signal number or zero. */ if (signo < 0 || signo >= NSIG) { error = EINVAL; break; } /* Prevent process deadlock */ if (resume_all) { #ifdef PT_STEP if (req == PT_STEP) { if (lt->l_flag & (LW_WSUSPEND | LW_DBGSUSPEND)) { error = EDEADLK; break; } } else #endif { error = EDEADLK; LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { if ((lt2->l_flag & (LW_WSUSPEND | LW_DBGSUSPEND)) == 0 ) { error = 0; break; } } if (error != 0) break; } } else { if (lt->l_flag & (LW_WSUSPEND | LW_DBGSUSPEND)) { error = EDEADLK; break; } } /* * Reject setting program counter to 0x0 if VA0 is disabled. * * Not all kernels implement this feature to set Program * Counter in one go in PT_CONTINUE and similar operations. * This causes portability issues as passing address 0x0 * on these kernels is no-operation, but can cause failure * in most cases on NetBSD. */ if (user_va0_disable && addr == 0) { error = EINVAL; break; } /* If the address parameter is not (int *)1, set the pc. */ if ((int *)addr != (int *)1) { error = process_set_pc(lt, addr); if (error != 0) break; } #ifdef PT_STEP /* * Arrange for a single-step, if that's requested and possible. * More precisely, set the single step status as requested for * the requested thread, and clear it for other threads. */ LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { if (ISSET(lt2->l_pflag, LP_SINGLESTEP)) { lwp_lock(lt2); process_sstep(lt2, 1); lwp_unlock(lt2); } else if (lt != lt2) { lwp_lock(lt2); process_sstep(lt2, 0); lwp_unlock(lt2); } } error = process_sstep(lt, ISSET(lt->l_pflag, LP_SINGLESTEP) || req == PT_STEP); if (error) break; #endif if (req == PT_DETACH) { CLR(t->p_slflag, PSL_TRACED|PSL_SYSCALL); /* give process back to original parent or init */ if (t->p_opptr != t->p_pptr) { struct proc *pp = t->p_opptr; proc_reparent(t, pp ? pp : initproc); } /* not being traced any more */ t->p_opptr = NULL; /* clear single step */ LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { CLR(lt2->l_pflag, LP_SINGLESTEP); } CLR(lt->l_pflag, LP_SINGLESTEP); } sendsig: error = ptrace_sendsig(l, req, t, lt, signo, resume_all); break; case PT_SYSCALLEMU: if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) { error = EINVAL; break; } SET(t->p_slflag, PSL_SYSCALLEMU); break; #ifdef PT_STEP case PT_SETSTEP: write = 1; /* FALLTHROUGH */ case PT_CLEARSTEP: /* write = 0 done above. */ if ((error = ptrace_update_lwp(t, <, data)) != 0) break; if (write) SET(lt->l_pflag, LP_SINGLESTEP); else CLR(lt->l_pflag, LP_SINGLESTEP); break; #endif case PT_KILL: /* just send the process a KILL signal. */ signo = SIGKILL; goto sendsig; /* in PT_CONTINUE, above. */ case PT_STOP: /* just send the process a STOP signal. */ signo = SIGSTOP; goto sendsig; /* in PT_CONTINUE, above. */ case PT_ATTACH: /* * Go ahead and set the trace flag. * Save the old parent (it's reset in * _DETACH, and also in kern_exit.c:wait4() * Reparent the process so that the tracing * proc gets to see all the action. * Stop the target. */ proc_changeparent(t, p); signo = SIGSTOP; goto sendsig; case PT_GET_EVENT_MASK: error = ptrace_get_event_mask(t, addr, data); break; case PT_SET_EVENT_MASK: error = ptrace_set_event_mask(t, addr, data); break; case PT_GET_PROCESS_STATE: error = ptrace_get_process_state(t, addr, data); break; case PT_LWPINFO: error = ptrace_lwpinfo(t, <, addr, data); break; case PT_SET_SIGINFO: error = ptrace_set_siginfo(t, <, ptm, addr, data); break; case PT_GET_SIGINFO: error = ptrace_get_siginfo(t, ptm, addr, data); break; case PT_RESUME: case PT_SUSPEND: error = ptrace_startstop(t, <, req, addr, data); break; + case PT_SET_THREAD_AREA: + error = ptrace_set_thread_area(t, <, ptm, addr, data); + break; + + case PT_GET_THREAD_AREA: + error = ptrace_get_thread_area(t, <, ptm, addr, data); + break; + #ifdef PT_REGISTERS case_PT_SETREGS case_PT_GETREGS case_PT_SETFPREGS case_PT_GETFPREGS case_PT_SETDBREGS case_PT_GETDBREGS error = ptrace_regs(l, <, req, ptm, addr, data); break; #endif #ifdef __HAVE_PTRACE_MACHDEP PTRACE_MACHDEP_REQUEST_CASES error = ptrace_machdep_dorequest(l, lt, req, addr, data); break; #endif } out: if (pheld) { mutex_exit(t->p_lock); mutex_exit(proc_lock); } if (lt != NULL) lwp_delref(lt); if (locked) rw_exit(&t->p_reflock); return error; } typedef int (*regrfunc_t)(struct lwp *, void *, size_t *); typedef int (*regwfunc_t)(struct lwp *, void *, size_t); #ifdef PT_REGISTERS static int proc_regio(struct lwp *l, struct uio *uio, size_t ks, regrfunc_t r, regwfunc_t w) { char buf[1024]; int error; char *kv; size_t kl; if (ks > sizeof(buf)) return E2BIG; if (uio->uio_offset < 0 || uio->uio_offset > (off_t)ks) return EINVAL; kv = buf + uio->uio_offset; kl = ks - uio->uio_offset; if (kl > uio->uio_resid) kl = uio->uio_resid; error = (*r)(l, buf, &ks); if (error == 0) error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (l->l_stat != LSSTOP) error = EBUSY; else error = (*w)(l, buf, ks); } uio->uio_offset = 0; return error; } #endif int process_doregs(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, struct uio *uio) { #if defined(PT_GETREGS) || defined(PT_SETREGS) size_t s; regrfunc_t r; regwfunc_t w; #ifdef COMPAT_NETBSD32 const bool pk32 = (curl->l_proc->p_flag & PK_32) != 0; if (__predict_false(pk32)) { if ((l->l_proc->p_flag & PK_32) == 0) { // 32 bit tracer can't trace 64 bit process return EINVAL; } s = sizeof(process_reg32); r = __FPTRCAST(regrfunc_t, process_read_regs32); w = __FPTRCAST(regwfunc_t, process_write_regs32); } else #endif { s = sizeof(struct reg); r = __FPTRCAST(regrfunc_t, process_read_regs); w = __FPTRCAST(regwfunc_t, process_write_regs); } return proc_regio(l, uio, s, r, w); #else return EINVAL; #endif } int process_validregs(struct lwp *l) { #if defined(PT_SETREGS) || defined(PT_GETREGS) return (l->l_flag & LW_SYSTEM) == 0; #else return 0; #endif } int process_dofpregs(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, struct uio *uio) { #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) size_t s; regrfunc_t r; regwfunc_t w; #ifdef COMPAT_NETBSD32 const bool pk32 = (curl->l_proc->p_flag & PK_32) != 0; if (__predict_false(pk32)) { if ((l->l_proc->p_flag & PK_32) == 0) { // 32 bit tracer can't trace 64 bit process return EINVAL; } s = sizeof(process_fpreg32); r = (regrfunc_t)process_read_fpregs32; w = (regwfunc_t)process_write_fpregs32; } else #endif { s = sizeof(struct fpreg); r = (regrfunc_t)process_read_fpregs; w = (regwfunc_t)process_write_fpregs; } return proc_regio(l, uio, s, r, w); #else return EINVAL; #endif } int process_validfpregs(struct lwp *l) { #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) return (l->l_flag & LW_SYSTEM) == 0; #else return 0; #endif } int process_dodbregs(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, struct uio *uio) { #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS) size_t s; regrfunc_t r; regwfunc_t w; #ifdef COMPAT_NETBSD32 const bool pk32 = (curl->l_proc->p_flag & PK_32) != 0; if (__predict_false(pk32)) { if ((l->l_proc->p_flag & PK_32) == 0) { // 32 bit tracer can't trace 64 bit process return EINVAL; } s = sizeof(process_dbreg32); r = (regrfunc_t)process_read_dbregs32; w = (regwfunc_t)process_write_dbregs32; } else #endif { s = sizeof(struct dbreg); r = (regrfunc_t)process_read_dbregs; w = (regwfunc_t)process_write_dbregs; } return proc_regio(l, uio, s, r, w); #else return EINVAL; #endif } int process_validdbregs(struct lwp *l) { #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) return (l->l_flag & LW_SYSTEM) == 0; #else return 0; #endif } static int process_auxv_offset(struct proc *p, struct uio *uio) { struct ps_strings pss; int error; off_t off = (off_t)p->p_psstrp; if ((error = copyin_psstrings(p, &pss)) != 0) return error; if (pss.ps_envstr == NULL) return EIO; #ifdef COMPAT_NETBSD32 if (p->p_flag & PK_32) uio->uio_offset += (off_t)((vaddr_t)pss.ps_envstr + sizeof(uint32_t) * (pss.ps_nenvstr + 1)); else #endif uio->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1); #ifdef __MACHINE_STACK_GROWS_UP if (uio->uio_offset < off) return EIO; #else if (uio->uio_offset > off) return EIO; if ((uio->uio_offset + uio->uio_resid) > off) uio->uio_resid = off - uio->uio_offset; #endif return 0; } #endif /* PTRACE */ MODULE(MODULE_CLASS_EXEC, ptrace_common, NULL); static int ptrace_common_modcmd(modcmd_t cmd, void *arg) { int error; switch (cmd) { case MODULE_CMD_INIT: error = ptrace_init(); break; case MODULE_CMD_FINI: error = ptrace_fini(); break; default: ptrace_hooks(); error = ENOTTY; break; } return error; } diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index b531fa33a4bc..ce65b25a993f 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -1,298 +1,305 @@ /* $NetBSD: ptrace.h,v 1.66 2019/10/09 13:19:43 kamil Exp $ */ /*- * Copyright (c) 1984, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ptrace.h 8.2 (Berkeley) 1/4/94 */ #ifndef _SYS_PTRACE_H_ #define _SYS_PTRACE_H_ #include #define PT_TRACE_ME 0 /* child declares it's being traced */ #define PT_READ_I 1 /* read word in child's I space */ #define PT_READ_D 2 /* read word in child's D space */ #define PT_WRITE_I 4 /* write word in child's I space */ #define PT_WRITE_D 5 /* write word in child's D space */ #define PT_CONTINUE 7 /* continue the child */ #define PT_KILL 8 /* kill the child process */ #define PT_ATTACH 9 /* attach to running process */ #define PT_DETACH 10 /* detach from running process */ #define PT_IO 11 /* do I/O to/from the stopped process */ #define PT_DUMPCORE 12 /* make child generate a core dump */ #define PT_LWPINFO 13 /* get info about the LWP */ #define PT_SYSCALL 14 /* stop on syscall entry/exit */ #define PT_SYSCALLEMU 15 /* cancel syscall, tracer emulates it */ #define PT_SET_EVENT_MASK 16 /* set the event mask, defined below */ #define PT_GET_EVENT_MASK 17 /* get the event mask, defined below */ #define PT_GET_PROCESS_STATE 18 /* get process state, defined below */ #define PT_SET_SIGINFO 19 /* set signal state, defined below */ #define PT_GET_SIGINFO 20 /* get signal state, defined below */ #define PT_RESUME 21 /* allow execution of the LWP */ #define PT_SUSPEND 22 /* prevent execution of the LWP */ #define PT_STOP 23 /* stop the child process */ +#define PT_SET_THREAD_AREA 24 /* set thread private area pointer */ +#define PT_GET_THREAD_AREA 25 /* get thread private area pointer */ #define PT_FIRSTMACH 32 /* for machine-specific requests */ #include /* machine-specific requests, if any */ #define PT_STRINGS \ /* 0 */ "PT_TRACE_ME", \ /* 1 */ "PT_READ_I", \ /* 2 */ "PT_READ_D", \ /* 3 */ "*PT_INVALID_3*", \ /* 4 */ "PT_WRITE_I", \ /* 5 */ "PT_WRITE_D", \ /* 6 */ "*PT_INVALID_6*", \ /* 7 */ "PT_CONTINUE", \ /* 8 */ "PT_KILL", \ /* 9 */ "PT_ATTACH", \ /* 10 */ "PT_DETACH", \ /* 11 */ "PT_IO", \ /* 12 */ "PT_DUMPCORE", \ /* 13 */ "PT_LWPINFO", \ /* 14 */ "PT_SYSCALL", \ /* 15 */ "PT_SYSCALLEMU", \ /* 16 */ "PT_SET_EVENT_MASK", \ /* 17 */ "PT_GET_EVENT_MASK", \ /* 18 */ "PT_GET_PROCESS_STATE", \ /* 19 */ "PT_SET_SIGINFO", \ /* 20 */ "PT_GET_SIGINFO", \ /* 21 */ "PT_RESUME", \ -/* 22 */ "PT_SUSPEND", +/* 22 */ "PT_SUSPEND", \ +/* 23 */ "PT_STOP", \ +/* 24 */ "PT_SET_THREAD_AREA", \ +/* 25 */ "PT_GET_THREAD_AREA" /* PT_{G,S}EVENT_MASK */ typedef struct ptrace_event { int pe_set_event; } ptrace_event_t; /* PT_GET_PROCESS_STATE */ typedef struct ptrace_state { int pe_report_event; union { pid_t _pe_other_pid; lwpid_t _pe_lwp; } _option; } ptrace_state_t; #define pe_other_pid _option._pe_other_pid #define pe_lwp _option._pe_lwp #define PTRACE_FORK 0x0001 /* Report forks */ #define PTRACE_VFORK 0x0002 /* Report vforks */ #define PTRACE_VFORK_DONE 0x0004 /* Report parent resumed from vforks */ #define PTRACE_LWP_CREATE 0x0008 /* Report LWP creation */ #define PTRACE_LWP_EXIT 0x0010 /* Report LWP termination */ #define PTRACE_POSIX_SPAWN 0x0020 /* Report posix_spawn */ /* * Argument structure for PT_IO. */ struct ptrace_io_desc { int piod_op; /* I/O operation (see below) */ void *piod_offs; /* child offset */ void *piod_addr; /* parent offset */ size_t piod_len; /* request length (in)/actual count (out) */ }; /* piod_op */ #define PIOD_READ_D 1 /* read from D space */ #define PIOD_WRITE_D 2 /* write to D spcae */ #define PIOD_READ_I 3 /* read from I space */ #define PIOD_WRITE_I 4 /* write to I space */ #define PIOD_READ_AUXV 5 /* Read from aux array */ /* * Argument structure for PT_LWPINFO. */ struct ptrace_lwpinfo { lwpid_t pl_lwpid; /* LWP described */ int pl_event; /* Event that stopped the LWP */ /* Add fields at the end */ }; #define PL_EVENT_NONE 0 #define PL_EVENT_SIGNAL 1 #define PL_EVENT_SUSPENDED 2 /* * Signal Information structure */ typedef struct ptrace_siginfo { siginfo_t psi_siginfo; /* signal information structure */ lwpid_t psi_lwpid; /* destination LWP of the signal * value 0 means the whole process * (route signal to all LWPs) */ } ptrace_siginfo_t; #ifdef _KERNEL #if defined(PT_GETREGS) || defined(PT_SETREGS) struct reg; #ifndef process_reg32 #define process_reg32 struct reg #endif #ifndef process_reg64 #define process_reg64 struct reg #endif #endif #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) struct fpreg; #ifndef process_fpreg32 #define process_fpreg32 struct fpreg #endif #ifndef process_fpreg64 #define process_fpreg64 struct fpreg #endif #endif #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS) struct dbreg; #ifndef process_dbreg32 #define process_dbreg32 struct dbreg #endif #ifndef process_dbreg64 #define process_dbreg64 struct dbreg #endif #endif struct ptrace_methods { int (*ptm_copyin_piod)(struct ptrace_io_desc *, const void *, size_t); int (*ptm_copyout_piod)(const struct ptrace_io_desc *, void *, size_t); int (*ptm_copyin_siginfo)(struct ptrace_siginfo *, const void *, size_t); int (*ptm_copyout_siginfo)(const struct ptrace_siginfo *, void *, size_t); + int (*ptm_copyin_thread_area)(void *, void *); + int (*ptm_copyout_thread_area)(const void *, void *); int (*ptm_doregs)(struct lwp *, struct lwp *, struct uio *); int (*ptm_dofpregs)(struct lwp *, struct lwp *, struct uio *); int (*ptm_dodbregs)(struct lwp *, struct lwp *, struct uio *); }; int ptrace_init(void); int ptrace_fini(void); void ptrace_hooks(void); int process_doregs(struct lwp *, struct lwp *, struct uio *); int process_validregs(struct lwp *); int process_dofpregs(struct lwp *, struct lwp *, struct uio *); int process_validfpregs(struct lwp *); int process_dodbregs(struct lwp *, struct lwp *, struct uio *); int process_validdbregs(struct lwp *); int process_domem(struct lwp *, struct lwp *, struct uio *); void proc_stoptrace(int, int, const register_t[], const register_t *, int); void proc_reparent(struct proc *, struct proc *); void proc_changeparent(struct proc *, struct proc *); int do_ptrace(struct ptrace_methods *, struct lwp *, int, pid_t, void *, int, register_t *); /* * 64bit architectures that support 32bit emulation (amd64 and sparc64) * will #define process_read_regs32 to netbsd32_process_read_regs (etc). * In all other cases these #defines drop the size suffix. */ #ifdef PT_GETDBREGS int process_read_dbregs(struct lwp *, struct dbreg *, size_t *); #ifndef process_read_dbregs32 #define process_read_dbregs32 process_read_dbregs #endif #ifndef process_read_dbregs64 #define process_read_dbregs64 process_read_dbregs #endif #endif #ifdef PT_GETFPREGS int process_read_fpregs(struct lwp *, struct fpreg *, size_t *); #ifndef process_read_fpregs32 #define process_read_fpregs32 process_read_fpregs #endif #ifndef process_read_fpregs64 #define process_read_fpregs64 process_read_fpregs #endif #endif #ifdef PT_GETREGS int process_read_regs(struct lwp *, struct reg *); #ifndef process_read_regs32 #define process_read_regs32 process_read_regs #endif #ifndef process_read_regs64 #define process_read_regs64 process_read_regs #endif #endif int process_set_pc(struct lwp *, void *); int process_sstep(struct lwp *, int); #ifdef PT_SETDBREGS int process_write_dbregs(struct lwp *, const struct dbreg *, size_t); #ifndef process_write_dbregs32 #define process_write_dbregs32 process_write_dbregs #endif #ifndef process_write_dbregs64 #define process_write_dbregs64 process_write_dbregs #endif #endif #ifdef PT_SETFPREGS int process_write_fpregs(struct lwp *, const struct fpreg *, size_t); #ifndef process_write_fpregs32 #define process_write_fpregs32 process_write_fpregs #endif #ifndef process_write_fpregs64 #define process_write_fpregs64 process_write_fpregs #endif #endif #ifdef PT_SETREGS int process_write_regs(struct lwp *, const struct reg *); #ifndef process_write_regs32 #define process_write_regs32 process_write_regs #endif #ifndef process_write_regs64 #define process_write_regs64 process_write_regs #endif #endif int ptrace_machdep_dorequest(struct lwp *, struct lwp *, int, void *, int); #ifndef FIX_SSTEP #define FIX_SSTEP(p) #endif #else /* !_KERNEL */ #include __BEGIN_DECLS int ptrace(int _request, pid_t _pid, void *_addr, int _data); __END_DECLS #endif /* !_KERNEL */ #endif /* !_SYS_PTRACE_H_ */